diff options
Diffstat (limited to 'driver/xf86-video-intel')
66 files changed, 5756 insertions, 2432 deletions
diff --git a/driver/xf86-video-intel/Makefile.am b/driver/xf86-video-intel/Makefile.am index 2b6c46aa1..b2398a884 100644 --- a/driver/xf86-video-intel/Makefile.am +++ b/driver/xf86-video-intel/Makefile.am @@ -21,9 +21,5 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = src man -if BUILD_LINUXDOC -README: README.sgml - $(MAKE_TEXT) README.sgml && mv README.txt README -endif - -EXTRA_DIST = README.sgml +EXTRA_DIST = README +DISTCLEANFILES = doltcompile diff --git a/driver/xf86-video-intel/Makefile.in b/driver/xf86-video-intel/Makefile.in index 8033f66cc..90f83fb2a 100644 --- a/driver/xf86-video-intel/Makefile.in +++ b/driver/xf86-video-intel/Makefile.in @@ -61,7 +61,8 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ config.sub depcomp install-sh ltmain.sh missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -120,6 +121,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -156,6 +158,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ @@ -251,6 +255,7 @@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign SUBDIRS = src man EXTRA_DIST = README +DISTCLEANFILES = doltcompile all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -614,6 +619,7 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" diff --git a/driver/xf86-video-intel/acinclude.m4 b/driver/xf86-video-intel/acinclude.m4 new file mode 100644 index 000000000..254b35290 --- /dev/null +++ b/driver/xf86-video-intel/acinclude.m4 @@ -0,0 +1,140 @@ +dnl dolt, a replacement for libtool +dnl Copyright © 2007-2008 Josh Triplett <josh@freedesktop.org> +dnl Copying and distribution of this file, with or without modification, +dnl are permitted in any medium without royalty provided the copyright +dnl notice and this notice are preserved. +dnl +dnl To use dolt, invoke the DOLT macro immediately after the libtool macros. +dnl Optionally, copy this file into acinclude.m4, to avoid the need to have it +dnl installed when running autoconf on your project. +dnl +dnl git snapshot: d91f2b4e9041538400e2703a2a6fbeecdb8ee27d +AC_DEFUN([DOLT], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +# dolt, a replacement for libtool +# Josh Triplett <josh@freedesktop.org> +AC_PATH_PROG(DOLT_BASH, bash) +AC_MSG_CHECKING([if libtool sucks]) +AC_MSG_RESULT([yup, it does]) +AC_MSG_CHECKING([if dolt supports this host]) +dolt_supported=yes +if test x$DOLT_BASH = x; then + dolt_supported=no +fi +if test x$GCC != xyes; then + dolt_supported=no +fi +case $host in +i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*) ;; +amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*) ;; +*) dolt_supported=no ;; +esac +if test x$dolt_supported = xno ; then + AC_MSG_RESULT([no, falling back to libtool]) + LTCOMPILE='$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(COMPILE)' + LTCXXCOMPILE='$(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXXCOMPILE)' +else + AC_MSG_RESULT([yes, replacing libtool]) + +dnl Start writing out doltcompile. + cat <<__DOLTCOMPILE__EOF__ >doltcompile +#!$DOLT_BASH +__DOLTCOMPILE__EOF__ + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +args=("$[]@") +for ((arg=0; arg<${#args@<:@@@:>@}; arg++)) ; do + if test x"${args@<:@$arg@:>@}" = x-o ; then + objarg=$((arg+1)) + break + fi +done +if test x$objarg = x ; then + echo 'Error: no -o on compiler command line' 1>&2 + exit 1 +fi +lo="${args@<:@$objarg@:>@}" +obj="${lo%.lo}" +if test x"$lo" = x"$obj" ; then + echo "Error: libtool object file name \"$lo\" does not end in .lo" 1>&2 + exit 1 +fi +objbase="${obj##*/}" +__DOLTCOMPILE__EOF__ + +dnl Write out shared compilation code. + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +libobjdir="${obj%$objbase}.libs" +if test ! -d "$libobjdir" ; then + mkdir_out="$(mkdir "$libobjdir" 2>&1)" + mkdir_ret=$? + if test "$mkdir_ret" -ne 0 && test ! -d "$libobjdir" ; then + echo "$mkdir_out" 1>&2 + exit $mkdir_ret + fi +fi +pic_object="$libobjdir/$objbase.o" +args@<:@$objarg@:>@="$pic_object" +"${args@<:@@@:>@}" -fPIC -DPIC || exit $? +__DOLTCOMPILE__EOF__ + fi + +dnl Write out static compilation code. +dnl Avoid duplicate compiler output if also building shared objects. + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +non_pic_object="$obj.o" +args@<:@$objarg@:>@="$non_pic_object" +__DOLTCOMPILE__EOF__ + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args@<:@@@:>@}" >/dev/null 2>&1 || exit $? +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args@<:@@@:>@}" || exit $? +__DOLTCOMPILE__EOF__ + fi + fi + +dnl Write out the code to write the .lo file. +dnl The second line of the .lo file must match "^# Generated by .*libtool" + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +{ +echo "# $lo - a libtool object file" +echo "# Generated by doltcompile, not libtool" +__DOLTCOMPILE__EOF__ + + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "pic_object='$pic_object'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo pic_object=none +__DOLTCOMPILE__EOF__ + fi + + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "non_pic_object='$non_pic_object'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo non_pic_object=none +__DOLTCOMPILE__EOF__ + fi + + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +} > "$lo" +__DOLTCOMPILE__EOF__ + +dnl Done writing out doltcompile; substitute it for libtool compilation. + chmod +x doltcompile + LTCOMPILE='$(top_builddir)/doltcompile $(COMPILE)' + LTCXXCOMPILE='$(top_builddir)/doltcompile $(CXXCOMPILE)' +fi +AC_SUBST(LTCOMPILE) +AC_SUBST(LTCXXCOMPILE) +# end dolt +]) diff --git a/driver/xf86-video-intel/aclocal.m4 b/driver/xf86-video-intel/aclocal.m4 index 57908664b..317352482 100644 --- a/driver/xf86-video-intel/aclocal.m4 +++ b/driver/xf86-video-intel/aclocal.m4 @@ -8196,3 +8196,4 @@ AC_DEFUN([XORG_RELEASE_VERSION],[ [Patch version of this package]) ]) +m4_include([acinclude.m4]) diff --git a/driver/xf86-video-intel/configure b/driver/xf86-video-intel/configure index ffe08fa21..fd51f08d5 100644 --- a/driver/xf86-video-intel/configure +++ b/driver/xf86-video-intel/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for xf86-video-intel 2.3.2. +# Generated by GNU Autoconf 2.59 for xf86-video-intel 2.4.2. # # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>. # @@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='xf86-video-intel' PACKAGE_TARNAME='xf86-video-intel' -PACKAGE_VERSION='2.3.2' -PACKAGE_STRING='xf86-video-intel 2.3.2' +PACKAGE_VERSION='2.4.2' +PACKAGE_STRING='xf86-video-intel 2.4.2' PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg' ac_unique_file="Makefile.am" @@ -465,7 +465,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL gen4asm HAVE_GEN4ASM_TRUE HAVE_GEN4ASM_FALSE PKG_CONFIG ac_pt_PKG_CONFIG XORG_CFLAGS XORG_LIBS PCIACCESS_CFLAGS PCIACCESS_LIBS XSERVER_LIBPCIACCESS_TRUE XSERVER_LIBPCIACCESS_FALSE LIBPCIACCESS_TRUE LIBPCIACCESS_FALSE XMODES_TRUE XMODES_FALSE XMODES_CFLAGS DRI_TRUE DRI_FALSE DRI_CFLAGS DRI_LIBS DRI_MM_CFLAGS DRI_MM_LIBS VIDEO_DEBUG_TRUE VIDEO_DEBUG_FALSE XVMCLIB_CFLAGS XVMCLIB_LIBS XVMC_TRUE XVMC_FALSE WARN_CFLAGS moduledir DRIVER_NAME APP_MAN_SUFFIX LIB_MAN_SUFFIX FILE_MAN_SUFFIX MISC_MAN_SUFFIX DRIVER_MAN_SUFFIX ADMIN_MAN_SUFFIX APP_MAN_DIR LIB_MAN_DIR FILE_MAN_DIR MISC_MAN_DIR DRIVER_MAN_DIR ADMIN_MAN_DIR LINUXDOC PS2PDF BUILD_LINUXDOC_TRUE BUILD_LINUXDOC_FALSE BUILD_PDFDOC_TRUE BUILD_PDFDOC_FALSE MAKE_TEXT MAKE_PS MAKE_PDF MAKE_HTML LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL DOLT_BASH LTCOMPILE LTCXXCOMPILE gen4asm HAVE_GEN4ASM_TRUE HAVE_GEN4ASM_FALSE PKG_CONFIG ac_pt_PKG_CONFIG XORG_CFLAGS XORG_LIBS PCIACCESS_CFLAGS PCIACCESS_LIBS XSERVER_LIBPCIACCESS_TRUE XSERVER_LIBPCIACCESS_FALSE LIBPCIACCESS_TRUE LIBPCIACCESS_FALSE XMODES_TRUE XMODES_FALSE XMODES_CFLAGS DRI_TRUE DRI_FALSE DRI_CFLAGS DRI_LIBS DRI_MM_CFLAGS DRI_MM_LIBS VIDEO_DEBUG_TRUE VIDEO_DEBUG_FALSE XVMCLIB_CFLAGS XVMCLIB_LIBS XVMC_TRUE XVMC_FALSE WARN_CFLAGS moduledir DRIVER_NAME APP_MAN_SUFFIX LIB_MAN_SUFFIX FILE_MAN_SUFFIX MISC_MAN_SUFFIX DRIVER_MAN_SUFFIX ADMIN_MAN_SUFFIX APP_MAN_DIR LIB_MAN_DIR FILE_MAN_DIR MISC_MAN_DIR DRIVER_MAN_DIR ADMIN_MAN_DIR LINUXDOC PS2PDF BUILD_LINUXDOC_TRUE BUILD_LINUXDOC_FALSE BUILD_PDFDOC_TRUE BUILD_PDFDOC_FALSE MAKE_TEXT MAKE_PS MAKE_PDF MAKE_HTML LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -998,7 +998,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-intel 2.3.2 to adapt to many kinds of systems. +\`configure' configures xf86-video-intel 2.4.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1064,7 +1064,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xf86-video-intel 2.3.2:";; + short | recursive ) echo "Configuration of xf86-video-intel 2.4.2:";; esac cat <<\_ACEOF @@ -1231,7 +1231,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -xf86-video-intel configure 2.3.2 +xf86-video-intel configure 2.4.2 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -1245,7 +1245,7 @@ cat >&5 <<_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-intel $as_me 2.3.2, which was +It was created by xf86-video-intel $as_me 2.4.2, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1848,7 +1848,7 @@ fi # Define the identity of the package. PACKAGE='xf86-video-intel' - VERSION='2.3.2' + VERSION='2.4.2' cat >>confdefs.h <<_ACEOF @@ -19080,6 +19080,171 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + +# dolt, a replacement for libtool +# Josh Triplett <josh@freedesktop.org> +# Extract the first word of "bash", so it can be a program name with args. +set dummy bash; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_DOLT_BASH+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $DOLT_BASH in + [\\/]* | ?:[\\/]*) + ac_cv_path_DOLT_BASH="$DOLT_BASH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DOLT_BASH="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +DOLT_BASH=$ac_cv_path_DOLT_BASH + +if test -n "$DOLT_BASH"; then + echo "$as_me:$LINENO: result: $DOLT_BASH" >&5 +echo "${ECHO_T}$DOLT_BASH" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +echo "$as_me:$LINENO: checking if libtool sucks" >&5 +echo $ECHO_N "checking if libtool sucks... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: yup, it does" >&5 +echo "${ECHO_T}yup, it does" >&6 +echo "$as_me:$LINENO: checking if dolt supports this host" >&5 +echo $ECHO_N "checking if dolt supports this host... $ECHO_C" >&6 +dolt_supported=yes +if test x$DOLT_BASH = x; then + dolt_supported=no +fi +if test x$GCC != xyes; then + dolt_supported=no +fi +case $host in +i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*) ;; +amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*) ;; +*) dolt_supported=no ;; +esac +if test x$dolt_supported = xno ; then + echo "$as_me:$LINENO: result: no, falling back to libtool" >&5 +echo "${ECHO_T}no, falling back to libtool" >&6 + LTCOMPILE='$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(COMPILE)' + LTCXXCOMPILE='$(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXXCOMPILE)' +else + echo "$as_me:$LINENO: result: yes, replacing libtool" >&5 +echo "${ECHO_T}yes, replacing libtool" >&6 + + cat <<__DOLTCOMPILE__EOF__ >doltcompile +#!$DOLT_BASH +__DOLTCOMPILE__EOF__ + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +args=("$@") +for ((arg=0; arg<${#args[@]}; arg++)) ; do + if test x"${args[$arg]}" = x-o ; then + objarg=$((arg+1)) + break + fi +done +if test x$objarg = x ; then + echo 'Error: no -o on compiler command line' 1>&2 + exit 1 +fi +lo="${args[$objarg]}" +obj="${lo%.lo}" +if test x"$lo" = x"$obj" ; then + echo "Error: libtool object file name \"$lo\" does not end in .lo" 1>&2 + exit 1 +fi +objbase="${obj##*/}" +__DOLTCOMPILE__EOF__ + + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +libobjdir="${obj%$objbase}.libs" +if test ! -d "$libobjdir" ; then + mkdir_out="$(mkdir "$libobjdir" 2>&1)" + mkdir_ret=$? + if test "$mkdir_ret" -ne 0 && test ! -d "$libobjdir" ; then + echo "$mkdir_out" 1>&2 + exit $mkdir_ret + fi +fi +pic_object="$libobjdir/$objbase.o" +args[$objarg]="$pic_object" +"${args[@]}" -fPIC -DPIC || exit $? +__DOLTCOMPILE__EOF__ + fi + + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +non_pic_object="$obj.o" +args[$objarg]="$non_pic_object" +__DOLTCOMPILE__EOF__ + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args[@]}" >/dev/null 2>&1 || exit $? +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args[@]}" || exit $? +__DOLTCOMPILE__EOF__ + fi + fi + + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +{ +echo "# $lo - a libtool object file" +echo "# Generated by doltcompile, not libtool" +__DOLTCOMPILE__EOF__ + + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "pic_object='$pic_object'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo pic_object=none +__DOLTCOMPILE__EOF__ + fi + + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "non_pic_object='$non_pic_object'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo non_pic_object=none +__DOLTCOMPILE__EOF__ + fi + + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +} > "$lo" +__DOLTCOMPILE__EOF__ + + chmod +x doltcompile + LTCOMPILE='$(top_builddir)/doltcompile $(COMPILE)' + LTCXXCOMPILE='$(top_builddir)/doltcompile $(CXXCOMPILE)' +fi + + +# end dolt + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -21068,9 +21233,7 @@ _ACEOF fi -echo "$as_me:$LINENO: checking whether to include DRI support" >&5 -echo $ECHO_N "checking whether to include DRI support... $ECHO_C" >&6 -if test x$DRI = xauto; then +if test x$DRI != xno; then as_ac_File=`echo "ac_cv_file_${sdkdir}/dri.h" | $as_tr_sh` echo "$as_me:$LINENO: checking for ${sdkdir}/dri.h" >&5 echo $ECHO_N "checking for ${sdkdir}/dri.h... $ECHO_C" >&6 @@ -21167,7 +21330,10 @@ else have_damage_h="no" fi - +fi +echo "$as_me:$LINENO: checking whether to include DRI support" >&5 +echo $ECHO_N "checking whether to include DRI support... $ECHO_C" >&6 +if test x$DRI = xauto; then if test "$have_dri_h" = yes -a \ "$have_sarea_h" = yes -a \ "$have_dristruct_h" = yes; then @@ -22833,7 +22999,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by xf86-video-intel $as_me 2.3.2, which was +This file was extended by xf86-video-intel $as_me 2.4.2, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -22896,7 +23062,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -xf86-video-intel config.status 2.3.2 +xf86-video-intel config.status 2.4.2 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -23177,6 +23343,9 @@ s,@F77@,$F77,;t t s,@FFLAGS@,$FFLAGS,;t t s,@ac_ct_F77@,$ac_ct_F77,;t t s,@LIBTOOL@,$LIBTOOL,;t t +s,@DOLT_BASH@,$DOLT_BASH,;t t +s,@LTCOMPILE@,$LTCOMPILE,;t t +s,@LTCXXCOMPILE@,$LTCXXCOMPILE,;t t s,@gen4asm@,$gen4asm,;t t s,@HAVE_GEN4ASM_TRUE@,$HAVE_GEN4ASM_TRUE,;t t s,@HAVE_GEN4ASM_FALSE@,$HAVE_GEN4ASM_FALSE,;t t diff --git a/driver/xf86-video-intel/configure.ac b/driver/xf86-video-intel/configure.ac index 796b829f4..809e84d8b 100644 --- a/driver/xf86-video-intel/configure.ac +++ b/driver/xf86-video-intel/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-intel], - 2.3.2, + 2.4.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) @@ -37,6 +37,7 @@ AM_MAINTAINER_MODE # Checks for programs. AC_DISABLE_STATIC AC_PROG_LIBTOOL +DOLT AC_PROG_CC AM_PROG_CC_C_O @@ -90,8 +91,7 @@ sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for header files. AC_HEADER_STDC -AC_MSG_CHECKING([whether to include DRI support]) -if test x$DRI = xauto; then +if test x$DRI != xno; then AC_CHECK_FILE([${sdkdir}/dri.h], [have_dri_h="yes"], [have_dri_h="no"]) AC_CHECK_FILE([${sdkdir}/sarea.h], @@ -100,7 +100,9 @@ if test x$DRI = xauto; then [have_dristruct_h="yes"], [have_dristruct_h="no"]) AC_CHECK_FILE([${sdkdir}/damage.h], [have_damage_h="yes"], [have_damage_h="no"]) - +fi +AC_MSG_CHECKING([whether to include DRI support]) +if test x$DRI = xauto; then if test "$have_dri_h" = yes -a \ "$have_sarea_h" = yes -a \ "$have_dristruct_h" = yes; then diff --git a/driver/xf86-video-intel/man/Makefile.in b/driver/xf86-video-intel/man/Makefile.in index 47e3cfa08..33b2c3c0e 100644 --- a/driver/xf86-video-intel/man/Makefile.in +++ b/driver/xf86-video-intel/man/Makefile.in @@ -65,7 +65,8 @@ host_triplet = @host@ subdir = man DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -112,6 +113,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -148,6 +150,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/Makefile.am b/driver/xf86-video-intel/src/Makefile.am index 19ed8fd0a..6507a2b07 100644 --- a/driver/xf86-video-intel/src/Makefile.am +++ b/driver/xf86-video-intel/src/Makefile.am @@ -36,6 +36,10 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \ intel_drv_la_LTLIBRARIES = intel_drv.la intel_drv_la_LDFLAGS = -module -avoid-version intel_drv_ladir = @moduledir@/drivers +intel_drv_la_LIBADD = +if XSERVER_LIBPCIACCESS +intel_drv_la_LIBADD += @PCIACCESS_LIBS@ +endif XMODE_SRCS=\ local_xf86Rename.h \ @@ -100,6 +104,7 @@ intel_drv_la_SOURCES = \ i830_driver.c \ i830_dvo.c \ i830.h \ + i830_hdmi.c \ i830_i2c.c \ i830_io.c \ i830_lvds.c \ @@ -133,6 +138,7 @@ INTEL_G4A = \ exa_wm_src_projective.g4a \ exa_wm_src_sample_argb.g4a \ exa_wm_src_sample_a.g4a \ + exa_wm_src_sample_planar.g4a \ exa_wm_mask_affine.g4a \ exa_wm_mask_projective.g4a \ exa_wm_mask_sample_argb.g4a \ @@ -141,6 +147,7 @@ INTEL_G4A = \ exa_wm_ca.g4a \ exa_wm_ca_srcalpha.g4a \ exa_wm_write.g4a \ + exa_wm_yuv_rgb.g4a \ exa_wm_xy.g4a INTEL_G4I = \ @@ -158,6 +165,7 @@ INTEL_G4B = \ exa_wm_src_projective.g4b \ exa_wm_src_sample_argb.g4b \ exa_wm_src_sample_a.g4b \ + exa_wm_src_sample_planar.g4b \ exa_wm_mask_affine.g4b \ exa_wm_mask_projective.g4b \ exa_wm_mask_sample_argb.g4b \ @@ -166,6 +174,7 @@ INTEL_G4B = \ exa_wm_ca.g4b \ exa_wm_ca_srcalpha.g4b \ exa_wm_write.g4b \ + exa_wm_yuv_rgb.g4b \ exa_wm_xy.g4b EXTRA_DIST = \ @@ -180,7 +189,7 @@ if HAVE_GEN4ASM SUFFIXES = .g4a .g4b .g4a.g4b: - m4 -s $*.g4a > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m + m4 -I$(srcdir) -s $< > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m $(INTEL_G4B): $(INTEL_G4I) @@ -198,6 +207,8 @@ endif if DRI intel_drv_la_SOURCES += \ $(INTEL_DRI_SRCS) +intel_drv_la_LIBADD += \ + $(DRI_LIBS) endif if XVMC diff --git a/driver/xf86-video-intel/src/Makefile.in b/driver/xf86-video-intel/src/Makefile.in index 4dcf0fd73..c78fb3592 100644 --- a/driver/xf86-video-intel/src/Makefile.in +++ b/driver/xf86-video-intel/src/Makefile.in @@ -56,19 +56,24 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@XMODES_TRUE@am__append_1 = \ +@XSERVER_LIBPCIACCESS_TRUE@am__append_1 = @PCIACCESS_LIBS@ +@XMODES_TRUE@am__append_2 = \ @XMODES_TRUE@ $(XMODE_SRCS) -@DRI_TRUE@am__append_2 = \ +@DRI_TRUE@am__append_3 = \ @DRI_TRUE@ $(INTEL_DRI_SRCS) -@XVMC_TRUE@am__append_3 = \ +@DRI_TRUE@am__append_4 = \ +@DRI_TRUE@ $(DRI_LIBS) + +@XVMC_TRUE@am__append_5 = \ @XVMC_TRUE@ $(INTEL_XVMC_SRCS) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -83,19 +88,22 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(intel_drv_ladir)" intel_drv_laLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(intel_drv_la_LTLIBRARIES) -intel_drv_la_LIBADD = +am__DEPENDENCIES_1 = +@DRI_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +intel_drv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) am__intel_drv_la_SOURCES_DIST = brw_defines.h brw_structs.h common.h \ i2c_vid.h i810_accel.c i810_common.h i810_cursor.c i810_dga.c \ i810_driver.c i810.h i810_io.c i810_memory.c i810_reg.h \ i810_ring.h i810_video.c i810_wmark.c i830_3d.c i830_accel.c \ i830_bios.c i830_bios.h i830_common.h i830_crt.c i830_cursor.c \ i830_debug.c i830_debug.h i830_display.c i830_display.h \ - i830_quirks.c i830_driver.c i830_dvo.c i830.h i830_i2c.c \ - i830_io.c i830_lvds.c i830_memory.c i830_modes.c i830_video.c \ - i830_video.h i830_reg.h i830_ring.h i830_sdvo.c i830_sdvo.h \ - i830_sdvo_regs.h i830_tv.c i915_3d.c i915_3d.h i915_reg.h \ - i915_video.c i965_video.c i830_exa.c i830_xaa.c i830_render.c \ - i915_render.c i965_render.c local_xf86Rename.h \ + i830_quirks.c i830_driver.c i830_dvo.c i830.h i830_hdmi.c \ + i830_i2c.c i830_io.c i830_lvds.c i830_memory.c i830_modes.c \ + i830_video.c i830_video.h i830_reg.h i830_ring.h i830_sdvo.c \ + i830_sdvo.h i830_sdvo_regs.h i830_tv.c i915_3d.c i915_3d.h \ + i915_reg.h i915_video.c i965_video.c i830_exa.c i830_xaa.c \ + i830_render.c i915_render.c i965_render.c local_xf86Rename.h \ parser/xf86Parser.h parser/xf86Optrec.h modes/xf86Modes.h \ modes/xf86Modes.c modes/xf86cvt.c modes/xf86Crtc.h \ modes/xf86Crtc.c modes/xf86Cursors.c modes/xf86EdidModes.c \ @@ -114,11 +122,11 @@ am_intel_drv_la_OBJECTS = i810_accel.lo i810_cursor.lo i810_dga.lo \ i810_driver.lo i810_io.lo i810_memory.lo i810_video.lo \ i810_wmark.lo i830_3d.lo i830_accel.lo i830_bios.lo \ i830_crt.lo i830_cursor.lo i830_debug.lo i830_display.lo \ - i830_quirks.lo i830_driver.lo i830_dvo.lo i830_i2c.lo \ - i830_io.lo i830_lvds.lo i830_memory.lo i830_modes.lo \ - i830_video.lo i830_sdvo.lo i830_tv.lo i915_3d.lo i915_video.lo \ - i965_video.lo i830_exa.lo i830_xaa.lo i830_render.lo \ - i915_render.lo i965_render.lo $(am__objects_2) \ + i830_quirks.lo i830_driver.lo i830_dvo.lo i830_hdmi.lo \ + i830_i2c.lo i830_io.lo i830_lvds.lo i830_memory.lo \ + i830_modes.lo i830_video.lo i830_sdvo.lo i830_tv.lo i915_3d.lo \ + i915_video.lo i965_video.lo i830_exa.lo i830_xaa.lo \ + i830_render.lo i915_render.lo i965_render.lo $(am__objects_2) \ $(am__objects_4) $(am__objects_6) intel_drv_la_OBJECTS = $(am_intel_drv_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -126,9 +134,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -174,6 +179,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -210,6 +216,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ @@ -316,6 +324,7 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \ intel_drv_la_LTLIBRARIES = intel_drv.la intel_drv_la_LDFLAGS = -module -avoid-version intel_drv_ladir = @moduledir@/drivers +intel_drv_la_LIBADD = $(am__append_1) $(am__append_4) XMODE_SRCS = \ local_xf86Rename.h \ parser/xf86Parser.h \ @@ -352,13 +361,13 @@ intel_drv_la_SOURCES = brw_defines.h brw_structs.h common.h i2c_vid.h \ i810_ring.h i810_video.c i810_wmark.c i830_3d.c i830_accel.c \ i830_bios.c i830_bios.h i830_common.h i830_crt.c i830_cursor.c \ i830_debug.c i830_debug.h i830_display.c i830_display.h \ - i830_quirks.c i830_driver.c i830_dvo.c i830.h i830_i2c.c \ - i830_io.c i830_lvds.c i830_memory.c i830_modes.c i830_video.c \ - i830_video.h i830_reg.h i830_ring.h i830_sdvo.c i830_sdvo.h \ - i830_sdvo_regs.h i830_tv.c i915_3d.c i915_3d.h i915_reg.h \ - i915_video.c i965_video.c i830_exa.c i830_xaa.c i830_render.c \ - i915_render.c i965_render.c $(am__append_1) $(am__append_2) \ - $(am__append_3) + i830_quirks.c i830_driver.c i830_dvo.c i830.h i830_hdmi.c \ + i830_i2c.c i830_io.c i830_lvds.c i830_memory.c i830_modes.c \ + i830_video.c i830_video.h i830_reg.h i830_ring.h i830_sdvo.c \ + i830_sdvo.h i830_sdvo_regs.h i830_tv.c i915_3d.c i915_3d.h \ + i915_reg.h i915_video.c i965_video.c i830_exa.c i830_xaa.c \ + i830_render.c i915_render.c i965_render.c $(am__append_2) \ + $(am__append_3) $(am__append_5) INTEL_G4A = \ packed_yuv_sf.g4a \ packed_yuv_wm.g4a \ @@ -368,6 +377,7 @@ INTEL_G4A = \ exa_wm_src_projective.g4a \ exa_wm_src_sample_argb.g4a \ exa_wm_src_sample_a.g4a \ + exa_wm_src_sample_planar.g4a \ exa_wm_mask_affine.g4a \ exa_wm_mask_projective.g4a \ exa_wm_mask_sample_argb.g4a \ @@ -376,6 +386,7 @@ INTEL_G4A = \ exa_wm_ca.g4a \ exa_wm_ca_srcalpha.g4a \ exa_wm_write.g4a \ + exa_wm_yuv_rgb.g4a \ exa_wm_xy.g4a INTEL_G4I = \ @@ -392,6 +403,7 @@ INTEL_G4B = \ exa_wm_src_projective.g4b \ exa_wm_src_sample_argb.g4b \ exa_wm_src_sample_a.g4b \ + exa_wm_src_sample_planar.g4b \ exa_wm_mask_affine.g4b \ exa_wm_mask_projective.g4b \ exa_wm_mask_sample_argb.g4b \ @@ -400,6 +412,7 @@ INTEL_G4B = \ exa_wm_ca.g4b \ exa_wm_ca_srcalpha.g4b \ exa_wm_write.g4b \ + exa_wm_yuv_rgb.g4b \ exa_wm_xy.g4b EXTRA_DIST = \ @@ -503,6 +516,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_driver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_dvo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_exa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_hdmi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_hwmc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_i2c.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_io.Plo@am__quote@ @@ -898,7 +912,7 @@ uninstall-info: uninstall-info-recursive uninstall-intel_drv_laLTLIBRARIES @HAVE_GEN4ASM_TRUE@.g4a.g4b: -@HAVE_GEN4ASM_TRUE@ m4 -s $*.g4a > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m +@HAVE_GEN4ASM_TRUE@ m4 -I$(srcdir) -s $< > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m @HAVE_GEN4ASM_TRUE@$(INTEL_G4B): $(INTEL_G4I) diff --git a/driver/xf86-video-intel/src/bios_reader/Makefile.in b/driver/xf86-video-intel/src/bios_reader/Makefile.in index 62bd96a59..8b7fe1b22 100644 --- a/driver/xf86-video-intel/src/bios_reader/Makefile.in +++ b/driver/xf86-video-intel/src/bios_reader/Makefile.in @@ -40,7 +40,8 @@ noinst_PROGRAMS = bios_reader$(EXEEXT) $(am__EXEEXT_1) subdir = src/bios_reader DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -61,9 +62,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -101,6 +99,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -137,6 +136,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/bios_reader/bios_reader.c b/driver/xf86-video-intel/src/bios_reader/bios_reader.c index ffa27f033..dbcd15038 100644 --- a/driver/xf86-video-intel/src/bios_reader/bios_reader.c +++ b/driver/xf86-video-intel/src/bios_reader/bios_reader.c @@ -25,11 +25,17 @@ * */ +#include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> #include <sys/types.h> + #include "../i830_bios.h" #define _PARSE_EDID_ @@ -51,108 +57,223 @@ struct _fake_i830 *pI830 = &I830; (pI830->VBIOS[_addr + 2] << 16) \ (pI830->VBIOS[_addr + 3] << 24)) +#define YESNO(val) ((val) ? "yes" : "no") + +static int tv_present; +static int lvds_present; +static int panel_type; + +static void *find_section(struct bdb_header *bdb, int section_id) +{ + unsigned char *base = (unsigned char *)bdb; + int index = 0; + uint16_t total, current_size; + unsigned char current_id; + + /* skip to first section */ + index += bdb->header_size; + total = bdb->bdb_size; + + /* walk the sections looking for section_id */ + while (index < total) { + current_id = *(base + index); + index++; + current_size = *((uint16_t *)(base + index)); + index += 2; + if (current_id == section_id) + return base + index; + index += current_size; + } + + return NULL; +} + +static void dump_general_features(void *data) +{ + struct bdb_general_features *features = data; + + if (!data) + return; + + printf("General features block:\n"); + + printf("\tPanel fitting: "); + switch (features->panel_fitting) { + case 0: + printf("disabled\n"); + break; + case 1: + printf("text only\n"); + break; + case 2: + printf("graphics only\n"); + break; + case 3: + printf("text & graphics\n"); + break; + } + printf("\tFlexaim: %s\n", YESNO(features->flexaim)); + printf("\tMessage: %s\n", YESNO(features->msg_enable)); + printf("\tClear screen: %d\n", features->clear_screen); + printf("\tDVO color flip required: %s\n", YESNO(features->color_flip)); + printf("\tExternal VBT: %s\n", YESNO(features->download_ext_vbt)); + printf("\tEnable SSC: %s\n", YESNO(features->enable_ssc)); + if (features->enable_ssc) + printf("\tSSC frequency: %s\n", features->ssc_freq ? + "100 MHz (66 MHz on 855)" : "96 MHz (48 MHz on 855)"); + printf("\tLFP on override: %s\n", YESNO(features->enable_lfp_on_override)); + printf("\tDisable SSC on clone: %s\n", YESNO(features->disable_ssc_ddt)); + printf("\tDisable smooth vision: %s\n", + YESNO(features->disable_smooth_vision)); + printf("\tSingle DVI for CRT/DVI: %s\n", YESNO(features->single_dvi)); + printf("\tLegacy monitor detect: %s\n", + YESNO(features->legacy_monitor_detect)); + printf("\tIntegrated CRT: %s\n", YESNO(features->int_crt_support)); + printf("\tIntegrated TV: %s\n", YESNO(features->int_tv_support)); + + tv_present = 1; /* should be based on whether TV DAC exists */ + lvds_present = 1; /* should be based on IS_MOBILE() */ +} + +static void dump_general_definitions(void *data) +{ + struct bdb_general_definitions *defs = data; + unsigned char *lvds_data = defs->tv_or_lvds_info; + + if (!data) + return; + + printf("General definitions block:\n"); + + printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin); + printf("\tUse ACPI DPMS CRT power states: %s\n", YESNO(defs->dpms_acpi)); + printf("\tSkip CRT detect at boot: %s\n", + YESNO(defs->skip_boot_crt_detect)); + printf("\tUse DPMS on AIM devices: %s\n", YESNO(defs->dpms_aim)); + printf("\tBoot display type: 0x%02x%02x\n", defs->boot_display[1], + defs->boot_display[0]); + printf("\tTV data block present: %s\n", YESNO(tv_present)); + if (tv_present) + lvds_data += 33; + if (lvds_present) + printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]); +} + +static void dump_lvds_options(void *data) +{ + struct bdb_lvds_options *options = data; + + if (!data) + return; + + printf("LVDS options block:\n"); + + panel_type = options->panel_type; + printf("\tPanel type: %d\n", panel_type); + printf("\tLVDS EDID available: %s\n", YESNO(options->lvds_edid)); + printf("\tPixel dither: %s\n", YESNO(options->pixel_dither)); + printf("\tPFIT auto ratio: %s\n", YESNO(options->pfit_ratio_auto)); + printf("\tPFIT enhanced graphics mode: %s\n", + YESNO(options->pfit_gfx_mode_enhanced)); + printf("\tPFIT enhanced text mode: %s\n", + YESNO(options->pfit_text_mode_enhanced)); + printf("\tPFIT mode: %d\n", options->pfit_mode); +} + +static void dump_lvds_data(void *data, unsigned char *base) +{ + struct bdb_lvds_lfp_data *lvds_data = data; + int i; + + if (!data) + return; + + printf("LVDS panel data block (preferred block marked with '*'):\n"); + + for (i = 0; i < 16; i++) { + struct bdb_lvds_lfp_data_entry *lfp_data = &lvds_data->data[i]; + uint8_t *timing_data = (uint8_t *)&lfp_data->dvo_timing; + char marker; + + if (i == panel_type) + marker = '*'; + else + marker = ' '; + + printf("%c\tpanel type %02i: %dx%d clock %d\n", marker, + i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res, + _PIXEL_CLOCK(timing_data)); + printf("\t\ttimings: %d %d %d %d %d %d %d %d\n", + _H_ACTIVE(timing_data), + _H_BLANK(timing_data), + _H_SYNC_OFF(timing_data), + _H_SYNC_WIDTH(timing_data), + _V_ACTIVE(timing_data), + _V_BLANK(timing_data), + _V_SYNC_OFF(timing_data), + _V_SYNC_WIDTH(timing_data)); + } + +} + int main(int argc, char **argv) { - FILE *f; - int bios_size = 65536; - struct vbt_header *vbt; + int fd; + struct vbt_header *vbt = NULL; struct bdb_header *bdb; - int vbt_off, bdb_off, bdb_block_off, block_size; - int panel_type = -1, i; + int vbt_off, bdb_off, i; char *filename = "bios"; + struct stat finfo; - if (argc == 2) - filename = argv[1]; + if (argc != 2) { + printf("usage: %s <rom file>\n", argv[0]); + return 1; + } + + filename = argv[1]; - f = fopen(filename, "r"); - if (!f) { - printf("Couldn't open %s\n", filename); + fd = open(filename, O_RDONLY); + if (fd == -1) { + printf("Couldn't open \"%s\": %s\n", filename, strerror(errno)); return 1; } - pI830->VBIOS = calloc(1, bios_size); - if (fread(pI830->VBIOS, 1, bios_size, f) != bios_size) + if (stat(filename, &finfo)) { + printf("failed to stat \"%s\": %s\n", filename, strerror(errno)); return 1; + } + + pI830->VBIOS = mmap(NULL, finfo.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (pI830->VBIOS == MAP_FAILED) { + printf("failed to map \"%s\": %s\n", filename, strerror(errno)); + return 1; + } + + /* Scour memory looking for the VBT signature */ + for (i = 0; i + 4 < finfo.st_size; i++) { + if (!memcmp(pI830->VBIOS + i, "$VBT", 4)) { + vbt_off = i; + vbt = (struct vbt_header *)(pI830->VBIOS + i); + break; + } + } + + if (!vbt) { + printf("VBT signature missing\n"); + return 1; + } - vbt_off = INTEL_BIOS_16(0x1a); - printf("VBT offset: %08x\n", vbt_off); - vbt = (struct vbt_header *)(pI830->VBIOS + vbt_off); - printf("VBT sig: %20s\n", vbt->signature); printf("VBT vers: %d.%d\n", vbt->version / 100, vbt->version % 100); bdb_off = vbt_off + vbt->bdb_offset; bdb = (struct bdb_header *)(pI830->VBIOS + bdb_off); printf("BDB sig: %16s\n", bdb->signature); printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100); - for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size; - bdb_block_off += block_size) - { - int start = bdb_off + bdb_block_off; - int id; - struct lvds_bdb_1 *lvds1; - struct lvds_bdb_2 *lvds2; - struct lvds_bdb_2_fp_params *fpparam; - struct lvds_bdb_2_fp_edid_dtd *fptiming; - uint8_t *timing_ptr; - - id = INTEL_BIOS_8(start); - block_size = INTEL_BIOS_16(start + 1) + 3; - printf("BDB block type %03d size %d\n", id, block_size); - switch (id) { - case 40: - lvds1 = (struct lvds_bdb_1 *)(pI830->VBIOS + start); - panel_type = lvds1->panel_type; - printf("Panel type: %d, caps %04x\n", panel_type, lvds1->caps); - break; - case 41: - if (panel_type == -1) { - printf("Found panel block with no panel type\n"); - break; - } - - lvds2 = (struct lvds_bdb_2 *)(pI830->VBIOS + start); - - printf("Entries per table: %d\n", lvds2->table_size); - for (i = 0; i < 16; i++) { - char marker; - fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS + - bdb_off + lvds2->panels[i].fp_params_offset); - fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(pI830->VBIOS + - bdb_off + lvds2->panels[i].fp_edid_dtd_offset); - timing_ptr = pI830->VBIOS + bdb_off + - lvds2->panels[i].fp_edid_dtd_offset; - if (fpparam->terminator != 0xffff) { - /* Apparently the offsets are wrong for some BIOSes, so we - * try the other offsets if we find a bad terminator. - */ - fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS + - bdb_off + lvds2->panels[i].fp_params_offset + 8); - fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(pI830->VBIOS + - bdb_off + lvds2->panels[i].fp_edid_dtd_offset + 8); - timing_ptr = pI830->VBIOS + bdb_off + - lvds2->panels[i].fp_edid_dtd_offset + 8; - - if (fpparam->terminator != 0xffff) - continue; - } - if (i == panel_type) - marker = '*'; - else - marker = ' '; - printf("%c Panel index %02i xres %d yres %d clock %d\n", marker, - i, fpparam->x_res, fpparam->y_res, - _PIXEL_CLOCK(timing_ptr)); - printf(" %d %d %d %d %d %d %d %d\n", - _H_ACTIVE(timing_ptr), _H_BLANK(timing_ptr), - _H_SYNC_OFF(timing_ptr), _H_SYNC_WIDTH(timing_ptr), - _V_ACTIVE(timing_ptr), _V_BLANK(timing_ptr), - _V_SYNC_OFF(timing_ptr), _V_SYNC_WIDTH(timing_ptr)); - } - - printf("Panel of size %dx%d\n", fpparam->x_res, fpparam->y_res); - break; - } - } + + dump_general_features(find_section(bdb, BDB_GENERAL_FEATURES)); + dump_general_definitions(find_section(bdb, BDB_GENERAL_DEFINITIONS)); + dump_lvds_options(find_section(bdb, BDB_LVDS_OPTIONS)); + dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), bdb); return 0; } diff --git a/driver/xf86-video-intel/src/ch7017/Makefile.in b/driver/xf86-video-intel/src/ch7017/Makefile.in index 63a298f2a..b8cdc8d90 100644 --- a/driver/xf86-video-intel/src/ch7017/Makefile.in +++ b/driver/xf86-video-intel/src/ch7017/Makefile.in @@ -39,7 +39,8 @@ host_triplet = @host@ subdir = src/ch7017 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -62,9 +63,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -102,6 +100,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -138,6 +137,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/ch7xxx/Makefile.in b/driver/xf86-video-intel/src/ch7xxx/Makefile.in index 082cde2dd..5ea4410e3 100644 --- a/driver/xf86-video-intel/src/ch7xxx/Makefile.in +++ b/driver/xf86-video-intel/src/ch7xxx/Makefile.in @@ -39,7 +39,8 @@ host_triplet = @host@ subdir = src/ch7xxx DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -62,9 +63,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -102,6 +100,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -138,6 +137,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/common.h b/driver/xf86-video-intel/src/common.h index 9a3e0ac3d..f2ae502b2 100644 --- a/driver/xf86-video-intel/src/common.h +++ b/driver/xf86-video-intel/src/common.h @@ -303,9 +303,24 @@ extern int I810_DEBUG; #define PCI_CHIP_Q33_G_BRIDGE 0x29D0 #endif -#ifndef PCI_CHIP_IGD_GM -#define PCI_CHIP_IGD_GM 0x2A42 -#define PCI_CHIP_IGD_GM_BRIDGE 0x2A40 +#ifndef PCI_CHIP_GM45_GM +#define PCI_CHIP_GM45_GM 0x2A42 +#define PCI_CHIP_GM45_BRIDGE 0x2A40 +#endif + +#ifndef PCI_CHIP_IGD_E_G +#define PCI_CHIP_IGD_E_G 0x2E02 +#define PCI_CHIP_IGD_E_G_BRIDGE 0x2E00 +#endif + +#ifndef PCI_CHIP_G45_G +#define PCI_CHIP_G45_G 0x2E22 +#define PCI_CHIP_G45_G_BRIDGE 0x2E20 +#endif + +#ifndef PCI_CHIP_Q45_G +#define PCI_CHIP_Q45_G 0x2E12 +#define PCI_CHIP_Q45_G_BRIDGE 0x2E10 #endif #if XSERVER_LIBPCIACCESS @@ -339,19 +354,28 @@ extern int I810_DEBUG; #define IS_I915GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_GM) #define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G) #define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME) -#define IS_IGD_GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_GM) +#define IS_GM45(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_GM45_GM) +#define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G) #define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME) -#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_IGD_GM(pI810)) +#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_GM45(pI810) || IS_G4X(pI810)) #define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G) #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810)) +#define IS_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810)) -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810)) +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_GM45(pI810)) /* mark chipsets for using gfx VM offset for overlay */ #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810)) +/* mark chipsets without overlay hw */ +#define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) /* chipsets require graphics mem for hardware status page */ -#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810)) +#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810)) +/* chipsets require status page in non stolen memory */ +#define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) +#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) +/* dsparb controlled by hw only */ +#define DSPARB_HWCONTROL(pI810) (IS_G4X(pI810) || IS_GM45(pI810)) #define GTT_PAGE_SIZE KB(4) #define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) diff --git a/driver/xf86-video-intel/src/exa_wm.g4i b/driver/xf86-video-intel/src/exa_wm.g4i index ee8e3ad03..5d3d45b1b 100644 --- a/driver/xf86-video-intel/src/exa_wm.g4i +++ b/driver/xf86-video-intel/src/exa_wm.g4i @@ -103,23 +103,39 @@ define(`mask_w_1', `src_w_1') /* sample src to these registers */ define(`src_sample_base', `g14') + +define(`src_sample_r', `g14') define(`src_sample_r_01', `g14') define(`src_sample_r_23', `g15') + +define(`src_sample_g', `g16') define(`src_sample_g_01', `g16') define(`src_sample_g_23', `g17') + +define(`src_sample_b', `g18') define(`src_sample_b_01', `g18') define(`src_sample_b_23', `g19') + +define(`src_sample_a', `g20') define(`src_sample_a_01', `g20') define(`src_sample_a_23', `g21') /* sample mask to these registers */ define(`mask_sample_base', `g22') + +define(`mask_sample_r', `g22') define(`mask_sample_r_01', `g22') define(`mask_sample_r_23', `g23') + +define(`mask_sample_g', `g24') define(`mask_sample_g_01', `g24') define(`mask_sample_g_23', `g25') + +define(`mask_sample_b', `g26') define(`mask_sample_b_01', `g26') define(`mask_sample_b_23', `g27') + +define(`mask_sample_a', `g28') define(`mask_sample_a_01', `g28') define(`mask_sample_a_23', `g29') diff --git a/driver/xf86-video-intel/src/exa_wm_projective.g4i b/driver/xf86-video-intel/src/exa_wm_projective.g4i index 3c3bbf0c3..7e2e0a82f 100644 --- a/driver/xf86-video-intel/src/exa_wm_projective.g4i +++ b/driver/xf86-video-intel/src/exa_wm_projective.g4i @@ -32,7 +32,7 @@ mul (16) temp_y<1>F dst_y<8,8,1>F dw_dy { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F temp_y<8,8,1>F { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F wo { compr align1 }; send (8) 0 w_0<1>F temp_x_0<8,8,1>F math inv mlen 1 rlen 1 { align1 }; -send (8) 0 w_1<1>F temp_x_1<8,8,1>F math inv mlen 1 rlen 1 { align1 }; +send (8) 0 w_1<1>F temp_x_1<8,8,1>F math inv mlen 1 rlen 1 { sechalf align1 }; /********** Compute u *************/ diff --git a/driver/xf86-video-intel/src/exa_wm_src_sample_planar.g4a b/driver/xf86-video-intel/src/exa_wm_src_sample_planar.g4a new file mode 100644 index 000000000..ca77b4846 --- /dev/null +++ b/driver/xf86-video-intel/src/exa_wm_src_sample_planar.g4a @@ -0,0 +1,65 @@ +/* + * Copyright © 2006 Intel Corporation + * + * 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: + * Wang Zhenyu <zhenyu.z.wang@intel.com> + * Keith Packard <keithp@keithp.com> + */ + +/* Sample the src surface in planar format */ + +include(`exa_wm.g4i') + +/* prepare sampler read back gX register, which would be written back to output */ + +/* use simd16 sampler, param 0 is u, param 1 is v. */ +/* 'payload' loading, assuming tex coord start from g4 */ + +/* load r */ +mov (1) g0.8<1>UD 0x0000e000UD { align1 mask_disable }; + +/* src_msg will be copied with g0, as it contains send desc */ +/* emit sampler 'send' cmd */ + +/* sample Y */ +send (16) src_msg_ind /* msg reg index */ + src_sample_g<1>UW /* readback */ + g0<8,8,1>UW /* copy to msg start reg*/ + sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) + /* here(src->dst) we should use src_sampler and src_surface */ + mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ + +/* sample U (Cr) */ +send (16) src_msg_ind /* msg reg index */ + src_sample_r<1>UW /* readback */ + g0<8,8,1>UW /* copy to msg start reg*/ + sampler (3,2,F) /* sampler message description, (binding_table,sampler_index,datatype) + /* here(src->dst) we should use src_sampler and src_surface */ + mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ + +/* sample V (Cb) */ +send (16) src_msg_ind /* msg reg index */ + src_sample_b<1>UW /* readback */ + g0<8,8,1>UW /* copy to msg start reg*/ + sampler (5,4,F) /* sampler message description, (binding_table,sampler_index,datatype) + /* here(src->dst) we should use src_sampler and src_surface */ + mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ diff --git a/driver/xf86-video-intel/src/exa_wm_src_sample_planar.g4b b/driver/xf86-video-intel/src/exa_wm_src_sample_planar.g4b new file mode 100644 index 000000000..77a5c2344 --- /dev/null +++ b/driver/xf86-video-intel/src/exa_wm_src_sample_planar.g4b @@ -0,0 +1,4 @@ + { 0x00000201, 0x20080061, 0x00000000, 0x0000e000 }, + { 0x01800031, 0x22001d29, 0x008d0000, 0x02520001 }, + { 0x01800031, 0x21c01d29, 0x008d0000, 0x02520203 }, + { 0x01800031, 0x22401d29, 0x008d0000, 0x02520405 }, diff --git a/driver/xf86-video-intel/src/exa_wm_write.g4a b/driver/xf86-video-intel/src/exa_wm_write.g4a index b16e6497f..faee80b33 100644 --- a/driver/xf86-video-intel/src/exa_wm_write.g4a +++ b/driver/xf86-video-intel/src/exa_wm_write.g4a @@ -40,13 +40,13 @@ mov (8) data_port_g_01<1>F src_sample_g_01<8,8,1>F { align1 }; mov (8) data_port_b_01<1>F src_sample_b_01<8,8,1>F { align1 }; mov (8) data_port_a_01<1>F src_sample_a_01<8,8,1>F { align1 }; -mov (8) data_port_r_23<1>F src_sample_r_23<8,8,1>F { align1 }; -mov (8) data_port_g_23<1>F src_sample_g_23<8,8,1>F { align1 }; -mov (8) data_port_b_23<1>F src_sample_b_23<8,8,1>F { align1 }; -mov (8) data_port_a_23<1>F src_sample_a_23<8,8,1>F { align1 }; +mov (8) data_port_r_23<1>F src_sample_r_23<8,8,1>F { sechalf align1 }; +mov (8) data_port_g_23<1>F src_sample_g_23<8,8,1>F { sechalf align1 }; +mov (8) data_port_b_23<1>F src_sample_b_23<8,8,1>F { sechalf align1 }; +mov (8) data_port_a_23<1>F src_sample_a_23<8,8,1>F { sechalf align1 }; /* m0, m1 are all direct passed by PS thread payload */ -mov (8) data_port_msg_1<1>UD g1<8,8,1>UD { align1 }; +mov (8) data_port_msg_1<1>UD g1<8,8,1>UD { mask_disable align1 }; /* write */ send (16) diff --git a/driver/xf86-video-intel/src/exa_wm_write.g4b b/driver/xf86-video-intel/src/exa_wm_write.g4b index 785fe3213..92e7b248d 100644 --- a/driver/xf86-video-intel/src/exa_wm_write.g4b +++ b/driver/xf86-video-intel/src/exa_wm_write.g4b @@ -2,11 +2,11 @@ { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 }, { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 }, { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 }, - { 0x00600001, 0x20c003be, 0x008d01e0, 0x00000000 }, - { 0x00600001, 0x20e003be, 0x008d0220, 0x00000000 }, - { 0x00600001, 0x210003be, 0x008d0260, 0x00000000 }, - { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 }, - { 0x00600001, 0x20200022, 0x008d0020, 0x00000000 }, + { 0x00601001, 0x20c003be, 0x008d01e0, 0x00000000 }, + { 0x00601001, 0x20e003be, 0x008d0220, 0x00000000 }, + { 0x00601001, 0x210003be, 0x008d0260, 0x00000000 }, + { 0x00601001, 0x212003be, 0x008d02a0, 0x00000000 }, + { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, diff --git a/driver/xf86-video-intel/src/exa_wm_yuv_rgb.g4a b/driver/xf86-video-intel/src/exa_wm_yuv_rgb.g4a new file mode 100644 index 000000000..4fb2576ab --- /dev/null +++ b/driver/xf86-video-intel/src/exa_wm_yuv_rgb.g4a @@ -0,0 +1,98 @@ +/* + * Copyright © 2006 Intel Corporation + * + * 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: + * Keith Packard <keithp@keithp.com> + * Eric Anholt <eric@anholt.net> + * + */ + +include(`exa_wm.g4i') + +define(`YCbCr_base', `src_sample_base') + +define(`Cr', `src_sample_r') +define(`Cr_01', `src_sample_r_01') +define(`Cr_23', `src_sample_r_23') + +define(`Y', `src_sample_g') +define(`Y_01', `src_sample_g_01') +define(`Y_23', `src_sample_g_23') + +define(`Cb', `src_sample_b') +define(`Cb_01', `src_sample_b_01') +define(`Cb_23', `src_sample_b_23') + +define(`Crn', `mask_sample_r') +define(`Crn_01', `mask_sample_r_01') +define(`Crn_23', `mask_sample_r_23') + +define(`Yn', `mask_sample_g') +define(`Yn_01', `mask_sample_g_01') +define(`Yn_23', `mask_sample_g_23') + +define(`Cbn', `mask_sample_b') +define(`Cbn_01', `mask_sample_b_01') +define(`Cbn_23', `mask_sample_b_23') + + /* color space conversion function: + * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1) + * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1) + * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1) + */ + + /* Normalize Y, Cb and Cr: + * + * Yn = (Y - 16/255) * 1.164 + * Crn = Cr - 128 / 255 + * Cbn = Cb - 128 / 255 + */ +add (16) Yn<1>F Y<8,8,1>F -0.0627451F { compr align1 }; +mul (16) Yn<1>F Yn<8,8,1>F 1.164F { compr align1 }; + +add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; + +add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; + + /* + * R = Y + Cr * 1.596 + */ +mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; +mac.sat(16) src_sample_r<1>F Crn<8,8,1>F 1.596F { compr align1 }; + + /* + * G = Crn * -0.813 + Cbn * -0.392 + Y + */ +mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; +mac (16) acc0<1>F Crn<8,8,1>F -0.813F { compr align1 }; +mac.sat(16) src_sample_g<1>F Cbn<8,8,1>F -0.392F { compr align1 }; + + /* + * B = Cbn * 2.017 + Y + */ +mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; +mac.sat(16) src_sample_b<1>F Cbn<8,8,1>F 2.017F { compr align1 }; + + /* + * A = 1.0 + */ +mov (16) src_sample_a<1>F 1.0F { compr align1 }; diff --git a/driver/xf86-video-intel/src/exa_wm_yuv_rgb.g4b b/driver/xf86-video-intel/src/exa_wm_yuv_rgb.g4b new file mode 100644 index 000000000..01f6e2b20 --- /dev/null +++ b/driver/xf86-video-intel/src/exa_wm_yuv_rgb.g4b @@ -0,0 +1,12 @@ + { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, + { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, + { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, + { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fcc49ba }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf5020c5 }, + { 0x80802048, 0x22007fbd, 0x008d0340, 0xbec8b439 }, + { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, + { 0x80802048, 0x22407fbd, 0x008d0340, 0x40011687 }, + { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, diff --git a/driver/xf86-video-intel/src/i810_driver.c b/driver/xf86-video-intel/src/i810_driver.c index 4b7166085..8540646d4 100644 --- a/driver/xf86-video-intel/src/i810_driver.c +++ b/driver/xf86-video-intel/src/i810_driver.c @@ -152,7 +152,10 @@ static const struct pci_id_match intel_device_match[] = { INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ), - INTEL_DEVICE_MATCH (PCI_CHIP_IGD_GM, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_GM45_GM, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_IGD_E_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_G45_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_Q45_G, 0 ), { 0, 0, 0 }, }; @@ -205,7 +208,10 @@ static SymTabRec I810Chipsets[] = { {PCI_CHIP_G33_G, "G33"}, {PCI_CHIP_Q35_G, "Q35"}, {PCI_CHIP_Q33_G, "Q33"}, - {PCI_CHIP_IGD_GM, "Intel Integrated Graphics Device"}, + {PCI_CHIP_GM45_GM, "Mobile Intel® GM45 Express Chipset"}, + {PCI_CHIP_IGD_E_G, "Intel Integrated Graphics Device"}, + {PCI_CHIP_G45_G, "G45/G43"}, + {PCI_CHIP_Q45_G, "Q45/Q43"}, {-1, NULL} }; @@ -235,7 +241,10 @@ static PciChipsets I810PciChipsets[] = { {PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA}, {PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA}, {PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA}, - {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, RES_SHARED_VGA}, + {PCI_CHIP_GM45_GM, PCI_CHIP_GM45_GM, RES_SHARED_VGA}, + {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, RES_SHARED_VGA}, + {PCI_CHIP_G45_G, PCI_CHIP_G45_G, RES_SHARED_VGA}, + {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -799,7 +808,10 @@ I810Probe(DriverPtr drv, int flags) case PCI_CHIP_G33_G: case PCI_CHIP_Q35_G: case PCI_CHIP_Q33_G: - case PCI_CHIP_IGD_GM: + case PCI_CHIP_GM45_GM: + case PCI_CHIP_IGD_E_G: + case PCI_CHIP_G45_G: + case PCI_CHIP_Q45_G: xf86SetEntitySharable(usedChips[i]); /* Allocate an entity private if necessary */ diff --git a/driver/xf86-video-intel/src/i810_reg.h b/driver/xf86-video-intel/src/i810_reg.h index 79a5b1e63..869095437 100644 --- a/driver/xf86-video-intel/src/i810_reg.h +++ b/driver/xf86-video-intel/src/i810_reg.h @@ -353,7 +353,37 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define IPEIR 0x2088 #define IPEHR 0x208C + #define INST_DONE 0x2090 +# define IDCT_DONE (1 << 30) +# define IQ_DONE (1 << 29) +# define PR_DONE (1 << 28) +# define VLD_DONE (1 << 27) +# define IP_DONE (1 << 26) +# define FBC_DONE (1 << 25) +# define BINNER_DONE (1 << 24) +# define SF_DONE (1 << 23) +# define SE_DONE (1 << 22) +# define WM_DONE (1 << 21) +# define IZ_DONE (1 << 20) +# define PERSPECTIVE_INTERP_DONE (1 << 19) +# define DISPATCHER_DONE (1 << 18) +# define PROJECTION_DONE (1 << 17) +# define DEPENDENT_ADDRESS_DONE (1 << 16) +# define QUAD_CACHE_DONE (1 << 15) +# define TEXTURE_FETCH_DONE (1 << 14) +# define TEXTURE_DECOMPRESS_DONE (1 << 13) +# define SAMPLER_CACHE_DONE (1 << 12) +# define FILTER_DONE (1 << 11) +# define BYPASS_FIFO_DONE (1 << 10) +# define PS_DONE (1 << 9) +# define CC_DONE (1 << 8) +# define MAP_FILTER_DONE (1 << 7) +# define MAP_L2_IDLE (1 << 6) +# define RING_2_ENABLE (1 << 2) +# define RING_1_ENABLE (1 << 1) +# define RING_0_ENABLE (1 << 0) + #define SCPD0 0x209c /* debug */ #define INST_PS 0x20c4 #define IPEIR_I965 0x2064 /* i965 */ @@ -1186,6 +1216,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define FP_M2_DIV_SHIFT 0 #define PORT_HOTPLUG_EN 0x61110 +# define HDMIB_HOTPLUG_INT_EN (1 << 29) +# define HDMIC_HOTPLUG_INT_EN (1 << 28) +# define HDMID_HOTPLUG_INT_EN (1 << 27) # define SDVOB_HOTPLUG_INT_EN (1 << 26) # define SDVOC_HOTPLUG_INT_EN (1 << 25) # define TV_HOTPLUG_INT_EN (1 << 18) @@ -1193,6 +1226,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define CRT_HOTPLUG_FORCE_DETECT (1 << 3) #define PORT_HOTPLUG_STAT 0x61114 +# define HDMIB_HOTPLUG_INT_STATUS (1 << 29) +# define HDMIC_HOTPLUG_INT_STATUS (1 << 28) +# define HDMID_HOTPLUG_INT_STATUS (1 << 27) # define CRT_HOTPLUG_INT_STATUS (1 << 11) # define TV_HOTPLUG_INT_STATUS (1 << 10) # define CRT_HOTPLUG_MONITOR_MASK (3 << 8) @@ -1221,9 +1257,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SDVO_PHASE_SELECT_DEFAULT (6 << 19) #define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) #define SDVOC_GANG_MODE (1 << 16) +#define SDVO_ENCODING_SDVO (0x0 << 10) +#define SDVO_ENCODING_HDMI (0x2 << 10) +/** Requird for HDMI operation */ +#define SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9) #define SDVO_BORDER_ENABLE (1 << 7) -/** new with 965, default is to be set */ +/** New with 965, default is to be set */ #define SDVO_VSYNC_ACTIVE_HIGH (1 << 4) +/** New with 965, default is to be set */ #define SDVO_HSYNC_ACTIVE_HIGH (1 << 3) /** 915/945 only, read-only bit */ #define SDVOB_PCIE_CONCURRENCY (1 << 3) @@ -1421,6 +1462,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /** @} */ +#define DP_B 0x64100 +#define DPB_AUX_CH_CTL 0x64110 +#define DPB_AUX_CH_DATA1 0x64114 +#define DPB_AUX_CH_DATA2 0x64118 +#define DPB_AUX_CH_DATA3 0x6411c +#define DPB_AUX_CH_DATA4 0x64120 +#define DPB_AUX_CH_DATA5 0x64124 + +#define DP_C 0x64200 +#define DPC_AUX_CH_CTL 0x64210 +#define DPC_AUX_CH_DATA1 0x64214 +#define DPC_AUX_CH_DATA2 0x64218 +#define DPC_AUX_CH_DATA3 0x6421c +#define DPC_AUX_CH_DATA4 0x64220 +#define DPC_AUX_CH_DATA5 0x64224 + +#define DP_D 0x64300 +#define DPD_AUX_CH_CTL 0x64310 +#define DPD_AUX_CH_DATA1 0x64314 +#define DPD_AUX_CH_DATA2 0x64318 +#define DPD_AUX_CH_DATA3 0x6431c +#define DPD_AUX_CH_DATA4 0x64320 +#define DPD_AUX_CH_DATA5 0x64324 + /* * Two channel clock control. Turn this on if you need clkb for two channel mode * Overridden by global LVDS power sequencing @@ -2077,6 +2142,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DSPARB 0x70030 +#define DSPARB_CSTART_SHIFT 7 +#define DSPARB_BSTART_SHIFT 0 +#define DSPARB_BEND_SHIFT 9 /* on 855 */ +#define DSPARB_AEND_SHIFT 0 #define DSPFW1 0x70034 #define DSPFW2 0x70038 #define DSPFW3 0x7003c @@ -2236,6 +2305,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) +#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4) +#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4) +#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) +#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) + #define I85X_CAPID 0x44 #define I85X_VARIANT_MASK 0x7 @@ -2739,4 +2813,6 @@ typedef enum { #define DPFC_STATUS2 0x3214 #define DPFC_FENCE_YOFF 0x3218 +#define PEG_BAND_GAP_DATA 0x14d68 + #endif /* _I810_REG_H */ diff --git a/driver/xf86-video-intel/src/i830.h b/driver/xf86-video-intel/src/i830.h index def693fbc..6a5de6bc5 100644 --- a/driver/xf86-video-intel/src/i830.h +++ b/driver/xf86-video-intel/src/i830.h @@ -85,7 +85,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef I830_USE_EXA #include "exa.h" Bool I830EXAInit(ScreenPtr pScreen); -#define EXA_LINEAR_EXTRA (64*1024) unsigned long long I830TexOffsetStart(PixmapPtr pPix); #endif @@ -239,6 +238,7 @@ typedef struct { #define I830_OUTPUT_SDVO 5 #define I830_OUTPUT_LVDS 6 #define I830_OUTPUT_TVOUT 7 +#define I830_OUTPUT_HDMI 8 struct _I830DVODriver { int type; @@ -251,8 +251,6 @@ struct _I830DVODriver { I830I2CVidOutputRec *vid_rec; void *dev_priv; pointer modhandle; - DisplayModePtr panel_fixed_mode; - Bool panel_wants_dither; }; extern const char *i830_output_type_names[]; @@ -288,6 +286,7 @@ typedef struct _I830OutputPrivateRec { I2CBusPtr pDDCBus; struct _I830DVODriver *i2c_drv; Bool load_detect_temp; + Bool needs_tv_clock; uint32_t lvds_bits; int pipe_mask; int clone_mask; @@ -397,7 +396,7 @@ typedef struct _I830Rec { i830_memory *xaa_scratch_2; #ifdef I830_USE_EXA i830_memory *exa_offscreen; - i830_memory *exa_965_state; + i830_memory *gen4_render_state_mem; #endif /* Regions allocated either from the above pools, or from agpgart. */ I830RingBuffer *LpRing; @@ -416,7 +415,6 @@ typedef struct _I830Rec { #ifdef INTEL_XVMC /* For XvMC */ Bool XvMCEnabled; - Bool IsXvMCSurface; #endif XF86ModReqInfo shadowReq; /* to test for later libshadow */ @@ -532,6 +530,9 @@ typedef struct _I830Rec { uint32_t mapstate[6]; uint32_t samplerstate[6]; + /* 965 render acceleration state */ + struct gen4_render_state *gen4_render_state; + Bool directRenderingDisabled; /* DRI disabled in PreInit. */ Bool directRenderingEnabled; /* DRI enabled this generation. */ @@ -551,6 +552,13 @@ typedef struct _I830Rec { OptionInfoPtr Options; Bool lvds_24_bit_mode; + Bool lvds_use_ssc; + int lvds_ssc_freq; /* in MHz */ + Bool lvds_dither; + DisplayModePtr lvds_fixed_mode; + Bool skip_panel_detect; + + Bool tv_present; /* TV connector present (from VBIOS) */ Bool StolenOnly; @@ -575,6 +583,7 @@ typedef struct _I830Rec { enum backlight_control backlight_control_method; + uint32_t saveDSPARB; uint32_t saveDSPACNTR; uint32_t saveDSPBCNTR; uint32_t savePIPEACONF; @@ -655,7 +664,6 @@ typedef struct _I830Rec { /** Enables logging of debug output related to mode switching. */ Bool debug_modes; - Bool lvds_fixed_mode; unsigned int quirk_flag; } I830Rec; @@ -798,6 +806,9 @@ void i830_crt_init(ScrnInfoPtr pScrn); /* i830_dvo.c */ void i830_dvo_init(ScrnInfoPtr pScrn); +/* i830_hdmi.c */ +void i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg); + /* i830_lvds.c */ void i830_lvds_init(ScrnInfoPtr pScrn); @@ -836,6 +847,9 @@ Bool i915_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, PixmapPtr pSrcPixmap, PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap); /* i965_render.c */ +unsigned int gen4_render_state_size(ScrnInfoPtr pScrn); +void gen4_render_state_init(ScrnInfoPtr pScrn); +void gen4_render_state_cleanup(ScrnInfoPtr pScrn); Bool i965_check_composite(int op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst); Bool i965_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask, diff --git a/driver/xf86-video-intel/src/i830_bios.c b/driver/xf86-video-intel/src/i830_bios.c index 02837d2e3..fe55d239c 100644 --- a/driver/xf86-video-intel/src/i830_bios.c +++ b/driver/xf86-video-intel/src/i830_bios.c @@ -31,6 +31,7 @@ #include <stdio.h> #include <string.h> +#include <stdlib.h> #define _PARSE_EDID_ #include "xf86.h" @@ -39,58 +40,152 @@ #include "edid.h" #define INTEL_BIOS_8(_addr) (bios[_addr]) -#define INTEL_BIOS_16(_addr) (bios[_addr] | \ +#define INTEL_BIOS_16(_addr) (bios[_addr] | \ (bios[_addr + 1] << 8)) -#define INTEL_BIOS_32(_addr) (bios[_addr] | \ - (bios[_addr + 1] << 8) \ - (bios[_addr + 2] << 16) \ +#define INTEL_BIOS_32(_addr) (bios[_addr] | \ + (bios[_addr + 1] << 8) \ + (bios[_addr + 2] << 16) \ (bios[_addr + 3] << 24)) /* XXX */ #define INTEL_VBIOS_SIZE (64 * 1024) +static void * +find_section(struct bdb_header *bdb, int section_id) +{ + unsigned char *base = (unsigned char *)bdb; + int index = 0; + uint16_t total, current_size; + unsigned char current_id; + + /* skip to first section */ + index += bdb->header_size; + total = bdb->bdb_size; + + /* walk the sections looking for section_id */ + while (index < total) { + current_id = *(base + index); + index++; + current_size = *((uint16_t *)(base + index)); + index += 2; + if (current_id == section_id) + return base + index; + index += current_size; + } + + return NULL; +} + +/** + * Returns the BIOS's fixed panel mode. + * + * Note that many BIOSes will have the appropriate tables for a panel even when + * a panel is not attached. Additionally, many BIOSes adjust table sizes or + * offsets, such that this parsing fails. Thus, almost any other method for + * detecting the panel mode is preferable. + */ static void -i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios) +parse_panel_data(I830Ptr pI830, struct bdb_header *bdb) { - const char *filename = "/tmp/xf86-video-intel-VBIOS"; - FILE *f; + struct bdb_lvds_options *lvds_options; + struct bdb_lvds_lfp_data *lvds_lfp_data; + struct bdb_lvds_lfp_data_entry *entry; + DisplayModePtr fixed_mode; + unsigned char *timing_ptr; - f = fopen(filename, "w"); - if (f == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't open %s\n", filename); + /* Defaults if we can't find VBT info */ + pI830->lvds_dither = 0; + + lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); + if (!lvds_options) return; - } - if (fwrite(bios, INTEL_VBIOS_SIZE, 1, f) != 1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't write BIOS data\n"); - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Wrote BIOS contents to %s\n", - filename); - fclose(f); + pI830->lvds_dither = lvds_options->pixel_dither; + if (lvds_options->panel_type == 0xff) + return; + + lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); + if (!lvds_lfp_data) + return; + + entry = &lvds_lfp_data->data[lvds_options->panel_type]; + timing_ptr = (unsigned char *)&entry->dvo_timing; + + fixed_mode = xnfalloc(sizeof(DisplayModeRec)); + memset(fixed_mode, 0, sizeof(*fixed_mode)); + + /* Since lvds_bdb_2_fp_edid_dtd is just an EDID detailed timing + * block, pull the contents out using EDID macros. + */ + fixed_mode->HDisplay = _H_ACTIVE(timing_ptr); + fixed_mode->VDisplay = _V_ACTIVE(timing_ptr); + fixed_mode->HSyncStart = fixed_mode->HDisplay + + _H_SYNC_OFF(timing_ptr); + fixed_mode->HSyncEnd = fixed_mode->HSyncStart + + _H_SYNC_WIDTH(timing_ptr); + fixed_mode->HTotal = fixed_mode->HDisplay + + _H_BLANK(timing_ptr); + fixed_mode->VSyncStart = fixed_mode->VDisplay + + _V_SYNC_OFF(timing_ptr); + fixed_mode->VSyncEnd = fixed_mode->VSyncStart + + _V_SYNC_WIDTH(timing_ptr); + fixed_mode->VTotal = fixed_mode->VDisplay + + _V_BLANK(timing_ptr); + fixed_mode->Clock = _PIXEL_CLOCK(timing_ptr) / 1000; + fixed_mode->type = M_T_PREFERRED; + + xf86SetModeDefaultName(fixed_mode); + + pI830->lvds_fixed_mode = fixed_mode; +} + +static void +parse_general_features(I830Ptr pI830, struct bdb_header *bdb) +{ + struct bdb_general_features *general; + + /* Set sensible defaults in case we can't find the general block */ + pI830->tv_present = 1; + + general = find_section(bdb, BDB_GENERAL_FEATURES); + if (!general) + return; + + pI830->tv_present = general->int_tv_support; + pI830->lvds_use_ssc = general->enable_ssc; + if (pI830->lvds_use_ssc) { + if (IS_I855(pI830)) + pI830->lvds_ssc_freq = general->ssc_freq ? 66 : 48; + else + pI830->lvds_ssc_freq = general->ssc_freq ? 100 : 96; + } } /** - * Loads the Video BIOS and checks that the VBT exists. + * i830_bios_init - map VBIOS, find VBT * * VBT existence is a sanity check that is relied on by other i830_bios.c code. * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may * feed an updated VBT back through that, compared to what we'll fetch using * this method of groping around in the BIOS data. + * + * Returns 0 on success, nonzero on failure. */ -unsigned char * -i830_bios_get (ScrnInfoPtr pScrn) +int +i830_bios_init(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); struct vbt_header *vbt; - int vbt_off; + struct bdb_header *bdb; + int vbt_off, bdb_off; unsigned char *bios; vbeInfoPtr pVbe; bios = xalloc(INTEL_VBIOS_SIZE); if (bios == NULL) - return NULL; + return -1; - pVbe = VBEInit (NULL, pI830->pEnt->index); + pVbe = VBEInit(NULL, pI830->pEnt->index); if (pVbe != NULL) { memcpy(bios, xf86int10Addr(pVbe->pInt10, pVbe->pInt10->BIOSseg << 4), @@ -104,15 +199,12 @@ i830_bios_get (ScrnInfoPtr pScrn) #endif } - if (0) - i830DumpBIOSToFile(pScrn, bios); - vbt_off = INTEL_BIOS_16(0x1a); if (vbt_off >= INTEL_VBIOS_SIZE) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad VBT offset: 0x%x\n", vbt_off); xfree(bios); - return NULL; + return -1; } vbt = (struct vbt_header *)(bios + vbt_off); @@ -120,179 +212,17 @@ i830_bios_get (ScrnInfoPtr pScrn) if (memcmp(vbt->signature, "$VBT", 4) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad VBT signature\n"); xfree(bios); - return NULL; + return -1; } - return bios; -} - -/** - * Returns the BIOS's fixed panel mode. - * - * Note that many BIOSes will have the appropriate tables for a panel even when - * a panel is not attached. Additionally, many BIOSes adjust table sizes or - * offsets, such that this parsing fails. Thus, almost any other method for - * detecting the panel mode is preferable. - */ -DisplayModePtr -i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither) -{ - I830Ptr pI830 = I830PTR(pScrn); - struct vbt_header *vbt; - struct bdb_header *bdb; - int vbt_off, bdb_off, bdb_block_off, block_size; - int panel_type = -1; - unsigned char *bios; - - bios = i830_bios_get (pScrn); - - if (bios == NULL) - return NULL; - - vbt_off = INTEL_BIOS_16(0x1a); - vbt = (struct vbt_header *)(bios + vbt_off); + /* Now that we've found the VBIOS, go scour the VBTs */ bdb_off = vbt_off + vbt->bdb_offset; bdb = (struct bdb_header *)(bios + bdb_off); - if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad BDB signature\n"); - xfree(bios); - return NULL; - } - - *wants_dither = FALSE; - for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size; - bdb_block_off += block_size) - { - int start = bdb_off + bdb_block_off; - int id; - struct lvds_bdb_1 *lvds1; - struct lvds_bdb_2 *lvds2; - struct lvds_bdb_2_fp_params *fpparam; - struct lvds_bdb_2_fp_edid_dtd *fptiming; - DisplayModePtr fixed_mode; - uint8_t *timing_ptr; - - id = INTEL_BIOS_8(start); - block_size = INTEL_BIOS_16(start + 1) + 3; - switch (id) { - case 40: - lvds1 = (struct lvds_bdb_1 *)(bios + start); - panel_type = lvds1->panel_type; - if (lvds1->caps & LVDS_CAP_DITHER) - *wants_dither = TRUE; - break; - case 41: - if (panel_type == -1) - break; - - lvds2 = (struct lvds_bdb_2 *)(bios + start); - fpparam = (struct lvds_bdb_2_fp_params *)(bios + - bdb_off + lvds2->panels[panel_type].fp_params_offset); - fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(bios + - bdb_off + lvds2->panels[panel_type].fp_edid_dtd_offset); - timing_ptr = bios + bdb_off + - lvds2->panels[panel_type].fp_edid_dtd_offset; - - if (fpparam->terminator != 0xffff) { - /* Apparently the offsets are wrong for some BIOSes, so we - * try the other offsets if we find a bad terminator. - */ - fpparam = (struct lvds_bdb_2_fp_params *)(bios + - bdb_off + lvds2->panels[panel_type].fp_params_offset + 8); - fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(bios + - bdb_off + lvds2->panels[panel_type].fp_edid_dtd_offset + 8); - timing_ptr = bios + bdb_off + - lvds2->panels[panel_type].fp_edid_dtd_offset + 8; - - if (fpparam->terminator != 0xffff) - continue; - } - - fixed_mode = xnfalloc(sizeof(DisplayModeRec)); - memset(fixed_mode, 0, sizeof(*fixed_mode)); - - /* Since lvds_bdb_2_fp_edid_dtd is just an EDID detailed timing - * block, pull the contents out using EDID macros. - */ - fixed_mode->HDisplay = _H_ACTIVE(timing_ptr); - fixed_mode->VDisplay = _V_ACTIVE(timing_ptr); - fixed_mode->HSyncStart = fixed_mode->HDisplay + - _H_SYNC_OFF(timing_ptr); - fixed_mode->HSyncEnd = fixed_mode->HSyncStart + - _H_SYNC_WIDTH(timing_ptr); - fixed_mode->HTotal = fixed_mode->HDisplay + - _H_BLANK(timing_ptr); - fixed_mode->VSyncStart = fixed_mode->VDisplay + - _V_SYNC_OFF(timing_ptr); - fixed_mode->VSyncEnd = fixed_mode->VSyncStart + - _V_SYNC_WIDTH(timing_ptr); - fixed_mode->VTotal = fixed_mode->VDisplay + - _V_BLANK(timing_ptr); - fixed_mode->Clock = _PIXEL_CLOCK(timing_ptr) / 1000; - fixed_mode->type = M_T_PREFERRED; - - xf86SetModeDefaultName(fixed_mode); - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Found panel mode in BIOS VBT tables:\n"); - xf86PrintModeline(pScrn->scrnIndex, fixed_mode); - } - - xfree(bios); - return fixed_mode; - } - } + parse_general_features(pI830, bdb); + parse_panel_data(pI830, bdb); xfree(bios); - return NULL; -} -unsigned char * -i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block) -{ - unsigned char *bios; - int bdb_off; - int vbt_off; - int aim_off; - struct vbt_header *vbt; - struct aimdb_header *aimdb; - struct aimdb_block *aimdb_block; - - bios = i830_bios_get (pScrn); - if (!bios) - return NULL; - - vbt_off = INTEL_BIOS_16(0x1a); - vbt = (struct vbt_header *)(bios + vbt_off); - - aim_off = vbt->aim_offset[aim]; - if (!aim_off) - { - xfree (bios); - return NULL; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "aim_off %d\n", aim_off); - aimdb = (struct aimdb_header *) (bios + vbt_off + aim_off); - bdb_off = aimdb->aimdb_header_size; - while (bdb_off < aimdb->aimdb_size) - { - aimdb_block = (struct aimdb_block *) (bios + vbt_off + aim_off + bdb_off); - if (aimdb_block->aimdb_id == data_block) - { - unsigned char *aim = malloc (aimdb_block->aimdb_size + sizeof (struct aimdb_block)); - if (!aim) - { - xfree (bios); - return NULL; - } - memcpy (aim, aimdb_block, aimdb_block->aimdb_size + sizeof (struct aimdb_block)); - xfree (bios); - return aim; - } - bdb_off += aimdb_block->aimdb_size + sizeof (struct aimdb_block); - } - xfree (bios); - return NULL; + return 0; } diff --git a/driver/xf86-video-intel/src/i830_bios.h b/driver/xf86-video-intel/src/i830_bios.h index 95230f5a5..85729f7c9 100644 --- a/driver/xf86-video-intel/src/i830_bios.h +++ b/driver/xf86-video-intel/src/i830_bios.h @@ -49,22 +49,112 @@ struct bdb_header { uint16_t bdb_size; /**< in bytes */ } __attribute__((packed)); -#define LVDS_CAP_EDID (1 << 6) -#define LVDS_CAP_DITHER (1 << 5) -#define LVDS_CAP_PFIT_AUTO_RATIO (1 << 4) -#define LVDS_CAP_PFIT_GRAPHICS_MODE (1 << 3) -#define LVDS_CAP_PFIT_TEXT_MODE (1 << 2) -#define LVDS_CAP_PFIT_GRAPHICS (1 << 1) -#define LVDS_CAP_PFIT_TEXT (1 << 0) -struct lvds_bdb_1 { - uint8_t id; /**< 40 */ - uint16_t size; +/* + * There are several types of BIOS data blocks (BDBs), each block has + * an ID and size in the first 3 bytes (ID in first, size in next 2). + * Known types are listed below. + */ +#define BDB_GENERAL_FEATURES 1 +#define BDB_GENERAL_DEFINITIONS 2 +#define BDB_OLD_TOGGLE_LIST 3 +#define BDB_MODE_SUPPORT_LIST 4 +#define BDB_GENERIC_MODE_TABLE 5 +#define BDB_EXT_MMIO_REGS 6 +#define BDB_SWF_IO 7 +#define BDB_SWF_MMIO 8 +#define BDB_DOT_CLOCK_TABLE 9 +#define BDB_MODE_REMOVAL_TABLE 10 +#define BDB_CHILD_DEVICE_TABLE 11 +#define BDB_DRIVER_FEATURES 12 +#define BDB_DRIVER_PERSISTENCE 13 +#define BDB_EXT_TABLE_PTRS 14 +#define BDB_DOT_CLOCK_OVERRIDE 15 +#define BDB_DISPLAY_SELECT 16 +/* 17 rsvd */ +#define BDB_DRIVER_ROTATION 18 +#define BDB_DISPLAY_REMOVE 19 +#define BDB_OEM_CUSTOM 20 +#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ +#define BDB_SDVO_LVDS_OPTIONS 22 +#define BDB_SDVO_PANEL_DTDS 23 +#define BDB_SDVO_LVDS_PNP_IDS 24 +#define BDB_SDVO_LVDS_POWER_SEQ 25 +#define BDB_TV_OPTIONS 26 +#define BDB_LVDS_OPTIONS 40 +#define BDB_LVDS_LFP_DATA_PTRS 41 +#define BDB_LVDS_LFP_DATA 42 +#define BDB_LVDS_BACKLIGHT 43 +#define BDB_LVDS_POWER 44 +#define BDB_SKIP 254 /* VBIOS private block, ignore */ + +struct bdb_general_features { + /* bits 1 */ + unsigned char panel_fitting:2; + unsigned char flexaim:1; + unsigned char msg_enable:1; + unsigned char clear_screen:3; + unsigned char color_flip:1; + + /* bits 2 */ + unsigned char download_ext_vbt:1; + unsigned char enable_ssc:1; + unsigned char ssc_freq:1; + unsigned char enable_lfp_on_override:1; + unsigned char disable_ssc_ddt:1; + unsigned char rsvd8:3; /* finish byte */ + + /* bits 3 */ + unsigned char disable_smooth_vision:1; + unsigned char single_dvi:1; + unsigned char rsvd9:6; /* finish byte */ + + /* bits 4 */ + unsigned char legacy_monitor_detect; + + /* bits 5 */ + unsigned char int_crt_support:1; + unsigned char int_tv_support:1; + unsigned char rsvd11:6; /* finish byte */ +} __attribute__((packed)); + +struct bdb_general_definitions { + /* DDC GPIO */ + unsigned char crt_ddc_gmbus_pin; + + /* DPMS bits */ + unsigned char dpms_acpi:1; + unsigned char skip_boot_crt_detect:1; + unsigned char dpms_aim:1; + unsigned char rsvd1:5; /* finish byte */ + + /* boot device bits */ + unsigned char boot_display[2]; + unsigned char child_dev_size; + + /* device info */ + unsigned char tv_or_lvds_info[33]; + unsigned char dev1[33]; + unsigned char dev2[33]; + unsigned char dev3[33]; + unsigned char dev4[33]; + /* may be another device block here on some platforms */ +} __attribute__((packed)); + +struct bdb_lvds_options { uint8_t panel_type; - uint8_t reserved0; - uint16_t caps; + uint8_t rsvd1; + /* LVDS capabilities, stored in a dword */ + uint8_t pfit_mode:2; + uint8_t pfit_text_mode_enhanced:1; + uint8_t pfit_gfx_mode_enhanced:1; + uint8_t pfit_ratio_auto:1; + uint8_t pixel_dither:1; + uint8_t lvds_edid:1; + uint8_t rsvd2:1; + uint8_t rsvd4; } __attribute__((packed)); -struct lvds_bdb_2_fp_params { +struct lvds_fp_timing { uint16_t x_res; uint16_t y_res; uint32_t lvds_reg; @@ -80,7 +170,7 @@ struct lvds_bdb_2_fp_params { uint16_t terminator; } __attribute__((packed)); -struct lvds_bdb_2_fp_edid_dtd { +struct lvds_dvo_timing { uint16_t dclk; /**< In 10khz */ uint8_t hactive; uint8_t hblank; @@ -98,24 +188,39 @@ struct lvds_bdb_2_fp_edid_dtd { uint8_t h_border; uint8_t v_border; uint8_t flags; -#define FP_EDID_FLAG_VSYNC_POSITIVE (1 << 2) -#define FP_EDID_FLAG_HSYNC_POSITIVE (1 << 1) } __attribute__((packed)); -struct lvds_bdb_2_entry { - uint16_t fp_params_offset; /**< From beginning of BDB */ - uint8_t fp_params_size; - uint16_t fp_edid_dtd_offset; - uint8_t fp_edid_dtd_size; - uint16_t fp_edid_pid_offset; - uint8_t fp_edid_pid_size; +struct lvds_pnp_id { + uint16_t mfg_name; + uint16_t product_code; + uint32_t serial; + uint8_t mfg_week; + uint8_t mfg_year; +} __attribute__((packed));; + +/* LFP pointer table contains entries to the struct below */ +struct bdb_lvds_lfp_data_ptr { + uint16_t fp_timing_offset; /* offsets are from start of bdb */ + uint8_t fp_table_size; + uint16_t dvo_timing_offset; + uint8_t dvo_table_size; + uint16_t panel_pnp_id_offset; + uint8_t pnp_table_size; } __attribute__((packed)); -struct lvds_bdb_2 { - uint8_t id; /**< 41 */ - uint16_t size; - uint8_t table_size; /* not sure on this one */ - struct lvds_bdb_2_entry panels[16]; +struct bdb_lvds_lfp_data_ptrs { + uint8_t lvds_entries; + struct bdb_lvds_lfp_data_ptr ptr[16]; +} __attribute__((packed)); + +struct bdb_lvds_lfp_data_entry { + struct lvds_fp_timing fp_timing; + struct lvds_dvo_timing dvo_timing; + struct lvds_pnp_id pnp_id; +} __attribute__((packed)); + +struct bdb_lvds_lfp_data { + struct bdb_lvds_lfp_data_entry data[16]; } __attribute__((packed)); struct aimdb_header { @@ -147,12 +252,6 @@ struct vch_bdb_22 { struct vch_panel_data panels[16]; } __attribute__((packed)); -unsigned char * -i830_bios_get (ScrnInfoPtr pScrn); - -DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither); - -unsigned char * -i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block); +int i830_bios_init(ScrnInfoPtr pScrn); #endif /* _I830_BIOS_H_ */ diff --git a/driver/xf86-video-intel/src/i830_debug.c b/driver/xf86-video-intel/src/i830_debug.c index 15b02ceb7..a7f168356 100644 --- a/driver/xf86-video-intel/src/i830_debug.c +++ b/driver/xf86-video-intel/src/i830_debug.c @@ -537,15 +537,6 @@ static struct i830SnapshotRec { DEFINEREG2(PIPEASRC, i830_debug_yxminus1), DEFINEREG2(PIPEASTAT, i830_debug_pipestat), - DEFINEREG(FBC_CFB_BASE), - DEFINEREG(FBC_LL_BASE), - DEFINEREG(FBC_CONTROL), - DEFINEREG(FBC_COMMAND), - DEFINEREG(FBC_STATUS), - DEFINEREG(FBC_CONTROL2), - DEFINEREG(FBC_FENCE_OFF), - DEFINEREG(FBC_MOD_NUM), - DEFINEREG2(FPA0, i830_debug_fp), DEFINEREG2(FPA1, i830_debug_fp), DEFINEREG2(DPLL_A, i830_debug_dpll), @@ -623,11 +614,45 @@ static struct i830SnapshotRec { DEFINEREG(TV_H_CHROMA_0), DEFINEREG(TV_H_CHROMA_59), + DEFINEREG(FBC_CFB_BASE), + DEFINEREG(FBC_LL_BASE), + DEFINEREG(FBC_CONTROL), + DEFINEREG(FBC_COMMAND), + DEFINEREG(FBC_STATUS), + DEFINEREG(FBC_CONTROL2), + DEFINEREG(FBC_FENCE_OFF), + DEFINEREG(FBC_MOD_NUM), + DEFINEREG(MI_MODE), /* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */ DEFINEREG(MI_ARB_STATE), DEFINEREG(MI_RDRET_STATE), DEFINEREG(ECOSKPD), + + DEFINEREG(DP_B), + DEFINEREG(DPB_AUX_CH_CTL), + DEFINEREG(DPB_AUX_CH_DATA1), + DEFINEREG(DPB_AUX_CH_DATA2), + DEFINEREG(DPB_AUX_CH_DATA3), + DEFINEREG(DPB_AUX_CH_DATA4), + DEFINEREG(DPB_AUX_CH_DATA5), + + DEFINEREG(DP_C), + DEFINEREG(DPC_AUX_CH_CTL), + DEFINEREG(DPC_AUX_CH_DATA1), + DEFINEREG(DPC_AUX_CH_DATA2), + DEFINEREG(DPC_AUX_CH_DATA3), + DEFINEREG(DPC_AUX_CH_DATA4), + DEFINEREG(DPC_AUX_CH_DATA5), + + DEFINEREG(DP_D), + DEFINEREG(DPD_AUX_CH_CTL), + DEFINEREG(DPD_AUX_CH_DATA1), + DEFINEREG(DPD_AUX_CH_DATA2), + DEFINEREG(DPD_AUX_CH_DATA3), + DEFINEREG(DPD_AUX_CH_DATA4), + DEFINEREG(DPD_AUX_CH_DATA5), + #if 0 DEFINEREG2(FENCE_NEW + 0, i810_debug_fence_new), DEFINEREG2(FENCE_NEW + 8, i810_debug_fence_new), @@ -697,6 +722,7 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where) } #endif /* !REG_DUMPER */ +#if 0 static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max) { I830Ptr pI830 = I830PTR(pScrn); @@ -737,6 +763,7 @@ static void i830DumpAR(ScrnInfoPtr pScrn) OUTREG8(0x3c0, orig_arx); INREG8(st01); /* switch back to index mode */ } +#endif void i830DumpRegs (ScrnInfoPtr pScrn) { @@ -748,8 +775,10 @@ void i830DumpRegs (ScrnInfoPtr pScrn) int ref; int dot; int phase; +#if 0 int msr; int crt; +#endif xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsBegin\n"); for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) { @@ -767,6 +796,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn) i830_snapshot[i].name, (unsigned int)val); } } +#if 0 i830DumpIndexed (pScrn, "SR", 0x3c4, 0x3c5, 0, 7); msr = INREG8(0x3cc); xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%02x\n", @@ -778,6 +808,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn) else crt = 0x3b0; i830DumpIndexed (pScrn, "CR", crt + 4, crt + 5, 0, 0x24); +#endif for (pipe = 0; pipe <= 1; pipe++) { fp = INREG(pipe == 0 ? FPA0 : FPB0); @@ -927,13 +958,542 @@ void i830DumpRegs (ScrnInfoPtr pScrn) #ifndef REG_DUMPER -#define NUM_RING_DUMP 64 +static char *mi_cmds[0x40] = { + "MI_NOOP", /* 00 */ + "Reserved 01", + "MI_USER_INTERRUPT", + "MI_WAIT_FOR_EVENT", + + "MI_FLUSH", /* 04 */ + "MI_ARB_CHECK", + NULL, + "MI_REPORT_HEAD", + + NULL, /* 08 */ + NULL, + "MI_BATCH_BUFFER_END", + NULL, + + NULL, /* 0c */ + NULL, + NULL, + NULL, + + NULL, /* 10 */ + "MI_OVERLAY_FLIP", + "MI_LOAD_SCAN_LINES_INCL", + "MI_LOAD_SCAN_LINES_EXCL", + + "MI_DISPLAY_BUFFER_INFO", /* 14 */ + NULL, + NULL, + NULL, + + "MI_SET_CONTEXT", /* 18 */ + NULL, + NULL, + NULL, + + NULL, /* 1c */ + NULL, + NULL, + NULL, + + "MI_STORE_DATA_IMM", /* 20 */ + "MI_STORE_DATA_INDEX", + "MI_LOAD_REGISTER_IMM", + NULL, + + "MI_STORE_REGISTER_MEM", /* 24 */ + NULL, + NULL, + NULL, + + NULL, /* 28 */ + NULL, + NULL, + NULL, + + NULL, /* 2c */ + NULL, + NULL, + NULL, + + NULL, /* 30 */ + "MI_BATCH_BUFFER_START", + NULL, + NULL, + + NULL, /* 34 */ + NULL, + NULL, + NULL, + + NULL, /* 38 */ + NULL, + NULL, + NULL, + + NULL, /* 3c */ + NULL, + NULL, + NULL, +}; + +static char *_2d_cmds[0x80] = { + NULL, /* 00 */ + "XY_SETUP_BLT", + NULL, + "XY_SETUP_CLIP_BLT", + + NULL, /* 04 */ + NULL, + NULL, + NULL, + + NULL, /* 08 */ + NULL, + NULL, + NULL, + + NULL, /* 0c */ + NULL, + NULL, + NULL, + + NULL, /* 10 */ + "XY_SETUP_MONO_PATTERN_SL_BLT", + NULL, + NULL, + + NULL, /* 14 */ + NULL, + NULL, + NULL, + + NULL, /* 18 */ + NULL, + NULL, + NULL, + + NULL, /* 1c */ + NULL, + NULL, + NULL, + + NULL, /* 20 */ + NULL, + NULL, + NULL, + + "XY_PIXEL_BLT", /* 24 */ + "XY_SCANLINE_BLT", + "XY_TEXT_BLT", + NULL, + + NULL, /* 28 */ + NULL, + NULL, + NULL, + + NULL, /* 2c */ + NULL, + NULL, + NULL, + + NULL, /* 30 */ + "XY_TEXT_IMMEDIATE_BLT", + NULL, + NULL, + + NULL, /* 34 */ + NULL, + NULL, + NULL, + + NULL, /* 38 */ + NULL, + NULL, + NULL, + + NULL, /* 3c */ + NULL, + NULL, + NULL, + + "COLOR_BLT", /* 40 */ + NULL, + NULL, + "SRC_COPY_BLT", + + NULL, /* 44 */ + NULL, + NULL, + NULL, + + NULL, /* 48 */ + NULL, + NULL, + NULL, + + NULL, /* 4c */ + NULL, + NULL, + NULL, + + "XY_COLOR_BLT", /* 50 */ + "XY_PAT_BLT", + "XY_MONO_PAT_BLT", + "XY_SRC_COPY_BLT", + + "XY_MONO_SRC_COPY_BLT", /* 54 */ + "XY_FULL_BLT", + "XY_FULL_MONO_SRC_BLT", + "XY_FULL_MONO_PATTERN_BLT", + + "XY_FULL_MONO_PATTERN_MONO_SRC_BLT", /* 58 */ + "XY_MONO_PAT_FIXED_BLT", + NULL, + NULL, + + NULL, /* 5c */ + NULL, + NULL, + NULL, + + NULL, /* 60 */ + NULL, + NULL, + NULL, + + NULL, /* 64 */ + NULL, + NULL, + NULL, + + NULL, /* 68 */ + NULL, + NULL, + NULL, + + NULL, /* 6c */ + NULL, + NULL, + NULL, + + NULL, /* 70 */ + "XY_MONO_SRC_COPY_IMMEDIATE_BLT", + "XY_PAT_BLT_IMMEDIATE", + "XY_SRC_COPY_CHROMA_BLT", + + "XY_FULL_IMMEDIATE_PATTERN_BLT", /* 74 */ + "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT", + "XY_PAT_CHROMA_BLT", + "XY_PAT_CHROMA_BLT_IMMEDIATE", + + NULL, /* 78 */ + NULL, + NULL, + NULL, + + NULL, /* 7c */ + NULL, + NULL, + NULL, + +}; + +#define _3D_ONE_WORD 1 + +static struct { + char *name; + int flags; +} _3d_cmds[0x4][0x8][0x100] = { + { /* Pipeline Type 00 (Common) */ + { /* Opcode 0 */ + { "URB_FENCE", 0 }, /* 00 */ + { "CS_URB_STATE", 0 }, + { "CONSTANT_BUFFER", 0 }, + { "STATE_PREFETCH", 0 }, + }, + { /* Opcode 1 */ + { NULL, 0 }, /* 00 */ + { "STATE_BASE_ADDRESS", 0 }, + { "STATE_SIP", 0 }, + { NULL, 0 }, + + { "PIPELINE_SELECT", _3D_ONE_WORD }, /* 04 */ + }, + }, + { /* Pipeline Type 01 (Single DW) */ + { /* Opcode 0 */ + }, + { /* Opcode 1 */ + { NULL, 0 }, /* 00 */ + { NULL, 0 }, + { NULL, 0 }, + { NULL, 0 }, + + { "PIPELINE_SELECT", 0 }, /* 04 */ + { NULL, 0 }, + { NULL, 0 }, + { NULL, 0 }, + }, + }, + { /* Pipeline Type 02 (Media) */ + { /* Opcode 0 */ + { "MEDIA_STATE_POINTERS", 0 }, /* 00 */ + }, + { /* Opcode 1 */ + { "MEDIA_OBJECT", 0 }, /* 00 */ + { "MEDIA_OBJECT_EX", 0 }, + { "MEDIA_OBJECT_PTR", 0 }, + }, + }, + { /* Pipeline Type 03 (3D) */ + { /* Opcode 0 */ + { "3DSTATE_PIPELINED_POINTERS", 0 }, /* 00 */ + { "3DSTATE_BINDING_TABLE_POINTERS", 0 }, + { NULL, 0 }, + { NULL, 0 }, + + { NULL, 0 }, /* 04 */ + { "3DSTATE_URB", 0 }, + { NULL, 0 }, + { NULL, 0 }, + + { "3DSTATE_VERTEX_BUFFERS", 0 }, /* 08 */ + { "3DSTATE_VERTEX_ELEMENTS", 0 }, + { "3DSTATE_INDEX_BUFFER", 0 }, + { "3DSTATE_VF_STATISTICS", _3D_ONE_WORD }, + + { NULL, 0 }, /* 0c */ + { "3DSTATE_VIEWPORT_STATE_POINTERS", 0 }, + }, + { /* Opcode 1 */ + { "3DSTATE_DRAWING_RECTANGLE", 0 }, /* 00 */ + { "3DSTATE_CONSTANT_COLOR", 0 }, + { "3DSTATE_SAMPLER_PALETTE_LOAD0", 0 }, + { NULL, 0 }, + + { "3DSTATE_CHROMA_KEY", 0 }, /* 04 */ + { "3DSTATE_DEPTH_BUFFER", 0 }, + { "3DSTATE_POLY_STIPPLE_OFFSET", 0 }, + { "3DSTATE_POLY_STIPPLE_PATTERN", 0 }, + + { "3DSTATE_LINE_STIPPLE", 0 }, /* 08 */ + { "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP", 0 }, + }, + { /* Opcode 2 */ + { "PIPE_CONTROL", 0 }, /* 00 */ + }, + { /* Opcode 3 */ + { "3DPRIMITIVE", 0 }, /* 00 */ + }, + }, +}; + +static int +i830_valid_command (uint32_t cmd) +{ + uint32_t type = (cmd >> 29) & 0x7; + uint32_t pipeline_type; + uint32_t opcode; + uint32_t subopcode; + uint32_t count; + + switch (type) { + case 0: /* Memory Interface */ + opcode = (cmd >> 23) & 0x3f; + if (opcode < 0x10) + count = 1; + else + count = (cmd & 0x3f) + 2; + if (opcode == 0x00 && cmd != 0x00000000) + return -1; + if (!mi_cmds[opcode]) + return -1; + break; + case 2: /* 2D */ + count = (cmd & 0x1f) + 2; + opcode = (cmd >> 22) & 0x7f; + if (!_2d_cmds[opcode]) + return -1; + break; + case 3: /* 3D */ + pipeline_type = (cmd >> 27) & 0x3; + opcode = (cmd >> 24) & 0x7; + subopcode = (cmd >> 16) & 0xff; + if (_3d_cmds[pipeline_type][opcode][subopcode].flags & _3D_ONE_WORD) + count = 1; + else + count = (cmd & 0xff) + 2; + if (pipeline_type <= 3) + return count; + if (!_3d_cmds[pipeline_type][opcode][subopcode].name) + return -1; + break; + default: + return -1; + } + return count; +} + +static int +i830_dump_cmd (uint32_t cmd, int count) +{ + uint32_t type = (cmd >> 29) & 0x7; + uint32_t pipeline_type; + uint32_t opcode; + uint32_t subopcode; + int ret = 1; + + ErrorF ("\t"); + switch (type) { + case 0: /* Memory Interface */ + opcode = (cmd >> 23) & 0x3f; + if (mi_cmds[opcode]) + ErrorF ("%-40.40s %d\n", mi_cmds[opcode], count); + else + ErrorF ("Memory Interface Reserved\n"); + break; + case 1: + break; + case 2: /* 2D */ + opcode = (cmd >> 22) & 0x7f; + if (_2d_cmds[opcode]) + ErrorF ("%-40.40s %d\n", _2d_cmds[opcode], count); + else + ErrorF ("2D Reserved\n"); + break; + case 3: /* 3D */ + pipeline_type = (cmd >> 27) & 0x3; + opcode = (cmd >> 24) & 0x7; + subopcode = (cmd >> 16) & 0xff; + if (_3d_cmds[pipeline_type][opcode][subopcode].name) { + ErrorF ("%-40.40s %d\n", + _3d_cmds[pipeline_type][opcode][subopcode].name, + count); + } else { + ErrorF ("3D/Media Reserved (pipe %d op %d sub %d)\n", pipeline_type, opcode, subopcode); + } + break; + default: + ErrorF ("Reserved\n"); + break; + } + return ret; +} + +static int +i830_valid_chain (ScrnInfoPtr pScrn, unsigned int ring, unsigned int end) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned int head, tail, mask; + volatile unsigned char *virt; + uint32_t data; + int count; + volatile uint32_t *ptr; + + head = (INREG (LP_RING + RING_HEAD)) & I830_HEAD_MASK; + tail = INREG (LP_RING + RING_TAIL) & I830_TAIL_MASK; + mask = pI830->LpRing->tail_mask; + + virt = pI830->LpRing->virtual_start; + ErrorF ("Ring at virtual %p head 0x%x tail 0x%x count %d\n", + virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); + + for (;;) + { + ptr = (volatile uint32_t *) (virt + ring); + data = *ptr; + count = i830_valid_command (data); + if (count < 0) + return 0; + while (count > 0 && ring != end) + { + ring = (ring + 4) & mask; + count--; + } + if (ring == end) { + if (count == 0) + return 1; + else + return 0; + } + } +} static void -i830_dump_ring(ScrnInfoPtr pScrn) +i830_dump_cmds (ScrnInfoPtr pScrn, + volatile unsigned char *virt, + uint32_t start, + uint32_t stop, + uint32_t mask, + uint32_t acthd) +{ + I830Ptr pI830 = I830PTR(pScrn); + uint32_t ring = start; + uint32_t cmd = start; + uint32_t data; + uint32_t batch_start_mask = ((0x7 << 29) | + (0x3f << 23) | + (0x7ff << 12) | + (1 << 11) | + (1 << 7) | + (1 << 6) | + (0x3f << 0)); + uint32_t batch_start_cmd = ((0x0 << 29) | + (0x31 << 23) | + (0x00 << 12) | + (0 << 11) | + (1 << 7) | + (0 << 6) | + (0 << 0)); + int count; + volatile uint32_t *ptr; + + while (ring != stop) + { + if (ring == acthd) + ErrorF ("****"); + ErrorF ("\t%08x: %08x", ring, *(volatile unsigned int *) (virt + ring)); + if (ring == cmd) + { + ptr = (volatile uint32_t *) (virt + ring); + data = *ptr; + count = i830_valid_command (data); + i830_dump_cmd (data, count); + + /* check for MI_BATCH_BUFFER_END */ + if (data == (0x0a << 23)) + stop = (ring + 4) & mask; + /* check for MI_BATCH_BUFFER_START */ + if ((data & batch_start_mask) == batch_start_cmd) + { + uint32_t batch = ptr[1]; + if (batch < pI830->FbMapSize) { + ErrorF ("\t%08x: %08x\n", (ring + 4) & mask, batch); + ErrorF ("Batch buffer at 0x%08x {\n", batch); + i830_dump_cmds (pScrn, pI830->FbBase, batch, + pI830->FbMapSize - batch, + 0xffffffff, acthd); + ErrorF ("}\n"); + ring = (ring + (count - 1) * 4) & mask; + } + } + cmd = (cmd + count * 4) & mask; + } else + ErrorF ("\n"); + ring = (ring + 4) & mask; + } +} + +static void +i830_dump_ring(ScrnInfoPtr pScrn, uint32_t acthd) { I830Ptr pI830 = I830PTR(pScrn); - unsigned int head, tail, ring, mask; + unsigned int head, tail, mask, cmd; volatile unsigned char *virt; head = (INREG (LP_RING + RING_HEAD)) & I830_HEAD_MASK; @@ -943,11 +1503,18 @@ i830_dump_ring(ScrnInfoPtr pScrn) virt = pI830->LpRing->virtual_start; ErrorF ("Ring at virtual %p head 0x%x tail 0x%x count %d\n", virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); - for (ring = (head - 128) & mask; ring != ((head + 4) & mask); - ring = (ring + 4) & mask) + + /* walk back by instructions */ + for (cmd = (head - 256) & mask; + cmd != (head & mask); + cmd = (cmd + 4) & mask) { - ErrorF ("\t%08x: %08x\n", ring, *(volatile unsigned int *) (virt + ring)); + if (i830_valid_chain (pScrn, cmd, (head & mask))) + break; } + + i830_dump_cmds (pScrn, virt, cmd, head, mask, acthd); + ErrorF ("Ring end\n"); } @@ -980,13 +1547,14 @@ i830_dump_error_state(ScrnInfoPtr pScrn) ErrorF("hwstam: 0x%04x ier: 0x%04x imr: 0x%04x iir: 0x%04x\n", INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); - i830_dump_ring (pScrn); + i830_dump_ring (pScrn, 0); } void i965_dump_error_state(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + uint32_t acthd; ErrorF("pgetbl_ctl: 0x%08x pgetbl_err: 0x%08x\n", INREG(PGETBL_CTL), INREG(PGE_ERR)); @@ -1016,8 +1584,9 @@ i965_dump_error_state(ScrnInfoPtr pScrn) "imr: 0x%08x iir: 0x%08x\n", INREG(HWSTAM), INREG(IER), INREG(IMR), INREG(IIR)); + acthd = INREG(ACTHD); ErrorF("acthd: 0x%08x dma_fadd_p: 0x%08x\n", - INREG(ACTHD), INREG(DMA_FADD_P)); + acthd, INREG(DMA_FADD_P)); ErrorF("ecoskpd: 0x%08x excc: 0x%08x\n", INREG(ECOSKPD), INREG(EXCC)); @@ -1062,6 +1631,7 @@ i965_dump_error_state(ScrnInfoPtr pScrn) INREG(TS_DEBUG_DATA)); ErrorF("TD_CTL 0x%08x / 0x%08x\n", INREG(TD_CTL), INREG(TD_CTL2)); + i830_dump_ring (pScrn, acthd); } /** diff --git a/driver/xf86-video-intel/src/i830_display.c b/driver/xf86-video-intel/src/i830_display.c index 3d0fe57f9..66990c2a5 100644 --- a/driver/xf86-video-intel/src/i830_display.c +++ b/driver/xf86-video-intel/src/i830_display.c @@ -668,7 +668,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc) ScrnInfoPtr pScrn = crtc->scrn; I830Ptr pI830 = I830PTR(pScrn); - if (IS_IGD_GM(pI830)) + if (IS_GM45(pI830)) return i830_enable_fb_compression2(crtc); i830_enable_fb_compression_8xx(crtc); @@ -680,7 +680,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc) ScrnInfoPtr pScrn = crtc->scrn; I830Ptr pI830 = I830PTR(pScrn); - if (IS_IGD_GM(pI830)) + if (IS_GM45(pI830)) return i830_disable_fb_compression2(crtc); i830_disable_fb_compression_8xx(crtc); @@ -693,6 +693,7 @@ i830_use_fb_compression(xf86CrtcPtr crtc) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + unsigned long uncompressed_size; int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); int i, count = 0; @@ -724,6 +725,19 @@ i830_use_fb_compression(xf86CrtcPtr crtc) pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ return FALSE; + /* Can't cache more lines than we can track */ + if (crtc->mode.VDisplay > FBC_LL_SIZE) + return FALSE; + + /* + * Make sure the compressor doesn't go past the end of our compressed + * buffer if the uncompressed size is large. + */ + uncompressed_size = crtc->mode.HDisplay * crtc->mode.VDisplay * + pI830->cpp; + if (pI830->compressed_front_buffer->size < uncompressed_size) + return FALSE; + /* * No checks for pixel multiply, incl. horizontal, or interlaced modes * since they're currently unused. @@ -752,12 +766,10 @@ static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre) /* On -> off is a pre modeset */ modeset.cmd = _DRM_PRE_MODESET; ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset); - ErrorF("modeset: on -> off on plane %d\n", modeset.crtc); } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) { /* Off -> on means post modeset */ modeset.cmd = _DRM_POST_MODESET; ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset); - ErrorF("modeset: off -> on on plane %d\n", modeset.crtc); } } #else @@ -767,7 +779,6 @@ static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state) } #endif /* DRM_IOCTL_MODESET_CTL && XF86DRI */ - /** * Sets the power management mode of the pipe and plane. * @@ -846,44 +857,43 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Give the overlay scaler a chance to disable if it's on this pipe */ i830_crtc_dpms_video(crtc, FALSE); - /* May need to leave pipe A on */ - if ((pipe == 0) && (pI830->quirk_flag & QUIRK_PIPEA_FORCE)) - return; - /* Disable the VGA plane that we never use */ OUTREG(VGACNTRL, VGA_DISP_DISABLE); - /* Disable display plane */ - temp = INREG(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) + /* May need to leave pipe A on */ + if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE)) { - OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - POSTING_READ(dspbase_reg); - } + /* Disable display plane */ + temp = INREG(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) + { + OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + OUTREG(dspbase_reg, INREG(dspbase_reg)); + POSTING_READ(dspbase_reg); + } - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } + if (!IS_I9XX(pI830)) { + /* Wait for vblank for the disable to take effect */ + i830WaitForVblank(pScrn); + } - /* Next, disable display pipes */ - temp = INREG(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - POSTING_READ(pipeconf_reg); - } + /* Next, disable display pipes */ + temp = INREG(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { + OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + POSTING_READ(pipeconf_reg); + } - /* Wait for vblank for the disable to take effect. */ - i830WaitForVblank(pScrn); + /* Wait for vblank for the disable to take effect. */ + i830WaitForVblank(pScrn); - temp = INREG(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); - POSTING_READ(dpll_reg); + temp = INREG(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) != 0) { + OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); + POSTING_READ(dpll_reg); + } } - /* Wait for the clocks to turn off. */ usleep(150); break; @@ -1085,6 +1095,69 @@ i830_panel_fitter_pipe(I830Ptr pI830) } /** + * Sets up the DSPARB register to split the display fifo appropriately between + * the display planes. + * + * Adjusting this register requires that the planes be off. + */ +static void +i830_update_dsparb(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + int total_hdisplay = 0, planea_hdisplay = 0, planeb_hdisplay = 0; + int fifo_entries = 0, planea_entries = 0, planeb_entries = 0, i; + + if ((INREG(DSPACNTR) & DISPLAY_PLANE_ENABLE) && + (INREG(DSPBCNTR) & DISPLAY_PLANE_ENABLE)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "tried to update DSPARB with both planes enabled!\n"); + + /* + * FIFO entries will be split based on programmed modes + */ + if (IS_I965GM(pI830) || IS_GM45(pI830)) + fifo_entries = 127; + else if (IS_I9XX(pI830)) + fifo_entries = 95; + else if (IS_MOBILE(pI830)) { + fifo_entries = 255; + } else { + /* The 845/865 only have a AEND field. Though the field size would + * allow 128 entries, the 865 rendered the cursor wrong then. + * The BIOS set it up for 96. + */ + fifo_entries = 95; + } + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + if (crtc->enabled) { + total_hdisplay += crtc->mode.HDisplay; + if (intel_crtc->plane == 0) + planea_hdisplay = crtc->mode.HDisplay; + else + planeb_hdisplay = crtc->mode.HDisplay; + } + } + + planea_entries = fifo_entries * planea_hdisplay / total_hdisplay; + planeb_entries = fifo_entries * planeb_hdisplay / total_hdisplay; + + if (IS_I9XX(pI830)) + OUTREG(DSPARB, + ((planea_entries + planeb_entries) << DSPARB_CSTART_SHIFT) | + (planea_entries << DSPARB_BSTART_SHIFT)); + else if (IS_MOBILE(pI830)) + OUTREG(DSPARB, + ((planea_entries + planeb_entries) << DSPARB_BEND_SHIFT) | + (planea_entries << DSPARB_AEND_SHIFT)); + else + OUTREG(DSPARB, planea_entries << DSPARB_AEND_SHIFT); +} + +/** * Sets up registers for the given mode/adjusted_mode pair. * * The clocks, CRTCs and outputs attached to this CRTC must be off. @@ -1119,7 +1192,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; - int i; + int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT; + int i, num_outputs = 0; int refclk; intel_clock_t clock; uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0; @@ -1142,7 +1216,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, lvds_bits = intel_output->lvds_bits; break; case I830_OUTPUT_SDVO: + case I830_OUTPUT_HDMI: is_sdvo = TRUE; + if (intel_output->needs_tv_clock) + is_tv = TRUE; break; case I830_OUTPUT_DVO_TMDS: case I830_OUTPUT_DVO_LVDS: @@ -1156,9 +1233,19 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, is_crt = TRUE; break; } + + num_outputs++; } - if (IS_I9XX(pI830)) { + if (num_outputs > 1) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n"); + + /* Don't use SSC when cloned */ + if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) { + refclk = pI830->lvds_ssc_freq * 1000; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "using SSC reference clock of %d MHz\n", refclk / 1000); + } else if (IS_I9XX(pI830)) { refclk = 96000; } else { refclk = 48000; @@ -1187,7 +1274,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, if (is_sdvo) { dpll |= DPLL_DVO_HIGH_SPEED; - if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) + if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) && + !is_tv) { int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; @@ -1210,7 +1298,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; break; } - if (IS_I965G(pI830)) + if (IS_I965G(pI830) && !IS_GM45(pI830)) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); } else { if (is_lvds) { @@ -1225,16 +1313,16 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, } } - if (is_tv) + if (is_sdvo && is_tv) + dpll |= PLL_REF_INPUT_TVCLKINBC; + else if (is_tv) { /* XXX: just matching BIOS for now */ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; } -#if 0 - else if (is_lvds) + else if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; -#endif else dpll |= PLL_REF_INPUT_DREFCLK; @@ -1381,6 +1469,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, /* Wait for the clocks to stabilize. */ usleep(150); + if (!DSPARB_HWCONTROL(pI830)) + i830_update_dsparb(pScrn); + OUTREG(htot_reg, (adjusted_mode->CrtcHDisplay - 1) | ((adjusted_mode->CrtcHTotal - 1) << 16)); OUTREG(hblank_reg, (adjusted_mode->CrtcHBlankStart - 1) | @@ -1413,6 +1504,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, #endif i830WaitForVblank(pScrn); + + /* Clear any FIFO underrun status that may have occurred normally */ + OUTREG(pipestat_reg, INREG(pipestat_reg) | FIFO_UNDERRUN); } diff --git a/driver/xf86-video-intel/src/i830_dri.c b/driver/xf86-video-intel/src/i830_dri.c index 4361ad0b9..6bc495787 100644 --- a/driver/xf86-video-intel/src/i830_dri.c +++ b/driver/xf86-video-intel/src/i830_dri.c @@ -386,7 +386,7 @@ I830InitVisualConfigs(ScreenPtr pScreen) i = 0; for (accum = 0; accum <= 1; accum++) { - for (depth = 0; depth <= 1; depth++) { /* and stencil */ + for (depth = 1; depth >= 0; depth--) { /* and stencil */ for (db = 1; db >= 0; db--) { pConfigs[i].vid = -1; pConfigs[i].class = -1; diff --git a/driver/xf86-video-intel/src/i830_driver.c b/driver/xf86-video-intel/src/i830_driver.c index 36ea7526b..cf2d53545 100644 --- a/driver/xf86-video-intel/src/i830_driver.c +++ b/driver/xf86-video-intel/src/i830_driver.c @@ -251,7 +251,10 @@ static SymTabRec I830Chipsets[] = { {PCI_CHIP_G33_G, "G33"}, {PCI_CHIP_Q35_G, "Q35"}, {PCI_CHIP_Q33_G, "Q33"}, - {PCI_CHIP_IGD_GM, "Intel Integrated Graphics Device"}, + {PCI_CHIP_GM45_GM, "Mobile Intel® GM45 Express Chipset"}, + {PCI_CHIP_IGD_E_G, "Intel Integrated Graphics Device"}, + {PCI_CHIP_G45_G, "G45/G43"}, + {PCI_CHIP_Q45_G, "Q45/Q43"}, {-1, NULL} }; @@ -275,7 +278,10 @@ static PciChipsets I830PciChipsets[] = { {PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA}, {PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA}, {PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA}, - {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, RES_SHARED_VGA}, + {PCI_CHIP_GM45_GM, PCI_CHIP_GM45_GM, RES_SHARED_VGA}, + {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, RES_SHARED_VGA}, + {PCI_CHIP_G45_G, PCI_CHIP_G45_G, RES_SHARED_VGA}, + {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED} }; @@ -511,6 +517,10 @@ I830DetectMemory(ScrnInfoPtr pScrn) */ range = gtt_size + 4; + /* new 4 series hardware has seperate GTT stolen with GFX stolen */ + if (IS_G4X(pI830)) + range = 0; + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { switch (gmch_ctrl & I855_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: @@ -544,6 +554,22 @@ I830DetectMemory(ScrnInfoPtr pScrn) if (IS_I9XX(pI830)) memsize = MB(256) - KB(range); break; + case INTEL_GMCH_GMS_STOLEN_96M: + if (IS_I9XX(pI830)) + memsize = MB(96) - KB(range); + break; + case INTEL_GMCH_GMS_STOLEN_160M: + if (IS_I9XX(pI830)) + memsize = MB(160) - KB(range); + break; + case INTEL_GMCH_GMS_STOLEN_224M: + if (IS_I9XX(pI830)) + memsize = MB(224) - KB(range); + break; + case INTEL_GMCH_GMS_STOLEN_352M: + if (IS_I9XX(pI830)) + memsize = MB(352) - KB(range); + break; } } else { switch (gmch_ctrl & I830_GMCH_GMS_MASK) { @@ -627,7 +653,7 @@ I830MapMMIO(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { - if (IS_IGD_GM(pI830)) { + if (IS_GM45(pI830) || IS_G4X(pI830)) { gttaddr = pI830->MMIOAddr + MB(2); pI830->GTTMapSize = MB(2); } else { @@ -898,12 +924,23 @@ I830SetupOutputs(ScrnInfoPtr pScrn) i830_lvds_init(pScrn); if (IS_I9XX(pI830)) { - i830_sdvo_init(pScrn, SDVOB); - i830_sdvo_init(pScrn, SDVOC); + if (INREG(SDVOB) & SDVO_DETECTED) { + Bool found = i830_sdvo_init(pScrn, SDVOB); + + if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) + i830_hdmi_init(pScrn, SDVOB); + } + + if (INREG(SDVOC) & SDVO_DETECTED) { + Bool found = i830_sdvo_init(pScrn, SDVOC); + + if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) + i830_hdmi_init(pScrn, SDVOC); + } } else { i830_dvo_init(pScrn); } - if (IS_I9XX(pI830) && !IS_I915G(pI830)) + if (IS_I9XX(pI830) && IS_MOBILE(pI830)) i830_tv_init(pScrn); for (o = 0; o < config->num_output; o++) @@ -936,7 +973,7 @@ i830_init_clock_gating(ScrnInfoPtr pScrn) /* Disable clock gating reported to work incorrectly according to the specs. */ - if (IS_IGD_GM(pI830)) { + if (IS_GM45(pI830) || IS_G4X(pI830)) { OUTREG(RENCLK_GATE_D1, 0); OUTREG(RENCLK_GATE_D2, 0); OUTREG(RAMCLK_GATE_D, 0); @@ -1181,9 +1218,18 @@ i830_detect_chipset(ScrnInfoPtr pScrn) case PCI_CHIP_Q33_G: chipname = "Q33"; break; - case PCI_CHIP_IGD_GM: + case PCI_CHIP_GM45_GM: + chipname = "Mobile Intel® GM45 Express Chipset"; + break; + case PCI_CHIP_IGD_E_G: chipname = "Intel Integrated Graphics Device"; break; + case PCI_CHIP_G45_G: + chipname = "G45/G43"; + break; + case PCI_CHIP_Q45_G: + chipname = "Q45/Q43"; + break; default: chipname = "unknown chipset"; break; @@ -1457,9 +1503,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { - pI830->lvds_fixed_mode = TRUE; + pI830->skip_panel_detect = FALSE; } else { - pI830->lvds_fixed_mode = FALSE; + pI830->skip_panel_detect = TRUE; } if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) @@ -1589,6 +1635,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) #endif + if (i830_bios_init(pScrn)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VBIOS initialization failed.\n"); + I830PreInitDDC(pScrn); for (i = 0; i < num_pipe; i++) { i830_crtc_init(pScrn, i); @@ -1908,22 +1958,6 @@ i830_refresh_ring(ScrnInfoPtr pScrn) i830MarkSync(pScrn); } -/* - * This should be called everytime the X server gains control of the screen, - * before any video modes are programmed (ScreenInit, EnterVT). - */ -static void -SetHWOperatingState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, "SetHWOperatingState\n"); - - i830_start_ring(pScrn); - if (!pI830->SWCursor) - I830InitHWCursor(pScrn); -} - enum pipe { PIPE_A = 0, PIPE_B, @@ -1988,6 +2022,9 @@ SaveHWState(ScrnInfoPtr pScrn) } /* Save video mode information for native mode-setting. */ + if (!DSPARB_HWCONTROL(pI830)) + pI830->saveDSPARB = INREG(DSPARB); + pI830->saveDSPACNTR = INREG(DSPACNTR); pI830->savePIPEACONF = INREG(PIPEACONF); pI830->savePIPEASRC = INREG(PIPEASRC); @@ -2069,7 +2106,7 @@ SaveHWState(ScrnInfoPtr pScrn) pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D); } - if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (IS_I965GM(pI830) || IS_GM45(pI830)) pI830->savePWRCTXA = INREG(PWRCTXA); if (IS_MOBILE(pI830) && !IS_I830(pI830)) @@ -2129,6 +2166,9 @@ RestoreHWState(ScrnInfoPtr pScrn) if (!IS_I830(pI830) && !IS_845G(pI830)) OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); + if (!DSPARB_HWCONTROL(pI830)) + OUTREG(DSPARB, pI830->saveDSPARB); + OUTREG(DSPCLK_GATE_D, pI830->saveDSPCLK_GATE_D); OUTREG(RENCLK_GATE_D1, pI830->saveRENCLK_GATE_D1); @@ -2137,7 +2177,7 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D); } - if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (IS_I965GM(pI830) || IS_GM45(pI830)) OUTREG(PWRCTXA, pI830->savePWRCTXA); /* @@ -2317,6 +2357,10 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); } + /* Clear any FIFO underrun status that may have occurred normally */ + OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN); + OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN); + vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); vgaHWLock(hwp); @@ -2449,6 +2493,7 @@ I830BlockHandler(int i, ScreenPtr pScreen = screenInfo.screens[i]; ScrnInfoPtr pScrn = xf86Screens[i]; I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); pScreen->BlockHandler = pI830->BlockHandler; @@ -2466,6 +2511,27 @@ I830BlockHandler(int i, if (pScrn->vtSema && !pI830->noAccel && !pI830->directRenderingEnabled) I830EmitFlush(pScrn); + /* + * Check for FIFO underruns at block time (which amounts to just + * periodically). If this happens, it means our DSPARB or some other + * memory arbitration setting is wrong for the current configuration + * (except for mode setting, where it may occur naturally). + * Check & ack the condition. + */ + if (pScrn->vtSema && !DSPARB_HWCONTROL(pI830)) { + if (xf86_config->crtc[0]->enabled && + (INREG(PIPEASTAT) & FIFO_UNDERRUN)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n"); + OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN); + } + if (xf86_config->num_crtc > 1 && + xf86_config->crtc[1]->enabled && + (INREG(PIPEBSTAT) & FIFO_UNDERRUN)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe B!\n"); + OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN); + } + } + I830VideoBlockHandler(i, blockData, pTimeout, pReadmask); } @@ -2527,7 +2593,7 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn) if (!i830_allocate_2d_memory(pScrn)) goto failed; - if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (IS_I965GM(pI830) || IS_GM45(pI830)) if (!i830_allocate_pwrctx(pScrn)) goto failed; @@ -2789,8 +2855,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } /* Enable FB compression if possible */ - if (i830_fb_compression_supported(pI830) && !IS_I965GM(pI830) - && !IS_IGD_GM(pI830)) + if (i830_fb_compression_supported(pI830)) pI830->fb_compression = TRUE; else pI830->fb_compression = FALSE; @@ -2901,7 +2966,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "needs 2D acceleration.\n"); pI830->XvEnabled = FALSE; } - if (!IS_IGD_GM(pI830) && pI830->overlay_regs == NULL) { + if (!OVERLAY_NOEXIST(pI830) && pI830->overlay_regs == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because the overlay register buffer " "allocation failed.\n"); @@ -2941,7 +3006,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * alone in that case. * Also make sure the DRM can handle the swap. */ - if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_IGD_GM(pI830) && + if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && (!pI830->directRenderingEnabled || (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " @@ -3177,8 +3242,8 @@ I830LeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); #ifndef HAVE_FREE_SHADOW + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int o; #endif @@ -3248,6 +3313,9 @@ I830LeaveVT(int scrnIndex, int flags) } #endif /* XF86DRI_MM */ + if (pI830->useEXA && IS_I965G(pI830)) + gen4_render_state_cleanup(pScrn); + if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; } @@ -3294,13 +3362,18 @@ I830EnterVT(int scrnIndex, int flags) /* Update the screen pixmap in case the buffer moved */ i830_update_front_offset(pScrn); + if (pI830->useEXA && IS_I965G(pI830)) + gen4_render_state_init(pScrn); + if (i830_check_error_state(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Existing errors found in hardware state.\n"); } i830_stop_ring(pScrn, FALSE); - SetHWOperatingState(pScrn); + i830_start_ring(pScrn); + if (!pI830->SWCursor) + I830InitHWCursor(pScrn); /* Tell the BIOS that we're in control of mode setting now. */ i830_init_bios_control(pScrn); diff --git a/driver/xf86-video-intel/src/i830_dvo.c b/driver/xf86-video-intel/src/i830_dvo.c index 9e8217105..832c76256 100644 --- a/driver/xf86-video-intel/src/i830_dvo.c +++ b/driver/xf86-video-intel/src/i830_dvo.c @@ -165,8 +165,9 @@ i830_dvo_restore(xf86OutputPtr output) static int i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; - struct _I830DVODriver *drv = intel_output->i2c_drv; void *dev_priv = intel_output->i2c_drv->dev_priv; if (pMode->Flags & V_DBLSCAN) @@ -174,10 +175,10 @@ i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) /* XXX: Validate clock range */ - if (drv->panel_fixed_mode) { - if (pMode->HDisplay > drv->panel_fixed_mode->HDisplay) + if (pI830->lvds_fixed_mode) { + if (pMode->HDisplay > pI830->lvds_fixed_mode->HDisplay) return MODE_PANEL; - if (pMode->VDisplay > drv->panel_fixed_mode->VDisplay) + if (pMode->VDisplay > pI830->lvds_fixed_mode->VDisplay) return MODE_PANEL; } @@ -188,24 +189,25 @@ static Bool i830_dvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) { + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; - struct _I830DVODriver *drv = intel_output->i2c_drv; /* If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - if (drv->panel_fixed_mode != NULL) { - adjusted_mode->HDisplay = drv->panel_fixed_mode->HDisplay; - adjusted_mode->HSyncStart = drv->panel_fixed_mode->HSyncStart; - adjusted_mode->HSyncEnd = drv->panel_fixed_mode->HSyncEnd; - adjusted_mode->HTotal = drv->panel_fixed_mode->HTotal; - adjusted_mode->VDisplay = drv->panel_fixed_mode->VDisplay; - adjusted_mode->VSyncStart = drv->panel_fixed_mode->VSyncStart; - adjusted_mode->VSyncEnd = drv->panel_fixed_mode->VSyncEnd; - adjusted_mode->VTotal = drv->panel_fixed_mode->VTotal; - adjusted_mode->Clock = drv->panel_fixed_mode->Clock; + if (pI830->lvds_fixed_mode != NULL) { + adjusted_mode->HDisplay = pI830->lvds_fixed_mode->HDisplay; + adjusted_mode->HSyncStart = pI830->lvds_fixed_mode->HSyncStart; + adjusted_mode->HSyncEnd = pI830->lvds_fixed_mode->HSyncEnd; + adjusted_mode->HTotal = pI830->lvds_fixed_mode->HTotal; + adjusted_mode->VDisplay = pI830->lvds_fixed_mode->VDisplay; + adjusted_mode->VSyncStart = pI830->lvds_fixed_mode->VSyncStart; + adjusted_mode->VSyncEnd = pI830->lvds_fixed_mode->VSyncEnd; + adjusted_mode->VTotal = pI830->lvds_fixed_mode->VTotal; + adjusted_mode->Clock = pI830->lvds_fixed_mode->Clock; xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); } @@ -287,8 +289,9 @@ i830_dvo_detect(xf86OutputPtr output) static DisplayModePtr i830_dvo_get_modes(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; - struct _I830DVODriver *drv = intel_output->i2c_drv; DisplayModePtr modes; /* We should probably have an i2c driver get_modes function for those @@ -307,8 +310,8 @@ i830_dvo_get_modes(xf86OutputPtr output) return modes; } - if (drv->panel_fixed_mode != NULL) - return xf86DuplicateMode(drv->panel_fixed_mode); + if (pI830->lvds_fixed_mode != NULL) + return xf86DuplicateMode(pI830->lvds_fixed_mode); return NULL; } @@ -530,8 +533,8 @@ i830_dvo_init(ScrnInfoPtr pScrn) * so for now, just get the current mode being output through * DVO. */ - drv->panel_fixed_mode = i830_dvo_get_current_mode(output); - drv->panel_wants_dither = TRUE; + pI830->lvds_fixed_mode = i830_dvo_get_current_mode(output); + pI830->lvds_dither = TRUE; } return; diff --git a/driver/xf86-video-intel/src/i830_exa.c b/driver/xf86-video-intel/src/i830_exa.c index 0ebf3dfd2..2c807c513 100644 --- a/driver/xf86-video-intel/src/i830_exa.c +++ b/driver/xf86-video-intel/src/i830_exa.c @@ -121,7 +121,6 @@ i830_pixmap_tiled(PixmapPtr pPixmap) return FALSE; } -#if EXA_VERSION_MINOR >= 2 static Bool i830_exa_pixmap_is_offscreen(PixmapPtr pPixmap) { @@ -137,7 +136,6 @@ i830_exa_pixmap_is_offscreen(PixmapPtr pPixmap) return FALSE; } } -#endif /** * I830EXASync - wait for a command to finish diff --git a/driver/xf86-video-intel/src/i830_hdmi.c b/driver/xf86-video-intel/src/i830_hdmi.c new file mode 100644 index 000000000..d56eec90f --- /dev/null +++ b/driver/xf86-video-intel/src/i830_hdmi.c @@ -0,0 +1,242 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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: + * Eric Anholt <eric@anholt.net> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "i830.h" +#include "xf86Modes.h" +#include "i830_display.h" + +struct i830_hdmi_priv { + uint32_t output_reg; + + uint32_t save_SDVO; +}; + +static int +i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode) +{ + if (mode->Clock > 165000) + return MODE_CLOCK_HIGH; + + if (mode->Clock < 20000) + return MODE_CLOCK_LOW; + + return MODE_OK; +} + +static Bool +i830_hdmi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + /* The HDMI output doesn't need the pixel multiplication that SDVO does, + * so no fixup. + */ + return TRUE; +} + +static void +i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcPtr crtc = output->crtc; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + uint32_t sdvox; + + sdvox = SDVO_ENCODING_HDMI | + SDVO_BORDER_ENABLE | + SDVO_VSYNC_ACTIVE_HIGH | + SDVO_HSYNC_ACTIVE_HIGH; + if (intel_crtc->pipe == 1) + sdvox |= SDVO_PIPE_B_SELECT; + + OUTREG(dev_priv->output_reg, sdvox); + POSTING_READ(dev_priv->output_reg); +} + +static void +i830_hdmi_dpms(xf86OutputPtr output, int mode) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + uint32_t temp; + + if (mode == DPMSModeOff) { + temp = INREG(dev_priv->output_reg); + OUTREG(dev_priv->output_reg, temp & ~SDVO_ENABLE); + } else { + temp = INREG(dev_priv->output_reg); + OUTREG(dev_priv->output_reg, temp | SDVO_ENABLE); + } +} + +static void +i830_hdmi_save(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + + dev_priv->save_SDVO = INREG(dev_priv->output_reg); +} + +static void +i830_hdmi_restore(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + + OUTREG(dev_priv->output_reg, dev_priv->save_SDVO); +} + +/** + * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect HDMI connection. + * + * \return TRUE if HDMI port is connected. + * \return FALSE if HDMI port is disconnected. + */ +static xf86OutputStatus +i830_hdmi_detect(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + uint32_t temp, bit; + + /* For G4X, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. + * Failure to do so will result in spurious interrupts being + * generated on the port when a cable is not attached. + */ + if (IS_G4X(pI830)) { + temp = INREG(PEG_BAND_GAP_DATA); + OUTREG(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); + } + + temp = INREG(PORT_HOTPLUG_EN); + + OUTREG(PORT_HOTPLUG_EN, + temp | + HDMIB_HOTPLUG_INT_EN | + HDMIC_HOTPLUG_INT_EN | + HDMID_HOTPLUG_INT_EN); + + POSTING_READ(PORT_HOTPLUG_EN); + + switch (dev_priv->output_reg) { + case SDVOB: + bit = HDMIB_HOTPLUG_INT_STATUS; + break; + case SDVOC: + bit = HDMIC_HOTPLUG_INT_STATUS; + break; + default: + return XF86OutputStatusUnknown; + } + + if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0) + return XF86OutputStatusConnected; + else + return XF86OutputStatusDisconnected; +} + +static void +i830_hdmi_destroy (xf86OutputPtr output) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + + if (intel_output != NULL) { + xf86DestroyI2CBusRec(intel_output->pDDCBus, FALSE, FALSE); + xfree(intel_output); + } +} + +static const xf86OutputFuncsRec i830_hdmi_output_funcs = { + .dpms = i830_hdmi_dpms, + .save = i830_hdmi_save, + .restore = i830_hdmi_restore, + .mode_valid = i830_hdmi_mode_valid, + .mode_fixup = i830_hdmi_mode_fixup, + .prepare = i830_output_prepare, + .mode_set = i830_hdmi_mode_set, + .commit = i830_output_commit, + .detect = i830_hdmi_detect, + .get_modes = i830_ddc_get_modes, + .destroy = i830_hdmi_destroy +}; + +void +i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg) +{ + xf86OutputPtr output; + I830OutputPrivatePtr intel_output; + struct i830_hdmi_priv *dev_priv; + + output = xf86OutputCreate(pScrn, &i830_hdmi_output_funcs, + (output_reg == SDVOB) ? "HDMI-1" : "HDMI-2"); + if (!output) + return; + intel_output = xnfcalloc(sizeof (I830OutputPrivateRec) + + sizeof (struct i830_hdmi_priv), 1); + if (intel_output == NULL) { + xf86OutputDestroy(output); + return; + } + output->driver_private = intel_output; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + + dev_priv = (struct i830_hdmi_priv *)(intel_output + 1); + dev_priv->output_reg = output_reg; + + intel_output->dev_priv = dev_priv; + intel_output->type = I830_OUTPUT_HDMI; + intel_output->pipe_mask = ((1 << 0) | (1 << 1)); + intel_output->clone_mask = (1 << I830_OUTPUT_HDMI); + + /* Set up the DDC bus. */ + if (output_reg == SDVOB) + I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_B"); + else + I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "HDMIDDC_C"); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HDMI output %d detected\n", + (output_reg == SDVOB) ? 1 : 2); +} diff --git a/driver/xf86-video-intel/src/i830_hwmc.c b/driver/xf86-video-intel/src/i830_hwmc.c index 7586ff71f..787d93da1 100644 --- a/driver/xf86-video-intel/src/i830_hwmc.c +++ b/driver/xf86-video-intel/src/i830_hwmc.c @@ -56,7 +56,7 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn) return FALSE; if (IS_I9XX(pI830)) { - if (!IS_I965G(pI830)) + if (IS_I915(pI830)) ret = intel_xvmc_set_driver(&i915_xvmc_driver); /* else @@ -122,9 +122,10 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen) Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + int size = KB(64); if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer", - &(xvmc_driver->batch), 8 * 1024, + &(xvmc_driver->batch), size, ALIGN_BOTH_ENDS)) return FALSE; diff --git a/driver/xf86-video-intel/src/i830_hwmc.h b/driver/xf86-video-intel/src/i830_hwmc.h index 6920e0168..4db9aea6f 100644 --- a/driver/xf86-video-intel/src/i830_hwmc.h +++ b/driver/xf86-video-intel/src/i830_hwmc.h @@ -47,6 +47,13 @@ #define XVMC_I945_MPEG2_VLD 0x04 #define XVMC_I965_MPEG2_VLD 0x08 +/* supported surface types */ +enum { + SURFACE_TYPE_MPEG2_MPML = FOURCC_XVMC, /* mpeg2 MP@ML */ + SURFACE_TYPE_MPEG1_MPML, /* mpeg1 MP@ML */ + SURFACE_TYPE_MAX +}; + /* common header for context private */ struct hwmc_buffer { diff --git a/driver/xf86-video-intel/src/i830_lvds.c b/driver/xf86-video-intel/src/i830_lvds.c index 4f62a2b60..96e9f003f 100644 --- a/driver/xf86-video-intel/src/i830_lvds.c +++ b/driver/xf86-video-intel/src/i830_lvds.c @@ -57,12 +57,6 @@ enum pfit_mode { }; struct i830_lvds_priv { - /* The BIOS's fixed timings for the LVDS */ - DisplayModePtr panel_fixed_mode; - - /* The panel needs dithering enabled */ - Bool panel_wants_dither; - /* The panel is in DPMS off */ Bool dpmsoff; @@ -83,6 +77,8 @@ struct i830_lvds_priv { * List of available kernel interfaces in priority order */ static char *backlight_interfaces[] = { + "asus-laptop", + "eeepc", "thinkpad_screen", "acpi_video1", "acpi_video0", @@ -132,7 +128,7 @@ i830_set_lvds_backlight_method(xf86OutputPtr output) if (i830_kernel_backlight_available(output)) { method = BCM_KERNEL; - } else if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) { + } else if (IS_I965GM(pI830) || IS_GM45(pI830)) { blc_pwm_ctl2 = INREG(BLC_PWM_CTL2); if (blc_pwm_ctl2 & BLM_LEGACY_MODE2) method = BCM_COMBO; @@ -180,7 +176,7 @@ i830_lvds_get_backlight_max_native(xf86OutputPtr output) uint32_t pwm_ctl = INREG(BLC_PWM_CTL); int val; - if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) { + if (IS_I965GM(pI830) || IS_GM45(pI830)) { val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >> BACKLIGHT_MODULATION_FREQ_SHIFT2); } else { @@ -451,7 +447,7 @@ i830_lvds_save (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (IS_I965GM(pI830) || IS_GM45(pI830)) pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); pI830->savePP_ON = INREG(LVDSPP_ON); pI830->savePP_OFF = INREG(LVDSPP_OFF); @@ -468,7 +464,7 @@ i830_lvds_restore(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (IS_I965GM(pI830) || IS_GM45(pI830)) OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2); OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL); OUTREG(LVDSPP_ON, pI830->savePP_ON); @@ -484,9 +480,9 @@ i830_lvds_restore(xf86OutputPtr output) static int i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - DisplayModePtr pFixedMode = dev_priv->panel_fixed_mode; + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + DisplayModePtr pFixedMode = pI830->lvds_fixed_mode; if (pFixedMode) { @@ -534,7 +530,7 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, } /* If we don't have a panel mode there's not much we can do */ - if (dev_priv->panel_fixed_mode == NULL) + if (pI830->lvds_fixed_mode == NULL) return TRUE; /* If we have timings from the BIOS for the panel, put them in @@ -542,19 +538,19 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - adjusted_mode->HDisplay = dev_priv->panel_fixed_mode->HDisplay; - adjusted_mode->HSyncStart = dev_priv->panel_fixed_mode->HSyncStart; - adjusted_mode->HSyncEnd = dev_priv->panel_fixed_mode->HSyncEnd; - adjusted_mode->HTotal = dev_priv->panel_fixed_mode->HTotal; - adjusted_mode->VDisplay = dev_priv->panel_fixed_mode->VDisplay; - adjusted_mode->VSyncStart = dev_priv->panel_fixed_mode->VSyncStart; - adjusted_mode->VSyncEnd = dev_priv->panel_fixed_mode->VSyncEnd; - adjusted_mode->VTotal = dev_priv->panel_fixed_mode->VTotal; - adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock; + adjusted_mode->HDisplay = pI830->lvds_fixed_mode->HDisplay; + adjusted_mode->HSyncStart = pI830->lvds_fixed_mode->HSyncStart; + adjusted_mode->HSyncEnd = pI830->lvds_fixed_mode->HSyncEnd; + adjusted_mode->HTotal = pI830->lvds_fixed_mode->HTotal; + adjusted_mode->VDisplay = pI830->lvds_fixed_mode->VDisplay; + adjusted_mode->VSyncStart = pI830->lvds_fixed_mode->VSyncStart; + adjusted_mode->VSyncEnd = pI830->lvds_fixed_mode->VSyncEnd; + adjusted_mode->VTotal = pI830->lvds_fixed_mode->VTotal; + adjusted_mode->Clock = pI830->lvds_fixed_mode->Clock; xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); /* Make sure pre-965s set dither correctly */ - if (!IS_I965G(pI830) && dev_priv->panel_wants_dither) + if (!IS_I965G(pI830) && pI830->lvds_dither) pfit_control |= PANEL_8TO6_DITHER_ENABLE; /* Native modes don't need fitting */ @@ -595,12 +591,12 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, * LVDS borders are enabled (see i830_display.c). */ left_border = - (dev_priv->panel_fixed_mode->HDisplay - mode->HDisplay) / 2; + (pI830->lvds_fixed_mode->HDisplay - mode->HDisplay) / 2; right_border = left_border; if (mode->HDisplay & 1) right_border++; top_border = - (dev_priv->panel_fixed_mode->VDisplay - mode->VDisplay) / 2; + (pI830->lvds_fixed_mode->VDisplay - mode->VDisplay) / 2; bottom_border = top_border; if (mode->VDisplay & 1) bottom_border++; @@ -659,7 +655,7 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, HORIZ_INTERP_BILINEAR; /* Pillar will have left/right borders */ - left_border = (dev_priv->panel_fixed_mode->HDisplay - + left_border = (pI830->lvds_fixed_mode->HDisplay - scaled_width) / 2; right_border = left_border; if (mode->HDisplay & 1) /* odd resolutions */ @@ -682,7 +678,7 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, HORIZ_INTERP_BILINEAR; /* Letterbox will have top/bottom borders */ - top_border = (dev_priv->panel_fixed_mode->VDisplay - + top_border = (pI830->lvds_fixed_mode->VDisplay - scaled_height) / 2; bottom_border = top_border; if (mode->VDisplay & 1) @@ -784,8 +780,9 @@ i830_lvds_detect(xf86OutputPtr output) static DisplayModePtr i830_lvds_get_modes(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; xf86MonPtr edid_mon; DisplayModePtr modes; @@ -814,8 +811,8 @@ i830_lvds_get_modes(xf86OutputPtr output) } } - if (dev_priv->panel_fixed_mode != NULL) - return xf86DuplicateMode(dev_priv->panel_fixed_mode); + if (pI830->lvds_fixed_mode != NULL) + return xf86DuplicateMode(pI830->lvds_fixed_mode); return NULL; } @@ -823,15 +820,13 @@ i830_lvds_get_modes(xf86OutputPtr output) static void i830_lvds_destroy (xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); I830OutputPrivatePtr intel_output = output->driver_private; + xf86DeleteMode (&pI830->lvds_fixed_mode, pI830->lvds_fixed_mode); if (intel_output) - { - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - - xf86DeleteMode (&dev_priv->panel_fixed_mode, dev_priv->panel_fixed_mode); xfree (intel_output); - } } #ifdef RANDR_12_INTERFACE @@ -1215,7 +1210,8 @@ i830_lvds_init(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); xf86OutputPtr output; I830OutputPrivatePtr intel_output; - DisplayModePtr modes, scan, bios_mode; + DisplayModePtr modes, scan; + DisplayModePtr lvds_ddc_mode = NULL; struct i830_lvds_priv *dev_priv; if (pI830->quirk_flag & QUIRK_IGNORE_LVDS) @@ -1242,17 +1238,27 @@ i830_lvds_init(ScrnInfoPtr pScrn) dev_priv = (struct i830_lvds_priv *) (intel_output + 1); intel_output->dev_priv = dev_priv; + + /* + * Mode detection algorithms for LFP: + * 1) if EDID present, use it, done + * 2) if VBT present, use it, done + * 3) if current mode is programmed, use it, done + * 4) check for Mac mini & other quirks + * 4) fail, assume no LFP + */ /* Set up the LVDS DDC channel. Most panels won't support it, but it can * be useful if available. */ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C"); - if (!pI830->lvds_fixed_mode) { + if (pI830->skip_panel_detect) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Skipping any attempt to determine panel fixed mode.\n"); - goto skip_panel_fixed_mode_setup; + goto found_mode; } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Attempting to determine panel fixed mode.\n"); @@ -1272,74 +1278,47 @@ i830_lvds_init(ScrnInfoPtr pScrn) scan->prev = scan->next; if (scan->next != NULL) scan->next = scan->prev; - dev_priv->panel_fixed_mode = scan; + lvds_ddc_mode = scan; } /* Delete the mode list */ while (modes != NULL) xf86DeleteMode(&modes, modes); - /* If we didn't get EDID, try checking if the panel is already turned on. - * If so, assume that whatever is currently programmed is the correct mode. - */ - if (dev_priv->panel_fixed_mode == NULL) { - uint32_t lvds = INREG(LVDS); - int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc = xf86_config->crtc[pipe]; - - if (lvds & LVDS_PORT_EN) { - dev_priv->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc); - if (dev_priv->panel_fixed_mode != NULL) - dev_priv->panel_fixed_mode->type |= M_T_PREFERRED; - } + if (lvds_ddc_mode) { + pI830->lvds_fixed_mode = lvds_ddc_mode; + goto found_mode; } /* Get the LVDS fixed mode out of the BIOS. We should support LVDS with * the BIOS being unavailable or broken, but lack the configuration options * for now. */ - bios_mode = i830_bios_get_panel_mode(pScrn, &dev_priv->panel_wants_dither); - if (bios_mode != NULL) { - if (dev_priv->panel_fixed_mode != NULL) { - /* Fixup for a 1280x768 panel with the horizontal trimmed - * down to 1024 for text mode. - */ - if (!xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode) && - dev_priv->panel_fixed_mode->HDisplay == 1024 && - dev_priv->panel_fixed_mode->HSyncStart == 1200 && - dev_priv->panel_fixed_mode->HSyncEnd == 1312 && - dev_priv->panel_fixed_mode->HTotal == 1688 && - dev_priv->panel_fixed_mode->VDisplay == 768) - { - dev_priv->panel_fixed_mode->HDisplay = 1280; - dev_priv->panel_fixed_mode->HSyncStart = 1328; - dev_priv->panel_fixed_mode->HSyncEnd = 1440; - dev_priv->panel_fixed_mode->HTotal = 1688; - } + if (pI830->lvds_fixed_mode) + goto found_mode; + + /* If we *still* don't have a mode, try checking if the panel is already + * turned on. If so, assume that whatever is currently programmed is the + * correct mode. + */ + if (!pI830->lvds_fixed_mode) { + uint32_t lvds = INREG(LVDS); + int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc = xf86_config->crtc[pipe]; - if (pI830->debug_modes && - !xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode)) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "BIOS panel mode data doesn't match probed data, " - "continuing with probed.\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n"); - xf86PrintModeline(pScrn->scrnIndex, bios_mode); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n"); - xf86PrintModeline(pScrn->scrnIndex, dev_priv->panel_fixed_mode); - xfree(bios_mode->name); - xfree(bios_mode); + if (lvds & LVDS_PORT_EN) { + pI830->lvds_fixed_mode = i830_crtc_mode_get(pScrn, crtc); + if (pI830->lvds_fixed_mode != NULL) { + pI830->lvds_fixed_mode->type |= M_T_PREFERRED; + goto found_mode; } - } else { - dev_priv->panel_fixed_mode = bios_mode; } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't detect panel mode. Disabling panel\n"); - goto disable_exit; } - skip_panel_fixed_mode_setup: + if (!pI830->lvds_fixed_mode) + goto disable_exit; + +found_mode: /* Blacklist machines with BIOSes that list an LVDS panel without actually * having one. @@ -1354,9 +1333,9 @@ i830_lvds_init(ScrnInfoPtr pScrn) * display. */ - if (dev_priv->panel_fixed_mode != NULL && - dev_priv->panel_fixed_mode->HDisplay == 800 && - dev_priv->panel_fixed_mode->VDisplay == 600) + if (pI830->lvds_fixed_mode != NULL && + pI830->lvds_fixed_mode->HDisplay == 800 && + pI830->lvds_fixed_mode->VDisplay == 600) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Suspected Mac Mini, ignoring the LVDS\n"); diff --git a/driver/xf86-video-intel/src/i830_memory.c b/driver/xf86-video-intel/src/i830_memory.c index ccbe7bd1e..0a2faebb3 100644 --- a/driver/xf86-video-intel/src/i830_memory.c +++ b/driver/xf86-video-intel/src/i830_memory.c @@ -335,7 +335,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn) pI830->xaa_scratch = NULL; pI830->xaa_scratch_2 = NULL; pI830->exa_offscreen = NULL; - pI830->exa_965_state = NULL; + pI830->gen4_render_state_mem = NULL; pI830->overlay_regs = NULL; pI830->logical_context = NULL; pI830->power_context = NULL; @@ -447,7 +447,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) /* Overlay and cursors, if physical, need to be allocated outside * of the kernel memory manager. */ - if (!OVERLAY_NOPHYSICAL(pI830) && !IS_IGD_GM(pI830)) { + if (!OVERLAY_NOPHYSICAL(pI830) && !OVERLAY_NOEXIST(pI830)) { mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE); } if (pI830->CursorNeedsPhysical) { @@ -459,7 +459,8 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) /* Can't do TTM on stolen memory */ mmsize -= pI830->stolen_size; - if (HWS_NEED_GFX(pI830) && IS_IGD_GM(pI830)) + /* new chipsets need non-stolen status page */ + if (HWS_NEED_GFX(pI830) && HWS_NEED_NONSTOLEN(pI830)) mmsize -= HWSTATUS_PAGE_SIZE; /* Create the aperture allocation */ @@ -1027,7 +1028,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) if (!pI830->XvEnabled) return TRUE; - if (IS_IGD_GM(pI830)) + if (OVERLAY_NOEXIST(pI830)) return TRUE; if (!OVERLAY_NOPHYSICAL(pI830)) @@ -1281,7 +1282,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn) goto out; } - if (IS_IGD_GM(pI830)) { + if (IS_GM45(pI830)) { /* Update i830_display.c too if compression ratio changes */ compressed_size = fb_height * (pScrn->displayWidth / 4); } else { @@ -1308,7 +1309,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn) goto out; } - if (!IS_IGD_GM(pI830)) { + if (!IS_GM45(pI830)) { pI830->compressed_ll_buffer = i830_allocate_memory(pScrn, "compressed ll buffer", FBC_LL_SIZE + FBC_LL_PAD, KB(4), @@ -1372,11 +1373,14 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) } /* even in XAA, 965G needs state mem buffer for rendering */ - if (IS_I965G(pI830) && !pI830->noAccel && pI830->exa_965_state == NULL) { - pI830->exa_965_state = + if (IS_I965G(pI830) && !pI830->noAccel && + pI830->gen4_render_state_mem == NULL) + { + pI830->gen4_render_state_mem = i830_allocate_memory(pScrn, "exa G965 state buffer", - EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); - if (pI830->exa_965_state == NULL) { + gen4_render_state_size(pScrn), + GTT_PAGE_SIZE, 0); + if (pI830->gen4_render_state_mem == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate exa state buffer for 965.\n"); return FALSE; @@ -1643,7 +1647,7 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn) * (i.e. not through buffer objects). */ flags = NEED_LIFETIME_FIXED; - if (IS_IGD_GM(pI830)) + if (HWS_NEED_NONSTOLEN(pI830)) flags |= NEED_NON_STOLEN; pI830->hw_status = i830_allocate_memory(pScrn, "HW status", HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, flags); diff --git a/driver/xf86-video-intel/src/i830_quirks.c b/driver/xf86-video-intel/src/i830_quirks.c index 1bd8885c0..a3ed04404 100644 --- a/driver/xf86-video-intel/src/i830_quirks.c +++ b/driver/xf86-video-intel/src/i830_quirks.c @@ -203,7 +203,8 @@ static void quirk_lenovo_tv_dmi (I830Ptr pI830) ErrorF("Failed to load DMI info, X60 TV quirk not applied.\n"); return; } - if (!strncmp(i830_dmi_data[bios_version], "7B", 2)) + if (!strncmp(i830_dmi_data[bios_version], "7B", 2) || /* X60, X60s */ + !strncmp(i830_dmi_data[bios_version], "7E", 2)) /* R60e */ pI830->quirk_flag |= QUIRK_IGNORE_TV; } @@ -222,6 +223,9 @@ static i830_quirk i830_quirk_list[] = { /* Apple Mac mini has no lvds, but macbook pro does */ { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini }, + /* Transtec Senyo 610 mini pc */ + { PCI_CHIP_I965_GM, 0x1509, 0x2f15, quirk_ignore_lvds }, + /* Clevo M720R has no tv output */ { PCI_CHIP_I965_GM, 0x1558, 0x0721, quirk_ignore_tv }, @@ -266,7 +270,7 @@ static i830_quirk i830_quirk_list[] = { { PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv }, /* HP Compaq 6730s has no TV output */ - { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv }, + { PCI_CHIP_GM45_GM, 0x103c, 0x30e8, quirk_ignore_tv }, /* Thinkpad R31 needs pipe A force quirk */ { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force }, @@ -284,10 +288,17 @@ static i830_quirk i830_quirk_list[] = { { PCI_CHIP_I915_GM, 0x1179, 0x0001, quirk_pipea_force }, /* Intel 855GM hardware (See LP: #216490) */ { PCI_CHIP_I855_GM, 0x1028, 0x00c8, quirk_pipea_force }, + /* Intel 855GM hardware (See Novell Bugzilla #406123) */ + { PCI_CHIP_I855_GM, 0x10cf, 0x1215, quirk_pipea_force }, + /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */ + { PCI_CHIP_I855_GM, 0x103c, 0x3084, quirk_pipea_force }, /* ThinkPad X40 needs pipe A force quirk */ { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force }, + /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ + { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_pipea_force }, + /* Sony vaio PCG-r600HFP (fix bug 13722) */ { PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob }, /* Sony vaio VGN-SZ4MN (See LP: #212163) */ @@ -302,6 +313,10 @@ static i830_quirk i830_quirk_list[] = { /* Littlebit Sepia X35 (rebranded Asus Z37E) (See LP: #201257) */ { PCI_CHIP_I965_GM, 0x1043, 0x8265, quirk_ignore_tv }, + /* 855 & before need to leave pipe A & dpll A up */ + { PCI_CHIP_I855_GM, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force }, + { PCI_CHIP_845_G, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force }, + { 0, 0, 0, NULL }, }; @@ -318,9 +333,10 @@ void i830_fixup_devices(ScrnInfoPtr scrn) while (p && p->chipType != 0) { if (DEVICE_ID(pI830->PciInfo) == p->chipType && - SUBVENDOR_ID(pI830->PciInfo) == p->subsysVendor && - (SUBSYS_ID(pI830->PciInfo) == p->subsysCard || - p->subsysCard == SUBSYS_ANY)) + (SUBVENDOR_ID(pI830->PciInfo) == p->subsysVendor || + p->subsysVendor == SUBSYS_ANY) && + (SUBSYS_ID(pI830->PciInfo) == p->subsysCard || + p->subsysCard == SUBSYS_ANY)) p->hook(pI830); ++p; } diff --git a/driver/xf86-video-intel/src/i830_sdvo.c b/driver/xf86-video-intel/src/i830_sdvo.c index 0dc6dca30..8f1b20b79 100644 --- a/driver/xf86-video-intel/src/i830_sdvo.c +++ b/driver/xf86-video-intel/src/i830_sdvo.c @@ -59,7 +59,7 @@ struct i830_sdvo_priv { int output_device; /** Active outputs controlled by this SDVO output */ - uint16_t active_outputs; + uint16_t controlled_output; /** * Capabilities of the SDVO device returned by i830_sdvo_get_capabilities() @@ -69,6 +69,40 @@ struct i830_sdvo_priv { /** Pixel clock limitations reported by the SDVO device, in kHz */ int pixel_clock_min, pixel_clock_max; + /** + * This is set if we're going to treat the device as TV-out. + * + * While we have these nice friendly flags for output types that ought to + * decide this for us, the S-Video output on our HDMI+S-Video card shows + * up as RGB1 (VGA). + */ + Bool is_tv; + + /** + * This is set if we treat the device as HDMI, instead of DVI. + */ + Bool is_hdmi; + + /** + * Returned SDTV resolutions allowed for the current format, if the + * device reported it. + */ + struct i830_sdvo_sdtv_resolution_reply sdtv_resolutions; + + /** + * Current selected TV format. + * + * This is stored in the same structure that's passed to the device, for + * convenience. + */ + struct i830_sdvo_tv_format tv_format; + + /** supported encoding mode, used to determine whether HDMI is supported */ + struct i830_sdvo_encode encode; + + /** DDC bus used by this SDVO output */ + uint8_t ddc_bus; + /** State for save/restore */ /** @{ */ int save_sdvo_mult; @@ -199,13 +233,35 @@ const static struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODER_POWER_STATE), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), + /* HDMI op code */ + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), }; static I2CSlaveAddr slaveAddr; -#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVO" : "SDVO") +#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") #define SDVO_PRIV(output) ((struct i830_sdvo_priv *) (output)->dev_priv) /** @@ -529,13 +585,12 @@ i830_sdvo_set_output_timing(xf86OutputPtr output, struct i830_sdvo_dtd *dtd) return i830_sdvo_set_timing(output, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); } -#if 0 static Bool i830_sdvo_create_preferred_input_timing(xf86OutputPtr output, uint16_t clock, uint16_t width, uint16_t height) { - struct i830_sdvo_priv *dev_priv = output->dev_priv; struct i830_sdvo_preferred_input_timing_args args; + uint8_t status; args.clock = clock; args.width = width; @@ -550,10 +605,10 @@ i830_sdvo_create_preferred_input_timing(xf86OutputPtr output, uint16_t clock, } static Bool -i830_sdvo_get_preferred_input_timing(I830OutputPtr output, +i830_sdvo_get_preferred_input_timing(xf86OutputPtr output, struct i830_sdvo_dtd *dtd) { - struct i830_sdvo_priv *dev_priv = output->dev_priv; + Bool status; i830_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, NULL, 0); @@ -571,7 +626,6 @@ i830_sdvo_get_preferred_input_timing(I830OutputPtr output, return TRUE; } -#endif /** Returns the SDVO_CLOCK_RATE_MULT_* for the current clock multiplier */ static int @@ -616,43 +670,16 @@ i830_sdvo_set_clock_rate_mult(xf86OutputPtr output, uint8_t val) return TRUE; } -static Bool -i830_sdvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO - * device will be told of the multiplier during mode_set. - */ - adjusted_mode->Clock *= i830_sdvo_get_pixel_multiplier(mode); - - return TRUE; -} - static void -i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) +i830_sdvo_get_dtd_from_mode(struct i830_sdvo_dtd *dtd, DisplayModePtr mode) { - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - uint32_t sdvox; - int sdvo_pixel_multiply; uint16_t width, height; uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; uint16_t h_sync_offset, v_sync_offset; - struct i830_sdvo_dtd output_dtd; - uint16_t no_outputs; - - no_outputs = 0; - if (!mode) - return; width = mode->CrtcHDisplay; height = mode->CrtcVDisplay; - + /* do some mode translations */ h_blank_len = mode->CrtcHBlankEnd - mode->CrtcHBlankStart; h_sync_len = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; @@ -663,37 +690,368 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, h_sync_offset = mode->CrtcHSyncStart - mode->CrtcHBlankStart; v_sync_offset = mode->CrtcVSyncStart - mode->CrtcVBlankStart; - output_dtd.part1.clock = mode->Clock / 10; - output_dtd.part1.h_active = width & 0xff; - output_dtd.part1.h_blank = h_blank_len & 0xff; - output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) | + dtd->part1.clock = mode->Clock / 10; + dtd->part1.h_active = width & 0xff; + dtd->part1.h_blank = h_blank_len & 0xff; + dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | ((h_blank_len >> 8) & 0xf); - output_dtd.part1.v_active = height & 0xff; - output_dtd.part1.v_blank = v_blank_len & 0xff; - output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) | + dtd->part1.v_active = height & 0xff; + dtd->part1.v_blank = v_blank_len & 0xff; + dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | ((v_blank_len >> 8) & 0xf); - output_dtd.part2.h_sync_off = h_sync_offset; - output_dtd.part2.h_sync_width = h_sync_len & 0xff; - output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | + dtd->part2.h_sync_off = h_sync_offset; + dtd->part2.h_sync_width = h_sync_len & 0xff; + dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | (v_sync_len & 0xf); - output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | + dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4); - output_dtd.part2.dtd_flags = 0x18; + dtd->part2.dtd_flags = 0x18; if (mode->Flags & V_PHSYNC) - output_dtd.part2.dtd_flags |= 0x2; + dtd->part2.dtd_flags |= 0x2; if (mode->Flags & V_PVSYNC) - output_dtd.part2.dtd_flags |= 0x4; + dtd->part2.dtd_flags |= 0x4; + + dtd->part2.sdvo_flags = 0; + dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; + dtd->part2.reserved = 0; +} + +static void +i830_sdvo_get_mode_from_dtd(DisplayModePtr mode, struct i830_sdvo_dtd *dtd) +{ + uint16_t width, height; + uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; + uint16_t h_sync_offset, v_sync_offset; + + width = mode->CrtcHDisplay; + height = mode->CrtcVDisplay; + + /* do some mode translations */ + h_blank_len = mode->CrtcHBlankEnd - mode->CrtcHBlankStart; + h_sync_len = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; + + v_blank_len = mode->CrtcVBlankEnd - mode->CrtcVBlankStart; + v_sync_len = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + + h_sync_offset = mode->CrtcHSyncStart - mode->CrtcHBlankStart; + v_sync_offset = mode->CrtcVSyncStart - mode->CrtcVBlankStart; + + mode->HDisplay = dtd->part1.h_active; + mode->HDisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; + mode->HSyncStart = mode->HDisplay + dtd->part2.h_sync_off; + mode->HSyncStart += (dtd->part2.sync_off_width_high & 0xa0) << 2; + mode->HSyncEnd = mode->HSyncStart + dtd->part2.h_sync_width; + mode->HSyncEnd += (dtd->part2.sync_off_width_high & 0x30) << 4; + mode->HTotal = mode->HDisplay + dtd->part1.h_blank; + mode->HTotal += (dtd->part1.h_high & 0xf) << 8; + + mode->VDisplay = dtd->part1.v_active; + mode->VDisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; + mode->VSyncStart = mode->VDisplay; + mode->VSyncStart += (dtd->part2.v_sync_off_width >> 4) & 0xf; + mode->VSyncStart += (dtd->part2.sync_off_width_high & 0x0a) << 2; + mode->VSyncStart += dtd->part2.v_sync_off_high & 0xc0; + mode->VSyncEnd = mode->VSyncStart + (dtd->part2.v_sync_off_width & 0xf); + mode->VSyncEnd += (dtd->part2.sync_off_width_high & 0x3) << 4; + mode->VTotal = mode->VDisplay + dtd->part1.v_blank; + mode->VTotal += (dtd->part1.v_high & 0xf) << 8; + + mode->Clock = dtd->part1.clock * 10; + + mode->Flags &= (V_PHSYNC | V_PVSYNC); + if (dtd->part2.dtd_flags & 0x2) + mode->Flags |= V_PHSYNC; + if (dtd->part2.dtd_flags & 0x4) + mode->Flags |= V_PVSYNC; +} + +static Bool +i830_sdvo_get_supp_encode(xf86OutputPtr output, struct i830_sdvo_encode *encode) +{ + uint8_t status; + + i830_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); + status = i830_sdvo_read_response(output, encode, sizeof(*encode)); + if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ + memset(encode, 0, sizeof(*encode)); + return FALSE; + } + + return TRUE; +} + +static Bool +i830_sdvo_set_encode(xf86OutputPtr output, uint8_t mode) +{ + uint8_t status; + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); + status = i830_sdvo_read_response(output, NULL, 0); + + return (status == SDVO_CMD_STATUS_SUCCESS); +} + +static Bool +i830_sdvo_set_colorimetry(xf86OutputPtr output, uint8_t mode) +{ + uint8_t status; + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); + status = i830_sdvo_read_response(output, NULL, 0); + + return (status == SDVO_CMD_STATUS_SUCCESS); +} + +#if 0 +static Bool +i830_sdvo_set_pixel_repli(xf86OutputPtr output, uint8_t repli) +{ + uint8_t status; + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_PIXEL_REPLI, &repli, 1); + status = i830_sdvo_read_response(output, NULL, 0); + + return (status == SDVO_CMD_STATUS_SUCCESS); +} +#endif + +static void i830_sdvo_dump_hdmi_buf(xf86OutputPtr output) +{ + int i, j; + uint8_t set_buf_index[2]; + uint8_t av_split; + uint8_t buf_size; + uint8_t buf[48]; + uint8_t *pos; + + i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); + i830_sdvo_read_response(output, &av_split, 1); + + for (i = 0; i <= av_split; i++) { + set_buf_index[0] = i; set_buf_index[1] = 0; + i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2); + i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); + i830_sdvo_read_response(output, &buf_size, 1); + + pos = buf; + for (j = 0; j <= buf_size; j += 8) { + i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, NULL, 0); + i830_sdvo_read_response(output, pos, 8); + pos += 8; + } + } +} + +static void i830_sdvo_set_hdmi_buf(xf86OutputPtr output, int index, + uint8_t *data, int8_t size, uint8_t tx_rate) +{ + uint8_t set_buf_index[2]; + + set_buf_index[0] = index; + set_buf_index[1] = 0; + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); + + for (; size > 0; size -= 8) { + i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); + data += 8; + } + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); +} + +static uint8_t i830_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) +{ + uint8_t csum = 0; + int i; + + for (i = 0; i < size; i++) + csum += data[i]; + + return 0x100 - csum; +} + +#define DIP_TYPE_AVI 0x82 +#define DIP_VERSION_AVI 0x2 +#define DIP_LEN_AVI 13 + +struct dip_infoframe { + uint8_t type; + uint8_t version; + uint8_t len; + uint8_t checksum; + union { + struct { + /* Packet Byte #1 */ + uint8_t S:2; + uint8_t B:2; + uint8_t A:1; + uint8_t Y:2; + uint8_t rsvd1:1; + /* Packet Byte #2 */ + uint8_t R:4; + uint8_t M:2; + uint8_t C:2; + /* Packet Byte #3 */ + uint8_t SC:2; + uint8_t Q:2; + uint8_t EC:3; + uint8_t ITC:1; + /* Packet Byte #4 */ + uint8_t VIC:7; + uint8_t rsvd2:1; + /* Packet Byte #5 */ + uint8_t PR:4; + uint8_t rsvd3:4; + /* Packet Byte #6~13 */ + uint16_t top_bar_end; + uint16_t bottom_bar_start; + uint16_t left_bar_end; + uint16_t right_bar_start; + } avi; + struct { + /* Packet Byte #1 */ + uint8_t CC:3; + uint8_t rsvd1:1; + uint8_t CT:4; + /* Packet Byte #2 */ + uint8_t SS:2; + uint8_t SF:3; + uint8_t rsvd2:3; + /* Packet Byte #3 */ + uint8_t CXT:5; + uint8_t rsvd3:3; + /* Packet Byte #4 */ + uint8_t CA; + /* Packet Byte #5 */ + uint8_t rsvd4:3; + uint8_t LSV:4; + uint8_t DM_INH:1; + } audio; + uint8_t payload[28]; + } __attribute__ ((packed)) u; +} __attribute__((packed)); + +static void i830_sdvo_set_avi_infoframe(xf86OutputPtr output, + DisplayModePtr mode) +{ + struct dip_infoframe avi_if = { + .type = DIP_TYPE_AVI, + .version = DIP_VERSION_AVI, + .len = DIP_LEN_AVI, + }; + + avi_if.u.avi.PR = i830_sdvo_get_pixel_multiplier(mode) - 1; + avi_if.checksum = i830_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, + 4 + avi_if.len); + i830_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, + SDVO_HBUF_TX_VSYNC); +} + +static Bool +i830_sdvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + + if (!dev_priv->is_tv) { + /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO + * device will be told of the multiplier during mode_set. + */ + adjusted_mode->Clock *= i830_sdvo_get_pixel_multiplier(mode); + } else { + struct i830_sdvo_dtd output_dtd; + Bool success; + + /* We need to construct preferred input timings based on our output + * timings. To do that, we have to set the output timings, even + * though this isn't really the right place in the sequence to do it. + * Oh well. + */ + + ErrorF("output modeline:\n"); + xf86PrintModeline(0, mode); + + /* Set output timings */ + i830_sdvo_get_dtd_from_mode(&output_dtd, mode); + i830_sdvo_set_target_output(output, dev_priv->controlled_output); + i830_sdvo_set_output_timing(output, &output_dtd); + + /* Set the input timing to the screen. Assume always input 0. */ + i830_sdvo_set_target_input(output, TRUE, FALSE); + + + success = i830_sdvo_create_preferred_input_timing(output, + mode->Clock / 10, + mode->HDisplay, + mode->VDisplay); + if (success) { + struct i830_sdvo_dtd input_dtd; + + i830_sdvo_get_preferred_input_timing(output, &input_dtd); + + i830_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); + + ErrorF("input modeline:\n"); + xf86PrintModeline(0, adjusted_mode); + } else { + return FALSE; + } + } + + return TRUE; +} - output_dtd.part2.sdvo_flags = 0; - output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0; - output_dtd.part2.reserved = 0; +static void +i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + xf86CrtcPtr crtc = output->crtc; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + uint32_t sdvox; + int sdvo_pixel_multiply; + struct i830_sdvo_in_out_map in_out; + struct i830_sdvo_dtd input_dtd; + uint8_t status; - /* Set the output timing to the screen */ - i830_sdvo_set_target_output(output, dev_priv->active_outputs); - i830_sdvo_set_output_timing(output, &output_dtd); + if (!mode) + return; + + /* First, set the input mapping for the first input to our controlled + * output. This is only correct if we're a single-input device, in + * which case the first input is the output from the appropriate SDVO + * channel on the motherboard. In a two-input device, the first input + * will be SDVOB and the second SDVOC. + */ + in_out.in0 = dev_priv->controlled_output; + in_out.in1 = 0; + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, + &in_out, sizeof(in_out)); + status = i830_sdvo_read_response(output, NULL, 0); + + if (dev_priv->is_hdmi) + i830_sdvo_set_avi_infoframe(output, mode); + + i830_sdvo_get_dtd_from_mode(&input_dtd, mode); + + /* If it's a TV, we already set the output timing in mode_fixup. + * Otherwise, the output timing is equal to the input timing. + */ + if (!dev_priv->is_tv) { + /* Set the output timing to the screen */ + i830_sdvo_set_target_output(output, dev_priv->controlled_output); + i830_sdvo_set_output_timing(output, &input_dtd); + } /* Set the input timing to the screen. Assume always input 0. */ i830_sdvo_set_target_input(output, TRUE, FALSE); @@ -713,7 +1071,7 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, i830_sdvo_set_input_timing(output, &input_dtd); } #else - i830_sdvo_set_input_timing(output, &output_dtd); + i830_sdvo_set_input_timing(output, &input_dtd); #endif switch (i830_sdvo_get_pixel_multiplier(mode)) { @@ -802,7 +1160,7 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) if (0) i830_sdvo_set_encoder_power_state(output, mode); - i830_sdvo_set_active_outputs(output, dev_priv->active_outputs); + i830_sdvo_set_active_outputs(output, dev_priv->controlled_output); } } @@ -820,12 +1178,10 @@ i830_sdvo_save(xf86OutputPtr output) dev_priv->save_sdvo_mult = i830_sdvo_get_clock_rate_mult(output); i830_sdvo_get_active_outputs(output, &dev_priv->save_active_outputs); - if (dev_priv->caps.sdvo_inputs_mask & 0x1) { - i830_sdvo_set_target_input(output, TRUE, FALSE); - i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1); - } + i830_sdvo_set_target_input(output, TRUE, FALSE); + i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1); - if (dev_priv->caps.sdvo_inputs_mask & 0x2) { + if (dev_priv->caps.sdvo_input_count >= 2) { i830_sdvo_set_target_input(output, FALSE, TRUE); i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_2); } @@ -839,6 +1195,9 @@ i830_sdvo_save(xf86OutputPtr output) i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd[o]); } } + if (dev_priv->is_tv) { + /* XXX: Save TV format/enhancements. */ + } dev_priv->save_SDVOX = INREG(dev_priv->output_device); } @@ -866,18 +1225,20 @@ i830_sdvo_restore(xf86OutputPtr output) } } - if (dev_priv->caps.sdvo_inputs_mask & 0x1) { - i830_sdvo_set_target_input(output, TRUE, FALSE); - i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1); - } + i830_sdvo_set_target_input(output, TRUE, FALSE); + i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1); - if (dev_priv->caps.sdvo_inputs_mask & 0x2) { + if (dev_priv->caps.sdvo_input_count >= 2) { i830_sdvo_set_target_input(output, FALSE, TRUE); i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2); } i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult); + if (dev_priv->is_tv) { + /* XXX: Restore TV format/enhancements. */ + } + i830_sdvo_write_sdvox(output, dev_priv->save_SDVOX); if (dev_priv->save_SDVOX & SDVO_ENABLE) @@ -972,8 +1333,9 @@ i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout) xf86OutputPtr output = b->DriverPrivate.ptr; I830OutputPrivatePtr intel_output = output->driver_private; I2CBusPtr i2cbus = intel_output->pI2CBus; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - i830_sdvo_set_control_bus_switch(output, SDVO_CONTROL_BUS_DDC2); + i830_sdvo_set_control_bus_switch(output, dev_priv->ddc_bus); return i2cbus->I2CStart(i2cbus, timeout); } @@ -1054,6 +1416,17 @@ i830_sdvo_dump_device(xf86OutputPtr output) i830_sdvo_dump_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT); i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_TV_FORMATS); i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TV_FORMAT); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS); + + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPP_ENCODE); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ENCODE); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_PIXEL_REPLI); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY_CAP); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER); + i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_STAT); + i830_sdvo_dump_hdmi_buf(output); } void @@ -1100,7 +1473,7 @@ i830_sdvo_detect(xf86OutputPtr output) } static DisplayModePtr -i830_sdvo_get_modes(xf86OutputPtr output) +i830_sdvo_get_ddc_modes(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -1132,6 +1505,127 @@ i830_sdvo_get_modes(xf86OutputPtr output) return modes; } +/** + * Constructs a DisplayModeRec for the given widht/height/refresh, which will + * be programmed into the display pipe. The TV encoder's scaler will filter + * this to the format actually required by the display. + */ +static void +i830_sdvo_get_tv_mode(DisplayModePtr *head, int width, int height, + float refresh) +{ + DisplayModePtr mode; + + mode = xcalloc(1, sizeof(*mode)); + if (mode == NULL) + return; + + mode->name = XNFprintf("%dx%d@%.2f", width, height, refresh); + mode->HDisplay = width; + mode->HSyncStart = width + 1; + mode->HSyncEnd = width + 64; + mode->HTotal = width + 96; + + mode->VDisplay = height; + mode->VSyncStart = height + 1; + mode->VSyncEnd = height + 32; + mode->VTotal = height + 33; + + mode->Clock = (int) (refresh * mode->VTotal * mode->HTotal / 1000.0); + mode->type = M_T_DRIVER; + mode->next = NULL; + mode->prev = NULL; + + mode->next = *head; + mode->prev = NULL; + if (*head != NULL) + (*head)->prev = mode; + *head = mode; +} + +/** + * This function checks the current TV format, and chooses a default if + * it hasn't been set. + */ +static void +i830_sdvo_check_tv_format(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + struct i830_sdvo_tv_format format, unset; + uint8_t status; + + i830_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); + status = i830_sdvo_read_response(output, &format, sizeof(format)); + if (status != SDVO_CMD_STATUS_SUCCESS) + return; + + memset(&unset, 0, sizeof(unset)); + if (memcmp(&format, &unset, sizeof(format))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s: Choosing default TV format of NTSC-M\n", + SDVO_NAME(dev_priv)); + + format.ntsc_m = TRUE; + i830_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0); + status = i830_sdvo_read_response(output, NULL, 0); + } +} + +static DisplayModePtr +i830_sdvo_get_tv_modes(xf86OutputPtr output) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + DisplayModePtr modes = NULL; + struct i830_sdvo_sdtv_resolution_reply *res = &dev_priv->sdtv_resolutions; + uint8_t status; + float refresh = 60; /* XXX */ + + i830_sdvo_check_tv_format(output); + + /* Read the list of supported input resolutions for the selected TV format. + */ + i830_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, NULL, 0); + status = i830_sdvo_read_response(output, res, sizeof(*res)); + if (status != SDVO_CMD_STATUS_SUCCESS) + return NULL; + + if (res->res_320x200) i830_sdvo_get_tv_mode(&modes, 320, 200, refresh); + if (res->res_320x240) i830_sdvo_get_tv_mode(&modes, 320, 240, refresh); + if (res->res_400x300) i830_sdvo_get_tv_mode(&modes, 400, 300, refresh); + if (res->res_640x350) i830_sdvo_get_tv_mode(&modes, 640, 350, refresh); + if (res->res_640x400) i830_sdvo_get_tv_mode(&modes, 640, 400, refresh); + if (res->res_640x480) i830_sdvo_get_tv_mode(&modes, 640, 480, refresh); + if (res->res_704x480) i830_sdvo_get_tv_mode(&modes, 704, 480, refresh); + if (res->res_704x576) i830_sdvo_get_tv_mode(&modes, 704, 576, refresh); + if (res->res_720x350) i830_sdvo_get_tv_mode(&modes, 720, 350, refresh); + if (res->res_720x400) i830_sdvo_get_tv_mode(&modes, 720, 400, refresh); + if (res->res_720x480) i830_sdvo_get_tv_mode(&modes, 720, 480, refresh); + if (res->res_720x540) i830_sdvo_get_tv_mode(&modes, 720, 540, refresh); + if (res->res_720x576) i830_sdvo_get_tv_mode(&modes, 720, 576, refresh); + if (res->res_800x600) i830_sdvo_get_tv_mode(&modes, 800, 600, refresh); + if (res->res_832x624) i830_sdvo_get_tv_mode(&modes, 832, 624, refresh); + if (res->res_920x766) i830_sdvo_get_tv_mode(&modes, 920, 766, refresh); + if (res->res_1024x768) i830_sdvo_get_tv_mode(&modes, 1024, 768, refresh); + if (res->res_1280x1024) i830_sdvo_get_tv_mode(&modes, 1280, 1024, refresh); + + return modes; +} + +static DisplayModePtr +i830_sdvo_get_modes(xf86OutputPtr output) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + + if (dev_priv->is_tv) + return i830_sdvo_get_tv_modes(output); + else + return i830_sdvo_get_ddc_modes(output); +} + static void i830_sdvo_destroy (xf86OutputPtr output) { @@ -1179,7 +1673,77 @@ static const xf86OutputFuncsRec i830_sdvo_output_funcs = { #endif }; -void +static unsigned int count_bits(uint32_t mask) +{ + unsigned int n; + + for (n = 0; mask; n++) + mask &= mask - 1; + + return n; +} + +/** + * Choose the appropriate DDC bus for control bus switch command for this + * SDVO output based on the controlled output. + * + * DDC bus number assignment is in a priority order of RGB outputs, then TMDS + * outputs, then LVDS outputs. + */ +static void +i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv) +{ + uint16_t mask = 0; + unsigned int num_bits; + + /* Make a mask of outputs less than or equal to our own priority in the + * list. + */ + switch (dev_priv->controlled_output) { + case SDVO_OUTPUT_LVDS1: + mask |= SDVO_OUTPUT_LVDS1; + case SDVO_OUTPUT_LVDS0: + mask |= SDVO_OUTPUT_LVDS0; + case SDVO_OUTPUT_TMDS1: + mask |= SDVO_OUTPUT_TMDS1; + case SDVO_OUTPUT_TMDS0: + mask |= SDVO_OUTPUT_TMDS0; + case SDVO_OUTPUT_RGB1: + mask |= SDVO_OUTPUT_RGB1; + case SDVO_OUTPUT_RGB0: + mask |= SDVO_OUTPUT_RGB0; + break; + } + + /* Count bits to find what number we are in the priority list. */ + mask &= dev_priv->caps.output_flags; + num_bits = count_bits(mask); + if (num_bits > 3) { + /* if more than 3 outputs, default to DDC bus 3 for now */ + num_bits = 3; + } + + /* Corresponds to SDVO_CONTROL_BUS_DDCx */ + dev_priv->ddc_bus = 1 << num_bits; +} + +static Bool +i830_sdvo_get_digital_encoding_mode(xf86OutputPtr output) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + uint8_t status; + + i830_sdvo_set_target_output(output, dev_priv->controlled_output); + + i830_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); + status = i830_sdvo_read_response(output, &dev_priv->is_hdmi, 1); + if (status != SDVO_CMD_STATUS_SUCCESS) + return FALSE; + return TRUE; +} + +Bool i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) { xf86OutputPtr output; @@ -1194,19 +1758,21 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,NULL); if (!output) - return; + return FALSE; intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) + sizeof (struct i830_sdvo_priv), 1); if (!intel_output) { xf86OutputDestroy (output); - return; + return FALSE; } output->driver_private = intel_output; + dev_priv = (struct i830_sdvo_priv *) (intel_output + 1); + intel_output->dev_priv = dev_priv; + output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; - dev_priv = (struct i830_sdvo_priv *) (intel_output + 1); intel_output->type = I830_OUTPUT_SDVO; intel_output->pipe_mask = ((1 << 0) | (1 << 1)); intel_output->clone_mask = (1 << I830_OUTPUT_SDVO); @@ -1222,7 +1788,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) if (i2cbus == NULL) { xf86OutputDestroy (output); - return; + return FALSE; } if (output_device == SDVOB) { @@ -1244,11 +1810,10 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) "Failed to initialize %s I2C device\n", SDVO_NAME(dev_priv)); xf86OutputDestroy (output); - return; + return FALSE; } intel_output->pI2CBus = i2cbus; - intel_output->dev_priv = dev_priv; /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { @@ -1257,7 +1822,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) "No SDVO device found on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); xf86OutputDestroy (output); - return; + return FALSE; } } @@ -1270,7 +1835,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) if (ddcbus == NULL) { xf86OutputDestroy (output); - return; + return FALSE; } if (output_device == SDVOB) ddcbus->BusName = "SDVOB DDC Bus"; @@ -1287,7 +1852,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) if (!xf86I2CBusInit(ddcbus)) { xf86OutputDestroy (output); - return; + return FALSE; } intel_output->pI2CBus = i2cbus; @@ -1296,28 +1861,41 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) i830_sdvo_get_capabilities(output, &dev_priv->caps); - memset(&dev_priv->active_outputs, 0, sizeof(dev_priv->active_outputs)); - if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) + if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { - dev_priv->active_outputs = SDVO_OUTPUT_TMDS0; + if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) + dev_priv->controlled_output = SDVO_OUTPUT_TMDS0; + else + dev_priv->controlled_output = SDVO_OUTPUT_TMDS1; output->subpixel_order = SubPixelHorizontalRGB; name_prefix="TMDS"; + + if (i830_sdvo_get_supp_encode(output, &dev_priv->encode) && + i830_sdvo_get_digital_encoding_mode(output) && + dev_priv->is_hdmi) { + /* enable hdmi encoding mode if supported */ + i830_sdvo_set_encode(output, SDVO_ENCODE_HDMI); + i830_sdvo_set_colorimetry(output, SDVO_COLORIMETRY_RGB256); + name_prefix = "HDMI"; + } } - else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) + else if (dev_priv->caps.output_flags & SDVO_OUTPUT_SVID0) { - dev_priv->active_outputs = SDVO_OUTPUT_TMDS1; - output->subpixel_order = SubPixelHorizontalRGB; - name_prefix="TMDS"; + dev_priv->controlled_output = SDVO_OUTPUT_SVID0; + output->subpixel_order = SubPixelHorizontalRGB; /* XXX */ + name_prefix="TV"; + dev_priv->is_tv = TRUE; + intel_output->needs_tv_clock = TRUE; } else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB0) { - dev_priv->active_outputs = SDVO_OUTPUT_RGB0; + dev_priv->controlled_output = SDVO_OUTPUT_RGB0; output->subpixel_order = SubPixelHorizontalRGB; name_prefix="VGA"; } else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB1) { - dev_priv->active_outputs = SDVO_OUTPUT_RGB1; + dev_priv->controlled_output = SDVO_OUTPUT_RGB1; output->subpixel_order = SubPixelHorizontalRGB; name_prefix="VGA"; } @@ -1325,22 +1903,25 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) { unsigned char bytes[2]; + dev_priv->controlled_output = 0; memcpy (bytes, &dev_priv->caps.output_flags, 2); - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR, - "%s: No active TMDS outputs (0x%02x%02x)\n", + xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING, + "%s: Unknown SDVO output type (0x%02x%02x)\n", SDVO_NAME(dev_priv), bytes[0], bytes[1]); name_prefix="Unknown"; } + strcpy (name, name_prefix); strcat (name, name_suffix); if (!xf86OutputRename (output, name)) { xf86OutputDestroy (output); - return; + return FALSE; } - - + + i830_sdvo_select_ddc_bus(dev_priv); + /* Set the input timing to the screen. Assume always input 0. */ i830_sdvo_set_target_input(output, TRUE, FALSE); @@ -1348,17 +1929,41 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) &dev_priv->pixel_clock_max); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s device VID/DID: %02X:%02X.%02X, " - "clock range %.1fMHz - %.1fMHz, " - "input 1: %c, input 2: %c, " - "output 1: %c, output 2: %c\n", + "%s: device VID/DID: %02X:%02X.%02X, " + "clock range %.1fMHz - %.1fMHz\n", SDVO_NAME(dev_priv), dev_priv->caps.vendor_id, dev_priv->caps.device_id, dev_priv->caps.device_rev_id, dev_priv->pixel_clock_min / 1000.0, - dev_priv->pixel_clock_max / 1000.0, - (dev_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', - (dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', - dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_TMDS0) ? 'Y' : 'N', - dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB1 | SDVO_OUTPUT_TMDS1) ? 'Y' : 'N'); + dev_priv->pixel_clock_max / 1000.0); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s: %d input channel%s\n", + SDVO_NAME(dev_priv), dev_priv->caps.sdvo_input_count, + dev_priv->caps.sdvo_input_count >= 2 ? "s" : ""); + +#define REPORT_OUTPUT_FLAG(flag, name) do { \ + if (dev_priv->caps.output_flags & flag) { \ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: %s output reported\n", \ + SDVO_NAME(dev_priv), name); \ + } \ +} while (0) + + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS0, "TMDS0"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB0, "RGB0"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS0, "CVBS0"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID0, "SVID0"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB0, "YPRPB0"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART0, "SCART0"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS0, "LVDS0"); + + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS1, "TMDS1"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB1, "RGB1"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS1, "CVBS1"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID1, "SVID1"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB1, "YPRPB1"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART1, "SCART1"); + REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS1, "LVDS1"); + + return TRUE; } diff --git a/driver/xf86-video-intel/src/i830_sdvo.h b/driver/xf86-video-intel/src/i830_sdvo.h index 1368e43b3..798a88df8 100644 --- a/driver/xf86-video-intel/src/i830_sdvo.h +++ b/driver/xf86-video-intel/src/i830_sdvo.h @@ -25,7 +25,7 @@ * */ -void +Bool i830_sdvo_init(ScrnInfoPtr pScrn, int output_device); int diff --git a/driver/xf86-video-intel/src/i830_sdvo_regs.h b/driver/xf86-video-intel/src/i830_sdvo_regs.h index 725460f26..4d5555576 100644 --- a/driver/xf86-video-intel/src/i830_sdvo_regs.h +++ b/driver/xf86-video-intel/src/i830_sdvo_regs.h @@ -52,7 +52,7 @@ struct i830_sdvo_caps { uint8_t device_rev_id; uint8_t sdvo_version_major; uint8_t sdvo_version_minor; - unsigned int sdvo_inputs_mask:2; + unsigned int sdvo_input_count:2; unsigned int smooth_scaling:1; unsigned int sharp_scaling:1; unsigned int up_scaling:1; @@ -174,6 +174,9 @@ struct i830_sdvo_get_trained_inputs_response { * Returns two struct i830_sdvo_output_flags structures. */ #define SDVO_CMD_GET_IN_OUT_MAP 0x06 +struct i830_sdvo_in_out_map { + uint16_t in0, in1; +}; /** * Sets the current mapping of SDVO inputs to outputs on the device. @@ -306,11 +309,107 @@ struct i830_sdvo_set_target_input_args { # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 +/** 5 bytes of bit flags for TV formats shared by all TV format functions */ +struct i830_sdvo_tv_format { + unsigned int ntsc_m:1; + unsigned int ntsc_j:1; + unsigned int ntsc_443:1; + unsigned int pal_b:1; + unsigned int pal_d:1; + unsigned int pal_g:1; + unsigned int pal_h:1; + unsigned int pal_i:1; + + unsigned int pal_m:1; + unsigned int pal_n:1; + unsigned int pal_nc:1; + unsigned int pal_60:1; + unsigned int secam_b:1; + unsigned int secam_d:1; + unsigned int secam_g:1; + unsigned int secam_k:1; + + unsigned int secam_k1:1; + unsigned int secam_l:1; + unsigned int secam_60:1; + unsigned int hdtv_std_smpte_240m_1080i_59:1; + unsigned int hdtv_std_smpte_240m_1080i_60:1; + unsigned int hdtv_std_smpte_260m_1080i_59:1; + unsigned int hdtv_std_smpte_260m_1080i_60:1; + unsigned int hdtv_std_smpte_270m_1080i_50:1; + + unsigned int hdtv_std_smpte_274m_1080i_50:1; + unsigned int hdtv_std_smpte_274m_1080i_59:1; + unsigned int hdtv_std_smpte_274m_1080i_60:1; + unsigned int hdtv_std_smpte_274m_1080p_23:1; + unsigned int hdtv_std_smpte_274m_1080p_24:1; + unsigned int hdtv_std_smpte_274m_1080p_25:1; + unsigned int hdtv_std_smpte_274m_1080p_29:1; + unsigned int hdtv_std_smpte_274m_1080p_50:1; + + unsigned int hdtv_std_smpte_274m_1080p_59:1; + unsigned int hdtv_std_smpte_274m_1080p_60:1; + unsigned int hdtv_std_smpte_295m_1080i_50:1; + unsigned int hdtv_std_smpte_295m_1080p_50:1; + unsigned int hdtv_std_smpte_296m_720p_59:1; + unsigned int hdtv_std_smpte_296m_720p_60:1; + unsigned int hdtv_std_smpte_296m_720p_50:1; + unsigned int hdtv_std_smpte_293m_480p_59:1; + + unsigned int hdtv_std_smpte_270m_480i_59:1; + unsigned int hdtv_std_iturbt601_576i_50:1; + unsigned int hdtv_std_iturbt601_576p_50:1; + unsigned int hdtv_std_eia_7702a_480i_60:1; + unsigned int hdtv_std_eia_7702a_480p_60:1; + unsigned int pad:3; +} __attribute__((packed)); #define SDVO_CMD_GET_TV_FORMAT 0x28 +/** This command should be run before SetOutputTimingsPart[12] */ #define SDVO_CMD_SET_TV_FORMAT 0x29 +/** Returns the resolutiosn that can be used with the given TV format */ +#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 +struct i830_sdvo_sdtv_resolution_request { + unsigned int ntsc_m:1; + unsigned int ntsc_j:1; + unsigned int ntsc_443:1; + unsigned int pal_b:1; + unsigned int pal_d:1; + unsigned int pal_g:1; + unsigned int pal_h:1; + unsigned int pal_i:1; + + unsigned int pal_m:1; + unsigned int pal_n:1; + unsigned int pal_nc:1; + unsigned int pal_60:1; +} __attribute__((packed)); +struct i830_sdvo_sdtv_resolution_reply { + unsigned int res_320x200:1; + unsigned int res_320x240:1; + unsigned int res_400x300:1; + unsigned int res_640x350:1; + unsigned int res_640x400:1; + unsigned int res_640x480:1; + unsigned int res_704x480:1; + unsigned int res_704x576:1; + + unsigned int res_720x350:1; + unsigned int res_720x400:1; + unsigned int res_720x480:1; + unsigned int res_720x540:1; + unsigned int res_720x576:1; + unsigned int res_800x600:1; + unsigned int res_832x624:1; + + unsigned int res_920x766:1; + unsigned int res_1024x768:1; + unsigned int res_1280x1024:1; + unsigned int pad:5; +} __attribute__((packed)); + #define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a #define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b #define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c @@ -319,11 +418,130 @@ struct i830_sdvo_set_target_input_args { # define SDVO_ENCODER_STATE_SUSPEND (1 << 2) # define SDVO_ENCODER_STATE_OFF (1 << 3) -#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 +#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 +struct i830_sdvo_enhancements_reply { + unsigned int flicker_filter:1; + unsigned int flicker_filter_adaptive:1; + unsigned int flicker_filter_2d:1; + unsigned int saturation:1; + unsigned int hue:1; + unsigned int brightness:1; + unsigned int contrast:1; + unsigned int overscan_h:1; + + unsigned int overscan_v:1; + unsigned int position_h:1; + unsigned int position_v:1; + unsigned int sharpness:1; + unsigned int dot_crawl:1; + unsigned int dither:1; + unsigned int max_tv_chroma_filter:1; + unsigned int max_tv_luma_filter:1; +} __attribute__((packed)); + +/* Picture enhancement limits below are dependent on the current TV format, + * and thus need to be queried and set after it. + */ +#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d +#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b +#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 +#define SDVO_CMD_GET_MAX_SATURATION 0x55 +#define SDVO_CMD_GET_MAX_HUE 0x58 +#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5c +#define SDVO_CMD_GET_MAX_CONTRAST 0x5e +#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 +#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 +#define SDVO_CMD_GET_MAX_POSITION_H 0x67 +#define SDVO_CMD_GET_MAX_POSITION_V 0x6a +#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d +#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 +#define SDVO_CMD_GET_MAX_TV_LUMA 0x77 +struct i830_sdvo_enhancement_limits_reply { + uint16_t max_value; + uint16_t default_value; +} __attribute__((packed)); -#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a -# define SDVO_CONTROL_BUS_PROM 0x0 -# define SDVO_CONTROL_BUS_DDC1 0x1 -# define SDVO_CONTROL_BUS_DDC2 0x2 -# define SDVO_CONTROL_BUS_DDC3 0x3 +#define SDVO_CMD_GET_FLICKER_FITER 0x4d +#define SDVO_CMD_SET_FLICKER_FITER 0x4e +#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 +#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 +#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 +#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 +#define SDVO_CMD_GET_SATURATION 0x56 +#define SDVO_CMD_SET_SATURATION 0x57 +#define SDVO_CMD_GET_HUE 0x59 +#define SDVO_CMD_SET_HUE 0x5a +#define SDVO_CMD_GET_BRIGHTNESS 0x5c +#define SDVO_CMD_SET_BRIGHTNESS 0x5d +#define SDVO_CMD_GET_CONTRAST 0x5f +#define SDVO_CMD_SET_CONTRAST 0x60 +#define SDVO_CMD_GET_OVERSCAN_H 0x62 +#define SDVO_CMD_SET_OVERSCAN_H 0x63 +#define SDVO_CMD_GET_OVERSCAN_V 0x65 +#define SDVO_CMD_SET_OVERSCAN_V 0x66 +#define SDVO_CMD_GET_POSITION_H 0x68 +#define SDVO_CMD_SET_POSITION_H 0x69 +#define SDVO_CMD_GET_POSITION_V 0x6b +#define SDVO_CMD_SET_POSITION_V 0x6c +#define SDVO_CMD_GET_SHARPNESS 0x6e +#define SDVO_CMD_SET_SHARPNESS 0x6f +#define SDVO_CMD_GET_TV_CHROMA 0x75 +#define SDVO_CMD_SET_TV_CHROMA 0x76 +#define SDVO_CMD_GET_TV_LUMA 0x78 +#define SDVO_CMD_SET_TV_LUMA 0x79 +struct i830_sdvo_enhancements_arg { + uint16_t value; +}__attribute__((packed)); + +#define SDVO_CMD_GET_DOT_CRAWL 0x70 +#define SDVO_CMD_SET_DOT_CRAWL 0x71 +# define SDVO_DOT_CRAWL_ON (1 << 0) +# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) + +#define SDVO_CMD_GET_DITHER 0x72 +#define SDVO_CMD_SET_DITHER 0x73 +# define SDVO_DITHER_ON (1 << 0) +# define SDVO_DITHER_DEFAULT_ON (1 << 1) +#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a +# define SDVO_CONTROL_BUS_PROM (1 << 0) +# define SDVO_CONTROL_BUS_DDC1 (1 << 1) +# define SDVO_CONTROL_BUS_DDC2 (1 << 2) +# define SDVO_CONTROL_BUS_DDC3 (1 << 3) + +/* HDMI op codes */ +#define SDVO_CMD_GET_SUPP_ENCODE 0x9d +#define SDVO_CMD_GET_ENCODE 0x9e +#define SDVO_CMD_SET_ENCODE 0x9f + #define SDVO_ENCODE_DVI 0x0 + #define SDVO_ENCODE_HDMI 0x1 +#define SDVO_CMD_SET_PIXEL_REPLI 0x8b +#define SDVO_CMD_GET_PIXEL_REPLI 0x8c +#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d +#define SDVO_CMD_SET_COLORIMETRY 0x8e + #define SDVO_COLORIMETRY_RGB256 0x0 + #define SDVO_COLORIMETRY_RGB220 0x1 + #define SDVO_COLORIMETRY_YCrCb422 0x3 + #define SDVO_COLORIMETRY_YCrCb444 0x4 +#define SDVO_CMD_GET_COLORIMETRY 0x8f +#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 +#define SDVO_CMD_SET_AUDIO_STAT 0x91 +#define SDVO_CMD_GET_AUDIO_STAT 0x92 +#define SDVO_CMD_SET_HBUF_INDEX 0x93 +#define SDVO_CMD_GET_HBUF_INDEX 0x94 +#define SDVO_CMD_GET_HBUF_INFO 0x95 +#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 +#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 +#define SDVO_CMD_SET_HBUF_DATA 0x98 +#define SDVO_CMD_GET_HBUF_DATA 0x99 +#define SDVO_CMD_SET_HBUF_TXRATE 0x9a +#define SDVO_CMD_GET_HBUF_TXRATE 0x9b + #define SDVO_HBUF_TX_DISABLED (0 << 6) + #define SDVO_HBUF_TX_ONCE (2 << 6) + #define SDVO_HBUF_TX_VSYNC (3 << 6) +#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c + +struct i830_sdvo_encode{ + uint8_t dvi_rev; + uint8_t hdmi_rev; +} __attribute__ ((packed)); diff --git a/driver/xf86-video-intel/src/i830_tv.c b/driver/xf86-video-intel/src/i830_tv.c index cde929a73..0a33357c6 100644 --- a/driver/xf86-video-intel/src/i830_tv.c +++ b/driver/xf86-video-intel/src/i830_tv.c @@ -36,6 +36,7 @@ #include "xf86.h" #include "i830.h" #include "i830_display.h" +#include "i830_bios.h" #include "X11/Xatom.h" #include <string.h> @@ -1715,6 +1716,9 @@ i830_tv_init(ScrnInfoPtr pScrn) (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) return; + if (!pI830->tv_present) /* VBIOS claims no TV connector */ + return; + output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV"); if (!output) diff --git a/driver/xf86-video-intel/src/i830_video.c b/driver/xf86-video-intel/src/i830_video.c index 91e0e0099..486f6708e 100644 --- a/driver/xf86-video-intel/src/i830_video.c +++ b/driver/xf86-video-intel/src/i830_video.c @@ -620,7 +620,7 @@ I830InitVideo(ScreenPtr pScreen) } /* Set up overlay video if we can do it at this depth. */ - if (!IS_IGD_GM(pI830) && pScrn->bitsPerPixel != 8 && + if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8 && pI830->overlay_regs != NULL) { overlayAdaptor = I830SetupImageVideoOverlay(pScreen); @@ -1350,65 +1350,6 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, } } -/* Copies planar data in *buf to UYVY-packed data in the screen atYBufXOffset. - */ -static void -I830CopyPlanarToPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, - unsigned char *buf, int srcPitch, - int srcPitch2, int dstPitch, int srcH, - int top, int left, int h, int w, int id) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint8_t *dst1, *srcy, *srcu, *srcv; - int y; - - if (pPriv->currentBuf == 0) - dst1 = pI830->FbBase + pPriv->YBuf0offset; - else - dst1 = pI830->FbBase + pPriv->YBuf1offset; - - srcy = buf + (top * srcPitch) + left; - if (id == FOURCC_YV12) { - srcu = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2); - srcv = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) + - ((top / 2) * srcPitch2) + (left / 2); - } else { - srcv = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2); - srcu = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) + - ((top / 2) * srcPitch2) + (left / 2); - } - - for (y = 0; y < h; y++) { - uint32_t *dst = (uint32_t *)dst1; - uint8_t *sy = srcy; - uint8_t *su = srcu; - uint8_t *sv = srcv; - int i; - - i = w / 2; - while(i > 4) { - dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24); - dst[1] = sy[2] | (sy[3] << 16) | (sv[1] << 8) | (su[1] << 24); - dst[2] = sy[4] | (sy[5] << 16) | (sv[2] << 8) | (su[2] << 24); - dst[3] = sy[6] | (sy[7] << 16) | (sv[3] << 8) | (su[3] << 24); - dst += 4; su += 4; sv += 4; sy += 8; - i -= 4; - } - while(i--) { - dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24); - dst++; su++; sv++; - sy += 2; - } - - dst1 += dstPitch; - srcy += srcPitch; - if (y & 1) { - srcu += srcPitch2; - srcv += srcPitch2; - } - } -} - static void I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, unsigned char *buf, int srcPitch, @@ -2269,7 +2210,8 @@ I830PutImage(ScrnInfoPtr pScrn, I830OverlayRegPtr overlay; PixmapPtr pPixmap; INT32 x1, x2, y1, y2; - int srcPitch, srcPitch2 = 0, dstPitch, destId; + int srcPitch = 0, srcPitch2 = 0, dstPitch, destId; + int dstPitch2 = 0; int top, left, npixels, nlines, size; BoxRec dstBox; int pitchAlignMask; @@ -2344,15 +2286,11 @@ I830PutImage(ScrnInfoPtr pScrn, case FOURCC_I420: srcPitch = (width + 0x3) & ~0x3; srcPitch2 = ((width >> 1) + 0x3) & ~0x3; + break; #ifdef INTEL_XVMC - if (pI830->IsXvMCSurface) { - srcPitch = (width + 0x3ff) & ~0x3ff; - srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff; - } -#endif - if (pPriv->textured && IS_I965G(pI830)) - destId = FOURCC_YUY2; + case FOURCC_XVMC: break; +#endif case FOURCC_UYVY: case FOURCC_YUY2: default: @@ -2365,6 +2303,11 @@ I830PutImage(ScrnInfoPtr pScrn, */ if (pPriv->textured) { pitchAlignMask = 3; +#ifdef INTEL_XVMC + /* for i915 xvmc, hw requires at least 1kb aligned surface */ + if ((id == FOURCC_XVMC) && IS_I915(pI830)) + pitchAlignMask = 0x3ff; +#endif } else { if (IS_I965G(pI830)) pitchAlignMask = 255; @@ -2378,9 +2321,6 @@ I830PutImage(ScrnInfoPtr pScrn, switch (destId) { case FOURCC_YV12: case FOURCC_I420: -#ifdef INTEL_XVMC - case FOURCC_XVMC: -#endif if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask; size = dstPitch * width * 3; @@ -2400,7 +2340,14 @@ I830PutImage(ScrnInfoPtr pScrn, size = dstPitch * height; } break; - default: +#ifdef INTEL_XVMC + case FOURCC_XVMC: + dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask; + dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask; + size = 0; + break; +#endif + default: dstPitch = 0; size = 0; break; @@ -2445,24 +2392,35 @@ I830PutImage(ScrnInfoPtr pScrn, (pPriv->doubleBuffer ? size * 2 : size); /* fixup pointers */ - pPriv->YBuf0offset = pPriv->buf->offset; - if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { - pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); - pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); - if(pPriv->doubleBuffer) { - pPriv->YBuf1offset = pPriv->YBuf0offset + size; - pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width); - pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2); - } +#ifdef INTEL_XVMC + if (id == FOURCC_XVMC && IS_I915(pI830)) { + pPriv->YBuf0offset = (uint32_t)buf; + pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); + pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); + destId = FOURCC_YV12; } else { - pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); - pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); - if(pPriv->doubleBuffer) { - pPriv->YBuf1offset = pPriv->YBuf0offset + size; - pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); - pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); +#endif + pPriv->YBuf0offset = pPriv->buf->offset; + if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset = pPriv->YBuf0offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2); + } + } else { + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset = pPriv->YBuf0offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); + } } +#ifdef INTEL_XVMC } +#endif /* Pick the idle buffer */ if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer) @@ -2478,14 +2436,8 @@ I830PutImage(ScrnInfoPtr pScrn, case FOURCC_I420: top &= ~1; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; - if (pPriv->textured && IS_I965G(pI830)) { - I830CopyPlanarToPackedData(pScrn, pPriv, buf, srcPitch, srcPitch2, - dstPitch, height, top, left, nlines, - npixels, id); - } else { - I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch, - height, top, left, nlines, npixels, id); - } + I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch, + height, top, left, nlines, npixels, id); break; case FOURCC_UYVY: case FOURCC_YUY2: @@ -2540,7 +2492,7 @@ I830PutImage(ScrnInfoPtr pScrn, src_w, src_h, drw_w, drw_h, pPixmap); } else { I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height, - dstPitch, x1, y1, x2, y2, + dstPitch, dstPitch2, x1, y1, x2, y2, src_w, src_h, drw_w, drw_h, pPixmap); } if (pPriv->textured) { diff --git a/driver/xf86-video-intel/src/i830_video.h b/driver/xf86-video-intel/src/i830_video.h index 52e6b4f84..91f767f9f 100644 --- a/driver/xf86-video-intel/src/i830_video.h +++ b/driver/xf86-video-intel/src/i830_video.h @@ -78,7 +78,7 @@ typedef struct { void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, RegionPtr dstRegion, short width, - short height, int video_pitch, + short height, int video_pitch, int video_pitch2, int x1, int y1, int x2, int y2, short src_w, short src_h, short drw_w, short drw_h, diff --git a/driver/xf86-video-intel/src/i915_hwmc.c b/driver/xf86-video-intel/src/i915_hwmc.c index 50e110685..659638e10 100644 --- a/driver/xf86-video-intel/src/i915_hwmc.c +++ b/driver/xf86-video-intel/src/i915_hwmc.c @@ -111,7 +111,7 @@ static XF86MCImageIDList yv12_subpicture_list = static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = { - FOURCC_YV12, + SURFACE_TYPE_MPEG2_MPML, XVMC_CHROMA_FORMAT_420, 0, 720, @@ -127,7 +127,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = { - FOURCC_YV12, + SURFACE_TYPE_MPEG1_MPML, XVMC_CHROMA_FORMAT_420, 0, 720, @@ -319,8 +319,8 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c I830Ptr pI830 = I830PTR(pScrn); int flags = ALIGN_BOTH_ENDS; - if (IS_I915G(pI830) || IS_I915GM(pI830) || - IS_I945G(pI830) || IS_I945GM(pI830)) + /* on 915G/GM, load indirect can only use physical address...sigh */ + if (IS_I915G(pI830) || IS_I915GM(pI830)) flags |= NEED_PHYSICAL_ADDR; if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State", @@ -353,14 +353,14 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c return FALSE; } - if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", &(ctxpriv->mcCorrdata), 512 * 1024, ALIGN_BOTH_ENDS)) { return FALSE; } - if (0) - i830_describe_allocations(pScrn, 1, ""); + if (1) + i830_describe_allocations(pScrn, 1, "i915_mc: "); return TRUE; } @@ -500,29 +500,32 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext, contextRec->sis.handle = ctxpriv->sis_handle; contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset; contextRec->sis.size = ctxpriv->mcStaticIndirectState->size; - contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr; contextRec->ssb.handle = ctxpriv->ssb_handle; contextRec->ssb.offset = ctxpriv->mcSamplerState->offset; contextRec->ssb.size = ctxpriv->mcSamplerState->size; - contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr; contextRec->msb.handle = ctxpriv->msb_handle; contextRec->msb.offset = ctxpriv->mcMapState->offset; contextRec->msb.size = ctxpriv->mcMapState->size; - contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr; contextRec->psp.handle = ctxpriv->psp_handle; contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset; contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size; - contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr; contextRec->psc.handle = ctxpriv->psc_handle; contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset; contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size; - contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr; contextRec->corrdata.handle = ctxpriv->corrdata_handle; contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset; contextRec->corrdata.size = ctxpriv->mcCorrdata->size; contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec); contextRec->deviceID = pI830DRI->deviceID; + if (IS_I915G(pI830) || IS_I915GM(pI830)) { + contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr; + contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr; + contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr; + contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr; + contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr; + } + pXvMC->ncontexts++; pXvMC->contexts[i] = pContext->context_id; pXvMC->ctxprivs[i] = ctxpriv; @@ -787,7 +790,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, short height, Bool sync, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) { - I830Ptr pI830 = I830PTR(pScrn); I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf; int ret; @@ -803,10 +805,8 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, return 1; } - buf = pI830->FbBase + - pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset; - id = xvmc_cmd->real_id; - pI830->IsXvMCSurface = 1; + /* use char *buf to hold our surface offset...hacky! */ + buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset; break; default: return 0; @@ -816,7 +816,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, drw_w, drw_h, id, buf, width, height, sync, clipBoxes, data, pDraw); - pI830->IsXvMCSurface = 0; return ret; } diff --git a/driver/xf86-video-intel/src/i915_hwmc.h b/driver/xf86-video-intel/src/i915_hwmc.h index 7d90afcc1..8f6557da7 100644 --- a/driver/xf86-video-intel/src/i915_hwmc.h +++ b/driver/xf86-video-intel/src/i915_hwmc.h @@ -29,6 +29,7 @@ #include "i830_hwmc.h" +/* i915 hw requires surface to be at least 1KB aligned */ #define STRIDE(w) (((w) + 0x3ff) & ~0x3ff) #define SIZE_Y420(w, h) (h * STRIDE(w)) #define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1)) diff --git a/driver/xf86-video-intel/src/i915_video.c b/driver/xf86-video-intel/src/i915_video.c index aeb372930..d2da94bb7 100644 --- a/driver/xf86-video-intel/src/i915_video.c +++ b/driver/xf86-video-intel/src/i915_video.c @@ -42,7 +42,7 @@ void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, RegionPtr dstRegion, - short width, short height, int video_pitch, + short width, short height, int video_pitch, int video_pitch2, int x1, int y1, int x2, int y2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pPixmap) @@ -271,7 +271,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); - OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); + /* check to see if Y has special pitch than normal double u/v pitch, + * e.g i915 XvMC hw requires at least 1K alignment, so Y pitch might + * be same as U/V's.*/ + if (video_pitch2) + OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT); + else + OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); OUT_BATCH(pPriv->UBuf0offset); ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; diff --git a/driver/xf86-video-intel/src/i965_render.c b/driver/xf86-video-intel/src/i965_render.c index 96082bb35..8360be4a1 100644 --- a/driver/xf86-video-intel/src/i965_render.c +++ b/driver/xf86-video-intel/src/i965_render.c @@ -1,5 +1,6 @@ /* - * Copyright © 2006 Intel Corporation + * Copyright © 2006,2008 Intel Corporation + * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,6 +24,8 @@ * Authors: * Wang Zhenyu <zhenyu.z.wang@intel.com> * Eric Anholt <eric@anholt.net> + * Carl Worth <cworth@redhat.com> + * Keith Packard <keithp@keithp.com> * */ @@ -56,6 +59,9 @@ do { \ } while(0) #endif +#define MAX_VERTEX_PER_COMPOSITE 24 +#define MAX_VERTEX_BUFFERS 256 + struct blendinfo { Bool dst_alpha; Bool src_alpha; @@ -99,6 +105,14 @@ static struct blendinfo i965_blend_op[] = { /* Add */ {0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ONE}, }; +/** + * Highest-valued BLENDFACTOR used in i965_blend_op. + * + * This leaves out BRW_BLENDFACTOR_INV_DST_COLOR, + * BRW_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, + * BRW_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} + */ +#define BRW_BLENDFACTOR_COUNT (BRW_BLENDFACTOR_INV_DST_ALPHA + 1) /* FIXME: surface format defined in brw_defines.h, shared Sampling engine * 1.7.2 @@ -248,46 +262,23 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) -static int urb_vs_start, urb_vs_size; -static int urb_gs_start, urb_gs_size; -static int urb_clip_start, urb_clip_size; -static int urb_sf_start, urb_sf_size; -static int urb_cs_start, urb_cs_size; - -static struct brw_surface_state *dest_surf_state, dest_surf_state_local; -static struct brw_surface_state *src_surf_state, src_surf_state_local; -static struct brw_surface_state *mask_surf_state, mask_surf_state_local; -static struct brw_sampler_state *src_sampler_state, src_sampler_state_local; -static struct brw_sampler_state *mask_sampler_state, mask_sampler_state_local; -static struct brw_sampler_default_color *default_color_state; - -static struct brw_vs_unit_state *vs_state, vs_state_local; -static struct brw_sf_unit_state *sf_state, sf_state_local; -static struct brw_wm_unit_state *wm_state, wm_state_local; -static struct brw_cc_unit_state *cc_state, cc_state_local; -static struct brw_cc_viewport *cc_viewport; - -static struct brw_instruction *sf_kernel; -static struct brw_instruction *ps_kernel; -static struct brw_instruction *sip_kernel; - -static uint32_t *binding_table; -static int binding_table_entries; - -static int dest_surf_offset, src_surf_offset, mask_surf_offset; -static int src_sampler_offset, mask_sampler_offset,vs_offset; -static int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset; -static int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset; -static int wm_scratch_offset; -static int binding_table_offset; -static int default_color_offset; -static int next_offset, total_state_size; -static char *state_base; -static int state_base_offset; -static float *vb; -static int vb_size = (2 + 3 + 3) * 3 * 4; /* (dst, src, mask) 3 vertices, 4 bytes */ - -static uint32_t src_blend, dst_blend; +/* Set up a default static partitioning of the URB, which is supposed to + * allow anything we would want to do, at potentially lower performance. + */ +#define URB_CS_ENTRY_SIZE 0 +#define URB_CS_ENTRIES 0 + +#define URB_VS_ENTRY_SIZE 1 // each 512-bit row +#define URB_VS_ENTRIES 8 // we needs at least 8 entries + +#define URB_GS_ENTRY_SIZE 0 +#define URB_GS_ENTRIES 0 + +#define URB_CLIP_ENTRY_SIZE 0 +#define URB_CLIP_ENTRIES 0 + +#define URB_SF_ENTRY_SIZE 2 +#define URB_SF_ENTRIES 1 static const uint32_t sip_kernel_static[][4] = { /* wait (1) a0<1>UW a145<0,1,0>UW { align1 + } */ @@ -324,7 +315,7 @@ static const uint32_t sf_kernel_static[][4] = { #include "exa_sf.g4b" }; -static const uint32_t sf_kernel_static_mask[][4] = { +static const uint32_t sf_kernel_mask_static[][4] = { #include "exa_sf_mask.g4b" }; @@ -334,21 +325,21 @@ static const uint32_t sf_kernel_static_mask[][4] = { #define PS_SCRATCH_SPACE 1024 #define PS_SCRATCH_SPACE_LOG 0 /* log2 (PS_SCRATCH_SPACE) - 10 (1024 is 0, 2048 is 1) */ -static const uint32_t ps_kernel_static_nomask_affine [][4] = { +static const uint32_t ps_kernel_nomask_affine_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_nomask_projective [][4] = { +static const uint32_t ps_kernel_nomask_projective_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_maskca_affine [][4] = { +static const uint32_t ps_kernel_maskca_affine_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" @@ -358,7 +349,7 @@ static const uint32_t ps_kernel_static_maskca_affine [][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_maskca_projective [][4] = { +static const uint32_t ps_kernel_maskca_projective_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" @@ -368,7 +359,7 @@ static const uint32_t ps_kernel_static_maskca_projective [][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_maskca_srcalpha_affine [][4] = { +static const uint32_t ps_kernel_maskca_srcalpha_affine_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_a.g4b" @@ -378,7 +369,7 @@ static const uint32_t ps_kernel_static_maskca_srcalpha_affine [][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_maskca_srcalpha_projective [][4] = { +static const uint32_t ps_kernel_maskca_srcalpha_projective_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_a.g4b" @@ -388,7 +379,7 @@ static const uint32_t ps_kernel_static_maskca_srcalpha_projective [][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_masknoca_affine [][4] = { +static const uint32_t ps_kernel_masknoca_affine_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" @@ -398,7 +389,7 @@ static const uint32_t ps_kernel_static_masknoca_affine [][4] = { #include "exa_wm_write.g4b" }; -static const uint32_t ps_kernel_static_masknoca_projective [][4] = { +static const uint32_t ps_kernel_masknoca_projective_static [][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" @@ -408,6 +399,405 @@ static const uint32_t ps_kernel_static_masknoca_projective [][4] = { #include "exa_wm_write.g4b" }; +/** + * Storage for the static kernel data with template name, rounded to 64 bytes. + */ +#define KERNEL_DECL(template) \ + uint32_t template [((sizeof (template ## _static) + 63) & ~63) / 16][4]; + +#define WM_STATE_DECL(kernel) \ + struct brw_wm_unit_state wm_state_ ## kernel[SAMPLER_STATE_FILTER_COUNT] \ + [SAMPLER_STATE_EXTEND_COUNT] \ + [SAMPLER_STATE_FILTER_COUNT] \ + [SAMPLER_STATE_EXTEND_COUNT] + +/* Many of the fields in the state structure must be aligned to a + * 64-byte boundary, (or a 32-byte boundary, but 64 is good enough for + * those too). + */ +#define PAD64_MULTI(previous, idx, factor) char previous ## _pad ## idx [(64 - (sizeof(struct previous) * (factor)) % 64) % 64] +#define PAD64(previous, idx) PAD64_MULTI(previous, idx, 1) + +typedef enum { + SAMPLER_STATE_FILTER_NEAREST, + SAMPLER_STATE_FILTER_BILINEAR, + SAMPLER_STATE_FILTER_COUNT +} sampler_state_filter_t; + +typedef enum { + SAMPLER_STATE_EXTEND_NONE, + SAMPLER_STATE_EXTEND_REPEAT, + SAMPLER_STATE_EXTEND_COUNT +} sampler_state_extend_t; + +typedef struct _brw_cc_unit_state_padded { + struct brw_cc_unit_state state; + char pad[64 - sizeof (struct brw_cc_unit_state)]; +} brw_cc_unit_state_padded; + +typedef struct brw_surface_state_padded { + struct brw_surface_state state; + char pad[32 - sizeof (struct brw_surface_state)]; +} brw_surface_state_padded; + +/** + * Gen4 rendering state buffer structure. + * + * Ideally this structure would contain static data for all of the + * combinations of state that we use for Render acceleration, and another + * buffer would be the use-and-throw-away surface and vertex data. See the + * intel-batchbuffer branch for an implementation of that. For now, it + * has the static program data, and then a changing buffer containing all + * the rest. + */ +typedef struct _gen4_state { + uint8_t wm_scratch[128 * PS_MAX_THREADS]; + + KERNEL_DECL (sip_kernel); + KERNEL_DECL (sf_kernel); + KERNEL_DECL (sf_kernel_mask); + KERNEL_DECL (ps_kernel_nomask_affine); + KERNEL_DECL (ps_kernel_nomask_projective); + KERNEL_DECL (ps_kernel_maskca_affine); + KERNEL_DECL (ps_kernel_maskca_projective); + KERNEL_DECL (ps_kernel_maskca_srcalpha_affine); + KERNEL_DECL (ps_kernel_maskca_srcalpha_projective); + KERNEL_DECL (ps_kernel_masknoca_affine); + KERNEL_DECL (ps_kernel_masknoca_projective); + + struct brw_vs_unit_state vs_state; + PAD64 (brw_vs_unit_state, 0); + + struct brw_sf_unit_state sf_state; + PAD64 (brw_sf_unit_state, 0); + struct brw_sf_unit_state sf_state_mask; + PAD64 (brw_sf_unit_state, 1); + + WM_STATE_DECL (nomask_affine); + WM_STATE_DECL (nomask_projective); + WM_STATE_DECL (maskca_affine); + WM_STATE_DECL (maskca_projective); + WM_STATE_DECL (maskca_srcalpha_affine); + WM_STATE_DECL (maskca_srcalpha_projective); + WM_STATE_DECL (masknoca_affine); + WM_STATE_DECL (masknoca_projective); + + uint32_t binding_table[128]; + + struct brw_surface_state_padded surface_state[32]; + + /* Index by [src_filter][src_extend][mask_filter][mask_extend]. Two of + * the structs happen to add to 32 bytes. + */ + struct brw_sampler_state sampler_state[SAMPLER_STATE_FILTER_COUNT] + [SAMPLER_STATE_EXTEND_COUNT] + [SAMPLER_STATE_FILTER_COUNT] + [SAMPLER_STATE_EXTEND_COUNT][2]; + + struct brw_sampler_default_color sampler_default_color; + PAD64 (brw_sampler_default_color, 0); + + /* Index by [src_blend][dst_blend] */ + brw_cc_unit_state_padded cc_state[BRW_BLENDFACTOR_COUNT] + [BRW_BLENDFACTOR_COUNT]; + struct brw_cc_viewport cc_viewport; + PAD64 (brw_cc_viewport, 0); + + float vb[MAX_VERTEX_PER_COMPOSITE * MAX_VERTEX_BUFFERS]; +} gen4_state_t; + +/** Private data for gen4 render accel implementation. */ +struct gen4_render_state { + gen4_state_t *card_state; + uint32_t card_state_offset; + + int binding_table_index; + int surface_state_index; + int vb_offset; + int vertex_size; +}; + +/** + * Sets up the SF state pointing at an SF kernel. + * + * The SF kernel does coord interp: for each attribute, + * calculate dA/dx and dA/dy. Hand these interpolation coefficients + * back to SF which then hands pixels off to WM. + */ +static void +sf_state_init (struct brw_sf_unit_state *sf_state, int kernel_offset) +{ + memset(sf_state, 0, sizeof(*sf_state)); + sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF); + sf_state->sf1.single_program_flow = 1; + sf_state->sf1.binding_table_entry_count = 0; + sf_state->sf1.thread_priority = 0; + sf_state->sf1.floating_point_mode = 0; /* Mesa does this */ + sf_state->sf1.illegal_op_exception_enable = 1; + sf_state->sf1.mask_stack_exception_enable = 1; + sf_state->sf1.sw_exception_enable = 1; + sf_state->thread2.per_thread_scratch_space = 0; + /* scratch space is not used in our kernel */ + sf_state->thread2.scratch_space_base_pointer = 0; + sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */ + sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */ + sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ + /* don't smash vertex header, read start from dw8 */ + sf_state->thread3.urb_entry_read_offset = 1; + sf_state->thread3.dispatch_grf_start_reg = 3; + sf_state->thread4.max_threads = SF_MAX_THREADS - 1; + sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; + sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES; + sf_state->thread4.stats_enable = 1; + sf_state->sf5.viewport_transform = FALSE; /* skip viewport */ + sf_state->sf6.cull_mode = BRW_CULLMODE_NONE; + sf_state->sf6.scissor = 0; + sf_state->sf7.trifan_pv = 2; + sf_state->sf6.dest_org_vbias = 0x8; + sf_state->sf6.dest_org_hbias = 0x8; + + assert((kernel_offset & 63) == 0); + sf_state->thread0.kernel_start_pointer = kernel_offset >> 6; +} + +static void +sampler_state_init (struct brw_sampler_state *sampler_state, + sampler_state_filter_t filter, + sampler_state_extend_t extend, + int default_color_offset) +{ + /* PS kernel use this sampler */ + memset(sampler_state, 0, sizeof(*sampler_state)); + + sampler_state->ss0.lod_preclamp = 1; /* GL mode */ + sampler_state->ss0.default_color_mode = 0; /* GL mode */ + + switch(filter) { + default: + case SAMPLER_STATE_FILTER_NEAREST: + sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; + sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST; + break; + case SAMPLER_STATE_FILTER_BILINEAR: + sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; + sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR; + break; + } + + switch (extend) { + default: + case SAMPLER_STATE_EXTEND_NONE: + sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; + sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; + sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; + break; + case SAMPLER_STATE_EXTEND_REPEAT: + sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; + sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP; + sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; + break; + } + + assert((default_color_offset & 31) == 0); + sampler_state->ss2.default_color_pointer = default_color_offset >> 5; + + sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */ +} + +static void +cc_state_init (struct brw_cc_unit_state *cc_state, + int src_blend, + int dst_blend, + int cc_viewport_offset) +{ + memset(cc_state, 0, sizeof(*cc_state)); + cc_state->cc0.stencil_enable = 0; /* disable stencil */ + cc_state->cc2.depth_test = 0; /* disable depth test */ + cc_state->cc2.logicop_enable = 0; /* disable logic op */ + cc_state->cc3.ia_blend_enable = 0; /* blend alpha same as colors */ + cc_state->cc3.blend_enable = 1; /* enable color blend */ + cc_state->cc3.alpha_test = 0; /* disable alpha test */ + + assert((cc_viewport_offset & 31) == 0); + cc_state->cc4.cc_viewport_state_offset = cc_viewport_offset >> 5; + + cc_state->cc5.dither_enable = 0; /* disable dither */ + cc_state->cc5.logicop_func = 0xc; /* COPY */ + cc_state->cc5.statistics_enable = 1; + cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD; + + /* Fill in alpha blend factors same as color, for the future. */ + cc_state->cc5.ia_src_blend_factor = src_blend; + cc_state->cc5.ia_dest_blend_factor = dst_blend; + + cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD; + cc_state->cc6.clamp_post_alpha_blend = 1; + cc_state->cc6.clamp_pre_alpha_blend = 1; + cc_state->cc6.clamp_range = 0; /* clamp range [0,1] */ + + cc_state->cc6.src_blend_factor = src_blend; + cc_state->cc6.dest_blend_factor = dst_blend; +} + +static void +wm_state_init (struct brw_wm_unit_state *wm_state, + Bool has_mask, + int scratch_offset, + int kernel_offset, + int sampler_state_offset) +{ + memset(wm_state, 0, sizeof (*wm_state)); + wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF); + wm_state->thread1.single_program_flow = 0; + + assert((scratch_offset & 1023) == 0); + wm_state->thread2.scratch_space_base_pointer = scratch_offset >> 10; + + wm_state->thread2.per_thread_scratch_space = PS_SCRATCH_SPACE_LOG; + wm_state->thread3.const_urb_entry_read_length = 0; + wm_state->thread3.const_urb_entry_read_offset = 0; + + wm_state->thread3.urb_entry_read_offset = 0; + /* wm kernel use urb from 3, see wm_program in compiler module */ + wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */ + + wm_state->wm4.stats_enable = 1; /* statistic */ + assert((sampler_state_offset & 31) == 0); + wm_state->wm4.sampler_state_pointer = sampler_state_offset >> 5; + wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */ + wm_state->wm5.max_threads = PS_MAX_THREADS - 1; + wm_state->wm5.transposed_urb_read = 0; + wm_state->wm5.thread_dispatch_enable = 1; + /* just use 16-pixel dispatch (4 subspans), don't need to change kernel + * start point + */ + wm_state->wm5.enable_16_pix = 1; + wm_state->wm5.enable_8_pix = 0; + wm_state->wm5.early_depth_test = 1; + + assert((kernel_offset & 63) == 0); + wm_state->thread0.kernel_start_pointer = kernel_offset >> 6; + + /* Each pair of attributes (src/mask coords) is two URB entries */ + if (has_mask) { + wm_state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */ + wm_state->thread3.urb_entry_read_length = 4; + } else { + wm_state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */ + wm_state->thread3.urb_entry_read_length = 2; + } +} + +/** + * Called at EnterVT to fill in our state buffer with any static information. + */ +static void +gen4_state_init (struct gen4_render_state *render_state) +{ + int i, j, k, l; + gen4_state_t *card_state = render_state->card_state; + uint32_t state_base_offset = render_state->card_state_offset; + +#define KERNEL_COPY(kernel) \ + memcpy(card_state->kernel, kernel ## _static, sizeof(kernel ## _static)) + + KERNEL_COPY (sip_kernel); + KERNEL_COPY (sf_kernel); + KERNEL_COPY (sf_kernel_mask); + KERNEL_COPY (ps_kernel_nomask_affine); + KERNEL_COPY (ps_kernel_nomask_projective); + KERNEL_COPY (ps_kernel_maskca_affine); + KERNEL_COPY (ps_kernel_maskca_projective); + KERNEL_COPY (ps_kernel_maskca_srcalpha_affine); + KERNEL_COPY (ps_kernel_maskca_srcalpha_projective); + KERNEL_COPY (ps_kernel_masknoca_affine); + KERNEL_COPY (ps_kernel_masknoca_projective); +#undef KERNEL_COPY + + /* Set up the vertex shader to be disabled (passthrough) */ + memset(&card_state->vs_state, 0, sizeof(card_state->vs_state)); + card_state->vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES; + card_state->vs_state.thread4.urb_entry_allocation_size = + URB_VS_ENTRY_SIZE - 1; + card_state->vs_state.vs6.vs_enable = 0; + card_state->vs_state.vs6.vert_cache_disable = 1; + + /* Set up the sampler default color (always transparent black) */ + memset(&card_state->sampler_default_color, 0, + sizeof(card_state->sampler_default_color)); + card_state->sampler_default_color.color[0] = 0.0; /* R */ + card_state->sampler_default_color.color[1] = 0.0; /* G */ + card_state->sampler_default_color.color[2] = 0.0; /* B */ + card_state->sampler_default_color.color[3] = 0.0; /* A */ + + card_state->cc_viewport.min_depth = -1.e35; + card_state->cc_viewport.max_depth = 1.e35; + + sf_state_init (&card_state->sf_state, + state_base_offset + + offsetof (gen4_state_t, sf_kernel)); + sf_state_init (&card_state->sf_state_mask, + state_base_offset + + offsetof (gen4_state_t, sf_kernel_mask)); + + for (i = 0; i < SAMPLER_STATE_FILTER_COUNT; i++) { + for (j = 0; j < SAMPLER_STATE_EXTEND_COUNT; j++) { + for (k = 0; k < SAMPLER_STATE_FILTER_COUNT; k++) { + for (l = 0; l < SAMPLER_STATE_EXTEND_COUNT; l++) { + sampler_state_init (&card_state->sampler_state[i][j][k][l][0], + i, j, + state_base_offset + + offsetof (gen4_state_t, + sampler_default_color)); + sampler_state_init (&card_state->sampler_state[i][j][k][l][1], + k, l, + state_base_offset + + offsetof (gen4_state_t, + sampler_default_color)); + } + } + } + } + + + for (i = 0; i < BRW_BLENDFACTOR_COUNT; i++) { + for (j = 0; j < BRW_BLENDFACTOR_COUNT; j++) { + cc_state_init (&card_state->cc_state[i][j].state, i, j, + state_base_offset + + offsetof (gen4_state_t, cc_viewport)); + } + } + +#define SETUP_WM_STATE(kernel, has_mask) \ + wm_state_init(&card_state->wm_state_ ## kernel [i][j][k][l], \ + has_mask, \ + state_base_offset + offsetof(gen4_state_t, \ + wm_scratch), \ + state_base_offset + offsetof(gen4_state_t, \ + ps_kernel_ ## kernel), \ + state_base_offset + offsetof(gen4_state_t, \ + sampler_state[i][j][k][l])); + + + for (i = 0; i < SAMPLER_STATE_FILTER_COUNT; i++) { + for (j = 0; j < SAMPLER_STATE_EXTEND_COUNT; j++) { + for (k = 0; k < SAMPLER_STATE_FILTER_COUNT; k++) { + for (l = 0; l < SAMPLER_STATE_EXTEND_COUNT; l++) { + SETUP_WM_STATE (nomask_affine, FALSE); + SETUP_WM_STATE (nomask_projective, FALSE); + SETUP_WM_STATE (maskca_affine, TRUE); + SETUP_WM_STATE (maskca_projective, TRUE); + SETUP_WM_STATE (maskca_srcalpha_affine, TRUE); + SETUP_WM_STATE (maskca_srcalpha_projective, TRUE); + SETUP_WM_STATE (masknoca_affine, TRUE); + SETUP_WM_STATE (masknoca_projective, TRUE); + } + } + } + } +#undef SETUP_WM_STATE +} + static uint32_t i965_get_card_format(PicturePtr pPict) { @@ -419,9 +809,97 @@ i965_get_card_format(PicturePtr pPict) if (i965_tex_formats[i].fmt == pPict->format) break; } + assert(i != sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0])); + return i965_tex_formats[i].card_fmt; } +static sampler_state_filter_t +sampler_state_filter_from_picture (int filter) +{ + switch (filter) { + case PictFilterNearest: + return SAMPLER_STATE_FILTER_NEAREST; + case PictFilterBilinear: + return SAMPLER_STATE_FILTER_BILINEAR; + default: + return -1; + } +} + +static sampler_state_extend_t +sampler_state_extend_from_picture (int repeat) +{ + switch (repeat) { + case RepeatNone: + return SAMPLER_STATE_EXTEND_NONE; + case RepeatNormal: + return SAMPLER_STATE_EXTEND_REPEAT; + default: + return -1; + } +} + +/** + * Sets up the common fields for a surface state buffer for the given picture + * in the surface state buffer at index, and returns the offset within the + * state buffer for this entry. + */ +static unsigned int +i965_set_picture_surface_state(ScrnInfoPtr pScrn, struct brw_surface_state *ss, + PicturePtr pPicture, PixmapPtr pPixmap, + Bool is_dst) +{ + I830Ptr pI830 = I830PTR(pScrn); + struct gen4_render_state *render_state= pI830->gen4_render_state; + gen4_state_t *card_state = render_state->card_state; + struct brw_surface_state local_ss; + uint32_t offset; + + /* Since ss is a pointer to WC memory, do all of our bit operations + * into a local temporary first. + */ + memset(&local_ss, 0, sizeof(local_ss)); + local_ss.ss0.surface_type = BRW_SURFACE_2D; + if (is_dst) { + uint32_t dst_format = 0; + Bool ret = TRUE; + + ret = i965_get_dest_format(pPicture, &dst_format); + assert(ret == TRUE); + local_ss.ss0.surface_format = dst_format; + } else { + local_ss.ss0.surface_format = i965_get_card_format(pPicture); + } + + local_ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; + local_ss.ss0.writedisable_alpha = 0; + local_ss.ss0.writedisable_red = 0; + local_ss.ss0.writedisable_green = 0; + local_ss.ss0.writedisable_blue = 0; + local_ss.ss0.color_blend = 1; + local_ss.ss0.vert_line_stride = 0; + local_ss.ss0.vert_line_stride_ofs = 0; + local_ss.ss0.mipmap_layout_mode = 0; + local_ss.ss0.render_cache_read_mode = 0; + local_ss.ss1.base_addr = intel_get_pixmap_offset(pPixmap); + + local_ss.ss2.mip_count = 0; + local_ss.ss2.render_target_rotation = 0; + local_ss.ss2.height = pPixmap->drawable.height - 1; + local_ss.ss2.width = pPixmap->drawable.width - 1; + local_ss.ss3.pitch = intel_get_pixmap_pitch(pPixmap) - 1; + local_ss.ss3.tile_walk = 0; /* Tiled X */ + local_ss.ss3.tiled_surface = i830_pixmap_tiled(pPixmap) ? 1 : 0; + + memcpy(ss, &local_ss, sizeof(local_ss)); + + offset = (char *)ss - (char *)card_state; + assert((offset & 31) == 0); + + return offset; +} + Bool i965_prepare_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, @@ -429,36 +907,26 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, { ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - uint32_t src_offset, src_pitch, src_tile_format = 0, src_tiled = 0; - uint32_t mask_offset = 0, mask_pitch = 0, mask_tile_format = 0, - mask_tiled = 0; - uint32_t dst_format, dst_offset, dst_pitch, dst_tile_format = 0, - dst_tiled = 0; + struct gen4_render_state *render_state= pI830->gen4_render_state; + gen4_state_t *card_state = render_state->card_state; + struct brw_surface_state_padded *ss; + uint32_t sf_state_offset; + sampler_state_filter_t src_filter, mask_filter; + sampler_state_extend_t src_extend, mask_extend; Bool is_affine_src, is_affine_mask, is_affine; + int urb_vs_start, urb_vs_size; + int urb_gs_start, urb_gs_size; + int urb_clip_start, urb_clip_size; + int urb_sf_start, urb_sf_size; + int urb_cs_start, urb_cs_size; + char *state_base; + int state_base_offset; + uint32_t src_blend, dst_blend; + uint32_t *binding_table; IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; - src_offset = intel_get_pixmap_offset(pSrc); - src_pitch = intel_get_pixmap_pitch(pSrc); - if (i830_pixmap_tiled(pSrc)) { - src_tiled = 1; - src_tile_format = 0; /* Tiled X */ - } - dst_offset = intel_get_pixmap_offset(pDst); - dst_pitch = intel_get_pixmap_pitch(pDst); - if (i830_pixmap_tiled(pDst)) { - dst_tiled = 1; - dst_tile_format = 0; /* Tiled X */ - } - if (pMask) { - mask_offset = intel_get_pixmap_offset(pMask); - mask_pitch = intel_get_pixmap_pitch(pMask); - if (i830_pixmap_tiled(pMask)) { - mask_tiled = 1; - mask_tile_format = 0; /* Tiled X */ - } - } pI830->scale_units[0][0] = pSrc->drawable.width; pI830->scale_units[0][1] = pSrc->drawable.height; @@ -479,139 +947,10 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, is_affine = is_affine_src && is_affine_mask; - /* setup 3d pipeline state */ - - binding_table_entries = 2; /* default no mask */ - - /* Set up our layout of state in framebuffer. First the general state: */ - next_offset = 0; - vs_offset = ALIGN(next_offset, 64); - next_offset = vs_offset + sizeof(*vs_state); - - sf_offset = ALIGN(next_offset, 32); - next_offset = sf_offset + sizeof(*sf_state); - - wm_offset = ALIGN(next_offset, 32); - next_offset = wm_offset + sizeof(*wm_state); - - wm_scratch_offset = ALIGN(next_offset, 1024); - next_offset = wm_scratch_offset + PS_SCRATCH_SPACE * PS_MAX_THREADS; - - cc_offset = ALIGN(next_offset, 32); - next_offset = cc_offset + sizeof(*cc_state); - - /* keep current sf_kernel, which will send one setup urb entry to - * PS kernel - */ - sf_kernel_offset = ALIGN(next_offset, 64); - if (pMask) - next_offset = sf_kernel_offset + sizeof (sf_kernel_static_mask); - else - next_offset = sf_kernel_offset + sizeof (sf_kernel_static); - - ps_kernel_offset = ALIGN(next_offset, 64); - if (pMask) { - if (pMaskPicture->componentAlpha && - PICT_FORMAT_RGB(pMaskPicture->format)) { - if (i965_blend_op[op].src_alpha) { - if (is_affine) - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca_srcalpha_affine); - else - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca_srcalpha_projective); - } else { - if (is_affine) - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca_affine); - else - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca_projective); - } - } else { - if (is_affine) - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_masknoca_affine); - else - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_masknoca_projective); - } - } else { - if (is_affine) - next_offset = ps_kernel_offset + sizeof (ps_kernel_static_nomask_affine); - else - next_offset = ps_kernel_offset + sizeof (ps_kernel_static_nomask_projective); - } - - sip_kernel_offset = ALIGN(next_offset, 64); - next_offset = sip_kernel_offset + sizeof (sip_kernel_static); - - /* needed? */ - cc_viewport_offset = ALIGN(next_offset, 32); - next_offset = cc_viewport_offset + sizeof(*cc_viewport); - - /* for texture sampler */ - src_sampler_offset = ALIGN(next_offset, 32); - next_offset = src_sampler_offset + sizeof(*src_sampler_state); - - if (pMask) { - mask_sampler_offset = ALIGN(next_offset, 32); - next_offset = mask_sampler_offset + sizeof(*mask_sampler_state); - } - /* Align VB to native size of elements, for safety */ - vb_offset = ALIGN(next_offset, 32); - next_offset = vb_offset + vb_size; - - /* And then the general state: */ - dest_surf_offset = ALIGN(next_offset, 32); - next_offset = dest_surf_offset + sizeof(*dest_surf_state); - - src_surf_offset = ALIGN(next_offset, 32); - next_offset = src_surf_offset + sizeof(*src_surf_state); - - if (pMask) { - mask_surf_offset = ALIGN(next_offset, 32); - next_offset = mask_surf_offset + sizeof(*mask_surf_state); - binding_table_entries = 3; - } - - binding_table_offset = ALIGN(next_offset, 32); - next_offset = binding_table_offset + (binding_table_entries * 4); - - default_color_offset = ALIGN(next_offset, 32); - next_offset = default_color_offset + sizeof(*default_color_state); - - total_state_size = next_offset; - assert(total_state_size < pI830->exa_965_state->size); - - state_base_offset = pI830->exa_965_state->offset; - state_base_offset = ALIGN(state_base_offset, 64); + state_base_offset = pI830->gen4_render_state_mem->offset; + assert((state_base_offset & 63) == 0); state_base = (char *)(pI830->FbBase + state_base_offset); - sf_kernel = (void *)(state_base + sf_kernel_offset); - ps_kernel = (void *)(state_base + ps_kernel_offset); - sip_kernel = (void *)(state_base + sip_kernel_offset); - - cc_viewport = (void *)(state_base + cc_viewport_offset); - - binding_table = (void *)(state_base + binding_table_offset); - - vb = (void *)(state_base + vb_offset); - - default_color_state = (void*)(state_base + default_color_offset); - - /* Set up a default static partitioning of the URB, which is supposed to - * allow anything we would want to do, at potentially lower performance. - */ -#define URB_CS_ENTRY_SIZE 0 -#define URB_CS_ENTRIES 0 - -#define URB_VS_ENTRY_SIZE 1 // each 512-bit row -#define URB_VS_ENTRIES 8 // we needs at least 8 entries - -#define URB_GS_ENTRY_SIZE 0 -#define URB_GS_ENTRIES 0 - -#define URB_CLIP_ENTRY_SIZE 0 -#define URB_CLIP_ENTRIES 0 - -#define URB_SF_ENTRY_SIZE 2 -#define URB_SF_ENTRIES 1 - urb_vs_start = 0; urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE; urb_gs_start = urb_vs_start + urb_vs_size; @@ -623,350 +962,69 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, urb_cs_start = urb_sf_start + urb_sf_size; urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE; - /* Because we only have a single static buffer for our state currently, - * we have to sync before updating it every time. - */ - i830WaitSync(pScrn); - - memset (cc_viewport, 0, sizeof (*cc_viewport)); - cc_viewport->min_depth = -1.e35; - cc_viewport->max_depth = 1.e35; - - /* Color calculator state */ - cc_state = &cc_state_local; - memset(cc_state, 0, sizeof(*cc_state)); - cc_state->cc0.stencil_enable = 0; /* disable stencil */ - cc_state->cc2.depth_test = 0; /* disable depth test */ - cc_state->cc2.logicop_enable = 0; /* disable logic op */ - cc_state->cc3.ia_blend_enable = 1; /* blend alpha just like colors */ - cc_state->cc3.blend_enable = 1; /* enable color blend */ - cc_state->cc3.alpha_test = 0; /* disable alpha test */ - cc_state->cc4.cc_viewport_state_offset = (state_base_offset + - cc_viewport_offset) >> 5; - cc_state->cc5.dither_enable = 0; /* disable dither */ - cc_state->cc5.logicop_func = 0xc; /* COPY */ - cc_state->cc5.statistics_enable = 1; - cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD; i965_get_blend_cntl(op, pMaskPicture, pDstPicture->format, &src_blend, &dst_blend); - /* XXX: alpha blend factor should be same as color, but check - * for CA case in future - */ - cc_state->cc5.ia_src_blend_factor = src_blend; - cc_state->cc5.ia_dest_blend_factor = dst_blend; - cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD; - cc_state->cc6.src_blend_factor = src_blend; - cc_state->cc6.dest_blend_factor = dst_blend; - cc_state->cc6.clamp_post_alpha_blend = 1; - cc_state->cc6.clamp_pre_alpha_blend = 1; - cc_state->cc6.clamp_range = 0; /* clamp range [0,1] */ - - cc_state = (void *)(state_base + cc_offset); - memcpy (cc_state, &cc_state_local, sizeof (cc_state_local)); - - /* Upload system kernel */ - memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static)); - - /* Set up the state buffer for the destination surface */ - dest_surf_state = &dest_surf_state_local; - memset(dest_surf_state, 0, sizeof(*dest_surf_state)); - dest_surf_state->ss0.surface_type = BRW_SURFACE_2D; - dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; - if (!i965_get_dest_format(pDstPicture, &dst_format)) - return FALSE; - dest_surf_state->ss0.surface_format = dst_format; - - dest_surf_state->ss0.writedisable_alpha = 0; - dest_surf_state->ss0.writedisable_red = 0; - dest_surf_state->ss0.writedisable_green = 0; - dest_surf_state->ss0.writedisable_blue = 0; - dest_surf_state->ss0.color_blend = 1; - dest_surf_state->ss0.vert_line_stride = 0; - dest_surf_state->ss0.vert_line_stride_ofs = 0; - dest_surf_state->ss0.mipmap_layout_mode = 0; - dest_surf_state->ss0.render_cache_read_mode = 0; - - dest_surf_state->ss1.base_addr = dst_offset; - dest_surf_state->ss2.height = pDst->drawable.height - 1; - dest_surf_state->ss2.width = pDst->drawable.width - 1; - dest_surf_state->ss2.mip_count = 0; - dest_surf_state->ss2.render_target_rotation = 0; - dest_surf_state->ss3.pitch = dst_pitch - 1; - dest_surf_state->ss3.tile_walk = dst_tile_format; - dest_surf_state->ss3.tiled_surface = dst_tiled; - - dest_surf_state = (void *)(state_base + dest_surf_offset); - memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local)); - - /* Set up the source surface state buffer */ - src_surf_state = &src_surf_state_local; - memset(src_surf_state, 0, sizeof(*src_surf_state)); - src_surf_state->ss0.surface_type = BRW_SURFACE_2D; - src_surf_state->ss0.surface_format = i965_get_card_format(pSrcPicture); - - src_surf_state->ss0.writedisable_alpha = 0; - src_surf_state->ss0.writedisable_red = 0; - src_surf_state->ss0.writedisable_green = 0; - src_surf_state->ss0.writedisable_blue = 0; - src_surf_state->ss0.color_blend = 1; - src_surf_state->ss0.vert_line_stride = 0; - src_surf_state->ss0.vert_line_stride_ofs = 0; - src_surf_state->ss0.mipmap_layout_mode = 0; - src_surf_state->ss0.render_cache_read_mode = 0; - - src_surf_state->ss1.base_addr = src_offset; - src_surf_state->ss2.width = pSrc->drawable.width - 1; - src_surf_state->ss2.height = pSrc->drawable.height - 1; - src_surf_state->ss2.mip_count = 0; - src_surf_state->ss2.render_target_rotation = 0; - src_surf_state->ss3.pitch = src_pitch - 1; - src_surf_state->ss3.tile_walk = src_tile_format; - src_surf_state->ss3.tiled_surface = src_tiled; - - src_surf_state = (void *)(state_base + src_surf_offset); - memcpy (src_surf_state, &src_surf_state_local, sizeof (src_surf_state_local)); - - /* setup mask surface */ - if (pMask) { - mask_surf_state = &mask_surf_state_local; - memset(mask_surf_state, 0, sizeof(*mask_surf_state)); - mask_surf_state->ss0.surface_type = BRW_SURFACE_2D; - mask_surf_state->ss0.surface_format = - i965_get_card_format(pMaskPicture); - - mask_surf_state->ss0.writedisable_alpha = 0; - mask_surf_state->ss0.writedisable_red = 0; - mask_surf_state->ss0.writedisable_green = 0; - mask_surf_state->ss0.writedisable_blue = 0; - mask_surf_state->ss0.color_blend = 1; - mask_surf_state->ss0.vert_line_stride = 0; - mask_surf_state->ss0.vert_line_stride_ofs = 0; - mask_surf_state->ss0.mipmap_layout_mode = 0; - mask_surf_state->ss0.render_cache_read_mode = 0; - - mask_surf_state->ss1.base_addr = mask_offset; - mask_surf_state->ss2.width = pMask->drawable.width - 1; - mask_surf_state->ss2.height = pMask->drawable.height - 1; - mask_surf_state->ss2.mip_count = 0; - mask_surf_state->ss2.render_target_rotation = 0; - mask_surf_state->ss3.pitch = mask_pitch - 1; - mask_surf_state->ss3.tile_walk = mask_tile_format; - mask_surf_state->ss3.tiled_surface = mask_tiled; - - mask_surf_state = (void *)(state_base + mask_surf_offset); - memcpy (mask_surf_state, &mask_surf_state_local, sizeof (mask_surf_state_local)); - } - - /* Set up a binding table for our surfaces. Only the PS will use it */ - binding_table[0] = state_base_offset + dest_surf_offset; - binding_table[1] = state_base_offset + src_surf_offset; - if (pMask) - binding_table[2] = state_base_offset + mask_surf_offset; - - /* PS kernel use this sampler */ - src_sampler_state = &src_sampler_state_local; - memset(src_sampler_state, 0, sizeof(*src_sampler_state)); - src_sampler_state->ss0.lod_preclamp = 1; /* GL mode */ - switch(pSrcPicture->filter) { - case PictFilterNearest: - src_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; - src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST; - break; - case PictFilterBilinear: - src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; - src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR; - break; - default: - I830FALLBACK("Bad filter 0x%x\n", pSrcPicture->filter); - } - memset(default_color_state, 0, sizeof(*default_color_state)); - default_color_state->color[0] = 0.0; /* R */ - default_color_state->color[1] = 0.0; /* G */ - default_color_state->color[2] = 0.0; /* B */ - default_color_state->color[3] = 0.0; /* A */ - - src_sampler_state->ss0.default_color_mode = 0; /* GL mode */ - - if (!pSrcPicture->repeat) { - src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; - src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; - src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; - src_sampler_state->ss2.default_color_pointer = - (state_base_offset + default_color_offset) >> 5; - } else { - src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; - src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP; - src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; - } - src_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */ - - src_sampler_state = (void *)(state_base + src_sampler_offset); - memcpy (src_sampler_state, &src_sampler_state_local, sizeof (src_sampler_state_local)); - - if (pMask) { - mask_sampler_state = &mask_sampler_state_local; - memset(mask_sampler_state, 0, sizeof(*mask_sampler_state)); - mask_sampler_state->ss0.lod_preclamp = 1; /* GL mode */ - switch(pMaskPicture->filter) { - case PictFilterNearest: - mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; - mask_sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST; - break; - case PictFilterBilinear: - mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; - mask_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR; - break; - default: - I830FALLBACK("Bad filter 0x%x\n", pMaskPicture->filter); - } - - mask_sampler_state->ss0.default_color_mode = 0; /* GL mode */ - if (!pMaskPicture->repeat) { - mask_sampler_state->ss1.r_wrap_mode = - BRW_TEXCOORDMODE_CLAMP_BORDER; - mask_sampler_state->ss1.s_wrap_mode = - BRW_TEXCOORDMODE_CLAMP_BORDER; - mask_sampler_state->ss1.t_wrap_mode = - BRW_TEXCOORDMODE_CLAMP_BORDER; - mask_sampler_state->ss2.default_color_pointer = - (state_base_offset + default_color_offset)>>5; - } else { - mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; - mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP; - mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; - } - mask_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */ - - mask_sampler_state = (void *)(state_base + mask_sampler_offset); - memcpy (mask_sampler_state, &mask_sampler_state_local, sizeof (mask_sampler_state_local)); + if ((render_state->binding_table_index + 3 >= + ARRAY_SIZE(card_state->binding_table)) || + (render_state->surface_state_index + 3 >= + ARRAY_SIZE(card_state->surface_state))) + { + i830WaitSync(pScrn); + render_state->binding_table_index = 0; + render_state->surface_state_index = 0; + render_state->vb_offset = 0; } - /* Set up the vertex shader to be disabled (passthrough) */ - vs_state = &vs_state_local; - memset(vs_state, 0, sizeof(*vs_state)); - vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES; - vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1; - vs_state->vs6.vs_enable = 0; - vs_state->vs6.vert_cache_disable = 1; - - vs_state = (void *)(state_base + vs_offset); - memcpy (vs_state, &vs_state_local, sizeof (vs_state_local)); - - /* Set up the SF kernel to do coord interp: for each attribute, - * calculate dA/dx and dA/dy. Hand these interpolation coefficients - * back to SF which then hands pixels off to WM. + binding_table = card_state->binding_table + + render_state->binding_table_index; + ss = card_state->surface_state + render_state->surface_state_index; + /* We only use 2 or 3 entries, but the table has to be 32-byte + * aligned. */ - if (pMask) - memcpy(sf_kernel, sf_kernel_static_mask, - sizeof (sf_kernel_static_mask)); - else - memcpy(sf_kernel, sf_kernel_static, sizeof (sf_kernel_static)); - - sf_state = &sf_state_local; - memset(sf_state, 0, sizeof(*sf_state)); - sf_state->thread0.kernel_start_pointer = - (state_base_offset + sf_kernel_offset) >> 6; - sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF); - sf_state->sf1.single_program_flow = 1; - sf_state->sf1.binding_table_entry_count = 0; - sf_state->sf1.thread_priority = 0; - sf_state->sf1.floating_point_mode = 0; /* Mesa does this */ - sf_state->sf1.illegal_op_exception_enable = 1; - sf_state->sf1.mask_stack_exception_enable = 1; - sf_state->sf1.sw_exception_enable = 1; - sf_state->thread2.per_thread_scratch_space = 0; - /* scratch space is not used in our kernel */ - sf_state->thread2.scratch_space_base_pointer = 0; - sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */ - sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */ - sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ - /* don't smash vertex header, read start from dw8 */ - sf_state->thread3.urb_entry_read_offset = 1; - sf_state->thread3.dispatch_grf_start_reg = 3; - sf_state->thread4.max_threads = SF_MAX_THREADS - 1; - sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; - sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES; - sf_state->thread4.stats_enable = 1; - sf_state->sf5.viewport_transform = FALSE; /* skip viewport */ - sf_state->sf6.cull_mode = BRW_CULLMODE_NONE; - sf_state->sf6.scissor = 0; - sf_state->sf7.trifan_pv = 2; - sf_state->sf6.dest_org_vbias = 0x8; - sf_state->sf6.dest_org_hbias = 0x8; - - sf_state = (void *)(state_base + sf_offset); - memcpy (sf_state, &sf_state_local, sizeof (sf_state_local)); - - /* Set up the PS kernel (dispatched by WM) */ + render_state->binding_table_index += 8; + render_state->surface_state_index += (pMask != NULL) ? 3 : 2; + + /* Set up and bind the state buffer for the destination surface */ + binding_table[0] = state_base_offset + + i965_set_picture_surface_state(pScrn, + &ss[0].state, + pDstPicture, pDst, TRUE); + + /* Set up and bind the source surface state buffer */ + binding_table[1] = state_base_offset + + i965_set_picture_surface_state(pScrn, + &ss[1].state, + pSrcPicture, pSrc, FALSE); if (pMask) { - if (pMaskPicture->componentAlpha && - PICT_FORMAT_RGB(pMaskPicture->format)) { - if (i965_blend_op[op].src_alpha) { - if (is_affine) - memcpy(ps_kernel, ps_kernel_static_maskca_srcalpha_affine, sizeof (ps_kernel_static_maskca_srcalpha_affine)); - else - memcpy(ps_kernel, ps_kernel_static_maskca_srcalpha_projective, sizeof (ps_kernel_static_maskca_srcalpha_projective)); - } else { - if (is_affine) - memcpy(ps_kernel, ps_kernel_static_maskca_affine, sizeof (ps_kernel_static_maskca_affine)); - else - memcpy(ps_kernel, ps_kernel_static_maskca_projective, sizeof (ps_kernel_static_maskca_projective)); - } - } else { - if (is_affine) - memcpy(ps_kernel, ps_kernel_static_masknoca_affine, sizeof (ps_kernel_static_masknoca_affine)); - else - memcpy(ps_kernel, ps_kernel_static_masknoca_projective, sizeof (ps_kernel_static_masknoca_projective)); - } + /* Set up and bind the mask surface state buffer */ + binding_table[2] = state_base_offset + + i965_set_picture_surface_state(pScrn, + &ss[2].state, + pMaskPicture, pMask, + FALSE); } else { - if (is_affine) - memcpy(ps_kernel, ps_kernel_static_nomask_affine, sizeof (ps_kernel_static_nomask_affine)); - else - memcpy(ps_kernel, ps_kernel_static_nomask_projective, sizeof (ps_kernel_static_nomask_projective)); + binding_table[2] = 0; } - wm_state = &wm_state_local; - memset(wm_state, 0, sizeof (*wm_state)); - wm_state->thread0.kernel_start_pointer = - (state_base_offset + ps_kernel_offset) >> 6; - wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF); - wm_state->thread1.single_program_flow = 0; - if (!pMask) - wm_state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */ - else - wm_state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */ - - wm_state->thread2.scratch_space_base_pointer = (state_base_offset + - wm_scratch_offset)>>10; - wm_state->thread2.per_thread_scratch_space = PS_SCRATCH_SPACE_LOG; - wm_state->thread3.const_urb_entry_read_length = 0; - wm_state->thread3.const_urb_entry_read_offset = 0; - /* Each pair of attributes (src/mask coords) is one URB entry */ - if (pMask) - wm_state->thread3.urb_entry_read_length = 4; - else - wm_state->thread3.urb_entry_read_length = 2; - wm_state->thread3.urb_entry_read_offset = 0; - /* wm kernel use urb from 3, see wm_program in compiler module */ - wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */ - - wm_state->wm4.stats_enable = 1; /* statistic */ - wm_state->wm4.sampler_state_pointer = (state_base_offset + - src_sampler_offset) >> 5; - wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */ - wm_state->wm5.max_threads = PS_MAX_THREADS - 1; - wm_state->wm5.transposed_urb_read = 0; - wm_state->wm5.thread_dispatch_enable = 1; - /* just use 16-pixel dispatch (4 subspans), don't need to change kernel - * start point - */ - wm_state->wm5.enable_16_pix = 1; - wm_state->wm5.enable_8_pix = 0; - wm_state->wm5.early_depth_test = 1; - - wm_state = (void *)(state_base + wm_offset); - memcpy (wm_state, &wm_state_local, sizeof (wm_state_local)); + src_filter = sampler_state_filter_from_picture (pSrcPicture->filter); + if (src_filter < 0) + I830FALLBACK ("Bad src filter 0x%x\n", pSrcPicture->filter); + src_extend = sampler_state_extend_from_picture (pSrcPicture->repeat); + if (src_extend < 0) + I830FALLBACK ("Bad src repeat 0x%x\n", pSrcPicture->repeat); + + if (pMaskPicture) { + mask_filter = sampler_state_filter_from_picture (pMaskPicture->filter); + if (mask_filter < 0) + I830FALLBACK ("Bad mask filter 0x%x\n", pMaskPicture->filter); + mask_extend = sampler_state_extend_from_picture (pMaskPicture->repeat); + if (mask_extend < 0) + I830FALLBACK ("Bad mask repeat 0x%x\n", pMaskPicture->repeat); + } else { + mask_filter = SAMPLER_STATE_FILTER_NEAREST; + mask_extend = SAMPLER_STATE_EXTEND_NONE; + } /* Begin the long sequence of commands needed to set up the 3D * rendering pipe @@ -983,7 +1041,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, BEGIN_BATCH(12); /* Match Mesa driver setup */ - if (IS_IGD_GM(pI830)) + if (IS_GM45(pI830) || IS_G4X(pI830)) OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); else OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); @@ -1006,7 +1064,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, /* Set system instruction pointer */ OUT_BATCH(BRW_STATE_SIP | 0); - OUT_BATCH(state_base_offset + sip_kernel_offset); + OUT_BATCH(state_base_offset + offsetof(gen4_state_t, sip_kernel)); OUT_BATCH(MI_NOOP); ADVANCE_BATCH(); } @@ -1028,7 +1086,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ /* Only the PS uses the binding table */ - OUT_BATCH(state_base_offset + binding_table_offset); /* ps */ + assert((((unsigned char *)binding_table - pI830->FbBase) & 31) == 0); + OUT_BATCH((unsigned char *)binding_table - pI830->FbBase); /* The drawing rectangle clipping is always on. Set it to values that * shouldn't do any clipping. @@ -1046,12 +1105,68 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, /* Set the pointers to the 3d pipeline state */ OUT_BATCH(BRW_3DSTATE_PIPELINED_POINTERS | 5); - OUT_BATCH(state_base_offset + vs_offset); /* 32 byte aligned */ + assert((offsetof(gen4_state_t, vs_state) & 31) == 0); + OUT_BATCH(state_base_offset + offsetof(gen4_state_t, vs_state)); OUT_BATCH(BRW_GS_DISABLE); /* disable GS, resulting in passthrough */ OUT_BATCH(BRW_CLIP_DISABLE); /* disable CLIP, resulting in passthrough */ - OUT_BATCH(state_base_offset + sf_offset); /* 32 byte aligned */ - OUT_BATCH(state_base_offset + wm_offset); /* 32 byte aligned */ - OUT_BATCH(state_base_offset + cc_offset); /* 64 byte aligned */ + + if (pMask) { + sf_state_offset = state_base_offset + + offsetof(gen4_state_t, sf_state_mask); + } else { + sf_state_offset = state_base_offset + + offsetof(gen4_state_t, sf_state); + } + assert((sf_state_offset & 31) == 0); + OUT_BATCH(sf_state_offset); + + /* Shorthand for long array lookup */ +#define OUT_WM_KERNEL(kernel) do { \ + uint32_t offset = state_base_offset + \ + offsetof(gen4_state_t, \ + wm_state_ ## kernel \ + [src_filter] \ + [src_extend] \ + [mask_filter] \ + [mask_extend]); \ + assert((offset & 31) == 0); \ + OUT_BATCH(offset); \ +} while (0) + + if (pMask) { + if (pMaskPicture->componentAlpha && + PICT_FORMAT_RGB(pMaskPicture->format)) + { + if (i965_blend_op[op].src_alpha) { + if (is_affine) + OUT_WM_KERNEL(maskca_srcalpha_affine); + else + OUT_WM_KERNEL(maskca_srcalpha_projective); + } else { + if (is_affine) + OUT_WM_KERNEL(maskca_affine); + else + OUT_WM_KERNEL(maskca_projective); + } + } else { + if (is_affine) + OUT_WM_KERNEL(masknoca_affine); + else + OUT_WM_KERNEL(masknoca_projective); + } + } else { + if (is_affine) + OUT_WM_KERNEL(nomask_affine); + else + OUT_WM_KERNEL(nomask_projective); + } +#undef OUT_WM_KERNEL + + /* 64 byte aligned */ + assert((offsetof(gen4_state_t, + cc_state[src_blend][dst_blend]) & 63) == 0); + OUT_BATCH(state_base_offset + + offsetof(gen4_state_t, cc_state[src_blend][dst_blend])); /* URB fence */ OUT_BATCH(BRW_URB_FENCE | @@ -1086,6 +1201,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, int selem = is_affine ? 2 : 3; uint32_t w_component; uint32_t src_format; + + render_state->vertex_size = 4 * (2 + nelem * selem); if (is_affine) { @@ -1097,17 +1214,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT; w_component = BRW_VFCOMPONENT_STORE_SRC; } - BEGIN_BATCH(pMask?12:10); - /* Set up the pointer to our (single) vertex buffer */ - OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3); - OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) | - VB0_VERTEXDATA | - ((4 * (2 + nelem * selem)) << VB0_BUFFER_PITCH_SHIFT)); - OUT_BATCH(state_base_offset + vb_offset); - OUT_BATCH(3); - OUT_BATCH(0); // ignore for VERTEXDATA, but still there - + BEGIN_BATCH(pMask?7:5); /* Set up our vertex elements, sourced from the single vertex buffer. + * that will be set up later. */ OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (1 + nelem)) - 1)); @@ -1161,9 +1270,12 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, { ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); + gen4_state_t *card_state = pI830->gen4_render_state->card_state; + struct gen4_render_state *render_state = pI830->gen4_render_state; Bool has_mask; Bool is_affine_src, is_affine_mask, is_affine; float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; + float *vb = card_state->vb; int i; is_affine_src = i830_transform_is_affine (pI830->transform[0]); @@ -1240,12 +1352,12 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } } - /* Wait for any existing composite rectangles to land before we overwrite - * the VB with the next one. - */ - i830WaitSync(pScrn); + if (render_state->vb_offset + MAX_VERTEX_PER_COMPOSITE >= ARRAY_SIZE(card_state->vb)) { + i830WaitSync(pScrn); + render_state->vb_offset = 0; + } - i = 0; + i = render_state->vb_offset; /* rect (x2,y2) */ vb[i++] = (float)(dstX + w); vb[i++] = (float)(dstY + h); @@ -1287,22 +1399,34 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, if (!is_affine) vb[i++] = mask_w[0]; } - assert (i * 4 <= vb_size); + assert (i * 4 <= sizeof(card_state->vb)); + + BEGIN_BATCH(12); + OUT_BATCH(MI_FLUSH); + /* Set up the pointer to our (single) vertex buffer */ + OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3); + OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) | + VB0_VERTEXDATA | + (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT)); + OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb) + + render_state->vb_offset * 4); + OUT_BATCH(3); + OUT_BATCH(0); // ignore for VERTEXDATA, but still there + + OUT_BATCH(BRW_3DPRIMITIVE | + BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | + (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | + (0 << 9) | /* CTG - indirect vertex count */ + 4); + OUT_BATCH(3); /* vertex count per instance */ + OUT_BATCH(0); /* start vertex offset */ + OUT_BATCH(1); /* single instance */ + OUT_BATCH(0); /* start instance location */ + OUT_BATCH(0); /* index buffer offset, ignored */ + ADVANCE_BATCH(); + + render_state->vb_offset = i; - { - BEGIN_BATCH(6); - OUT_BATCH(BRW_3DPRIMITIVE | - BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | - (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | - (0 << 9) | /* CTG - indirect vertex count */ - 4); - OUT_BATCH(3); /* vertex count per instance */ - OUT_BATCH(0); /* start vertex offset */ - OUT_BATCH(1); /* single instance */ - OUT_BATCH(0); /* start instance location */ - OUT_BATCH(0); /* index buffer offset, ignored */ - ADVANCE_BATCH(); - } #ifdef I830DEBUG ErrorF("sync after 3dprimitive\n"); I830Sync(pScrn); @@ -1328,3 +1452,41 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, */ i830MarkSync(pScrn); } + +/** + * Called at EnterVT so we can set up our offsets into the state buffer. + */ +void +gen4_render_state_init(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + struct gen4_render_state *render_state; + + if (pI830->gen4_render_state == NULL) + pI830->gen4_render_state = calloc(sizeof(*render_state), 1); + + render_state = pI830->gen4_render_state; + + render_state->card_state_offset = pI830->gen4_render_state_mem->offset; + render_state->card_state = (gen4_state_t *) + (pI830->FbBase + render_state->card_state_offset); + + gen4_state_init(render_state); +} + +/** + * Called at LeaveVT. + */ +void +gen4_render_state_cleanup(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + pI830->gen4_render_state->card_state = NULL; +} + +unsigned int +gen4_render_state_size(ScrnInfoPtr pScrn) +{ + return sizeof(gen4_state_t); +} diff --git a/driver/xf86-video-intel/src/i965_video.c b/driver/xf86-video-intel/src/i965_video.c index 153a967c6..4c79259bf 100644 --- a/driver/xf86-video-intel/src/i965_video.c +++ b/driver/xf86-video-intel/src/i965_video.c @@ -78,7 +78,7 @@ static const uint32_t sip_kernel_static[][4] = { #define SF_MAX_THREADS 1 static const uint32_t sf_kernel_static[][4] = { -#include "packed_yuv_sf.g4b" +#include "exa_sf.g4b" }; /* @@ -93,15 +93,25 @@ static const uint32_t sf_kernel_static[][4] = { #define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) -static const uint32_t ps_kernel_static[][4] = { -#include "packed_yuv_wm.g4b" +static const uint32_t ps_kernel_packed_static[][4] = { +#include "exa_wm_xy.g4b" +#include "exa_wm_src_affine.g4b" +#include "exa_wm_src_sample_argb.g4b" +#include "exa_wm_yuv_rgb.g4b" +#include "exa_wm_write.g4b" +}; + +static const uint32_t ps_kernel_planar_static[][4] = { +#include "exa_wm_xy.g4b" +#include "exa_wm_src_affine.g4b" +#include "exa_wm_src_sample_planar.g4b" +#include "exa_wm_yuv_rgb.g4b" +#include "exa_wm_write.g4b" }; #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define WM_BINDING_TABLE_ENTRIES 2 - static uint32_t float_to_uint (float f) { union {uint32_t i; float f;} x; x.f = f; @@ -161,8 +171,8 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, int urb_sf_start, urb_sf_size; int urb_cs_start, urb_cs_size; struct brw_surface_state *dest_surf_state; - struct brw_surface_state *src_surf_state; - struct brw_sampler_state *src_sampler_state; + struct brw_surface_state *src_surf_state[6]; + struct brw_sampler_state *src_sampler_state[6]; struct brw_vs_unit_state *vs_state; struct brw_sf_unit_state *sf_state; struct brw_wm_unit_state *wm_state; @@ -175,7 +185,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, float src_scale_x, src_scale_y; uint32_t *binding_table; Bool first_output = TRUE; - int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset; + int dest_surf_offset, src_surf_offset[6], src_sampler_offset[6], vs_offset; int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset; int wm_scratch_offset; int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset; @@ -184,6 +194,16 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */ char *state_base; int state_base_offset; + int src_surf; + int n_src_surf; + uint32_t src_surf_format; + uint32_t src_surf_base[6]; + int src_width[6]; + int src_height[6]; + int src_pitch[6]; + int wm_binding_table_entries; + const uint32_t *ps_kernel_static; + int ps_kernel_static_size; #if 0 ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height, @@ -198,7 +218,53 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM)); #endif - assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2)); + src_surf_base[0] = pPriv->YBuf0offset; + src_surf_base[1] = pPriv->YBuf0offset; + src_surf_base[2] = pPriv->VBuf0offset; + src_surf_base[3] = pPriv->VBuf0offset; + src_surf_base[4] = pPriv->UBuf0offset; + src_surf_base[5] = pPriv->UBuf0offset; +#if 0 + ErrorF ("base 0 0x%x base 1 0x%x base 2 0x%x\n", + src_surf_base[0], src_surf_base[1], src_surf_base[2]); +#endif + + switch (id) { + case FOURCC_UYVY: + src_surf_format = BRW_SURFACEFORMAT_YCRCB_SWAPY; + n_src_surf = 1; + ps_kernel_static = &ps_kernel_packed_static[0][0]; + ps_kernel_static_size = sizeof (ps_kernel_packed_static); + src_width[0] = width; + src_height[0] = height; + src_pitch[0] = video_pitch; + break; + case FOURCC_YUY2: + src_surf_format = BRW_SURFACEFORMAT_YCRCB_NORMAL; + ps_kernel_static = &ps_kernel_packed_static[0][0]; + ps_kernel_static_size = sizeof (ps_kernel_packed_static); + src_width[0] = width; + src_height[0] = height; + src_pitch[0] = video_pitch; + n_src_surf = 1; + break; + case FOURCC_I420: + case FOURCC_YV12: + src_surf_format = BRW_SURFACEFORMAT_R8_UNORM; + ps_kernel_static = &ps_kernel_planar_static[0][0]; + ps_kernel_static_size = sizeof (ps_kernel_planar_static); + src_width[1] = src_width[0] = width; + src_width[1] = src_height[0] = height; + src_pitch[1] = src_pitch[0] = video_pitch * 2; + src_width[4] = src_width[5] = src_width[2] = src_width[3] = width / 2; + src_height[4] = src_height[5] = src_height[2] = src_height[3] = height / 2; + src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = video_pitch; + n_src_surf = 6; + break; + default: + return; + } + wm_binding_table_entries = 1 + n_src_surf; IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_VIDEO; @@ -220,15 +286,17 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, sf_kernel_offset = ALIGN(next_offset, 64); next_offset = sf_kernel_offset + sizeof (sf_kernel_static); ps_kernel_offset = ALIGN(next_offset, 64); - next_offset = ps_kernel_offset + sizeof (ps_kernel_static); + next_offset = ps_kernel_offset + ps_kernel_static_size; sip_kernel_offset = ALIGN(next_offset, 64); next_offset = sip_kernel_offset + sizeof (sip_kernel_static); cc_viewport_offset = ALIGN(next_offset, 32); next_offset = cc_viewport_offset + sizeof(*cc_viewport); - src_sampler_offset = ALIGN(next_offset, 32); - next_offset = src_sampler_offset + sizeof(*src_sampler_state); - + for (src_surf = 0; src_surf < n_src_surf; src_surf++) { + src_sampler_offset[src_surf] = ALIGN(next_offset, 32); + next_offset = src_sampler_offset[src_surf] + sizeof(struct brw_sampler_state); + } + /* Align VB to native size of elements, for safety */ vb_offset = ALIGN(next_offset, 8); next_offset = vb_offset + vb_size; @@ -236,10 +304,14 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, /* And then the general state: */ dest_surf_offset = ALIGN(next_offset, 32); next_offset = dest_surf_offset + sizeof(*dest_surf_state); - src_surf_offset = ALIGN(next_offset, 32); - next_offset = src_surf_offset + sizeof(*src_surf_state); + + for (src_surf = 0; src_surf < n_src_surf; src_surf++) { + src_surf_offset[src_surf] = ALIGN(next_offset, 32); + next_offset = src_surf_offset[src_surf] + sizeof(struct brw_surface_state); + } + binding_table_offset = ALIGN(next_offset, 32); - next_offset = binding_table_offset + (WM_BINDING_TABLE_ENTRIES * 4); + next_offset = binding_table_offset + (wm_binding_table_entries * 4); /* Allocate an area in framebuffer for our state layout we just set up */ total_state_size = next_offset; @@ -266,8 +338,12 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, cc_viewport = (void *)(state_base + cc_viewport_offset); dest_surf_state = (void *)(state_base + dest_surf_offset); - src_surf_state = (void *)(state_base + src_surf_offset); - src_sampler_state = (void *)(state_base + src_sampler_offset); + + for (src_surf = 0; src_surf < n_src_surf; src_surf++) + { + src_surf_state[src_surf] = (void *)(state_base + src_surf_offset[src_surf]); + src_sampler_state[src_surf] = (void *)(state_base + src_sampler_offset[src_surf]); + } binding_table = (void *)(state_base + binding_table_offset); vb = (void *)(state_base + vb_offset); @@ -380,50 +456,49 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, dest_surf_state->ss3.tiled_surface = i830_pixmap_tiled(pPixmap); dest_surf_state->ss3.tile_walk = 0; /* TileX */ - /* Set up the source surface state buffer */ - memset(src_surf_state, 0, sizeof(*src_surf_state)); - src_surf_state->ss0.surface_type = BRW_SURFACE_2D; - /* src_surf_state->ss0.data_return_format = - BRW_SURFACERETURNFORMAT_FLOAT32; */ - switch (id) { - case FOURCC_YUY2: - src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL; - break; - case FOURCC_UYVY: - src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_SWAPY; - break; + for (src_surf = 0; src_surf < n_src_surf; src_surf++) + { + /* Set up the source surface state buffer */ + memset(src_surf_state[src_surf], 0, sizeof(struct brw_surface_state)); + src_surf_state[src_surf]->ss0.surface_type = BRW_SURFACE_2D; + src_surf_state[src_surf]->ss0.surface_format = src_surf_format; + src_surf_state[src_surf]->ss0.writedisable_alpha = 0; + src_surf_state[src_surf]->ss0.writedisable_red = 0; + src_surf_state[src_surf]->ss0.writedisable_green = 0; + src_surf_state[src_surf]->ss0.writedisable_blue = 0; + src_surf_state[src_surf]->ss0.color_blend = 1; + src_surf_state[src_surf]->ss0.vert_line_stride = 0; + src_surf_state[src_surf]->ss0.vert_line_stride_ofs = 0; + src_surf_state[src_surf]->ss0.mipmap_layout_mode = 0; + src_surf_state[src_surf]->ss0.render_cache_read_mode = 0; + + src_surf_state[src_surf]->ss1.base_addr = src_surf_base[src_surf]; + src_surf_state[src_surf]->ss2.width = src_width[src_surf] - 1; + src_surf_state[src_surf]->ss2.height = src_height[src_surf] - 1; + src_surf_state[src_surf]->ss2.mip_count = 0; + src_surf_state[src_surf]->ss2.render_target_rotation = 0; + src_surf_state[src_surf]->ss3.pitch = src_pitch[src_surf] - 1; } - src_surf_state->ss0.writedisable_alpha = 0; - src_surf_state->ss0.writedisable_red = 0; - src_surf_state->ss0.writedisable_green = 0; - src_surf_state->ss0.writedisable_blue = 0; - src_surf_state->ss0.color_blend = 1; - src_surf_state->ss0.vert_line_stride = 0; - src_surf_state->ss0.vert_line_stride_ofs = 0; - src_surf_state->ss0.mipmap_layout_mode = 0; - src_surf_state->ss0.render_cache_read_mode = 0; - - src_surf_state->ss1.base_addr = pPriv->YBuf0offset; - src_surf_state->ss2.width = width - 1; - src_surf_state->ss2.height = height - 1; - src_surf_state->ss2.mip_count = 0; - src_surf_state->ss2.render_target_rotation = 0; - src_surf_state->ss3.pitch = video_pitch - 1; /* FIXME: account for tiling if we ever do it */ /* Set up a binding table for our two surfaces. Only the PS will use it */ /* XXX: are these offset from the right place? */ binding_table[0] = state_base_offset + dest_surf_offset; - binding_table[1] = state_base_offset + src_surf_offset; + + for (src_surf = 0; src_surf < n_src_surf; src_surf++) + binding_table[1 + src_surf] = state_base_offset + src_surf_offset[src_surf]; /* Set up the packed YUV source sampler. Doesn't do colorspace conversion. */ - memset(src_sampler_state, 0, sizeof(*src_sampler_state)); - src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; - src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR; - src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; - src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; - src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + for (src_surf = 0; src_surf < n_src_surf; src_surf++) + { + memset(src_sampler_state[src_surf], 0, sizeof(struct brw_sampler_state)); + src_sampler_state[src_surf]->ss0.min_filter = BRW_MAPFILTER_LINEAR; + src_sampler_state[src_surf]->ss0.mag_filter = BRW_MAPFILTER_LINEAR; + src_sampler_state[src_surf]->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + src_sampler_state[src_surf]->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + src_sampler_state[src_surf]->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + } /* Set up the vertex shader to be disabled (passthrough) */ memset(vs_state, 0, sizeof(*vs_state)); @@ -468,13 +543,13 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, sf_state->sf6.dest_org_vbias = 0x8; sf_state->sf6.dest_org_hbias = 0x8; - memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static)); + memcpy (ps_kernel, ps_kernel_static, ps_kernel_static_size); memset (wm_state, 0, sizeof (*wm_state)); wm_state->thread0.kernel_start_pointer = (state_base_offset + ps_kernel_offset) >> 6; wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF); wm_state->thread1.single_program_flow = 1; /* XXX */ - wm_state->thread1.binding_table_entry_count = 2; + wm_state->thread1.binding_table_entry_count = 1 + n_src_surf; /* Though we never use the scratch space in our WM kernel, it has to be * set, and the minimum allocation is 1024 bytes. */ @@ -488,7 +563,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, wm_state->thread3.urb_entry_read_offset = 0; /* XXX */ wm_state->wm4.stats_enable = 1; wm_state->wm4.sampler_state_pointer = (state_base_offset + - src_sampler_offset) >> 5; + src_sampler_offset[0]) >> 5; wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */ wm_state->wm5.max_threads = PS_MAX_THREADS - 1; wm_state->wm5.thread_dispatch_enable = 1; @@ -509,7 +584,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, { BEGIN_BATCH(12); /* Match Mesa driver setup */ - if (IS_IGD_GM(pI830)) + if (IS_GM45(pI830) || IS_G4X(pI830)) OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); else OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); diff --git a/driver/xf86-video-intel/src/ivch/Makefile.in b/driver/xf86-video-intel/src/ivch/Makefile.in index 360696a54..97976ef30 100644 --- a/driver/xf86-video-intel/src/ivch/Makefile.in +++ b/driver/xf86-video-intel/src/ivch/Makefile.in @@ -39,7 +39,8 @@ host_triplet = @host@ subdir = src/ivch DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -62,9 +63,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -102,6 +100,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -138,6 +137,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/reg_dumper/Makefile.am b/driver/xf86-video-intel/src/reg_dumper/Makefile.am index b840b2441..d49a59b1e 100644 --- a/driver/xf86-video-intel/src/reg_dumper/Makefile.am +++ b/driver/xf86-video-intel/src/reg_dumper/Makefile.am @@ -1,4 +1,4 @@ -noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping +noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_hotplug intel_reg_dumper_SOURCES = \ main.c \ @@ -12,9 +12,16 @@ intel_idle_SOURCES = \ xprintf.c \ ../i830_debug.c +intel_hotplug_SOURCES = \ + hotplug.c \ + reg_dumper.h \ + xprintf.c \ + ../i830_debug.c + intel_stepping_SOURCES = \ stepping.c +intel_hotplug_LDADD = $(PCIACCESS_LIBS) intel_reg_dumper_LDADD = $(PCIACCESS_LIBS) intel_idle_LDADD = $(PCIACCESS_LIBS) intel_stepping_LDADD = $(PCIACCESS_LIBS) diff --git a/driver/xf86-video-intel/src/reg_dumper/Makefile.in b/driver/xf86-video-intel/src/reg_dumper/Makefile.in index 3170a9061..d3ce79e93 100644 --- a/driver/xf86-video-intel/src/reg_dumper/Makefile.in +++ b/driver/xf86-video-intel/src/reg_dumper/Makefile.in @@ -37,21 +37,26 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = intel_reg_dumper$(EXEEXT) intel_idle$(EXEEXT) \ - intel_stepping$(EXEEXT) + intel_stepping$(EXEEXT) intel_hotplug$(EXEEXT) subdir = src/reg_dumper DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = PROGRAMS = $(noinst_PROGRAMS) +am_intel_hotplug_OBJECTS = hotplug.$(OBJEXT) xprintf.$(OBJEXT) \ + i830_debug.$(OBJEXT) +intel_hotplug_OBJECTS = $(am_intel_hotplug_OBJECTS) +am__DEPENDENCIES_1 = +intel_hotplug_DEPENDENCIES = $(am__DEPENDENCIES_1) am_intel_idle_OBJECTS = idle.$(OBJEXT) xprintf.$(OBJEXT) \ i830_debug.$(OBJEXT) intel_idle_OBJECTS = $(am_intel_idle_OBJECTS) -am__DEPENDENCIES_1 = intel_idle_DEPENDENCIES = $(am__DEPENDENCIES_1) am_intel_reg_dumper_OBJECTS = main.$(OBJEXT) xprintf.$(OBJEXT) \ i830_debug.$(OBJEXT) @@ -65,16 +70,13 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(intel_idle_SOURCES) $(intel_reg_dumper_SOURCES) \ - $(intel_stepping_SOURCES) -DIST_SOURCES = $(intel_idle_SOURCES) $(intel_reg_dumper_SOURCES) \ - $(intel_stepping_SOURCES) +SOURCES = $(intel_hotplug_SOURCES) $(intel_idle_SOURCES) \ + $(intel_reg_dumper_SOURCES) $(intel_stepping_SOURCES) +DIST_SOURCES = $(intel_hotplug_SOURCES) $(intel_idle_SOURCES) \ + $(intel_reg_dumper_SOURCES) $(intel_stepping_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -107,6 +109,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -143,6 +146,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ @@ -247,9 +252,16 @@ intel_idle_SOURCES = \ xprintf.c \ ../i830_debug.c +intel_hotplug_SOURCES = \ + hotplug.c \ + reg_dumper.h \ + xprintf.c \ + ../i830_debug.c + intel_stepping_SOURCES = \ stepping.c +intel_hotplug_LDADD = $(PCIACCESS_LIBS) intel_reg_dumper_LDADD = $(PCIACCESS_LIBS) intel_idle_LDADD = $(PCIACCESS_LIBS) intel_stepping_LDADD = $(PCIACCESS_LIBS) @@ -296,6 +308,9 @@ clean-noinstPROGRAMS: echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done +intel_hotplug$(EXEEXT): $(intel_hotplug_OBJECTS) $(intel_hotplug_DEPENDENCIES) + @rm -f intel_hotplug$(EXEEXT) + $(LINK) $(intel_hotplug_LDFLAGS) $(intel_hotplug_OBJECTS) $(intel_hotplug_LDADD) $(LIBS) intel_idle$(EXEEXT): $(intel_idle_OBJECTS) $(intel_idle_DEPENDENCIES) @rm -f intel_idle$(EXEEXT) $(LINK) $(intel_idle_LDFLAGS) $(intel_idle_OBJECTS) $(intel_idle_LDADD) $(LIBS) @@ -312,6 +327,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hotplug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i830_debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ diff --git a/driver/xf86-video-intel/src/reg_dumper/hotplug.c b/driver/xf86-video-intel/src/reg_dumper/hotplug.c new file mode 100644 index 000000000..68fe58428 --- /dev/null +++ b/driver/xf86-video-intel/src/reg_dumper/hotplug.c @@ -0,0 +1,151 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <pciaccess.h> +#include <err.h> +#include <unistd.h> + +#include "reg_dumper.h" +#include "../i810_reg.h" + +struct idle_flags { + uint32_t instdone_flag; + char *name; + unsigned int count; +}; + +int main(int argc, char **argv) +{ + struct pci_device *dev; + I830Rec i830; + I830Ptr pI830 = &i830; + ScrnInfoRec scrn; + int err, mmio_bar; + void *mmio; + int i; + + err = pci_system_init(); + if (err != 0) { + fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err)); + exit(1); + } + + /* Grab the graphics card */ + dev = pci_device_find_by_slot(0, 0, 2, 0); + if (dev == NULL) + errx(1, "Couldn't find graphics card"); + + err = pci_device_probe(dev); + if (err != 0) { + fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); + exit(1); + } + + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + + i830.PciInfo = &i830.pci_info_rec; + i830.PciInfo->chipType = dev->device_id; + + i830.pci_dev = dev; + + mmio_bar = IS_I9XX((&i830)) ? 0 : 1; + + err = pci_device_map_range (dev, + dev->regions[mmio_bar].base_addr, + dev->regions[mmio_bar].size, + PCI_DEV_MAP_FLAG_WRITABLE, + &mmio); + + if (err != 0) { + fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err)); + exit(1); + } + i830.mmio = mmio; + + scrn.scrnIndex = 0; + scrn.pI830 = &i830; + + OUTREG(SDVOB, (0x0 << 10)); + OUTREG(SDVOC, (0x0 << 10)); + + OUTREG(PORT_HOTPLUG_EN, + (1 << 29) | + (1 << 28) | + (1 << 27) | + SDVOB_HOTPLUG_INT_EN | + SDVOC_HOTPLUG_INT_EN | + (1 << 24) | + CRT_HOTPLUG_INT_EN | + TV_HOTPLUG_INT_EN | + CRT_HOTPLUG_INT_EN); + + for (i = 0;; i++) { + OUTREG(PORT_HOTPLUG_STAT, + (1 << 20) | + (1 << 19) | + (1 << 18) | + (1 << 17) | + CRT_HOTPLUG_INT_STATUS | + TV_HOTPLUG_INT_STATUS | + SDVOC_HOTPLUG_INT_STATUS | + SDVOB_HOTPLUG_INT_STATUS); + INREG(PORT_HOTPLUG_STAT); + + usleep(500 * 1000); + + printf("%5d: 0x%08x\n", i, INREG(PORT_HOTPLUG_STAT)); + sleep(1); + } + + return 0; +} + +void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...) +{ + va_list va; + + switch (severity) { + case X_INFO: + printf("(II): "); + break; + case X_WARNING: + printf("(WW): "); + break; + case X_ERROR: + printf("(EE): "); + break; + } + + va_start(va, format); + vprintf(format, va); + va_end(va); +} diff --git a/driver/xf86-video-intel/src/reg_dumper/idle.c b/driver/xf86-video-intel/src/reg_dumper/idle.c index bc9dbb71c..46a2fd5cd 100644 --- a/driver/xf86-video-intel/src/reg_dumper/idle.c +++ b/driver/xf86-video-intel/src/reg_dumper/idle.c @@ -42,6 +42,36 @@ struct idle_flags { unsigned int count; }; +struct idle_flags i915_idle_flags[] = { + {IDCT_DONE, "IDCT"}, + {IQ_DONE, "IQ"}, + {PR_DONE, "PR"}, + {VLD_DONE, "VLD"}, + {IP_DONE, "IP"}, + {FBC_DONE, "FBC"}, + {BINNER_DONE, "BINNER"}, + {SF_DONE, "SF"}, + {SE_DONE, "SE"}, + {WM_DONE, "WM"}, + {IZ_DONE, "IZ"}, + {PERSPECTIVE_INTERP_DONE, "perspective interpolation"}, + {DISPATCHER_DONE, "dispatcher"}, + {PROJECTION_DONE, "projection and LOD"}, + {DEPENDENT_ADDRESS_DONE, "dependent address calc"}, + {TEXTURE_FETCH_DONE, "texture fetch"}, + {TEXTURE_DECOMPRESS_DONE, "texture decompress"}, + {SAMPLER_CACHE_DONE, "sampler cache"}, + {FILTER_DONE, "filter"}, + {BYPASS_FIFO_DONE, "bypass FIFO"}, + {PS_DONE, "PS"}, + {CC_DONE, "CC"}, + {MAP_FILTER_DONE, "map filter"}, + {MAP_L2_IDLE, "map L2"}, + + {0, "total"}, + {0, "other"}, +}; + struct idle_flags i965_idle_flags[] = { {I965_SF_DONE, "SF"}, {I965_SE_DONE, "SE"}, @@ -60,12 +90,17 @@ struct idle_flags i965_idle_flags[] = { /* Fills in the "other" and "total" fields' idle flags */ static void -setup_other_flags(struct idle_flags *idle_flags, int idle_flag_count) +setup_other_flags(I830Ptr pI830, + struct idle_flags *idle_flags, int idle_flag_count) { uint32_t other_idle_flags, total_idle_flags = 0; int i; - other_idle_flags = ~(I965_RING_0_ENABLE); + if (IS_I965G(pI830)) + other_idle_flags = ~(I965_RING_0_ENABLE); + else + other_idle_flags = ~(RING_0_ENABLE | RING_1_ENABLE | RING_2_ENABLE); + for (i = 0; i < idle_flag_count - 2; i++) { other_idle_flags &= ~idle_flags[i].instdone_flag; total_idle_flags |= idle_flags[i].instdone_flag; @@ -127,17 +162,26 @@ int main(int argc, char **argv) scrn.scrnIndex = 0; scrn.pI830 = &i830; - /* if (IS_I965) { */ - idle_flags = i965_idle_flags; - idle_flag_count = sizeof(i965_idle_flags) / sizeof(i965_idle_flags[0]); + if (IS_I965G(pI830)) { + idle_flags = i965_idle_flags; + idle_flag_count = ARRAY_SIZE(i965_idle_flags); + } else { + idle_flags = i915_idle_flags; + idle_flag_count = ARRAY_SIZE(i915_idle_flags); + } - setup_other_flags(idle_flags, idle_flag_count); + setup_other_flags(pI830, idle_flags, idle_flag_count); for (;;) { int i, j; for (i = 0; i < 100; i++) { - uint32_t instdone = INREG(INST_DONE_I965); + uint32_t instdone; + + if (IS_I965G(pI830)) + instdone = INREG(INST_DONE_I965); + else + instdone = INREG(INST_DONE); for (j = 0; j < idle_flag_count; j++) { if ((instdone & idle_flags[j].instdone_flag) != @@ -149,7 +193,7 @@ int main(int argc, char **argv) } for (j = 0; j < idle_flag_count; j++) { - printf("%15s: %3d\n", idle_flags[j].name, idle_flags[j].count); + printf("%25s: %3d\n", idle_flags[j].name, idle_flags[j].count); idle_flags[j].count = 0; } printf("\n"); diff --git a/driver/xf86-video-intel/src/reg_dumper/reg_dumper.h b/driver/xf86-video-intel/src/reg_dumper/reg_dumper.h index 769adb276..9a723b9b1 100644 --- a/driver/xf86-video-intel/src/reg_dumper/reg_dumper.h +++ b/driver/xf86-video-intel/src/reg_dumper/reg_dumper.h @@ -69,6 +69,8 @@ typedef struct _scrn { #define I830PTR(pScrn) (pScrn->pI830) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define INREG8(reg) (*(volatile uint8_t *)((pI830)->mmio + (reg))) #define INREG16(reg) (*(volatile uint16_t *)((pI830)->mmio + (reg))) #define INREG(reg) (*(volatile uint32_t *)((pI830)->mmio + (reg))) diff --git a/driver/xf86-video-intel/src/sil164/Makefile.in b/driver/xf86-video-intel/src/sil164/Makefile.in index f7643e7a3..631226501 100644 --- a/driver/xf86-video-intel/src/sil164/Makefile.in +++ b/driver/xf86-video-intel/src/sil164/Makefile.in @@ -39,7 +39,8 @@ host_triplet = @host@ subdir = src/sil164 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -62,9 +63,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -102,6 +100,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -138,6 +137,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/tfp410/Makefile.in b/driver/xf86-video-intel/src/tfp410/Makefile.in index f3ee49bed..af7dcc206 100644 --- a/driver/xf86-video-intel/src/tfp410/Makefile.in +++ b/driver/xf86-video-intel/src/tfp410/Makefile.in @@ -39,7 +39,8 @@ host_triplet = @host@ subdir = src/tfp410 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -62,9 +63,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -102,6 +100,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -138,6 +137,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ diff --git a/driver/xf86-video-intel/src/xvmc/I810XvMC.c b/driver/xf86-video-intel/src/xvmc/I810XvMC.c index 89aa3ea4b..ce5395acc 100644 --- a/driver/xf86-video-intel/src/xvmc/I810XvMC.c +++ b/driver/xf86-video-intel/src/xvmc/I810XvMC.c @@ -130,7 +130,6 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) { i810XvMCContext *pI810XvMC; - char busIdString[10]; int priv_count; uint *priv_data; uint magic; @@ -217,7 +216,6 @@ Status XvMCCreateContext(Display *display, XvPortID port, /* Open DRI Device */ if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) { printf("DRM Device for i810 could not be opened.\n"); - free(busIdString); free(pI810XvMC); return BadAccess; } /* !pI810XvMC->fd */ @@ -1558,6 +1556,11 @@ static __inline__ void renderDualPrimeinField(uint **datay,uint **datau, // Description: inline function that sets hardware parameters for a Field // encoded macroblock in a frame picture. ***************************************************************************/ +typedef union { + short s[4]; + uint u[2]; +} su_t; + static __inline__ void renderFieldinFrame(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb,short *block_ptr, @@ -1568,8 +1571,8 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, register uint *dv = *datav; /* Motion Vectors */ - short fmv[4]; - short bmv[4]; + su_t fmv; + su_t bmv; /* gfxblock dword 1 */ uint dw1[2]; @@ -1589,23 +1592,23 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, (((mb->coded_block_pattern & 0x3) | ((mb->coded_block_pattern & 0xc)<<2))<<22); - fmv[0] = mb->PMV[0][0][1]/2; - fmv[1] = mb->PMV[0][0][0]; - fmv[2] = mb->PMV[1][0][1]/2; - fmv[3] = mb->PMV[1][0][0]; + fmv.s[0] = mb->PMV[0][0][1]/2; + fmv.s[1] = mb->PMV[0][0][0]; + fmv.s[2] = mb->PMV[1][0][1]/2; + fmv.s[3] = mb->PMV[1][0][0]; - bmv[0] = mb->PMV[0][1][1]/2; - bmv[1] = mb->PMV[0][1][0]; - bmv[2] = mb->PMV[1][1][1]/2; - bmv[3] = mb->PMV[1][1][0]; + bmv.s[0] = mb->PMV[0][1][1]/2; + bmv.s[1] = mb->PMV[0][1][0]; + bmv.s[2] = mb->PMV[1][1][1]/2; + bmv.s[3] = mb->PMV[1][1][0]; /* First Y Block */ *dy++ = GFXBLOCK + 4 + (y1size>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[0]; - *dy++ = *(uint *)&bmv[0]; + *dy++ = fmv.u[0]; + *dy++ = bmv.u[0]; PACK_CORR_DATA(dy,block_ptr,y1size); block_ptr = (short *)((unsigned long)block_ptr + y1size); @@ -1614,21 +1617,21 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; + *dy++ = fmv.u[1]; + *dy++ = bmv.u[1]; PACK_CORR_DATA(dy,block_ptr,y2size); block_ptr = (short *)((unsigned long)block_ptr + y2size); /* End Y Blocks */ - fmv[0] /= 2; - fmv[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; + fmv.s[0] /= 2; + fmv.s[1] /= 2; + fmv.s[2] /= 2; + fmv.s[3] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; + bmv.s[0] /= 2; + bmv.s[1] /= 2; + bmv.s[2] /= 2; + bmv.s[3] /= 2; xy >>= 1; @@ -1637,8 +1640,8 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[0]; - *du++ = *(uint *)&bmv[0]; + *du++ = fmv.u[0]; + *du++ = bmv.u[0]; if(usize) { PACK_CORR_DATA_SHORT(du,block_ptr); } @@ -1648,8 +1651,8 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; + *du++ = fmv.u[1]; + *du++ = bmv.u[1]; if(usize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); @@ -1662,8 +1665,8 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[0]; - *dv++ = *(uint *)&bmv[0]; + *dv++ = fmv.u[0]; + *dv++ = bmv.u[0]; if(vsize) { PACK_CORR_DATA_SHORT(dv,block_ptr); } @@ -1673,8 +1676,8 @@ static __inline__ void renderFieldinFrame(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; + *dv++ = fmv.u[1]; + *dv++ = bmv.u[1]; if(vsize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); @@ -1701,8 +1704,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, register uint *dv = *datav; /* Motion Vectors */ - short fmv[4]; - short bmv[4]; + su_t fmv; + su_t bmv; /* CBP */ uint cbp = (uint)mb->coded_block_pattern; /* gfxblock dword 1 */ @@ -1728,15 +1731,15 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, ((cbp | ((cbp<<2) & 0x30))<<22); - fmv[0] = mb->PMV[0][0][1]/2; - fmv[1] = mb->PMV[0][0][0]; - fmv[2] = mb->PMV[1][0][1]/2; - fmv[3] = mb->PMV[1][0][0]; + fmv.s[0] = mb->PMV[0][0][1]/2; + fmv.s[1] = mb->PMV[0][0][0]; + fmv.s[2] = mb->PMV[1][0][1]/2; + fmv.s[3] = mb->PMV[1][0][0]; - bmv[0] = mb->PMV[0][1][1]/2; - bmv[1] = mb->PMV[0][1][0]; - bmv[2] = mb->PMV[1][1][1]/2; - bmv[3] = mb->PMV[1][1][0]; + bmv.s[0] = mb->PMV[0][1][1]/2; + bmv.s[1] = mb->PMV[0][1][0]; + bmv.s[2] = mb->PMV[1][1][1]/2; + bmv.s[3] = mb->PMV[1][1][0]; /* The i810 cannot use DCT0 directly with field motion, we have to @@ -1772,8 +1775,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[0]; - *dy++ = *(uint *)&bmv[0]; + *dy++ = fmv.u[0]; + *dy++ = bmv.u[0]; if(dw1[0] & (1<<27)) { PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); } @@ -1786,8 +1789,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; + *dy++ = fmv.u[1]; + *dy++ = bmv.u[1]; if(dw1[1] & (1<<27)) { top_left_b = (short *)((unsigned long)top_left_b + 16); bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); @@ -1800,15 +1803,15 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, } /* End Y Blocks */ - fmv[0] /= 2; - fmv[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; + fmv.s[0] /= 2; + fmv.s[1] /= 2; + fmv.s[2] /= 2; + fmv.s[3] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; + bmv.s[0] /= 2; + bmv.s[1] /= 2; + bmv.s[2] /= 2; + bmv.s[3] /= 2; xy >>= 1; @@ -1817,8 +1820,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[0]; - *du++ = *(uint *)&bmv[0]; + *du++ = fmv.u[0]; + *du++ = bmv.u[0]; if(usize) { PACK_CORR_DATA_SHORT(du,block_ptr); } @@ -1828,8 +1831,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; + *du++ = fmv.u[1]; + *du++ = bmv.u[1]; if(usize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); @@ -1842,8 +1845,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[0]; - *dv++ = *(uint *)&bmv[0]; + *dv++ = fmv.u[0]; + *dv++ = bmv.u[0]; if(vsize) { PACK_CORR_DATA_SHORT(dv,block_ptr); } @@ -1853,8 +1856,8 @@ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; + *dv++ = fmv.u[1]; + *dv++ = bmv.u[1]; if(vsize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); @@ -1882,8 +1885,8 @@ static __inline__ void renderFrameinFrame(uint **datay,uint **datau, register uint *dv = *datav; /* Motion Vectors */ - short fmv[2]; - short bmv[2]; + su_t fmv; + su_t bmv; /* gfxblock dword 1 */ uint dw1; @@ -1897,28 +1900,28 @@ static __inline__ void renderFrameinFrame(uint **datay,uint **datau, (((uint)mb->coded_block_pattern)<<22); - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; + fmv.s[0] = mb->PMV[0][0][1]; + fmv.s[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; + bmv.s[0] = mb->PMV[0][1][1]; + bmv.s[1] = mb->PMV[0][1][0]; /* Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (3<<28) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; + *dy++ = fmv.u[0]; + *dy++ = bmv.u[0]; PACK_CORR_DATA(dy,block_ptr,ysize); block_ptr = (short *)((unsigned long)block_ptr + ysize); /* End Y Blocks */ - fmv[0] /= 2; - fmv[1] /= 2; + fmv.s[0] /= 2; + fmv.s[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; + bmv.s[0] /= 2; + bmv.s[1] /= 2; xy >>= 1; @@ -1927,8 +1930,8 @@ static __inline__ void renderFrameinFrame(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1; *du++ = xy; *du++ = (8<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; + *du++ = fmv.u[0]; + *du++ = bmv.u[0]; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* End U Block */ @@ -1938,8 +1941,8 @@ static __inline__ void renderFrameinFrame(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; + *dv++ = fmv.u[0]; + *dv++ = bmv.u[0]; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); /* End V Block */ @@ -1963,8 +1966,8 @@ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, register uint *dv = *datav; /* Motion Vectors */ - short fmv[4]; - short bmv[4]; + su_t fmv; + su_t bmv; short * top_left_b = NULL; short * top_right_b = NULL; @@ -1982,11 +1985,11 @@ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, uint dw1 = type_table[mb->macroblock_type & 0xf] | (((uint)mb->coded_block_pattern)<<22); - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; + fmv.s[0] = mb->PMV[0][0][1]; + fmv.s[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; + bmv.s[0] = mb->PMV[0][1][1]; + bmv.s[1] = mb->PMV[0][1][0]; /* It is easiest to find out what blocks are in need of reading first @@ -2026,8 +2029,8 @@ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, *dy++ = (1<<30) | (3<<28) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; + *dy++ = fmv.u[0]; + *dy++ = bmv.u[0]; if(dw1 & (1<<27)) { PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); top_left_b = (short *)((unsigned long)top_left_b + 64); @@ -2046,11 +2049,11 @@ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, } /* End Y Block */ - fmv[0] /= 2; - fmv[1] /= 2; + fmv.s[0] /= 2; + fmv.s[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; + bmv.s[0] /= 2; + bmv.s[1] /= 2; xy >>= 1; @@ -2059,8 +2062,8 @@ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1; *du++ = xy; *du++ = (8<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; + *du++ = fmv.u[0]; + *du++ = bmv.u[0]; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); @@ -2069,8 +2072,8 @@ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; + *dv++ = fmv.u[0]; + *dv++ = bmv.u[0]; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); @@ -2093,8 +2096,8 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, register uint *dv = *datav; /* Motion Vectors */ - short fmv[4]; - short bmv[4]; + su_t fmv; + su_t bmv; /* gfxblock dword 1 */ uint dw1[2]; @@ -2115,23 +2118,23 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, ((mb->coded_block_pattern & 0xc)<<2))<<22) | 3<<12 | 3<<6 | 3<<3 | 2; - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[1][0][1]; - bmv[1] = mb->PMV[1][0][0]; + fmv.s[0] = mb->PMV[0][0][1]; + fmv.s[1] = mb->PMV[0][0][0]; + bmv.s[0] = mb->PMV[1][0][1]; + bmv.s[1] = mb->PMV[1][0][0]; - fmv[2] = mb->PMV[0][0][1]; - fmv[3] = mb->PMV[0][0][0]; - bmv[2] = mb->PMV[1][1][1]; - bmv[3] = mb->PMV[1][1][0]; + fmv.s[2] = mb->PMV[0][0][1]; + fmv.s[3] = mb->PMV[0][0][0]; + bmv.s[2] = mb->PMV[1][1][1]; + bmv.s[3] = mb->PMV[1][1][0]; /* First Y Block */ *dy++ = GFXBLOCK + 4 + (y1size>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv;; + *dy++ = fmv.u[0]; + *dy++ = bmv.u[0];; PACK_CORR_DATA(dy,block_ptr,y1size); block_ptr = (short *)((unsigned long)block_ptr + y1size); @@ -2140,20 +2143,20 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; + *dy++ = fmv.u[1]; + *dy++ = bmv.u[1]; PACK_CORR_DATA(dy,block_ptr,y2size); block_ptr = (short *)((unsigned long)block_ptr + y2size); - fmv[0] /= 2; - fmv[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; + fmv.s[0] /= 2; + fmv.s[1] /= 2; + bmv.s[0] /= 2; + bmv.s[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; + fmv.s[2] /= 2; + fmv.s[3] /= 2; + bmv.s[2] /= 2; + bmv.s[3] /= 2; xy >>= 1; @@ -2162,8 +2165,8 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; + *du++ = fmv.u[0]; + *du++ = bmv.u[0]; if(dw1[0] & (1<<23)) { PACK_CORR_DATA_SHORT(du,block_ptr); } @@ -2173,8 +2176,8 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; + *du++ = fmv.u[1]; + *du++ = bmv.u[1]; if(dw1[1] & (1<<23)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); @@ -2187,8 +2190,8 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; + *dv++ = fmv.u[0]; + *dv++ = bmv.u[0]; if(dw1[0] & (1<<22)) { PACK_CORR_DATA_SHORT(dv,block_ptr); } @@ -2198,8 +2201,8 @@ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; + *dv++ = fmv.u[1]; + *dv++ = bmv.u[1]; if(dw1[1] & (1<<22)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); @@ -2228,8 +2231,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, register uint *dv = *datav; /* Motion Vectors */ - short fmv[4]; - short bmv[4]; + su_t fmv; + su_t bmv; /* gfxblock dword 1 */ uint dw1[2]; @@ -2255,15 +2258,15 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, dw1[1] = ((cbp | ((cbp<<2) & 0x30))<<22) | 3<<12 | 3<<6 | 3<<3 | 2; - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[1][0][1]; - bmv[1] = mb->PMV[1][0][0]; + fmv.s[0] = mb->PMV[0][0][1]; + fmv.s[1] = mb->PMV[0][0][0]; + bmv.s[0] = mb->PMV[1][0][1]; + bmv.s[1] = mb->PMV[1][0][0]; - fmv[2] = mb->PMV[0][0][1]; - fmv[3] = mb->PMV[0][0][0]; - bmv[2] = mb->PMV[1][1][1]; - bmv[3] = mb->PMV[1][1][0]; + fmv.s[2] = mb->PMV[0][0][1]; + fmv.s[3] = mb->PMV[0][0][0]; + bmv.s[2] = mb->PMV[1][1][1]; + bmv.s[3] = mb->PMV[1][1][0]; /* The i810 cannot use DCT0 directly with field motion, we have to @@ -2299,8 +2302,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; + *dy++ = fmv.u[0]; + *dy++ = bmv.u[0]; if(cbp & 0x20) { PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); } @@ -2313,8 +2316,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; + *dy++ = fmv.u[1]; + *dy++ = bmv.u[1]; if(cbp & 0x20) { top_left_b = (short *)((unsigned long)top_left_b + 16); bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); @@ -2328,15 +2331,15 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, /* End Y Blocks */ - fmv[0] /= 2; - fmv[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; + fmv.s[0] /= 2; + fmv.s[1] /= 2; + bmv.s[0] /= 2; + bmv.s[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; + fmv.s[2] /= 2; + fmv.s[3] /= 2; + bmv.s[2] /= 2; + bmv.s[3] /= 2; xy >>= 1; @@ -2345,8 +2348,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; + *du++ = fmv.u[0]; + *du++ = bmv.u[0]; if(cbp & (1<<23)) { PACK_CORR_DATA_SHORT(du,block_ptr); } @@ -2356,8 +2359,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; + *du++ = fmv.u[1]; + *du++ = bmv.u[1]; if(cbp & (1<<23)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); @@ -2370,8 +2373,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; + *dv++ = fmv.u[0]; + *dv++ = bmv.u[0]; if(cbp & (1<<22)) { PACK_CORR_DATA_SHORT(dv,block_ptr); } @@ -2381,8 +2384,8 @@ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; + *dv++ = fmv.u[1]; + *dv++ = bmv.u[1]; if(cbp & (1<<22)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); diff --git a/driver/xf86-video-intel/src/xvmc/Makefile.am b/driver/xf86-video-intel/src/xvmc/Makefile.am index f2dab22c3..345160fb6 100644 --- a/driver/xf86-video-intel/src/xvmc/Makefile.am +++ b/driver/xf86-video-intel/src/xvmc/Makefile.am @@ -11,6 +11,7 @@ libI810XvMC_la_LIBADD = @DRI_LIBS@ libIntelXvMC_la_SOURCES = intel_xvmc.c \ intel_xvmc.h \ + intel_xvmc_dump.c \ i915_structs.h \ i915_program.h \ i915_xvmc.c \ diff --git a/driver/xf86-video-intel/src/xvmc/Makefile.in b/driver/xf86-video-intel/src/xvmc/Makefile.in index 625ad3c68..f0c73b889 100644 --- a/driver/xf86-video-intel/src/xvmc/Makefile.in +++ b/driver/xf86-video-intel/src/xvmc/Makefile.in @@ -39,7 +39,8 @@ host_triplet = @host@ subdir = src/xvmc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -61,10 +62,11 @@ libI810XvMC_la_OBJECTS = $(am_libI810XvMC_la_OBJECTS) @XVMC_TRUE@am_libI810XvMC_la_rpath = -rpath $(libdir) libIntelXvMC_la_DEPENDENCIES = am__libIntelXvMC_la_SOURCES_DIST = intel_xvmc.c intel_xvmc.h \ - i915_structs.h i915_program.h i915_xvmc.c i915_xvmc.h \ - intel_batchbuffer.c intel_batchbuffer.h xf86dri.c xf86dri.h \ - xf86dristr.h + intel_xvmc_dump.c i915_structs.h i915_program.h i915_xvmc.c \ + i915_xvmc.h intel_batchbuffer.c intel_batchbuffer.h xf86dri.c \ + xf86dri.h xf86dristr.h @XVMC_TRUE@am_libIntelXvMC_la_OBJECTS = libIntelXvMC_la-intel_xvmc.lo \ +@XVMC_TRUE@ libIntelXvMC_la-intel_xvmc_dump.lo \ @XVMC_TRUE@ libIntelXvMC_la-i915_xvmc.lo \ @XVMC_TRUE@ libIntelXvMC_la-intel_batchbuffer.lo \ @XVMC_TRUE@ libIntelXvMC_la-xf86dri.lo @@ -75,9 +77,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -116,6 +115,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOLT_BASH = @DOLT_BASH@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRIVER_NAME = @DRIVER_NAME@ @@ -152,6 +152,8 @@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ LN_S = @LN_S@ +LTCOMPILE = @LTCOMPILE@ +LTCXXCOMPILE = @LTCXXCOMPILE@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ @@ -255,6 +257,7 @@ target_alias = @target_alias@ @XVMC_TRUE@libI810XvMC_la_LIBADD = @DRI_LIBS@ @XVMC_TRUE@libIntelXvMC_la_SOURCES = intel_xvmc.c \ @XVMC_TRUE@ intel_xvmc.h \ +@XVMC_TRUE@ intel_xvmc_dump.c \ @XVMC_TRUE@ i915_structs.h \ @XVMC_TRUE@ i915_program.h \ @XVMC_TRUE@ i915_xvmc.c \ @@ -343,6 +346,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libIntelXvMC_la-i915_xvmc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libIntelXvMC_la-intel_batchbuffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libIntelXvMC_la-intel_xvmc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libIntelXvMC_la-intel_xvmc_dump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libIntelXvMC_la-xf86dri.Plo@am__quote@ .c.o: @@ -380,6 +384,13 @@ libIntelXvMC_la-intel_xvmc.lo: intel_xvmc.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIntelXvMC_la_CFLAGS) $(CFLAGS) -c -o libIntelXvMC_la-intel_xvmc.lo `test -f 'intel_xvmc.c' || echo '$(srcdir)/'`intel_xvmc.c +libIntelXvMC_la-intel_xvmc_dump.lo: intel_xvmc_dump.c +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIntelXvMC_la_CFLAGS) $(CFLAGS) -MT libIntelXvMC_la-intel_xvmc_dump.lo -MD -MP -MF "$(DEPDIR)/libIntelXvMC_la-intel_xvmc_dump.Tpo" -c -o libIntelXvMC_la-intel_xvmc_dump.lo `test -f 'intel_xvmc_dump.c' || echo '$(srcdir)/'`intel_xvmc_dump.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libIntelXvMC_la-intel_xvmc_dump.Tpo" "$(DEPDIR)/libIntelXvMC_la-intel_xvmc_dump.Plo"; else rm -f "$(DEPDIR)/libIntelXvMC_la-intel_xvmc_dump.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intel_xvmc_dump.c' object='libIntelXvMC_la-intel_xvmc_dump.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIntelXvMC_la_CFLAGS) $(CFLAGS) -c -o libIntelXvMC_la-intel_xvmc_dump.lo `test -f 'intel_xvmc_dump.c' || echo '$(srcdir)/'`intel_xvmc_dump.c + libIntelXvMC_la-i915_xvmc.lo: i915_xvmc.c @am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIntelXvMC_la_CFLAGS) $(CFLAGS) -MT libIntelXvMC_la-i915_xvmc.lo -MD -MP -MF "$(DEPDIR)/libIntelXvMC_la-i915_xvmc.Tpo" -c -o libIntelXvMC_la-i915_xvmc.lo `test -f 'i915_xvmc.c' || echo '$(srcdir)/'`i915_xvmc.c; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libIntelXvMC_la-i915_xvmc.Tpo" "$(DEPDIR)/libIntelXvMC_la-i915_xvmc.Plo"; else rm -f "$(DEPDIR)/libIntelXvMC_la-i915_xvmc.Tpo"; exit 1; fi diff --git a/driver/xf86-video-intel/src/xvmc/i915_structs.h b/driver/xf86-video-intel/src/xvmc/i915_structs.h index a25d73493..b5185cb76 100644 --- a/driver/xf86-video-intel/src/xvmc/i915_structs.h +++ b/driver/xf86-video-intel/src/xvmc/i915_structs.h @@ -28,6 +28,8 @@ #ifndef _I915_STRUCTS_H #define _I915_STRUCTS_H +#include <stdint.h> + /* MI_INSTRUCTION */ #define CMD_MI 0x00 @@ -352,7 +354,7 @@ struct i915_3dstate_dest_buffer_variables_mpeg unsigned rcontrol : 1; unsigned decode_mode : 2; } dw1; - + struct { unsigned pad0 : 1; unsigned picture_coding_type : 2; @@ -372,6 +374,15 @@ struct i915_3dstate_dest_buffer_variables_mpeg } dw2; }; +struct i915_mc_static_indirect_state_buffer { + struct i915_3dstate_buffer_info dest_y; + struct i915_3dstate_buffer_info dest_u; + struct i915_3dstate_buffer_info dest_v; + struct i915_3dstate_dest_buffer_variables dest_buf; + struct i915_3dstate_dest_buffer_variables_mpeg dest_buf_mpeg; + struct i915_3dstate_buffer_info corr; +}; + #define MAP_MAP0 0x0001 #define MAP_MAP1 0x0002 #define MAP_MAP2 0x0004 @@ -432,7 +443,18 @@ struct i915_3dstate_map_state unsigned map_mask : 16; unsigned pad0 : 16; } dw1; -// struct texture_map *tms; +}; + +struct i915_mc_map_state { + struct i915_3dstate_map_state y_map; + struct texture_map y_forward; + struct texture_map y_backward; + struct i915_3dstate_map_state u_map; + struct texture_map u_forward; + struct texture_map u_backward; + struct i915_3dstate_map_state v_map; + struct texture_map v_forward; + struct texture_map v_backward; }; #define SAMPLER_SAMPLER0 0x0001 @@ -532,6 +554,9 @@ struct i915_3dstate_sampler_state unsigned sampler_masker : 16; unsigned pad0 : 16; } dw1; + /* we always use two samplers for mc */ + struct texture_sampler sampler0; + struct texture_sampler sampler1; }; struct arithmetic_inst @@ -641,17 +666,48 @@ union shader_inst struct declaration_inst d; }; +struct i915_3dstate_pixel_shader_header { + unsigned length : 9; + unsigned pad0 : 6; + unsigned retain : 1; + unsigned opcode : 13; + unsigned type : 3; +}; + struct i915_3dstate_pixel_shader_program { - struct { - unsigned length : 9; - unsigned pad0 : 6; - unsigned retain : 1; - unsigned opcode : 13; - unsigned type : 3; - } dw0; - - // union shader_inst *insts; + struct i915_3dstate_pixel_shader_header shader0; + /* mov oC, c0.0000 */ + uint32_t inst0[3]; + + struct i915_3dstate_pixel_shader_header shader1; + /* dcl t0.xy */ + /* dcl t1.xy */ + /* dcl_2D s0 */ + /* texld r0, t0, s0 */ + /* mov oC, r0 */ + uint32_t inst1[3*5]; + + struct i915_3dstate_pixel_shader_header shader2; + /* dcl t2.xy */ + /* dcl t3.xy */ + /* dcl_2D s1 */ + /* texld r0, t2, s1 */ + /* mov oC, r0 */ + uint32_t inst2[3*5]; + + struct i915_3dstate_pixel_shader_header shader3; + /* dcl t0.xy */ + /* dcl t1.xy */ + /* dcl t2.xy */ + /* dcl t3.xy */ + /* dcl_2D s0 */ + /* dcl_2D s1 */ + /* texld r0, t0, s0 */ + /* texld r0, t2, s1 */ + /* add r0, r0, r1*/ + /* mov oC, r0 */ + uint32_t inst3[3*10]; }; #define REG_CR0 0x00000001 @@ -707,7 +763,8 @@ struct i915_3dstate_pixel_shader_constants struct { unsigned reg_mask; } dw1; - // struct shader_constant *consts; + /* we only need one constant */ + struct shader_constant value; }; #define BLOCK_SIS 0x01 diff --git a/driver/xf86-video-intel/src/xvmc/i915_xvmc.c b/driver/xf86-video-intel/src/xvmc/i915_xvmc.c index b1a17b4e8..c32073a1b 100644 --- a/driver/xf86-video-intel/src/xvmc/i915_xvmc.c +++ b/driver/xf86-video-intel/src/xvmc/i915_xvmc.c @@ -38,22 +38,10 @@ #define VOFFSET(surface) (surface->srf.offset + \ SIZE_Y420(surface->width, surface->height)) -/* Lookup tables to speed common calculations */ -static unsigned int mb_bytes[] = { - 000, 128, 128, 256, 128, 256, 256, 384, // 0 - 128, 256, 256, 384, 256, 384, 384, 512, // 1 - 128, 256, 256, 384, 256, 384, 384, 512, // 10 - 256, 384, 384, 512, 384, 512, 512, 640, // 11 - 128, 256, 256, 384, 256, 384, 384, 512, // 100 - 256, 384, 384, 512, 384, 512, 512, 640, // 101 - 256, 384, 384, 512, 384, 512, 512, 640, // 110 - 384, 512, 512, 640, 512, 640, 640, 768 // 111 -}; - typedef union { - short s[4]; - uint u[2]; -} su_t; + int16_t component[2]; + int32_t v; +} vector_t; #if 0 static int findOverlap(unsigned int width, unsigned int height, @@ -93,577 +81,6 @@ static int findOverlap(unsigned int width, unsigned int height, } #endif -static void i915_flush(int map, int render) -{ - struct i915_mi_flush mi_flush; - - memset(&mi_flush, 0, sizeof(mi_flush)); - mi_flush.dw0.type = CMD_MI; - mi_flush.dw0.opcode = OPC_MI_FLUSH; - mi_flush.dw0.map_cache_invalidate = map; - mi_flush.dw0.render_cache_flush_inhibit = render; - - intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0); -} - -/* for MC picture rendering */ -static void i915_mc_static_indirect_state_buffer(XvMCContext *context, - XvMCSurface *surface, - unsigned int picture_structure, - unsigned int flags, - unsigned int picture_coding_type) -{ - struct i915_3dstate_buffer_info *buffer_info; - struct i915_3dstate_dest_buffer_variables *dest_buffer_variables; - struct i915_3dstate_dest_buffer_variables_mpeg *dest_buffer_variables_mpeg; - i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int w = surface->width; - - /* 3DSTATE_BUFFER_INFO */ - /* DEST Y */ - buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map; - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK; - buffer_info->dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */ - buffer_info->dw1.tiled_surface = 0; /* linear */ - buffer_info->dw1.walk = TILEWALK_XMAJOR; - buffer_info->dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */ - buffer_info->dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */ - - /* DEST U */ - ++buffer_info; - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX; - buffer_info->dw1.fence_regs = 0; - buffer_info->dw1.tiled_surface = 0; - buffer_info->dw1.walk = TILEWALK_XMAJOR; - buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */ - buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */ - - /* DEST V */ - ++buffer_info; - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 1; - buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX; - buffer_info->dw1.fence_regs = 0; - buffer_info->dw1.tiled_surface = 0; - buffer_info->dw1.walk = TILEWALK_XMAJOR; - buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */ - buffer_info->dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */ - - /* 3DSTATE_DEST_BUFFER_VARIABLES */ - dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info); - memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables)); - dest_buffer_variables->dw0.type = CMD_3D; - dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; - dest_buffer_variables->dw0.length = 0; - dest_buffer_variables->dw1.dest_v_bias = 8; /* 0.5 */ - dest_buffer_variables->dw1.dest_h_bias = 8; /* 0.5 */ - dest_buffer_variables->dw1.color_fmt = COLORBUFFER_8BIT; - dest_buffer_variables->dw1.v_ls = 0; - dest_buffer_variables->dw1.v_ls_offset = 0; - - if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { - ; - } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { - dest_buffer_variables->dw1.v_ls = 1; - } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { - dest_buffer_variables->dw1.v_ls = 1; - dest_buffer_variables->dw1.v_ls_offset = 1; - } - - /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */ - dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables); - memset(dest_buffer_variables_mpeg, 0, sizeof(*dest_buffer_variables_mpeg)); - dest_buffer_variables_mpeg->dw0.type = CMD_3D; - dest_buffer_variables_mpeg->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; - dest_buffer_variables_mpeg->dw0.length = 1; - dest_buffer_variables_mpeg->dw1.decode_mode = MPEG_DECODE_MC; - dest_buffer_variables_mpeg->dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ - dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ - dest_buffer_variables_mpeg->dw1.abort_on_error = 1; - dest_buffer_variables_mpeg->dw1.intra8 = 0; /* 16-bit formatted correction data */ - dest_buffer_variables_mpeg->dw1.tff = 1; - - if (picture_structure & XVMC_FRAME_PICTURE) { - ; - } else if (picture_structure & XVMC_TOP_FIELD) { - if (flags & XVMC_SECOND_FIELD) - dest_buffer_variables_mpeg->dw1.tff = 0; - else - dest_buffer_variables_mpeg->dw1.tff = 1; - } else if (picture_structure & XVMC_BOTTOM_FIELD) { - if (flags & XVMC_SECOND_FIELD) - dest_buffer_variables_mpeg->dw1.tff = 1; - else - dest_buffer_variables_mpeg->dw1.tff = 0; - } - - dest_buffer_variables_mpeg->dw1.v_subsample_factor = MC_SUB_1V; - dest_buffer_variables_mpeg->dw1.h_subsample_factor = MC_SUB_1H; - dest_buffer_variables_mpeg->dw1.picture_width = (w >> 4); /* in macroblocks */ - dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type; - - /* 3DSATE_BUFFER_INFO */ - /* CORRECTION DATA */ - buffer_info = (struct i915_3dstate_buffer_info *)(++dest_buffer_variables_mpeg); - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.buffer_id = BUFFERID_MC_INTRA_CORR; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.fence_regs = 0; - buffer_info->dw1.tiled_surface = 0; - buffer_info->dw1.walk = 0; - buffer_info->dw1.pitch = 0; - buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */ -} - -static void i915_mc_map_state_buffer(XvMCContext *context, - i915XvMCSurface *privTarget, - i915XvMCSurface *privPast, - i915XvMCSurface *privFuture) -{ - struct i915_3dstate_map_state *map_state; - struct texture_map *tm; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int w = context->width, h = context->height; - - /* 3DSATE_MAP_STATE: Y */ - map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map; - memset(map_state, 0, sizeof(*map_state)); - map_state->dw0.type = CMD_3D; - map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; - map_state->dw0.retain = 1; - map_state->dw0.length = 6; - map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1; - - /* texture map: Forward (Past) */ - tm = (struct texture_map *)(++map_state); - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (YOFFSET(privPast) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; /* FIXME: tiled y for performace */ - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; /* 8bit */ - tm->tm1.surface_fmt = 1; /* 8bit */ - tm->tm1.width = w - 1; - tm->tm1.height = h - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */ - - /* texture map: Backward (Future) */ - ++tm; - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (YOFFSET(privFuture) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; /* 8bit */ - tm->tm1.surface_fmt = 1; /* 8bit */ - tm->tm1.width = w - 1; - tm->tm1.height = h - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privFuture->yStride >> 2) - 1; - - /* 3DSATE_MAP_STATE: U */ - map_state = (struct i915_3dstate_map_state *)(++tm); - memset(map_state, 0, sizeof(*map_state)); - map_state->dw0.type = CMD_3D; - map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; - map_state->dw0.retain = 1; - map_state->dw0.length = 6; - map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1; - - /* texture map: Forward */ - tm = (struct texture_map *)(++map_state); - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (UOFFSET(privPast) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; /* 8bit */ - tm->tm1.surface_fmt = 1; /* 8bit */ - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ - - /* texture map: Backward */ - ++tm; - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (UOFFSET(privFuture) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; - tm->tm1.surface_fmt = 1; - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privFuture->uvStride >> 2) - 1; - - /* 3DSATE_MAP_STATE: V */ - map_state = (struct i915_3dstate_map_state *)(++tm); - memset(map_state, 0, sizeof(*map_state)); - map_state->dw0.type = CMD_3D; - map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; - map_state->dw0.retain = 1; - map_state->dw0.length = 6; - map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1; - - /* texture map: Forward */ - tm = (struct texture_map *)(++map_state); - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (VOFFSET(privPast) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; - tm->tm1.surface_fmt = 1; - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ - - /* texture map: Backward */ - ++tm; - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (VOFFSET(privFuture) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; - tm->tm1.surface_fmt = 1; - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privFuture->uvStride >> 2) - 1; -} - -static void i915_mc_load_sis_msb_buffers(XvMCContext *context) -{ - struct i915_3dstate_load_indirect *load_indirect; - sis_state *sis = NULL; - msb_state *msb = NULL; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - void *base = NULL; - unsigned int size; - int mem_select = 1; - - /* 3DSTATE_LOAD_INDIRECT */ - size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb); - base = calloc(1, size); - load_indirect = (struct i915_3dstate_load_indirect *)base; - load_indirect->dw0.type = CMD_3D; - load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; - load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB; - load_indirect->dw0.length = (size >> 2) - 2; - - if (pI915XvMC->deviceID == PCI_CHIP_I915_G || - pI915XvMC->deviceID == PCI_CHIP_I915_GM || - pI915XvMC->deviceID == PCI_CHIP_I945_G || - pI915XvMC->deviceID == PCI_CHIP_I945_GM) - mem_select = 0; - - load_indirect->dw0.mem_select = mem_select; - - /* SIS */ - sis = (sis_state *)(++load_indirect); - sis->dw0.valid = 1; - sis->dw0.force = 1; - sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1 - - if (mem_select) - sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); - else - sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2); - - /* MSB */ - msb = (msb_state *)(++sis); - msb->dw0.valid = 1; - msb->dw0.force = 1; - msb->dw1.length = 23; // 3 * 8 - 1 - - if (mem_select) - msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); - else - msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2); - - intelBatchbufferData(base, size, 0); - free(base); -} - -static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_set_origin set_origin; - - /* 3DMPEG_SET_ORIGIN */ - memset(&set_origin, 0, sizeof(set_origin)); - set_origin.dw0.type = CMD_3D; - set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; - set_origin.dw0.length = 0; - set_origin.dw1.h_origin = mb->x; - set_origin.dw1.v_origin = mb->y; - - intelBatchbufferData(&set_origin, sizeof(set_origin), 0); -} - -static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; - - /* 3DMPEG_MACROBLOCK_IPICTURE */ - memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); - macroblock_ipicture.dw0.type = CMD_3D; - macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; - macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - - intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 0); -} - -#if 0 -static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_macroblock_0mv macroblock_0mv; - - /* 3DMPEG_MACROBLOCK(0mv) */ - memset(¯oblock_0mv, 0, sizeof(macroblock_0mv)); - macroblock_0mv.header.dw0.type = CMD_3D; - macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; - macroblock_0mv.header.dw0.length = 0; - macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */ - macroblock_0mv.header.dw1.forward = 0; /* should be 0 */ - macroblock_0mv.header.dw1.backward = 0; /* should be 0 */ - macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */ - macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - -/* - if (!mb->coded_block_pattern) - macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; -*/ - - macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3); - macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf; - macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; - macroblock_0mv.header.dw1.skipped_macroblocks = 0; - - intelBatchbufferData(¯oblock_0mv, sizeof(macroblock_0mv), 0); -} -#endif - -static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; - - /* Motion Vectors */ - su_t fmv; - su_t bmv; - - /* 3DMPEG_MACROBLOCK(1fbmv) */ - memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); - macroblock_1fbmv.header.dw0.type = CMD_3D; - macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; - macroblock_1fbmv.header.dw0.length = 2; - macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ - macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); - macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); - macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ - macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - - if (!(mb->coded_block_pattern & 0x3f)) - macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; - - macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); - macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); - macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; - macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; - - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1]; - bmv.s[0] = mb->PMV[0][1][0]; - bmv.s[1] = mb->PMV[0][1][1]; - - macroblock_1fbmv.dw2 = fmv.u[0]; - macroblock_1fbmv.dw3 = bmv.u[0]; - - intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); -} - -static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps) -{ - struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; - - /* Motion Vectors */ - su_t fmv; - su_t bmv; - - /* 3DMPEG_MACROBLOCK(2fbmv) */ - memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); - macroblock_2fbmv.header.dw0.type = CMD_3D; - macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; - macroblock_2fbmv.header.dw0.length = 4; - macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ - macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); - macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); - macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ - macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - - if (!(mb->coded_block_pattern & 0x3f)) - macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; - - macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); - macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); - macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; - macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; - - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1]; - fmv.s[2] = mb->PMV[1][0][0]; - fmv.s[3] = mb->PMV[1][0][1]; - bmv.s[0] = mb->PMV[0][1][0]; - bmv.s[1] = mb->PMV[0][1][1]; - bmv.s[2] = mb->PMV[1][1][0]; - bmv.s[3] = mb->PMV[1][1][1]; - - if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { - if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1] >> 1; - fmv.s[2] = mb->PMV[1][0][0]; - fmv.s[3] = mb->PMV[1][0][1] >> 1; - bmv.s[0] = mb->PMV[0][1][0]; - bmv.s[1] = mb->PMV[0][1][1] >> 1; - bmv.s[2] = mb->PMV[1][1][0]; - bmv.s[3] = mb->PMV[1][1][1] >> 1; - } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1] >> 1; - fmv.s[2] = mb->PMV[0][0][0]; - fmv.s[3] = mb->PMV[0][0][1] >> 1; // MPEG2 MV[0][1] isn't used - bmv.s[0] = mb->PMV[1][0][0]; - bmv.s[1] = mb->PMV[1][0][1] >> 1; - bmv.s[2] = mb->PMV[1][1][0]; - bmv.s[3] = mb->PMV[1][1][1] >> 1; - } - } - - macroblock_2fbmv.dw2 = fmv.u[0]; - macroblock_2fbmv.dw3 = bmv.u[0]; - macroblock_2fbmv.dw4 = fmv.u[1]; - macroblock_2fbmv.dw5 = bmv.u[1]; - - intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); -} - -/* for MC context initialization */ -static void i915_mc_sampler_state_buffer(XvMCContext *context) -{ - struct i915_3dstate_sampler_state *sampler_state; - struct texture_sampler *ts; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - - /* 3DSATE_SAMPLER_STATE */ - sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map; - memset(sampler_state, 0, sizeof(*sampler_state)); - sampler_state->dw0.type = CMD_3D; - sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; - sampler_state->dw0.length = 6; - sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; - - /* Sampler 0 */ - ts = (struct texture_sampler *)(++sampler_state); - memset(ts, 0, sizeof(*ts)); - ts->ts0.reverse_gamma = 0; - ts->ts0.planar2packet = 0; - ts->ts0.color_conversion = 0; - ts->ts0.chromakey_index = 0; - ts->ts0.base_level = 0; - ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ - ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.lod_bias = 0; /* 0.0 */ - ts->ts0.shadow_enable = 0; - ts->ts0.max_anisotropy = ANISORATIO_2; - ts->ts0.shadow_function = PREFILTEROP_ALWAYS; - ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ - ts->ts1.kill_pixel = 0; - ts->ts1.keyed_texture_filter = 0; - ts->ts1.chromakey_enable = 0; - ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; - ts->ts1.normalized_coor = 0; - ts->ts1.map_index = 0; - ts->ts1.east_deinterlacer = 0; - ts->ts2.default_color = 0; - - /* Sampler 1 */ - ++ts; - memset(ts, 0, sizeof(*ts)); - ts->ts0.reverse_gamma = 0; - ts->ts0.planar2packet = 0; - ts->ts0.color_conversion = 0; - ts->ts0.chromakey_index = 0; - ts->ts0.base_level = 0; - ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ - ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.lod_bias = 0; /* 0.0 */ - ts->ts0.shadow_enable = 0; - ts->ts0.max_anisotropy = ANISORATIO_2; - ts->ts0.shadow_function = PREFILTEROP_ALWAYS; - ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ - ts->ts1.kill_pixel = 0; - ts->ts1.keyed_texture_filter = 0; - ts->ts1.chromakey_enable = 0; - ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; - ts->ts1.normalized_coor = 0; - ts->ts1.map_index = 1; - ts->ts1.east_deinterlacer = 0; - ts->ts2.default_color = 0; -} - static void i915_inst_arith(unsigned int *inst, unsigned int op, unsigned int dest, @@ -707,191 +124,245 @@ static void i915_inst_texld(unsigned int *inst, *inst = T2_MBZ; } -static void i915_mc_pixel_shader_program_buffer(XvMCContext *context) +static void i915_emit_batch(void *data, int size, int flag) +{ + intelBatchbufferData(data, size, flag); +} + +/* one time context initialization buffer */ +static uint32_t *one_time_load_state_imm1; +static uint32_t *one_time_load_indirect; +static int one_time_load_state_imm1_size, one_time_load_indirect_size; + +/* load indirect buffer for mc rendering */ +static uint32_t *mc_render_load_indirect; +static int mc_render_load_indirect_size; + +static void i915_mc_one_time_context_init(XvMCContext *context) { - struct i915_3dstate_pixel_shader_program *pixel_shader_program; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int *inst; unsigned int dest, src0, src1, src2; + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + int i; + struct i915_3dstate_sampler_state *sampler_state; + struct i915_3dstate_pixel_shader_program *pixel_shader_program; + struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; - /* Shader 0 */ + /* sampler static state */ + sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map; + /* pixel shader static state */ pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map; + /* pixel shader contant static state */ + pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map; + + memset(sampler_state, 0, sizeof(*sampler_state)); + sampler_state->dw0.type = CMD_3D; + sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; + sampler_state->dw0.length = 6; + sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; + + sampler_state->sampler0.ts0.reverse_gamma = 0; + sampler_state->sampler0.ts0.planar2packet = 0; + sampler_state->sampler0.ts0.color_conversion = 0; + sampler_state->sampler0.ts0.chromakey_index = 0; + sampler_state->sampler0.ts0.base_level = 0; + sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ + sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */ + sampler_state->sampler0.ts0.shadow_enable = 0; + sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2; + sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS; + sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ + sampler_state->sampler0.ts1.kill_pixel = 0; + sampler_state->sampler0.ts1.keyed_texture_filter = 0; + sampler_state->sampler0.ts1.chromakey_enable = 0; + sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler0.ts1.normalized_coor = 0; + sampler_state->sampler0.ts1.map_index = 0; + sampler_state->sampler0.ts1.east_deinterlacer = 0; + sampler_state->sampler0.ts2.default_color = 0; + + sampler_state->sampler1.ts0.reverse_gamma = 0; + sampler_state->sampler1.ts0.planar2packet = 0; + sampler_state->sampler1.ts0.color_conversion = 0; + sampler_state->sampler1.ts0.chromakey_index = 0; + sampler_state->sampler1.ts0.base_level = 0; + sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ + sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */ + sampler_state->sampler1.ts0.shadow_enable = 0; + sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2; + sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS; + sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ + sampler_state->sampler1.ts1.kill_pixel = 0; + sampler_state->sampler1.ts1.keyed_texture_filter = 0; + sampler_state->sampler1.ts1.chromakey_enable = 0; + sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler1.ts1.normalized_coor = 0; + sampler_state->sampler1.ts1.map_index = 1; + sampler_state->sampler1.ts1.east_deinterlacer = 0; + sampler_state->sampler1.ts2.default_color = 0; + memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 2; - /* mov oC, c0.0000 */ - inst = (unsigned int*)(++pixel_shader_program); + pixel_shader_program->shader0.type = CMD_3D; + pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader0.retain = 1; + pixel_shader_program->shader0.length = 2; /* 1 inst */ + i = 0; + dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_CONST, 0); src1 = 0; src2 = 0; - i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL, - A0_DEST_SATURATE, src0, src1, src2); - inst += 3; - - /* Shader 1 */ - pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst; - memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 14; + i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV, + dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); + + pixel_shader_program->shader1.type = CMD_3D; + pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader1.retain = 1; + pixel_shader_program->shader1.length = 14; /* 5 inst */ + i = 0; /* dcl t0.xy */ - inst = (unsigned int*)(++pixel_shader_program); - i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); + i+=3; /* dcl t1.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); /* dcl_2D s0 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); /* texld r0, t0, s0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 0); /* COORD */ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1); /* mov oC, r0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = src2 = 0; - i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); - inst += 3; - /* Shader 2 */ - pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst; - memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 14; + + pixel_shader_program->shader2.type = CMD_3D; + pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader2.retain = 1; + pixel_shader_program->shader2.length = 14; /* 5 inst */ + i = 0; /* dcl t2.xy */ - inst = (unsigned int*)(++pixel_shader_program); - i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); /* dcl t3.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); /* dcl_2D s1 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); /* texld r0, t2, s1 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 2); /* COORD */ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1); /* mov oC, r0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = src2 = 0; - i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); - inst += 3; /* Shader 3 */ - pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst; - memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 29; + pixel_shader_program->shader3.type = CMD_3D; + pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader3.retain = 1; + pixel_shader_program->shader3.length = 29; /* 10 inst */ + i = 0; /* dcl t0.xy */ - inst = (unsigned int*)(++pixel_shader_program); - i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); /* dcl t1.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); /* dcl t2.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); /* dcl t3.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); /* dcl_2D s0 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); /* dcl_2D s1 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); /* texld r0, t0, s0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 0); /* COORD */ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); /* texld r1, t2, s1 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 1); src0 = UREG(REG_TYPE_T, 2); /* COORD */ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); /* add r0, r0, r1 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_R, 0); src1 = UREG(REG_TYPE_R, 1); src2 = 0; - i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL, 0 /* A0_DEST_SATURATE */, src0, src1, src2); /* mul oC, r0, c0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = UREG(REG_TYPE_CONST, 0); src2 = 0; - i915_inst_arith(inst, A0_MUL, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); - inst += 3; -} - -static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context) -{ - struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - float *value; - pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map; memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants)); pixel_shader_constants->dw0.type = CMD_3D; pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS; pixel_shader_constants->dw0.length = 4; pixel_shader_constants->dw1.reg_mask = REG_CR0; - value = (float *)(++pixel_shader_constants); - *(value++) = 0.5; - *(value++) = 0.5; - *(value++) = 0.5; - *(value++) = 0.5; + pixel_shader_constants->value.x = 0.5; + pixel_shader_constants->value.y = 0.5; + pixel_shader_constants->value.z = 0.5; + pixel_shader_constants->value.w = 0.5; + } -static void i915_mc_one_time_state_initialization(XvMCContext *context) +static void i915_mc_one_time_state_init(XvMCContext *context) { - struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL; struct s3_dword *s3 = NULL; struct s6_dword *s6 = NULL; - struct i915_3dstate_load_indirect *load_indirect = NULL; dis_state *dis = NULL; ssb_state *ssb = NULL; psp_state *psp = NULL; psc_state *psc = NULL; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int size; - void *base = NULL; - int mem_select = 1; + struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1; + struct i915_3dstate_load_indirect *load_indirect; + int mem_select; /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ - size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6); - base = calloc(1, size); - load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base; + one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6); + one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size); + load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1; load_state_immediate_1->dw0.type = CMD_3D; load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1; load_state_immediate_1->dw0.load_s3 = 1; load_state_immediate_1->dw0.load_s6 = 1; - load_state_immediate_1->dw0.length = (size >> 2) - 2; + load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2; s3 = (struct s3_dword *)(++load_state_immediate_1); s3->set0_pcd = 1; @@ -917,33 +388,31 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context) s6->color_buffer_write = 1; s6->triangle_pv = 0; - intelBatchbufferData(base, size, 0); - free(base); - /* 3DSTATE_LOAD_INDIRECT */ - size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc); - base = calloc(1, size); - load_indirect = (struct i915_3dstate_load_indirect *)base; + one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc); + one_time_load_indirect = calloc(1, one_time_load_indirect_size); + load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect; load_indirect->dw0.type = CMD_3D; load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC; - load_indirect->dw0.length = (size >> 2) - 2; + load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2; if (pI915XvMC->deviceID == PCI_CHIP_I915_G || - pI915XvMC->deviceID == PCI_CHIP_I915_GM || - pI915XvMC->deviceID == PCI_CHIP_I945_G || - pI915XvMC->deviceID == PCI_CHIP_I945_GM) - mem_select = 0; + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + mem_select = 0; /* use physical address */ + else + mem_select = 1; /* use gfx address */ load_indirect->dw0.mem_select = mem_select; - /* DIS */ + + /* Dynamic indirect state buffer */ dis = (dis_state *)(++load_indirect); dis->dw0.valid = 0; dis->dw0.reset = 0; dis->dw0.buffer_address = 0; - /* SSB */ + /* Sample state buffer */ ssb = (ssb_state *)(++dis); ssb->dw0.valid = 1; ssb->dw0.force = 1; @@ -952,20 +421,20 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context) if (mem_select) ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2); else - ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2); + ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2); - /* PSP */ + /* Pixel shader program buffer */ psp = (psp_state *)(++ssb); psp->dw0.valid = 1; psp->dw0.force = 1; psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */ if (mem_select) - psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); + psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); else - psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2); + psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2); - /* PSC */ + /* Pixel shader constant buffer */ psc = (psc_state *)(++psp); psc->dw0.valid = 1; psc->dw0.force = 1; @@ -975,9 +444,483 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context) psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2); else psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2); +} - intelBatchbufferData(base, size, 0); - free(base); +static void i915_mc_one_time_state_emit(void) +{ + i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0); + i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0); +} + +static void i915_mc_static_indirect_state_init(XvMCContext *context) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + struct i915_mc_static_indirect_state_buffer *buffer_info = + (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map; + + memset(buffer_info, 0, sizeof(*buffer_info)); + /* dest Y */ + buffer_info->dest_y.dw0.type = CMD_3D; + buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->dest_y.dw0.length = 1; + buffer_info->dest_y.dw1.aux_id = 0; + buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK; + buffer_info->dest_y.dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */ + buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */ + buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR; + + /* dest U */ + buffer_info->dest_u.dw0.type = CMD_3D; + buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->dest_u.dw0.length = 1; + buffer_info->dest_u.dw1.aux_id = 0; + buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX; + buffer_info->dest_u.dw1.fence_regs = 0; + buffer_info->dest_u.dw1.tiled_surface = 0; + buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR; + + /* dest V */ + buffer_info->dest_v.dw0.type = CMD_3D; + buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->dest_v.dw0.length = 1; + buffer_info->dest_v.dw1.aux_id = 1; + buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX; + buffer_info->dest_v.dw1.fence_regs = 0; + buffer_info->dest_v.dw1.tiled_surface = 0; + buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR; + + buffer_info->dest_buf.dw0.type = CMD_3D; + buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; + buffer_info->dest_buf.dw0.length = 0; + buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */ + buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */ + buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT; + buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */ + buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */ + + buffer_info->dest_buf_mpeg.dw0.type = CMD_3D; + buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; + buffer_info->dest_buf_mpeg.dw0.length = 1; + buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC; + buffer_info->dest_buf_mpeg.dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ + buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ + buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1; + buffer_info->dest_buf_mpeg.dw1.intra8 = 0; /* 16-bit formatted correction data */ + buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */ + + buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V; + buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H; + + buffer_info->corr.dw0.type = CMD_3D; + buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->corr.dw0.length = 1; + buffer_info->corr.dw1.aux_id = 0; + buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR; + buffer_info->corr.dw1.aux_id = 0; + buffer_info->corr.dw1.fence_regs = 0; + buffer_info->corr.dw1.tiled_surface = 0; + buffer_info->corr.dw1.walk = 0; + buffer_info->corr.dw1.pitch = 0; + buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */ +} + +static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest, + unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData; + struct i915_mc_static_indirect_state_buffer *buffer_info = + (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map; + unsigned int w = dest->width; + + buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */ + buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */ + buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */ + buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */ + buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */ + buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */ + + if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + ; + } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { + buffer_info->dest_buf.dw1.v_ls = 1; + } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { + buffer_info->dest_buf.dw1.v_ls = 1; + buffer_info->dest_buf.dw1.v_ls_offset = 1; + } + + if (picture_structure & XVMC_FRAME_PICTURE) { + ; + } else if (picture_structure & XVMC_TOP_FIELD) { + if (flags & XVMC_SECOND_FIELD) + buffer_info->dest_buf_mpeg.dw1.tff = 0; + else + buffer_info->dest_buf_mpeg.dw1.tff = 1; + } else if (picture_structure & XVMC_BOTTOM_FIELD) { + if (flags & XVMC_SECOND_FIELD) + buffer_info->dest_buf_mpeg.dw1.tff = 1; + else + buffer_info->dest_buf_mpeg.dw1.tff = 0; + } + + buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4); /* in macroblocks */ + buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type; +} + +static void i915_mc_map_state_init(XvMCContext *context) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + unsigned int w = context->width; + unsigned int h = context->height; + struct i915_mc_map_state *map_state; + + map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map; + + memset(map_state, 0, sizeof(*map_state)); + + /* 3DSATE_MAP_STATE: Y */ + map_state->y_map.dw0.type = CMD_3D; + map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; + map_state->y_map.dw0.retain = 1; + map_state->y_map.dw0.length = 6; + map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; + + /* Y Forward (Past) */ + map_state->y_forward.tm0.v_ls_offset = 0; + map_state->y_forward.tm0.v_ls = 0; + map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->y_forward.tm1.tiled_surface = 0; + map_state->y_forward.tm1.utilize_fence_regs = 0; + map_state->y_forward.tm1.texel_fmt = 0; /* 8bit */ + map_state->y_forward.tm1.surface_fmt = 1; /* 8bit */ + map_state->y_forward.tm1.width = w - 1; + map_state->y_forward.tm1.height = h - 1; + map_state->y_forward.tm2.depth = 0; + map_state->y_forward.tm2.max_lod = 0; + map_state->y_forward.tm2.cube_face = 0; + + /* Y Backward (Future) */ + map_state->y_backward.tm0.v_ls_offset = 0; + map_state->y_backward.tm0.v_ls = 0; + map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->y_backward.tm1.tiled_surface = 0; + map_state->y_backward.tm1.utilize_fence_regs = 0; + map_state->y_backward.tm1.texel_fmt = 0; /* 8bit */ + map_state->y_backward.tm1.surface_fmt = 1; /* 8bit */ + map_state->y_backward.tm1.width = w - 1; + map_state->y_backward.tm1.height = h - 1; + map_state->y_backward.tm2.depth = 0; + map_state->y_backward.tm2.max_lod = 0; + map_state->y_backward.tm2.cube_face = 0; + + /* 3DSATE_MAP_STATE: U */ + map_state->u_map.dw0.type = CMD_3D; + map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; + map_state->u_map.dw0.retain = 1; + map_state->u_map.dw0.length = 6; + map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; + + /* U Forward */ + map_state->u_forward.tm0.v_ls_offset = 0; + map_state->u_forward.tm0.v_ls = 0; + map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->u_forward.tm1.tiled_surface = 0; + map_state->u_forward.tm1.utilize_fence_regs = 0; + map_state->u_forward.tm1.texel_fmt = 0; /* 8bit */ + map_state->u_forward.tm1.surface_fmt = 1; /* 8bit */ + map_state->u_forward.tm1.width = (w >> 1) - 1; + map_state->u_forward.tm1.height = (h >> 1) - 1; + map_state->u_forward.tm2.depth = 0; + map_state->u_forward.tm2.max_lod = 0; + map_state->u_forward.tm2.cube_face = 0; + + /* U Backward */ + map_state->u_backward.tm0.v_ls_offset = 0; + map_state->u_backward.tm0.v_ls = 0; + map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->u_backward.tm1.tiled_surface = 0; + map_state->u_backward.tm1.utilize_fence_regs = 0; + map_state->u_backward.tm1.texel_fmt = 0; + map_state->u_backward.tm1.surface_fmt = 1; + map_state->u_backward.tm1.width = (w >> 1) - 1; + map_state->u_backward.tm1.height = (h >> 1) - 1; + map_state->u_backward.tm2.depth = 0; + map_state->u_backward.tm2.max_lod = 0; + map_state->u_backward.tm2.cube_face = 0; + + /* 3DSATE_MAP_STATE: V */ + map_state->v_map.dw0.type = CMD_3D; + map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; + map_state->v_map.dw0.retain = 1; + map_state->v_map.dw0.length = 6; + map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; + + /* V Forward */ + map_state->v_forward.tm0.v_ls_offset = 0; + map_state->v_forward.tm0.v_ls = 0; + map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->v_forward.tm1.tiled_surface = 0; + map_state->v_forward.tm1.utilize_fence_regs = 0; + map_state->v_forward.tm1.texel_fmt = 0; + map_state->v_forward.tm1.surface_fmt = 1; + map_state->v_forward.tm1.width = (w >> 1) - 1; + map_state->v_forward.tm1.height = (h >> 1) - 1; + map_state->v_forward.tm2.depth = 0; + map_state->v_forward.tm2.max_lod = 0; + map_state->v_forward.tm2.cube_face = 0; + + /* V Backward */ + map_state->v_backward.tm0.v_ls_offset = 0; + map_state->v_backward.tm0.v_ls = 0; + map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->v_backward.tm1.tiled_surface = 0; + map_state->v_backward.tm1.utilize_fence_regs = 0; + map_state->v_backward.tm1.texel_fmt = 0; + map_state->v_backward.tm1.surface_fmt = 1; + map_state->v_backward.tm1.width = (w >> 1) - 1; + map_state->v_backward.tm1.height = (h >> 1) - 1; + map_state->v_backward.tm2.depth = 0; + map_state->v_backward.tm2.max_lod = 0; + map_state->v_backward.tm2.cube_face = 0; +} + +static void i915_mc_map_state_set(XvMCContext *context, + i915XvMCSurface *privPast, + i915XvMCSurface *privFuture) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + struct i915_mc_map_state *map_state; + + map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map; + + map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2); + map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */ + map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2); + map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1; + map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2); + map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ + map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2); + map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1; + map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2); + map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ + map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2); + map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1; +} + +static void i915_flush(int map, int render) +{ + struct i915_mi_flush mi_flush; + + memset(&mi_flush, 0, sizeof(mi_flush)); + mi_flush.dw0.type = CMD_MI; + mi_flush.dw0.opcode = OPC_MI_FLUSH; + mi_flush.dw0.map_cache_invalidate = map; + mi_flush.dw0.render_cache_flush_inhibit = render; + + intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0); +} + +static void i915_mc_load_indirect_render_init(XvMCContext *context) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + sis_state *sis; + msb_state *msb; + struct i915_3dstate_load_indirect *load_indirect; + int mem_select; + + mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis) + + sizeof(*msb); + mc_render_load_indirect = calloc(1, mc_render_load_indirect_size); + + load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect; + load_indirect->dw0.type = CMD_3D; + load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; + load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB; + load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2; + + if (pI915XvMC->deviceID == PCI_CHIP_I915_G || + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + mem_select = 0; + else + mem_select = 1; + + load_indirect->dw0.mem_select = mem_select; + + /* Static Indirect state buffer (dest buffer info) */ + sis = (sis_state *)(++load_indirect); + sis->dw0.valid = 1; + sis->dw0.force = 1; + sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */ + + if (mem_select) + sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); + else + sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2); + + /* Map state buffer (reference buffer info) */ + msb = (msb_state *)(++sis); + msb->dw0.valid = 1; + msb->dw0.force = 1; + msb->dw1.length = 23; /* 3 * 8 - 1 */ + + if (mem_select) + msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); + else + msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2); +} + +static void i915_mc_load_indirect_render_emit(void) +{ + i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0); +} + +static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_set_origin set_origin; + + /* 3DMPEG_SET_ORIGIN */ + memset(&set_origin, 0, sizeof(set_origin)); + set_origin.dw0.type = CMD_3D; + set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; + set_origin.dw0.length = 0; + set_origin.dw1.h_origin = mb->x; + set_origin.dw1.v_origin = mb->y; + + intelBatchbufferData(&set_origin, sizeof(set_origin), 0); +} + +static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; + + /* 3DMPEG_MACROBLOCK_IPICTURE */ + memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); + macroblock_ipicture.dw0.type = CMD_3D; + macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; + macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 0); +} + +#if 0 +static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_0mv macroblock_0mv; + + /* 3DMPEG_MACROBLOCK(0mv) */ + memset(¯oblock_0mv, 0, sizeof(macroblock_0mv)); + macroblock_0mv.header.dw0.type = CMD_3D; + macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; + macroblock_0mv.header.dw0.length = 0; + macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */ + macroblock_0mv.header.dw1.forward = 0; /* should be 0 */ + macroblock_0mv.header.dw1.backward = 0; /* should be 0 */ + macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */ + macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + +/* + if (!mb->coded_block_pattern) + macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; +*/ + + macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3); + macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf; + macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; + macroblock_0mv.header.dw1.skipped_macroblocks = 0; + + intelBatchbufferData(¯oblock_0mv, sizeof(macroblock_0mv), 0); +} +#endif + +static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; + vector_t mv0[2]; + + /* 3DMPEG_MACROBLOCK(1fbmv) */ + memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); + macroblock_1fbmv.header.dw0.type = CMD_3D; + macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; + macroblock_1fbmv.header.dw0.length = 2; + macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ + macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); + macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); + macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ + macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + if (!(mb->coded_block_pattern & 0x3f)) + macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; + + macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); + macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); + macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; + macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; + + mv0[0].component[0] = mb->PMV[0][0][0]; + mv0[0].component[1] = mb->PMV[0][0][1]; + mv0[1].component[0] = mb->PMV[0][1][0]; + mv0[1].component[1] = mb->PMV[0][1][1]; + + macroblock_1fbmv.dw2 = mv0[0].v; + macroblock_1fbmv.dw3 = mv0[1].v; + + intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); +} + +static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps) +{ + struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; + vector_t mv0[2]; + vector_t mv1[2]; + + /* 3DMPEG_MACROBLOCK(2fbmv) */ + memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); + macroblock_2fbmv.header.dw0.type = CMD_3D; + macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; + macroblock_2fbmv.header.dw0.length = 4; + macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ + macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); + macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); + macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ + macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + if (!(mb->coded_block_pattern & 0x3f)) + macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; + + macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); + macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); + macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; + macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; + + mv0[0].component[0] = mb->PMV[0][0][0]; + mv0[0].component[1] = mb->PMV[0][0][1]; + mv0[1].component[0] = mb->PMV[0][1][0]; + mv0[1].component[1] = mb->PMV[0][1][1]; + mv1[0].component[0] = mb->PMV[1][0][0]; + mv1[0].component[1] = mb->PMV[1][0][1]; + mv1[1].component[0] = mb->PMV[1][1][0]; + mv1[1].component[1] = mb->PMV[1][1][1]; + + if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { + mv0[0].component[1] = mb->PMV[0][0][1] >> 1; + mv0[1].component[1] = mb->PMV[0][1][1] >> 1; + mv1[0].component[1] = mb->PMV[1][0][1] >> 1; + mv1[1].component[1] = mb->PMV[1][1][1] >> 1; + } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { + mv0[0].component[1] = mb->PMV[0][0][1] >> 1; + mv0[1].component[1] = mb->PMV[0][1][1] >> 1; // MPEG2 MV[0][1] isn't used + mv1[0].component[1] = mb->PMV[1][0][1] >> 1; + mv1[1].component[1] = mb->PMV[1][1][1] >> 1; + } + } + + macroblock_2fbmv.dw2 = mv0[0].v; + macroblock_2fbmv.dw3 = mv0[1].v; + macroblock_2fbmv.dw4 = mv1[0].v; + macroblock_2fbmv.dw5 = mv1[1].v; + + intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); } #if 0 @@ -1658,9 +1601,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context pI915XvMC->psc.size = tmpComm->psc.size; if (pI915XvMC->deviceID == PCI_CHIP_I915_G || - pI915XvMC->deviceID == PCI_CHIP_I915_GM || - pI915XvMC->deviceID == PCI_CHIP_I945_G || - pI915XvMC->deviceID == PCI_CHIP_I945_GM) { + pI915XvMC->deviceID == PCI_CHIP_I915_GM) { pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr; pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr; pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr; @@ -1695,6 +1636,16 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context pI915XvMC->last_flip = 0; pI915XvMC->port = context->port; pI915XvMC->ref = 1; + + /* pre-init state buffers */ + i915_mc_one_time_context_init(context); + i915_mc_one_time_state_init(context); + + i915_mc_static_indirect_state_init(context); + + i915_mc_map_state_init(context); + + i915_mc_load_indirect_render_init(context); return Success; } @@ -1707,6 +1658,10 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context) /* Pass Control to the X server to destroy the drm_context_t */ i915_release_resource(display,context); + + free(one_time_load_state_imm1); + free(one_time_load_indirect); + free(mc_render_load_indirect); return Success; } @@ -1862,9 +1817,8 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, if (!(privTarget = target_surface->privData)) return XvMCBadSurface; - /* Test For YV12 Surface */ - if (context->surface_type_id != FOURCC_YV12) { - XVMC_ERR("HWMC only possible on YV12 Surfaces."); + if (context->surface_type_id >= SURFACE_TYPE_MAX) { + XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id); return BadValue; } @@ -1931,7 +1885,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, XVMC_INFO("no coded blocks present!"); } - bspm = mb_bytes[mb->coded_block_pattern]; + bspm = mb_bytes_420[mb->coded_block_pattern]; if (!bspm) continue; @@ -1950,16 +1904,15 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC); - i915_mc_sampler_state_buffer(context); - i915_mc_pixel_shader_program_buffer(context); - i915_mc_pixel_shader_constants_buffer(context); - i915_mc_one_time_state_initialization(context); + i915_mc_one_time_state_emit(); + + i915_mc_static_indirect_state_set(context, target_surface, picture_structure, + flags, picture_coding_type); + /* setup reference surfaces */ + i915_mc_map_state_set(context, privPast, privFuture); + + i915_mc_load_indirect_render_emit(); - i915_mc_static_indirect_state_buffer(context, target_surface, - picture_structure, flags, - picture_coding_type); - i915_mc_map_state_buffer(context, privTarget, privPast, privFuture); - i915_mc_load_sis_msb_buffers(context); i915_mc_mpeg_set_origin(context, ¯oblock_array->macro_blocks[first_macroblock]); for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { diff --git a/driver/xf86-video-intel/src/xvmc/intel_xvmc.c b/driver/xf86-video-intel/src/xvmc/intel_xvmc.c index 3c14f7391..ea39069e0 100644 --- a/driver/xf86-video-intel/src/xvmc/intel_xvmc.c +++ b/driver/xf86-video-intel/src/xvmc/intel_xvmc.c @@ -26,10 +26,89 @@ */ #include "intel_xvmc.h" +/* global */ struct _intel_xvmc_driver *xvmc_driver = NULL; + +/* Lookup tables to speed common calculations for coded_block_pattern */ +/* each block is ((8*8) * sizeof(short)) */ +unsigned int mb_bytes_420[] = { + 0, /* 0 */ + 128, /* 1 */ + 128, /* 10 */ + 256, /* 11 */ + 128, /* 100 */ + 256, /* 101 */ + 256, /* 110 */ + 384, /* 111 */ + 128, /* 1000 */ + 256, /* 1001 */ + 256, /* 1010 */ + 384, /* 1011 */ + 256, /* 1100 */ + 384, /* 1101 */ + 384, /* 1110 */ + 512, /* 1111 */ + 128, /* 10000 */ + 256, /* 10001 */ + 256, /* 10010 */ + 384, /* 10011 */ + 256, /* 10100 */ + 384, /* 10101 */ + 384, /* 10110 */ + 512, /* 10111 */ + 256, /* 11000 */ + 384, /* 11001 */ + 384, /* 11010 */ + 512, /* 11011 */ + 384, /* 11100 */ + 512, /* 11101 */ + 512, /* 11110 */ + 640, /* 11111 */ + 128, /* 100000 */ + 256, /* 100001 */ + 256, /* 100010 */ + 384, /* 100011 */ + 256, /* 100100 */ + 384, /* 100101 */ + 384, /* 100110 */ + 512, /* 100111 */ + 256, /* 101000 */ + 384, /* 101001 */ + 384, /* 101010 */ + 512, /* 101011 */ + 384, /* 101100 */ + 512, /* 101101 */ + 512, /* 101110 */ + 640, /* 101111 */ + 256, /* 110000 */ + 384, /* 110001 */ + 384, /* 110010 */ + 512, /* 110011 */ + 384, /* 110100 */ + 512, /* 110101 */ + 512, /* 110110 */ + 640, /* 110111 */ + 384, /* 111000 */ + 512, /* 111001 */ + 512, /* 111010 */ + 640, /* 111011 */ + 512, /* 111100 */ + 640, /* 111101 */ + 640, /* 111110 */ + 768 /* 111111 */ +}; + +int DEBUG; + static int error_base; static int event_base; +static void intel_xvmc_debug_init(void) +{ + if (getenv("INTEL_XVMC_DEBUG")) + DEBUG = 1; +} + /* locking */ static void intel_xvmc_try_heavy_lock(drm_context_t ctx) { @@ -211,6 +290,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, return BadValue; } + intel_xvmc_debug_init(); + /* Open DRI Device */ if((fd = drmOpen("i915", NULL)) < 0) { XVMC_ERR("DRM Device could not be opened."); @@ -360,6 +441,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, intelInitBatchBuffer(); + intel_xvmc_dump_open(); + return Success; } @@ -375,11 +458,11 @@ Status XvMCCreateContext(Display *display, XvPortID port, Status XvMCDestroyContext(Display *display, XvMCContext *context) { Status ret; - int screen = DefaultScreen(display); + int screen; if (!display || !context) return XvMCBadContext; - + screen = DefaultScreen(display); ret = (xvmc_driver->destroy_context)(display, context); if (ret) { XVMC_ERR("destroy context fail\n"); @@ -407,6 +490,8 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context) xvmc_driver->fd = -1; intelFiniBatchBuffer(); + + intel_xvmc_dump_close(); } return Success; } @@ -595,6 +680,10 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, if (!target_surface) return XvMCBadSurface; + intel_xvmc_dump_render(context, picture_structure, target_surface, + past_surface, future_surface, flags, num_macroblocks, + first_macroblock, macroblock_array, blocks); + ret = (xvmc_driver->render_surface)(display, context, picture_structure, target_surface, past_surface, future_surface, flags, num_macroblocks, first_macroblock, macroblock_array, diff --git a/driver/xf86-video-intel/src/xvmc/intel_xvmc.h b/driver/xf86-video-intel/src/xvmc/intel_xvmc.h index bc863c475..c4dfd770e 100644 --- a/driver/xf86-video-intel/src/xvmc/intel_xvmc.h +++ b/driver/xf86-video-intel/src/xvmc/intel_xvmc.h @@ -38,6 +38,7 @@ #include <string.h> #include <assert.h> #include <signal.h> +#include <stdint.h> #include <xf86drm.h> #include "i830_common.h" @@ -56,7 +57,7 @@ #include "intel_batchbuffer.h" -#define DEBUG 0 +extern int DEBUG; #define XVMC_ERR(s, arg...) \ do { \ @@ -249,4 +250,15 @@ static inline const char* intel_xvmc_decoder_string(int flag) extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id); extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id); +extern unsigned int mb_bytes_420[64]; + +/* dump function */ +extern void intel_xvmc_dump_open(void); +extern void intel_xvmc_dump_close(void); +extern void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure, + XvMCSurface *target_surface, XvMCSurface *past_surface, + XvMCSurface *future_surface, unsigned int flags, + unsigned int num_macroblocks, unsigned int first_macroblock, + XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks); + #endif diff --git a/driver/xf86-video-intel/src/xvmc/intel_xvmc_dump.c b/driver/xf86-video-intel/src/xvmc/intel_xvmc_dump.c new file mode 100644 index 000000000..419bd0d82 --- /dev/null +++ b/driver/xf86-video-intel/src/xvmc/intel_xvmc_dump.c @@ -0,0 +1,149 @@ +/* + * Copyright © 2008 Intel Corporation + * + * 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: + * Zhenyu Wang <zhenyu.z.wang@intel.com> + * + */ +#include "intel_xvmc.h" + +#define DUMPFILE "./intel_xvmc_dump" + +static int xvmc_dump = 0; +static FILE *fp = NULL; + +void intel_xvmc_dump_open(void) +{ + char *d = NULL; + + if (xvmc_dump) + return; + + if (d = getenv("INTEL_XVMC_DUMP")) + xvmc_dump = 1; + + if (xvmc_dump) { + fp = fopen(DUMPFILE, "a"); + if (!fp) + xvmc_dump = 0; + } +} + +void intel_xvmc_dump_close(void) +{ + if (xvmc_dump) { + fclose(fp); + xvmc_dump = 0; + } +} + +void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure, + XvMCSurface *target, XvMCSurface *past, XvMCSurface *future, unsigned int flags, + unsigned int num_macroblocks, unsigned int first_macroblock, + XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks) +{ + int i; + XvMCMacroBlock *mb; + + if (!xvmc_dump) + return; + + fprintf(fp, "========== new surface rendering ==========\n"); + fprintf(fp, "Context (id:%d) (surface_type_id:%d) (width:%d) (height:%d)\n", + context->context_id, context->surface_type_id, context->width, context->height); + + if (picture_structure == XVMC_FRAME_PICTURE) + fprintf(fp, "picture structure: frame picture\n"); + else if (picture_structure == XVMC_TOP_FIELD) + fprintf(fp, "picture structure: top field picture (%s)\n", + (flags == XVMC_SECOND_FIELD)?"second":"first"); + else if (picture_structure == XVMC_BOTTOM_FIELD) + fprintf(fp, "picture structure: bottom field picture (%s)\n", + (flags == XVMC_SECOND_FIELD)?"second":"first"); + + if (!past && !future) + fprintf(fp, "picture type: I\n"); + else if (past && !future) + fprintf(fp, "picture type: P\n"); + else if (past && future) + fprintf(fp, "picture type: B\n"); + else + fprintf(fp, "picture type: Bad!\n"); + + fprintf(fp, "target picture: id (%d) width (%d) height (%d)\n", target->surface_id, + target->width, target->height); + if (past) + fprintf(fp, "past picture: id (%d) width (%d) height (%d)\n", past->surface_id, + past->width, past->height); + if (future) + fprintf(fp, "future picture: id (%d) width (%d) height (%d)\n", future->surface_id, + future->width, future->height); + + fprintf(fp, "num macroblocks: %d, first macroblocks %d\n", num_macroblocks, first_macroblock); + + for (i = first_macroblock; i < (first_macroblock + num_macroblocks); i++) { + mb = ¯oblock_array->macro_blocks[i]; + + fprintf(fp, "- MB(%d): ", i); + fprintf(fp, "x (%d) y (%d) ", mb->x, mb->y); + fprintf(fp, "macroblock type ("); + if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) + fprintf(fp, "motion_forward "); + if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) + fprintf(fp, "motion_backward "); + if (mb->macroblock_type & XVMC_MB_TYPE_PATTERN) + fprintf(fp, "pattern "); + if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) + fprintf(fp, "intra "); + fprintf(fp, ") "); + fprintf(fp, "mc type "); + if (picture_structure == XVMC_FRAME_PICTURE) { + if (mb->motion_type & XVMC_PREDICTION_FIELD) + fprintf(fp, "(field) "); + else if (mb->motion_type & XVMC_PREDICTION_FRAME) + fprintf(fp, "(frame) "); + else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) + fprintf(fp, "(dual-prime) "); + else + fprintf(fp, "(unknown %d) ", mb->motion_type); + } else { /* field */ + if (mb->motion_type & XVMC_PREDICTION_FIELD) + fprintf(fp, "(field) "); + else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) + fprintf(fp, "(dual-prime) "); + else if (mb->motion_type & XVMC_PREDICTION_16x8) + fprintf(fp, "(16x8) "); + else + fprintf(fp, "(unknown %d) ", mb->motion_type); + } + + if (mb->dct_type == XVMC_DCT_TYPE_FRAME) + fprintf(fp, "dct type (frame) "); + else if (mb->dct_type == XVMC_DCT_TYPE_FIELD) + fprintf(fp, "dct type (field) "); + + fprintf(fp, "coded_block_pattern (0x%x)\n", mb->coded_block_pattern); + + /* XXX mv dump */ + } + +} |