diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-01-15 08:46:13 +0100 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-01-15 08:46:13 +0100 |
commit | 7fe60435bce6595a9c58a9bfd8244d74b5320e96 (patch) | |
tree | 1ac714a916e02fc90901ddac8bc2a3c6d051d28c /Source/DirectFB/gfxdrivers/radeon | |
download | directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.tar.gz directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.tar.bz2 directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.zip |
Import DirectFB141_2k11R3_beta5
Diffstat (limited to 'Source/DirectFB/gfxdrivers/radeon')
22 files changed, 14990 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/radeon/Makefile.am b/Source/DirectFB/gfxdrivers/radeon/Makefile.am new file mode 100755 index 0000000..322ae30 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/Makefile.am @@ -0,0 +1,52 @@ +## Makefile.am for DirectFB/src/core/gfxcards/radeon + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/systems + +radeon_LTLIBRARIES = libdirectfb_radeon.la + +if BUILD_STATIC +radeon_DATA = $(radeon_LTLIBRARIES:.la=.o) +endif + +radeondir = $(MODULEDIR)/gfxdrivers + +libdirectfb_radeon_la_SOURCES = \ + radeon.c \ + r100_state.c \ + r200_state.c \ + r300_state.c \ + radeon_2d.c \ + r100_3d.c \ + r200_3d.c \ + r300_3d.c \ + radeon_overlay.c \ + radeon_crtc1.c \ + radeon_crtc2.c \ + radeon.h \ + radeon_chipsets.h \ + radeon_regs.h \ + r300_program.h \ + radeon_mmio.h \ + radeon_state.h \ + radeon_2d.h \ + radeon_3d.h \ + vertex_shader.h + +libdirectfb_radeon_la_LDFLAGS = \ + -module \ + -avoid-version \ + $(DFB_LDFLAGS) -lm + +libdirectfb_radeon_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + + +include $(top_srcdir)/rules/libobject.make + diff --git a/Source/DirectFB/gfxdrivers/radeon/Makefile.in b/Source/DirectFB/gfxdrivers/radeon/Makefile.in new file mode 100755 index 0000000..50e9cb1 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/Makefile.in @@ -0,0 +1,625 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/rules/libobject.make +subdir = gfxdrivers/radeon +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(radeondir)" "$(DESTDIR)$(radeondir)" +radeonLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(radeon_LTLIBRARIES) +libdirectfb_radeon_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la +am_libdirectfb_radeon_la_OBJECTS = radeon.lo r100_state.lo \ + r200_state.lo r300_state.lo radeon_2d.lo r100_3d.lo r200_3d.lo \ + r300_3d.lo radeon_overlay.lo radeon_crtc1.lo radeon_crtc2.lo +libdirectfb_radeon_la_OBJECTS = $(am_libdirectfb_radeon_la_OBJECTS) +libdirectfb_radeon_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libdirectfb_radeon_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libdirectfb_radeon_la_SOURCES) +DIST_SOURCES = $(libdirectfb_radeon_la_SOURCES) +radeonDATA_INSTALL = $(INSTALL_DATA) +DATA = $(radeon_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ASFLAGS = @ASFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@ +DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@ +DFB_LDFLAGS = @DFB_LDFLAGS@ +DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@ +DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@ +DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@ +DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@ +DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@ +DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@ +DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@ +DIRECTFB_VERSION = @DIRECTFB_VERSION@ +DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@ +DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@ +DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@ +DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@ +DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@ +DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@ +DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@ +DSYMUTIL = @DSYMUTIL@ +DYNLIB = @DYNLIB@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +FREETYPE_PROVIDER = @FREETYPE_PROVIDER@ +FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@ +FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@ +FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@ +GIF_PROVIDER = @GIF_PROVIDER@ +GREP = @GREP@ +HAVE_LINUX = @HAVE_LINUX@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@ +JPEG_PROVIDER = @JPEG_PROVIDER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPNG_CONFIG = @LIBPNG_CONFIG@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_BINARY = @LT_BINARY@ +LT_CURRENT = @LT_CURRENT@ +LT_RELEASE = @LT_RELEASE@ +LT_REVISION = @LT_REVISION@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +MKDIR_P = @MKDIR_P@ +MODULEDIR = @MODULEDIR@ +MODULEDIRNAME = @MODULEDIRNAME@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +OSX_LIBS = @OSX_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PNG_PROVIDER = @PNG_PROVIDER@ +RANLIB = @RANLIB@ +RUNTIME_SYSROOT = @RUNTIME_SYSROOT@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOPATH = @SOPATH@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +SYSFS_LIBS = @SYSFS_LIBS@ +THREADFLAGS = @THREADFLAGS@ +THREADLIB = @THREADLIB@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +VERSION = @VERSION@ +VNC_CFLAGS = @VNC_CFLAGS@ +VNC_CONFIG = @VNC_CONFIG@ +VNC_LIBS = @VNC_LIBS@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/systems + +radeon_LTLIBRARIES = libdirectfb_radeon.la +@BUILD_STATIC_TRUE@radeon_DATA = $(radeon_LTLIBRARIES:.la=.o) +radeondir = $(MODULEDIR)/gfxdrivers +libdirectfb_radeon_la_SOURCES = \ + radeon.c \ + r100_state.c \ + r200_state.c \ + r300_state.c \ + radeon_2d.c \ + r100_3d.c \ + r200_3d.c \ + r300_3d.c \ + radeon_overlay.c \ + radeon_crtc1.c \ + radeon_crtc2.c \ + radeon.h \ + radeon_chipsets.h \ + radeon_regs.h \ + r300_program.h \ + radeon_mmio.h \ + radeon_state.h \ + radeon_2d.h \ + radeon_3d.h \ + vertex_shader.h + +libdirectfb_radeon_la_LDFLAGS = \ + -module \ + -avoid-version \ + $(DFB_LDFLAGS) -lm + +libdirectfb_radeon_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.make $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gfxdrivers/radeon/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu gfxdrivers/radeon/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-radeonLTLIBRARIES: $(radeon_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(radeondir)" || $(MKDIR_P) "$(DESTDIR)$(radeondir)" + @list='$(radeon_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(radeonLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(radeondir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(radeonLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(radeondir)/$$f"; \ + else :; fi; \ + done + +uninstall-radeonLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(radeon_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(radeondir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(radeondir)/$$p"; \ + done + +clean-radeonLTLIBRARIES: + -test -z "$(radeon_LTLIBRARIES)" || rm -f $(radeon_LTLIBRARIES) + @list='$(radeon_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libdirectfb_radeon.la: $(libdirectfb_radeon_la_OBJECTS) $(libdirectfb_radeon_la_DEPENDENCIES) + $(libdirectfb_radeon_la_LINK) -rpath $(radeondir) $(libdirectfb_radeon_la_OBJECTS) $(libdirectfb_radeon_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r100_3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r100_state.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r200_3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r200_state.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r300_3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r300_state.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_crtc1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_crtc2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_overlay.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-radeonDATA: $(radeon_DATA) + @$(NORMAL_INSTALL) + test -z "$(radeondir)" || $(MKDIR_P) "$(DESTDIR)$(radeondir)" + @list='$(radeon_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(radeonDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(radeondir)/$$f'"; \ + $(radeonDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(radeondir)/$$f"; \ + done + +uninstall-radeonDATA: + @$(NORMAL_UNINSTALL) + @list='$(radeon_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(radeondir)/$$f'"; \ + rm -f "$(DESTDIR)$(radeondir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(radeondir)" "$(DESTDIR)$(radeondir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-radeonLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-radeonDATA install-radeonLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-radeonDATA uninstall-radeonLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-radeonLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-radeonDATA install-radeonLTLIBRARIES install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-radeonDATA \ + uninstall-radeonLTLIBRARIES + +%.o: .libs/%.a %.la + rm -f $<.tmp/*.o + if test -d $<.tmp; then rmdir $<.tmp; fi + mkdir $<.tmp + (cd $<.tmp && $(AR) x ../../$<) + $(LD) -o $@ -r $<.tmp/*.o + rm -f $<.tmp/*.o && rmdir $<.tmp + +.PHONY: $(LTLIBRARIES:%.la=.libs/%.a) +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Source/DirectFB/gfxdrivers/radeon/r100_3d.c b/Source/DirectFB/gfxdrivers/radeon/r100_3d.c new file mode 100755 index 0000000..c647b55 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r100_3d.c @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <dfb_types.h> +#include <directfb.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/state.h> +#include <core/gfxcard.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_3d.h" + + +#define EMIT_VERTICES( rdrv, rdev, mmio ) { \ + u32 *_v = (rdev)->vb; \ + u32 _s = (rdev)->vb_size; \ + radeon_waitfifo( rdrv, rdev, 1 ); \ + radeon_out32( mmio, SE_VF_CNTL, rdev->vb_type | VF_PRIM_WALK_DATA | VF_RADEON_MODE | \ + (rdev->vb_count << VF_NUM_VERTICES_SHIFT) ); \ + do { \ + u32 _n = MIN(_s, 64); \ + _s -= _n; \ + radeon_waitfifo( rdrv, rdev, _n ); \ + while (_n--) \ + radeon_out32( mmio, SE_PORT_DATA0, *_v++ ); \ + } while (_s); \ +} + +static void +r100_flush_vb( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + EMIT_VERTICES( rdrv, rdev, mmio ); + + if (DFB_PLANAR_PIXELFORMAT(rdev->dst_format)) { + DFBRegion *clip = &rdev->clip; + bool s420 = DFB_PLANAR_PIXELFORMAT(rdev->src_format); + int i; + + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + for (i = 0; i < rdev->vb_size; i += 4) { + rdev->vb[i+0] = f2d(d2f(rdev->vb[i+0])*0.5f); + rdev->vb[i+1] = f2d(d2f(rdev->vb[i+1])*0.5f); + if (s420) { + rdev->vb[i+2] = f2d(d2f(rdev->vb[i+2])*0.5f); + rdev->vb[i+3] = f2d(d2f(rdev->vb[i+3])*0.5f); + } + } + } else { + for (i = 0; i < rdev->vb_size; i += 2) { + rdev->vb[i+0] = f2d(d2f(rdev->vb[i+0])*0.5f); + rdev->vb[i+1] = f2d(d2f(rdev->vb[i+1])*0.5f); + } + } + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2/2 << 16) | + (clip->x2/2 & 0xffff) ); + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + radeon_out32( mmio, PP_TFACTOR_0, rdev->cb_cop ); + if (s420) { + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, PP_TEX_SIZE_0, ((rdev->src_height/2-1) << 16) | + ((rdev->src_width/2-1) & 0xffff) ); + radeon_out32( mmio, PP_TEX_PITCH_0, rdev->src_pitch/2 - 32 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset_cb ); + } + } else { + radeon_out32( mmio, PP_TFACTOR_1, rdev->cb_cop ); + } + + /* Fill Cb plane */ + EMIT_VERTICES( rdrv, rdev, mmio ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cr ); + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + radeon_out32( mmio, PP_TFACTOR_0, rdev->cr_cop ); + if (s420) { + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset_cr ); + } + } else { + radeon_out32( mmio, PP_TFACTOR_1, rdev->cr_cop ); + } + + /* Fill Cr plane */ + EMIT_VERTICES( rdrv, rdev, mmio ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch ); + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2 << 16) | + (clip->x2 & 0xffff) ); + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + radeon_out32( mmio, PP_TFACTOR_0, rdev->y_cop ); + if (s420) { + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, PP_TEX_SIZE_0, ((rdev->src_height-1) << 16) | + ((rdev->src_width-1) & 0xffff) ); + radeon_out32( mmio, PP_TEX_PITCH_0, rdev->src_pitch - 32 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset ); + } + } else { + radeon_out32( mmio, PP_TFACTOR_1, rdev->y_cop ); + } + } + + rdev->vb_size = 0; + rdev->vb_count = 0; +} + +static inline u32* +r100_init_vb( RadeonDriverData *rdrv, RadeonDeviceData *rdev, u32 type, u32 count, u32 size ) +{ + u32 *vb; + + if ((rdev->vb_size && rdev->vb_type != type) || + rdev->vb_size+size > D_ARRAY_SIZE(rdev->vb)) + r100_flush_vb( rdrv, rdev ); + + vb = &rdev->vb[rdev->vb_size]; + rdev->vb_type = type; + rdev->vb_size += size; + rdev->vb_count += count; + + return vb; +} + + +bool r100FillRectangle3D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + if (rect->w == 1 && rect->h == 1) { + x1 = rect->x+1; y1 = rect->y+1; + if (rdev->matrix) + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_POINT_LIST, 1, 2 ); + *v++ = f2d(x1); *v++ = f2d(y1); + + return true; + } + + x1 = rect->x; y1 = rect->y; + x2 = rect->x+rect->w; y2 = rect->y+rect->h; + if (rdev->matrix) { + float X1, Y1, X2, Y2, X3, Y3, X4, Y4; + + RADEON_TRANSFORM( x1, y1, X1, Y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y1, X2, Y2, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, X3, Y3, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x1, y2, X4, Y4, rdev->matrix, rdev->affine_matrix ); + + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_TRIANGLE_LIST, 6, 12 ); + *v++ = f2d(X1); *v++ = f2d(Y1); + *v++ = f2d(X2); *v++ = f2d(Y2); + *v++ = f2d(X3); *v++ = f2d(Y3); + *v++ = f2d(X1); *v++ = f2d(Y1); + *v++ = f2d(X3); *v++ = f2d(Y3); + *v++ = f2d(X4); *v++ = f2d(Y4); + } + else { + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_RECTANGLE_LIST, 3, 6 ); + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y2); + } + + return true; +} + +bool r100FillTriangle( void *drv, void *dev, DFBTriangle *tri ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + float x3, y3; + u32 *v; + + x1 = tri->x1; y1 = tri->y1; + x2 = tri->x2; y2 = tri->y2; + x3 = tri->x3; y3 = tri->y3; + if (rdev->matrix) { + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, x2, y2, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x3, y3, x3, y3, rdev->matrix, rdev->affine_matrix ); + } + + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_TRIANGLE_LIST, 3, 6 ); + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y2); + *v++ = f2d(x3); *v++ = f2d(y3); + + return true; +} + +bool r100DrawRectangle3D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + x1 = rect->x; y1 = rect->y; + x2 = rect->x+rect->w; y2 = rect->y+rect->h; + if (rdev->matrix) { + float x, y; + + /* XXX: better LINE_STRIP?! */ + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LIST, 8, 16 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + } + else { + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_RECTANGLE_LIST, 12, 24 ); + /* top line */ + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y1+1); + /* right line */ + *v++ = f2d(x2-1); *v++ = f2d(y1+1); + *v++ = f2d(x2); *v++ = f2d(y1+1); + *v++ = f2d(x2); *v++ = f2d(y2-1); + /* bottom line */ + *v++ = f2d(x1); *v++ = f2d(y2-1); + *v++ = f2d(x2); *v++ = f2d(y2-1); + *v++ = f2d(x2); *v++ = f2d(y2); + /* left line */ + *v++ = f2d(x1); *v++ = f2d(y1+1); + *v++ = f2d(x1+1); *v++ = f2d(y1+1); + *v++ = f2d(x1+1); *v++ = f2d(y2-1); + } + + return true; +} + +bool r100DrawLine3D( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + x1 = line->x1; y1 = line->y1; + x2 = line->x2; y2 = line->y2; + if (rdev->matrix) { + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, x2, y2, rdev->matrix, rdev->affine_matrix ); + } + + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LIST, 2, 4 ); + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y2); + + return true; +} + +bool r100Blit3D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + DFBRectangle dr = { dx, dy, sr->w, sr->h }; + + return r100StretchBlit( drv, dev, sr, &dr ); +} + +bool r100StretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + float s1, t1; + float s2, t2; + u32 *v; + + if (rdev->blittingflags & DSBLIT_DEINTERLACE) { + sr->y /= 2; + sr->h /= 2; + } + + s1 = sr->x; t1 = sr->y; + s2 = sr->x+sr->w; t2 = sr->y+sr->h; + if (rdev->blittingflags & DSBLIT_ROTATE180) { + float tmp; + tmp = s2; s2 = s1; s1 = tmp; + tmp = t2; t2 = t1; t1 = tmp; + } + + x1 = dr->x; y1 = dr->y; + x2 = dr->x+dr->w; y2 = dr->y+dr->h; + if (rdev->matrix) { + float X1, Y1, X2, Y2, X3, Y3, X4, Y4; + + RADEON_TRANSFORM( x1, y1, X1, Y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y1, X2, Y2, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, X3, Y3, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x1, y2, X4, Y4, rdev->matrix, rdev->affine_matrix ); + + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_TRIANGLE_LIST, 6, 24 ); + *v++ = f2d(X1); *v++ = f2d(Y1); *v++ = f2d(s1); *v++ = f2d(t1); + *v++ = f2d(X2); *v++ = f2d(Y2); *v++ = f2d(s2); *v++ = f2d(t1); + *v++ = f2d(X3); *v++ = f2d(Y3); *v++ = f2d(s2); *v++ = f2d(t2); + *v++ = f2d(X1); *v++ = f2d(Y1); *v++ = f2d(s1); *v++ = f2d(t1); + *v++ = f2d(X3); *v++ = f2d(Y3); *v++ = f2d(s2); *v++ = f2d(t2); + *v++ = f2d(X4); *v++ = f2d(Y4); *v++ = f2d(s1); *v++ = f2d(t2); + } + else { + v = r100_init_vb( rdrv, rdev, VF_PRIM_TYPE_RECTANGLE_LIST, 3, 12 ); + *v++ = f2d(x1); *v++ = f2d(y1); *v++ = f2d(s1); *v++ = f2d(t1); + *v++ = f2d(x2); *v++ = f2d(y1); *v++ = f2d(s2); *v++ = f2d(t1); + *v++ = f2d(x2); *v++ = f2d(y2); *v++ = f2d(s2); *v++ = f2d(t2); + } + + return true; +} + +static void +r100DoTextureTriangles( RadeonDriverData *rdrv, RadeonDeviceData *rdev, + DFBVertex *ve, int num, u32 primitive ) +{ + volatile u8 *mmio = rdrv->mmio_base; + int i; + + radeon_waitfifo( rdrv, rdev, 1 ); + + radeon_out32( mmio, SE_VF_CNTL, primitive | + VF_PRIM_WALK_DATA | + VF_RADEON_MODE | + (num << VF_NUM_VERTICES_SHIFT) ); + + for (; num >= 10; num -= 10) { + radeon_waitfifo( rdrv, rdev, 60 ); + for (i = 0; i < 10; i++) { + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].x) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].y) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].z) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].w) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].s) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].t) ); + } + ve += 10; + } + + if (num > 0) { + radeon_waitfifo( rdrv, rdev, num*6 ); + for (i = 0; i < num; i++) { + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].x) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].y) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].z) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].w) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].s) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].t) ); + } + } +} + +bool r100TextureTriangles( void *drv, void *dev, DFBVertex *ve, + int num, DFBTriangleFormation formation ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + u32 prim = 0; + int i; + + if (num > 65535) { + D_WARN( "R100 supports maximum 65535 vertices" ); + return false; + } + + switch (formation) { + case DTTF_LIST: + prim = VF_PRIM_TYPE_TRIANGLE_LIST; + break; + case DTTF_STRIP: + prim = VF_PRIM_TYPE_TRIANGLE_STRIP; + break; + case DTTF_FAN: + prim = VF_PRIM_TYPE_TRIANGLE_FAN; + break; + default: + D_BUG( "unexpected triangle formation" ); + return false; + } + + if (rdev->matrix) { + for (i = 0; i < num; i++) + RADEON_TRANSFORM( ve[i].x, ve[i].y, ve[i].x, ve[i].y, rdev->matrix, rdev->affine_matrix ); + } + + r100DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + if (DFB_PLANAR_PIXELFORMAT(rdev->dst_format)) { + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + bool s420 = DFB_PLANAR_PIXELFORMAT(rdev->src_format); + int i; + + /* Scale coordinates */ + for (i = 0; i < num; i++) { + ve[i].x *= 0.5; + ve[i].y *= 0.5; + } + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, s420 ? 8 : 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch/2 ); + if (s420) { + radeon_out32( mmio, PP_TEX_SIZE_0, ((rdev->src_height/2-1) << 16) | + ((rdev->src_width/2-1) & 0xffff) ); + radeon_out32( mmio, PP_TEX_PITCH_0, rdev->src_pitch/2 - 32 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset_cb ); + } + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2/2 << 16) | + (clip->x2/2 & 0xffff) ); + radeon_out32( mmio, PP_TFACTOR_0, rdev->cb_cop ); + + /* Map Cb plane */ + r100DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, s420 ? 3 : 2 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cr ); + if (s420) + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset_cr ); + radeon_out32( mmio, PP_TFACTOR_0, rdev->cr_cop ); + + /* Map Cr plane */ + r100DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, s420 ? 8 : 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch ); + if (s420) { + radeon_out32( mmio, PP_TEX_SIZE_0, ((rdev->src_height-1) << 16) | + ((rdev->src_width-1) & 0xffff) ); + radeon_out32( mmio, PP_TEX_PITCH_0, rdev->src_pitch - 32 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset ); + } + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2 << 16) | + (clip->x2 & 0xffff) ); + radeon_out32( mmio, PP_TFACTOR_0, rdev->y_cop ); + } + + return true; +} + +void r100EmitCommands3D( void *drv, void *dev ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->vb_count) + r100_flush_vb( rdrv, rdev ); +} diff --git a/Source/DirectFB/gfxdrivers/radeon/r100_state.c b/Source/DirectFB/gfxdrivers/radeon/r100_state.c new file mode 100755 index 0000000..8985733 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r100_state.c @@ -0,0 +1,954 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <directfb.h> + +#include <direct/messages.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/state.h> +#include <core/gfxcard.h> +#include <core/surface.h> + +#include <gfx/convert.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_state.h" + + +static const u32 r100SrcBlend[] = { + SRC_BLEND_GL_ZERO, // DSBF_ZERO + SRC_BLEND_GL_ONE, // DSBF_ONE + SRC_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR + SRC_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR + SRC_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA + SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA + SRC_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA + SRC_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA + SRC_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR + SRC_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR + SRC_BLEND_GL_SRC_ALPHA_SATURATE // DSBF_SRCALPHASAT +}; + +static const u32 r100DstBlend[] = { + DST_BLEND_GL_ZERO, // DSBF_ZERO + DST_BLEND_GL_ONE, // DSBF_ONE + DST_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR + DST_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR + DST_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA + DST_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA + DST_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA + DST_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA + DST_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR + DST_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR + DST_BLEND_GL_ZERO // DSBF_SRCALPHASAT +}; + + +void r100_restore( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 8 ); + /* enable caches */ + radeon_out32( mmio, RB2D_DSTCACHE_MODE, RB2D_DC_2D_CACHE_AUTOFLUSH | + RB2D_DC_3D_CACHE_AUTOFLUSH ); + radeon_out32( mmio, RB3D_DSTCACHE_MODE, RB3D_DC_2D_CACHE_AUTOFLUSH | + RB3D_DC_3D_CACHE_AUTOFLUSH ); + /* restore 3d engine state */ + radeon_out32( mmio, SE_COORD_FMT, VTX_XY_PRE_MULT_1_OVER_W0 | + TEX1_W_ROUTING_USE_W0 ); + radeon_out32( mmio, SE_LINE_WIDTH, 0x10 ); +#ifdef WORDS_BIGENDIAN + radeon_out32( mmio, SE_CNTL_STATUS, TCL_BYPASS | VC_32BIT_SWAP ); +#else + radeon_out32( mmio, SE_CNTL_STATUS, TCL_BYPASS ); +#endif + radeon_out32( mmio, PP_MISC, ALPHA_TEST_PASS ); + radeon_out32( mmio, RB3D_ZSTENCILCNTL, Z_TEST_ALWAYS ); + radeon_out32( mmio, RB3D_ROPCNTL, ROP_XOR ); +} + +void r100_set_destination( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->destination; + CoreSurfaceBuffer *buffer = state->dst.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 offset; + u32 pitch; + + if (RADEON_IS_SET( DESTINATION )) + return; + + D_ASSERT( (state->dst.offset % 32) == 0 ); + D_ASSERT( (state->dst.pitch % 32) == 0 ); + + offset = radeon_buffer_offset( rdev, &state->dst ); + pitch = state->dst.pitch; + + if (rdev->dst_offset != offset || + rdev->dst_pitch != pitch || + rdev->dst_format != buffer->format) + { + bool dst_422 = false; + + switch (buffer->format) { + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_A8: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB8; + break; + case DSPF_RGB332: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB332 | DITHER_ENABLE; + break; + case DSPF_ARGB2554: + rdev->gui_master_cntl = GMC_DST_16BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB565; + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + rdev->gui_master_cntl = GMC_DST_16BPP; + rdev->rb3d_cntl = COLOR_FORMAT_ARGB4444 | DITHER_ENABLE; + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + rdev->gui_master_cntl = GMC_DST_15BPP; + rdev->rb3d_cntl = COLOR_FORMAT_ARGB1555 | DITHER_ENABLE; + break; + case DSPF_RGB16: + rdev->gui_master_cntl = GMC_DST_16BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB565 | DITHER_ENABLE; + break; + case DSPF_RGB32: + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + rdev->gui_master_cntl = GMC_DST_32BPP; + rdev->rb3d_cntl = COLOR_FORMAT_ARGB8888; + break; + case DSPF_UYVY: + rdev->gui_master_cntl = GMC_DST_YVYU; + rdev->rb3d_cntl = COLOR_FORMAT_YUV422_YVYU; + dst_422 = true; + break; + case DSPF_YUY2: + rdev->gui_master_cntl = GMC_DST_VYUY; + rdev->rb3d_cntl = COLOR_FORMAT_YUV422_VYUY; + dst_422 = true; + break; + case DSPF_I420: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB8; + rdev->dst_offset_cb = offset + pitch * surface->config.size.h; + rdev->dst_offset_cr = rdev->dst_offset_cb + + pitch/2 * surface->config.size.h/2; + break; + case DSPF_YV12: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB8; + rdev->dst_offset_cr = offset + pitch * surface->config.size.h; + rdev->dst_offset_cb = rdev->dst_offset_cr + + pitch/2 * surface->config.size.h/2; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + rdev->gui_master_cntl |= GMC_DP_SRC_SOURCE_MEMORY | + GMC_WR_MSK_DIS | + GMC_SRC_PITCH_OFFSET_CNTL | + GMC_DST_PITCH_OFFSET_CNTL | + GMC_DST_CLIPPING; + + radeon_waitfifo( rdrv, rdev, 4 ); + radeon_out32( mmio, DST_OFFSET, offset ); + radeon_out32( mmio, DST_PITCH, pitch ); + radeon_out32( mmio, RB3D_COLOROFFSET, offset ); + radeon_out32( mmio, RB3D_COLORPITCH, + pitch / DFB_BYTES_PER_PIXEL(buffer->format) ); + + if (rdev->dst_format != buffer->format) { + if (dst_422 && !rdev->dst_422) { + RADEON_UNSET( SOURCE ); + RADEON_UNSET( CLIP ); + } + + RADEON_UNSET( COLOR ); + RADEON_UNSET( DST_BLEND ); + } + + rdev->dst_format = buffer->format; + rdev->dst_offset = offset; + rdev->dst_pitch = pitch; + rdev->dst_422 = dst_422; + } + + RADEON_SET( DESTINATION ); +} + +void r100_set_source( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->source; + CoreSurfaceBuffer *buffer = state->src.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 txformat = TXFORMAT_NON_POWER2; + u32 txfilter = MAG_FILTER_LINEAR | + MIN_FILTER_LINEAR | + CLAMP_S_CLAMP_LAST | + CLAMP_T_CLAMP_LAST; + + if (RADEON_IS_SET( SOURCE )) { + if ((state->blittingflags & DSBLIT_DEINTERLACE) == + (rdev->blittingflags & DSBLIT_DEINTERLACE)) + return; + } + + D_ASSERT( (state->src.offset % 32) == 0 ); + D_ASSERT( (state->src.pitch % 32) == 0 ); + + rdev->src_offset = radeon_buffer_offset( rdev, &state->src ); + rdev->src_pitch = state->src.pitch; + rdev->src_width = surface->config.size.w; + rdev->src_height = surface->config.size.h; + + switch (buffer->format) { + case DSPF_LUT8: + txformat |= TXFORMAT_I8; + txfilter &= ~(MAG_FILTER_LINEAR | + MIN_FILTER_LINEAR); + rdev->src_mask = 0x000000ff; + break; + case DSPF_ALUT44: + txformat |= TXFORMAT_I8; + txfilter &= ~(MAG_FILTER_LINEAR | + MIN_FILTER_LINEAR); + rdev->src_mask = 0x0000000f; + break; + case DSPF_A8: + txformat |= TXFORMAT_I8 | + TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0; + break; + case DSPF_RGB332: + txformat |= TXFORMAT_RGB332; + rdev->src_mask = 0x000000ff; + break; + case DSPF_ARGB2554: + txformat |= TXFORMAT_RGB565; + txfilter &= ~(MAG_FILTER_LINEAR | + MIN_FILTER_LINEAR); + rdev->src_mask = 0x00003fff; + break; + case DSPF_RGB444: + txformat |= TXFORMAT_ARGB4444; + rdev->src_mask = 0x00000fff; + break; + case DSPF_ARGB4444: + txformat |= TXFORMAT_ARGB4444 | + TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0x00000fff; + break; + case DSPF_RGB555: + txformat |= TXFORMAT_ARGB1555; + rdev->src_mask = 0x00007fff; + break; + case DSPF_ARGB1555: + txformat |= TXFORMAT_ARGB1555 | + TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0x00007fff; + break; + case DSPF_RGB16: + txformat |= TXFORMAT_RGB565; + rdev->src_mask = 0x0000ffff; + break; + case DSPF_RGB32: + txformat |= TXFORMAT_ARGB8888; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + txformat |= TXFORMAT_ARGB8888 | + TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_UYVY: + txformat |= TXFORMAT_YVYU422; + if (!rdev->dst_422) + txfilter |= YUV_TO_RGB; + rdev->src_mask = 0xffffffff; + break; + case DSPF_YUY2: + txformat |= TXFORMAT_VYUY422; + if (!rdev->dst_422) + txfilter |= YUV_TO_RGB; + rdev->src_mask = 0xffffffff; + break; + case DSPF_I420: + txformat |= TXFORMAT_I8; + rdev->src_offset_cb = rdev->src_offset + + rdev->src_pitch * rdev->src_height; + rdev->src_offset_cr = rdev->src_offset_cb + + rdev->src_pitch/2 * rdev->src_height/2; + rdev->src_mask = 0x000000ff; + break; + case DSPF_YV12: + txformat |= TXFORMAT_I8; + rdev->src_offset_cr = rdev->src_offset + + rdev->src_pitch * rdev->src_height; + rdev->src_offset_cb = rdev->src_offset_cr + + rdev->src_pitch/2 * rdev->src_height/2; + rdev->src_mask = 0x000000ff; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + rdev->src_height /= 2; + if (surface->config.caps & DSCAPS_SEPARATED) { + if (surface->field) { + rdev->src_offset += rdev->src_height * rdev->src_pitch; + rdev->src_offset_cr += rdev->src_height * rdev->src_pitch/4; + rdev->src_offset_cb += rdev->src_height * rdev->src_pitch/4; + } + } else { + if (surface->field) { + rdev->src_offset += rdev->src_pitch; + rdev->src_offset_cr += rdev->src_pitch/2; + rdev->src_offset_cb += rdev->src_pitch/2; + } + rdev->src_pitch *= 2; + } + } + + radeon_waitfifo( rdrv, rdev, 7 ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch ); + radeon_out32( mmio, PP_TXFILTER_0, txfilter ); + radeon_out32( mmio, PP_TXFORMAT_0, txformat ); + radeon_out32( mmio, PP_TEX_SIZE_0, ((rdev->src_height-1) << 16) | + ((rdev->src_width-1) & 0xffff) ); + radeon_out32( mmio, PP_TEX_PITCH_0, rdev->src_pitch - 32 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset ); + + if (rdev->src_format != buffer->format) + RADEON_UNSET( BLITTING_FLAGS ); + rdev->src_format = buffer->format; + + RADEON_SET( SOURCE ); +} + +void r100_set_source_mask( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->source_mask; + CoreSurfaceBuffer *buffer = state->src_mask.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 txformat = TXFORMAT_NON_POWER2; + u32 txfilter = MAG_FILTER_LINEAR | + MIN_FILTER_LINEAR | + CLAMP_S_CLAMP_LAST | + CLAMP_T_CLAMP_LAST; + + if (RADEON_IS_SET( SOURCE_MASK )) { + if ((state->blittingflags & DSBLIT_DEINTERLACE) == + (rdev->blittingflags & DSBLIT_DEINTERLACE)) + return; + } + + D_ASSERT( (state->src_mask.offset % 32) == 0 ); + D_ASSERT( (state->src_mask.pitch % 32) == 0 ); + + rdev->msk_format = buffer->format; + rdev->msk_offset = radeon_buffer_offset( rdev, &state->src_mask ); + rdev->msk_pitch = state->src_mask.pitch; + rdev->msk_width = surface->config.size.w; + rdev->msk_height = surface->config.size.h; + + switch (buffer->format) { + case DSPF_A8: + txformat |= TXFORMAT_I8 | + TXFORMAT_ALPHA_IN_MAP; + break; + case DSPF_RGB332: + txformat |= TXFORMAT_RGB332; + break; + case DSPF_RGB444: + txformat |= TXFORMAT_ARGB4444; + break; + case DSPF_ARGB4444: + txformat |= TXFORMAT_ARGB4444 | + TXFORMAT_ALPHA_IN_MAP; + break; + case DSPF_RGB555: + txformat |= TXFORMAT_ARGB1555; + break; + case DSPF_ARGB1555: + txformat |= TXFORMAT_ARGB1555 | + TXFORMAT_ALPHA_IN_MAP; + break; + case DSPF_RGB16: + txformat |= TXFORMAT_RGB565; + break; + case DSPF_RGB32: + txformat |= TXFORMAT_ARGB8888; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + txformat |= TXFORMAT_ARGB8888 | + TXFORMAT_ALPHA_IN_MAP; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + rdev->msk_height /= 2; + if (surface->config.caps & DSCAPS_SEPARATED) { + if (surface->field) + rdev->msk_offset += rdev->msk_height * rdev->msk_pitch; + } else { + if (surface->field) + rdev->msk_offset += rdev->msk_pitch; + rdev->msk_pitch *= 2; + } + } + + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, PP_TXFILTER_1, txfilter ); + radeon_out32( mmio, PP_TXFORMAT_1, txformat ); + radeon_out32( mmio, PP_TEX_SIZE_1, ((rdev->msk_height-1) << 16) | + ((rdev->msk_width-1) & 0xffff) ); + radeon_out32( mmio, PP_TEX_PITCH_1, rdev->msk_pitch - 32 ); + radeon_out32( mmio, PP_TXOFFSET_1, rdev->msk_offset ); + + RADEON_SET( SOURCE_MASK ); +} + +void r100_set_clip( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBRegion *clip = &state->clip; + volatile u8 *mmio = rdrv->mmio_base; + + if (RADEON_IS_SET( CLIP )) + return; + + /* 2d clip */ + radeon_waitfifo( rdrv, rdev, 2 ); + if (rdev->dst_422) { + radeon_out32( mmio, SC_TOP_LEFT, + (clip->y1 << 16) | (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, + ((clip->y2+1) << 16) | ((clip->x2+1)/2 & 0xffff) ); + } else { + radeon_out32( mmio, SC_TOP_LEFT, + (clip->y1 << 16) | (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, + ((clip->y2+1) << 16) | ((clip->x2+1) & 0xffff) ); + } + + /* 3d clip */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, RE_TOP_LEFT, + (clip->y1 << 16) | (clip->x1 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, + (clip->y2 << 16) | (clip->x2 & 0xffff) ); + + rdev->clip = state->clip; + + RADEON_SET( CLIP ); +} + +#define R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v ) { \ + radeon_out32( (rdrv)->fb_base, (rdev)->yuv422_buffer, \ + PIXEL_YUY2( y, u, v ) ); \ + radeon_in8( (rdrv)->fb_base, (rdev)->yuv422_buffer ); \ + radeon_waitfifo( rdrv, rdev, 3 ); \ + radeon_out32( (rdrv)->mmio_base, PP_TXFILTER_1, 0 ); \ + radeon_out32( (rdrv)->mmio_base, PP_TXFORMAT_1, TXFORMAT_VYUY422 ); \ + radeon_out32( (rdrv)->mmio_base, PP_TXOFFSET_1, \ + (rdev)->fb_offset + (rdev)->yuv422_buffer ); \ +} + +void r100_set_drawing_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + int index = state->color_index; + u32 color2d; + u32 color3d; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) { + color.r = color.r * color.a / 255; + color.g = color.g * color.a / 255; + color.b = color.b * color.a / 255; + } + + color3d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + + switch (rdev->dst_format) { + case DSPF_ALUT44: + index |= (color.a & 0xf0); + case DSPF_LUT8: + color2d = index; + color3d = PIXEL_RGB32( index, index, index ); + break; + case DSPF_A8: + color2d = color.a; + color3d = (color.a << 24) | 0x00ffffff; + break; + case DSPF_RGB332: + color2d = PIXEL_RGB332( color.r, color.g, color.b ); + break; + case DSPF_ARGB2554: + color2d = PIXEL_ARGB2554( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + color2d = PIXEL_ARGB4444( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + color2d = PIXEL_ARGB1555( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB16: + color2d = PIXEL_RGB16( color.r, color.g, color.b ); + break; + case DSPF_RGB32: + color2d = PIXEL_RGB32( color.r, color.g, color.b ); + break; + case DSPF_ARGB: + color2d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + break; + case DSPF_AiRGB: + color2d = PIXEL_AiRGB( color.a, color.r, + color.g, color.b ); + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color3d = color2d = PIXEL_AYUV( color.a, y, u, v ); + break; + case DSPF_UYVY: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_UYVY( y, u, v ); + R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + break; + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_YUY2( y, u, v ); + R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + break; + case DSPF_I420: + case DSPF_YV12: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + rdev->y_cop = PIXEL_ARGB( color.a, y, y, y ); + rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u ); + rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v ); + color3d = color2d = rdev->y_cop; + break; + default: + D_BUG( "unexpected pixelformat" ); + color2d = 0; + break; + } + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( rdrv->mmio_base, DP_BRUSH_FRGD_CLR, color2d ); + radeon_out32( rdrv->mmio_base, PP_TFACTOR_1, color3d ); + + RADEON_SET( COLOR ); +} + +void r100_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + u32 color3d; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( BLITTING_FLAGS )) + return; + + if (state->blittingflags & DSBLIT_COLORIZE && + state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { + color.r = ((long) color.r * color.a / 255L); + color.g = ((long) color.g * color.a / 255L); + color.b = ((long) color.b * color.a / 255L); + } + + switch (rdev->dst_format) { + case DSPF_A8: + color3d = (color.a << 24) | 0x00ffffff; + break; + case DSPF_I420: + case DSPF_YV12: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + rdev->y_cop = PIXEL_ARGB( color.a, y, y, y ); + rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u ); + rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v ); + color3d = rdev->y_cop; + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color3d = PIXEL_AYUV( color.a, y, u, v ); + break; + case DSPF_UYVY: + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + default: + color3d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + break; + } + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, PP_TFACTOR_0, color3d ); + + RADEON_SET( COLOR ); +} + +void r100_set_src_colorkey( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + if (RADEON_IS_SET( SRC_COLORKEY )) + return; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, CLR_CMP_CLR_SRC, state->src_colorkey ); + radeon_out32( mmio, CLR_CMP_MASK, rdev->src_mask ); + + RADEON_SET( SRC_COLORKEY ); +} + +void r100_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 sblend; + u32 dblend; + + if (RADEON_IS_SET( SRC_BLEND ) && RADEON_IS_SET( DST_BLEND )) + return; + + sblend = r100SrcBlend[state->src_blend-1]; + dblend = r100DstBlend[state->dst_blend-1]; + + if (!DFB_PIXELFORMAT_HAS_ALPHA(rdev->dst_format)) { + if (sblend == SRC_BLEND_GL_DST_ALPHA) + sblend = SRC_BLEND_GL_ONE; + else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA) + sblend = SRC_BLEND_GL_ZERO; + + if (dblend == DST_BLEND_GL_DST_ALPHA) + dblend = DST_BLEND_GL_ONE; + else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA) + dblend = DST_BLEND_GL_ZERO; + } + else if (rdev->dst_format == DSPF_A8) { + if (sblend == SRC_BLEND_GL_DST_ALPHA) + sblend = SRC_BLEND_GL_DST_COLOR; + else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA) + sblend = SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + + if (dblend == DST_BLEND_GL_DST_ALPHA) + dblend = DST_BLEND_GL_DST_COLOR; + else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA) + dblend = DST_BLEND_GL_ONE_MINUS_DST_COLOR; + } + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, RB3D_BLENDCNTL, sblend | dblend ); + + RADEON_SET( SRC_BLEND ); + RADEON_SET( DST_BLEND ); +} + +void r100_set_render_options( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + if (RADEON_IS_SET( RENDER_OPTIONS )) + return; + + if (state->render_options & DSRO_MATRIX && + (!state->affine_matrix || + state->matrix[0] != (1<<16) || state->matrix[1] != 0 || state->matrix[2] != 0 || + state->matrix[3] != 0 || state->matrix[4] != (1<<16) || state->matrix[5] != 0)) { + rdev->matrix = state->matrix; + rdev->affine_matrix = state->affine_matrix; + } + else { + rdev->matrix = NULL; + } + + if ((rdev->render_options & DSRO_ANTIALIAS) != (state->render_options & DSRO_ANTIALIAS)) { + RADEON_UNSET( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); + } + rdev->render_options = state->render_options; + + RADEON_SET( RENDER_OPTIONS ); +} + +/* NOTES: + * - We use texture unit 0 for blitting functions, + * texture unit 1 for drawing functions + * - Default blend equation is ADD_CLAMP (A * B + C) + */ + +void r100_set_drawingflags( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 master_cntl = rdev->gui_master_cntl | + GMC_SRC_DATATYPE_MONO_FG_LA | + GMC_BRUSH_SOLID_COLOR | + GMC_CLR_CMP_CNTL_DIS; + u32 rb3d_cntl = rdev->rb3d_cntl & ~DITHER_ENABLE; + u32 pp_cntl = SCISSOR_ENABLE | TEX_BLEND_1_ENABLE; + u32 cblend = COLOR_ARG_C_TFACTOR_COLOR; + + if (RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (rdev->dst_422) { + pp_cntl |= TEX_1_ENABLE; + cblend = COLOR_ARG_C_T1_COLOR; + } + else if (rdev->dst_format == DSPF_A8) { + cblend = COLOR_ARG_C_TFACTOR_ALPHA; + } + + if (state->drawingflags & DSDRAW_BLEND) + rb3d_cntl |= ALPHA_BLEND_ENABLE; + + if (state->drawingflags & DSDRAW_XOR) { + rb3d_cntl |= ROP_ENABLE; + master_cntl |= GMC_ROP3_PATXOR; + } + else { + master_cntl |= GMC_ROP3_PATCOPY; + } + + if (state->render_options & DSRO_ANTIALIAS) + pp_cntl |= ANTI_ALIAS_LINE_POLY; + + radeon_waitfifo( rdrv, rdev, 8 ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + radeon_out32( mmio, DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM ); + radeon_out32( mmio, RB3D_CNTL, rb3d_cntl ); + radeon_out32( mmio, SE_CNTL, DIFFUSE_SHADE_FLAT | + ALPHA_SHADE_FLAT | + BFACE_SOLID | + FFACE_SOLID | + VTX_PIX_CENTER_OGL | + ROUND_MODE_ROUND | + ROUND_PREC_4TH_PIX ); + radeon_out32( mmio, PP_CNTL, pp_cntl ); + radeon_out32( mmio, PP_TXCBLEND_1, cblend ); + radeon_out32( mmio, PP_TXABLEND_1, ALPHA_ARG_C_TFACTOR_ALPHA ); + radeon_out32( mmio, SE_VTX_FMT, SE_VTX_FMT_XY ); + + rdev->drawingflags = state->drawingflags; + + RADEON_SET ( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); +} + +void r100_set_blittingflags( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 master_cntl = rdev->gui_master_cntl | + GMC_BRUSH_NONE | + GMC_SRC_DATATYPE_COLOR; + u32 cmp_cntl = 0; + u32 rb3d_cntl = rdev->rb3d_cntl; + u32 se_cntl = BFACE_SOLID | + FFACE_SOLID | + VTX_PIX_CENTER_OGL | + ROUND_MODE_ROUND; + u32 pp_cntl = SCISSOR_ENABLE | + TEX_0_ENABLE | + TEX_BLEND_0_ENABLE; + u32 cblend = COLOR_ARG_C_T0_COLOR; + u32 ablend = ALPHA_ARG_C_T0_ALPHA; + u32 vtx_fmt = SE_VTX_FMT_XY | SE_VTX_FMT_ST0; + u32 coord_fmt = VTX_XY_PRE_MULT_1_OVER_W0 | + TEX1_W_ROUTING_USE_W0; + + if (RADEON_IS_SET( BLITTING_FLAGS )) + return; + + if (rdev->accel == DFXL_TEXTRIANGLES) { + se_cntl |= DIFFUSE_SHADE_GOURAUD | + ALPHA_SHADE_GOURAUD | + SPECULAR_SHADE_GOURAUD | + FLAT_SHADE_VTX_LAST | + ROUND_PREC_8TH_PIX; + vtx_fmt |= SE_VTX_FMT_W0 | SE_VTX_FMT_Z; + } + else { + se_cntl |= DIFFUSE_SHADE_FLAT | + ALPHA_SHADE_FLAT | + ROUND_PREC_4TH_PIX; + coord_fmt |= VTX_ST0_NONPARAMETRIC | + VTX_ST1_NONPARAMETRIC; + } + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_BLEND_ALPHACHANNEL)) { + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + ablend = ALPHA_ARG_A_T0_ALPHA | ALPHA_ARG_B_TFACTOR_ALPHA; + else + ablend = ALPHA_ARG_C_TFACTOR_ALPHA; + } + + rb3d_cntl |= ALPHA_BLEND_ENABLE; + } + + if (rdev->dst_format != DSPF_A8) { + if (state->blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR)) { + if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) + ablend = ALPHA_ARG_A_T0_ALPHA | ALPHA_ARG_B_T1_ALPHA; + + if (state->blittingflags & DSBLIT_SRC_MASK_COLOR) + cblend = COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_T1_COLOR; + + pp_cntl |= TEX_1_ENABLE; + } + else if (state->blittingflags & DSBLIT_COLORIZE) { + if (rdev->dst_422) { + cblend = (rdev->src_format == DSPF_A8) + ? (COLOR_ARG_C_T1_COLOR) + : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_T1_COLOR); + + pp_cntl |= TEX_1_ENABLE; + } + else { + cblend = (rdev->src_format == DSPF_A8) + ? (COLOR_ARG_C_TFACTOR_COLOR) + : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_TFACTOR_COLOR); + } + } + else if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { + cblend = (rdev->src_format == DSPF_A8) + ? (COLOR_ARG_C_T0_ALPHA) + : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_TFACTOR_ALPHA); + } + else if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + cblend = (rdev->src_format == DSPF_A8) + ? (COLOR_ARG_C_T0_ALPHA) + : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_T0_ALPHA); + } + } /* DSPF_A8 */ + else { + if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) { + ablend = ALPHA_ARG_A_T0_ALPHA | ALPHA_ARG_B_T1_ALPHA; + cblend = COLOR_ARG_A_T0_ALPHA | COLOR_ARG_B_T1_ALPHA; + pp_cntl |= TEX_1_ENABLE; + } + else if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + cblend = COLOR_ARG_A_T0_ALPHA | COLOR_ARG_B_TFACTOR_ALPHA; + else + cblend = COLOR_ARG_C_TFACTOR_ALPHA; + } + else { + cblend = COLOR_ARG_C_T0_ALPHA; + } + } + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + cmp_cntl = SRC_CMP_EQ_COLOR | CLR_CMP_SRC_SOURCE; + else + master_cntl |= GMC_CLR_CMP_CNTL_DIS; + + if (state->blittingflags & DSBLIT_XOR) { + master_cntl |= GMC_ROP3_XOR; + rb3d_cntl |= ROP_ENABLE; + } + else { + master_cntl |= GMC_ROP3_SRCCOPY; + } + + if (state->render_options & DSRO_ANTIALIAS) + pp_cntl |= ANTI_ALIAS_POLY; + + radeon_waitfifo( rdrv, rdev, 9 ); + radeon_out32( mmio, CLR_CMP_CNTL, cmp_cntl ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + radeon_out32( mmio, RB3D_CNTL, rb3d_cntl ); + radeon_out32( mmio, SE_CNTL, se_cntl ); + radeon_out32( mmio, PP_CNTL, pp_cntl ); + radeon_out32( mmio, PP_TXCBLEND_0, cblend ); + radeon_out32( mmio, PP_TXABLEND_0, ablend ); + radeon_out32( mmio, SE_VTX_FMT, vtx_fmt ); + radeon_out32( mmio, SE_COORD_FMT, coord_fmt ); + + rdev->blittingflags = state->blittingflags; + + RADEON_SET ( BLITTING_FLAGS ); + RADEON_UNSET( DRAWING_FLAGS ); +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/r200_3d.c b/Source/DirectFB/gfxdrivers/radeon/r200_3d.c new file mode 100755 index 0000000..2521c68 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r200_3d.c @@ -0,0 +1,508 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <dfb_types.h> +#include <directfb.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/state.h> +#include <core/gfxcard.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_3d.h" + + +#define EMIT_VERTICES( rdrv, rdev, mmio ) { \ + u32 *_v = (rdev)->vb; \ + u32 _s = (rdev)->vb_size; \ + radeon_waitfifo( rdrv, rdev, 1 ); \ + radeon_out32( mmio, SE_VF_CNTL, rdev->vb_type | VF_PRIM_WALK_DATA | \ + (rdev->vb_count << VF_NUM_VERTICES_SHIFT) ); \ + do { \ + u32 _n = MIN(_s, 64); \ + _s -= _n; \ + radeon_waitfifo( rdrv, rdev, _n ); \ + while (_n--) \ + radeon_out32( mmio, SE_PORT_DATA0, *_v++ ); \ + } while (_s); \ +} + +static void +r200_flush_vb( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + EMIT_VERTICES( rdrv, rdev, mmio ); + + if (DFB_PLANAR_PIXELFORMAT(rdev->dst_format)) { + DFBRegion *clip = &rdev->clip; + bool s420 = DFB_PLANAR_PIXELFORMAT(rdev->src_format); + int i; + + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + for (i = 0; i < rdev->vb_size; i += 4) { + rdev->vb[i+0] = f2d(d2f(rdev->vb[i+0])*0.5f); + rdev->vb[i+1] = f2d(d2f(rdev->vb[i+1])*0.5f); + if (s420) { + rdev->vb[i+2] = f2d(d2f(rdev->vb[i+2])*0.5f); + rdev->vb[i+3] = f2d(d2f(rdev->vb[i+3])*0.5f); + } + } + } else { + for (i = 0; i < rdev->vb_size; i += 2) { + rdev->vb[i+0] = f2d(d2f(rdev->vb[i+0])*0.5f); + rdev->vb[i+1] = f2d(d2f(rdev->vb[i+1])*0.5f); + } + } + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2/2 << 16) | + (clip->x2/2 & 0xffff) ); + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + radeon_out32( mmio, R200_PP_TFACTOR_0, rdev->cb_cop ); + if (s420) { + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, R200_PP_TXSIZE_0, ((rdev->src_height/2-1) << 16) | + ((rdev->src_width/2-1) & 0xffff) ); + radeon_out32( mmio, R200_PP_TXPITCH_0, rdev->src_pitch/2 - 32 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset_cb ); + } + } else { + radeon_out32( mmio, R200_PP_TFACTOR_1, rdev->cb_cop ); + } + + /* Fill Cb plane */ + EMIT_VERTICES( rdrv, rdev, mmio ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cr ); + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + radeon_out32( mmio, R200_PP_TFACTOR_0, rdev->cr_cop ); + if (s420) { + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset_cr ); + } + } else { + radeon_out32( mmio, R200_PP_TFACTOR_1, rdev->cr_cop ); + } + + /* Fill Cr plane */ + EMIT_VERTICES( rdrv, rdev, mmio ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch ); + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2 << 16) | + (clip->x2 & 0xffff) ); + if (DFB_BLITTING_FUNCTION(rdev->accel)) { + radeon_out32( mmio, R200_PP_TFACTOR_0, rdev->y_cop ); + if (s420) { + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, R200_PP_TXSIZE_0, ((rdev->src_height-1) << 16) | + ((rdev->src_width-1) & 0xffff) ); + radeon_out32( mmio, R200_PP_TXPITCH_0, rdev->src_pitch - 32 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset ); + } + } else { + radeon_out32( mmio, R200_PP_TFACTOR_1, rdev->y_cop ); + } + } + + rdev->vb_size = 0; + rdev->vb_count = 0; +} + +static inline u32* +r200_init_vb( RadeonDriverData *rdrv, RadeonDeviceData *rdev, u32 type, u32 count, u32 size ) +{ + u32 *vb; + + if ((rdev->vb_size && rdev->vb_type != type) || + rdev->vb_size+size > D_ARRAY_SIZE(rdev->vb)) + r200_flush_vb( rdrv, rdev ); + + vb = &rdev->vb[rdev->vb_size]; + rdev->vb_type = type; + rdev->vb_size += size; + rdev->vb_count += count; + + return vb; +} + + +bool r200FillRectangle3D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + if (rect->w == 1 && rect->h == 1) { + x1 = rect->x+1; y1 = rect->y+1; + if (rdev->matrix) + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_POINT_LIST, 1, 2 ); + *v++ = f2d(x1); *v++ = f2d(y1); + + return true; + } + + x1 = rect->x; y1 = rect->y; + x2 = rect->x+rect->w; y2 = rect->y+rect->h; + if (rdev->matrix) { + float x, y; + + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_QUAD_LIST, 4, 8 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + } + else { + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_RECTANGLE_LIST, 3, 6 ); + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y2); + } + + return true; +} + +bool r200FillTriangle( void *drv, void *dev, DFBTriangle *tri ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + float x3, y3; + u32 *v; + + x1 = tri->x1; y1 = tri->y1; + x2 = tri->x2; y2 = tri->y2; + x3 = tri->x3; y3 = tri->y3; + if (rdev->matrix) { + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, x2, y2, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x3, y3, x3, y3, rdev->matrix, rdev->affine_matrix ); + } + + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_TRIANGLE_LIST, 3, 6 ); + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y2); + *v++ = f2d(x3); *v++ = f2d(y3); + + return true; +} + +bool r200DrawRectangle3D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + x1 = rect->x; y1 = rect->y; + x2 = rect->x+rect->w; y2 = rect->y+rect->h; + if (rdev->matrix) { + float x, y; + + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LOOP, 4, 8 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); + } + else { + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_RECTANGLE_LIST, 12, 24 ); + /* top line */ + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y1+1); + /* right line */ + *v++ = f2d(x2-1); *v++ = f2d(y1+1); + *v++ = f2d(x2); *v++ = f2d(y1+1); + *v++ = f2d(x2); *v++ = f2d(y2-1); + /* bottom line */ + *v++ = f2d(x1); *v++ = f2d(y2-1); + *v++ = f2d(x2); *v++ = f2d(y2-1); + *v++ = f2d(x2); *v++ = f2d(y2); + /* left line */ + *v++ = f2d(x1); *v++ = f2d(y1+1); + *v++ = f2d(x1+1); *v++ = f2d(y1+1); + *v++ = f2d(x1+1); *v++ = f2d(y2-1); + } + + return true; +} + +bool r200DrawLine3D( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + x1 = line->x1; y1 = line->y1; + x2 = line->x2; y2 = line->y2; + if (rdev->matrix) { + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, x2, y2, rdev->matrix, rdev->affine_matrix ); + } + + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LIST, 2, 4 ); + *v++ = f2d(x1); *v++ = f2d(y1); + *v++ = f2d(x2); *v++ = f2d(y2); + + return true; +} + +bool r200Blit3D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + DFBRectangle dr = { dx, dy, sr->w, sr->h }; + + return r200StretchBlit( drv, dev, sr, &dr ); +} + +bool r200StretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + float s1, t1; + float s2, t2; + u32 *v; + + if (rdev->blittingflags & DSBLIT_DEINTERLACE) { + sr->y /= 2; + sr->h /= 2; + } + + s1 = sr->x; t1 = sr->y; + s2 = sr->x+sr->w; t2 = sr->y+sr->h; + if (rdev->blittingflags & DSBLIT_ROTATE180) { + float tmp; + tmp = s2; s2 = s1; s1 = tmp; + tmp = t2; t2 = t1; t1 = tmp; + } + + x1 = dr->x; y1 = dr->y; + x2 = dr->x+dr->w; y2 = dr->y+dr->h; + if (rdev->matrix) { + float x, y; + + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_QUAD_LIST, 4, 16 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); *v++ = f2d(s1); *v++ = f2d(t1); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); *v++ = f2d(s2); *v++ = f2d(t1); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); *v++ = f2d(s2); *v++ = f2d(t2); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + *v++ = f2d(x); *v++ = f2d(y); *v++ = f2d(s1); *v++ = f2d(t2); + } + else { + v = r200_init_vb( rdrv, rdev, VF_PRIM_TYPE_RECTANGLE_LIST, 3, 12 ); + *v++ = f2d(x1); *v++ = f2d(y1); *v++ = f2d(s1); *v++ = f2d(t1); + *v++ = f2d(x2); *v++ = f2d(y1); *v++ = f2d(s2); *v++ = f2d(t1); + *v++ = f2d(x2); *v++ = f2d(y2); *v++ = f2d(s2); *v++ = f2d(t2); + } + + return true; +} + +static void +r200DoTextureTriangles( RadeonDriverData *rdrv, RadeonDeviceData *rdev, + DFBVertex *ve, int num, u32 primitive ) +{ + volatile u8 *mmio = rdrv->mmio_base; + int i; + + radeon_waitfifo( rdrv, rdev, 1 ); + + radeon_out32( mmio, SE_VF_CNTL, primitive | VF_PRIM_WALK_DATA | + (num << VF_NUM_VERTICES_SHIFT) ); + + for (; num >= 10; num -= 10) { + radeon_waitfifo( rdrv, rdev, 60 ); + for (i = 0; i < 10; i++) { + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].x) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].y) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].z) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].w) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].s) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].t) ); + } + ve += 10; + } + + if (num > 0) { + radeon_waitfifo( rdrv, rdev, num*6 ); + for (i = 0; i < num; i++) { + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].x) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].y) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].z) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].w) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].s) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].t) ); + } + } +} + +bool r200TextureTriangles( void *drv, void *dev, DFBVertex *ve, + int num, DFBTriangleFormation formation ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + u32 prim = 0; + int i; + + if (num > 65535) { + D_WARN( "R200 supports maximum 65535 vertices" ); + return false; + } + + switch (formation) { + case DTTF_LIST: + prim = VF_PRIM_TYPE_TRIANGLE_LIST; + break; + case DTTF_STRIP: + prim = VF_PRIM_TYPE_TRIANGLE_STRIP; + break; + case DTTF_FAN: + prim = VF_PRIM_TYPE_TRIANGLE_FAN; + break; + default: + D_BUG( "unexpected triangle formation" ); + return false; + } + + if (rdev->matrix) { + for (i = 0; i < num; i++) + RADEON_TRANSFORM( ve[i].x, ve[i].y, ve[i].x, ve[i].y, rdev->matrix, rdev->affine_matrix ); + } + + r200DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + if (DFB_PLANAR_PIXELFORMAT(rdev->dst_format)) { + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + bool s420 = DFB_PLANAR_PIXELFORMAT(rdev->src_format); + + /* Scale coordinates */ + for (i = 0; i < num; i++) { + ve[i].x *= 0.5; + ve[i].y *= 0.5; + } + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, s420 ? 8 : 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch/2 ); + if (s420) { + radeon_out32( mmio, R200_PP_TXSIZE_0, ((rdev->src_height/2-1) << 16) | + ((rdev->src_width/2-1) & 0xffff) ); + radeon_out32( mmio, R200_PP_TXPITCH_0, rdev->src_pitch/2 - 32 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset_cb ); + } + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2/2 << 16) | + (clip->x2/2 & 0xffff) ); + radeon_out32( mmio, R200_PP_TFACTOR_0, rdev->cb_cop ); + + /* Map Cb plane */ + r200DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, s420 ? 3 : 2 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset_cr ); + if (s420) + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset_cr ); + radeon_out32( mmio, R200_PP_TFACTOR_0, rdev->cr_cop ); + + /* Map Cr plane */ + r200DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, s420 ? 8 : 5 ); + radeon_out32( mmio, RB3D_COLOROFFSET, rdev->dst_offset ); + radeon_out32( mmio, RB3D_COLORPITCH, rdev->dst_pitch ); + if (s420) { + radeon_out32( mmio, R200_PP_TXSIZE_0, ((rdev->src_height-1) << 16) | + ((rdev->src_width-1) & 0xffff) ); + radeon_out32( mmio, R200_PP_TXPITCH_0, rdev->src_pitch - 32 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset ); + } + radeon_out32( mmio, RE_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, (clip->y2 << 16) | + (clip->x2 & 0xffff) ); + radeon_out32( mmio, R200_PP_TFACTOR_0, rdev->y_cop ); + } + + return true; +} + +void r200EmitCommands3D( void *drv, void *dev ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->vb_count) + r200_flush_vb( rdrv, rdev ); +} diff --git a/Source/DirectFB/gfxdrivers/radeon/r200_state.c b/Source/DirectFB/gfxdrivers/radeon/r200_state.c new file mode 100755 index 0000000..c3bf768 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r200_state.c @@ -0,0 +1,985 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <directfb.h> + +#include <direct/messages.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/state.h> +#include <core/gfxcard.h> +#include <core/surface.h> + +#include <gfx/convert.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_state.h" + + +static const u32 r200SrcBlend[] = { + SRC_BLEND_GL_ZERO, // DSBF_ZERO + SRC_BLEND_GL_ONE, // DSBF_ONE + SRC_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR + SRC_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR + SRC_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA + SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA + SRC_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA + SRC_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA + SRC_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR + SRC_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR + SRC_BLEND_GL_SRC_ALPHA_SATURATE // DSBF_SRCALPHASAT +}; + +static const u32 r200DstBlend[] = { + DST_BLEND_GL_ZERO, // DSBF_ZERO + DST_BLEND_GL_ONE, // DSBF_ONE + DST_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR + DST_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR + DST_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA + DST_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA + DST_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA + DST_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA + DST_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR + DST_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR + DST_BLEND_GL_ZERO // DSBF_SRCALPHASAT +}; + + +void r200_restore( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 15 ); + /* enable caches */ + radeon_out32( mmio, RB2D_DSTCACHE_MODE, RB2D_DC_2D_CACHE_AUTOFLUSH | + RB2D_DC_3D_CACHE_AUTOFLUSH | + R200_RB2D_DC_2D_CACHE_AUTOFREE | + R200_RB2D_DC_3D_CACHE_AUTOFREE ); + radeon_out32( mmio, RB3D_DSTCACHE_MODE, RB3D_DC_2D_CACHE_AUTOFLUSH | + RB3D_DC_3D_CACHE_AUTOFLUSH | + R200_RB3D_DC_2D_CACHE_AUTOFREE | + R200_RB3D_DC_3D_CACHE_AUTOFREE ); + /* restore 3d engine state */ + radeon_out32( mmio, SE_LINE_WIDTH, 0x10 ); + radeon_out32( mmio, RE_POINTSIZE, 0x10 ); + radeon_out32( mmio, PP_MISC, ALPHA_TEST_PASS ); + radeon_out32( mmio, R200_PP_CNTL_X, 0 ); + radeon_out32( mmio, R200_PP_TXMULTI_CTL_0, 0 ); + radeon_out32( mmio, R200_RE_CNTL, R200_SCISSOR_ENABLE ); + radeon_out32( mmio, R200_SE_VTX_STATE_CNTL, 0 ); + radeon_out32( mmio, R200_SE_VAP_CNTL, R200_VAP_VF_MAX_VTX_NUM | + R200_VAP_FORCE_W_TO_ONE ); +#ifdef WORDS_BIGENDIAN + radeon_out32( mmio, R200_SE_VAP_CNTL_STATUS, R200_TCL_BYPASS | R200_VC_32BIT_SWAP ); +#else + radeon_out32( mmio, R200_SE_VAP_CNTL_STATUS, R200_TCL_BYPASS ); +#endif + radeon_out32( mmio, RB3D_ZSTENCILCNTL, Z_TEST_ALWAYS ); + radeon_out32( mmio, RB3D_ROPCNTL, ROP_XOR ); + radeon_out32( mmio, R200_PP_TXFORMAT_X_0, 0 ); + radeon_out32( mmio, R200_PP_TXFORMAT_X_1, 0 ); +} + +void r200_set_destination( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->destination; + CoreSurfaceBuffer *buffer = state->dst.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 offset; + u32 pitch; + + if (RADEON_IS_SET( DESTINATION )) + return; + + D_ASSERT( (state->dst.offset % 32) == 0 ); + D_ASSERT( (state->dst.pitch % 32) == 0 ); + + offset = radeon_buffer_offset( rdev, &state->dst ); + pitch = state->dst.pitch; + + if (rdev->dst_offset != offset || + rdev->dst_pitch != pitch || + rdev->dst_format != buffer->format) + { + bool dst_422 = false; + + switch (buffer->format) { + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_A8: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB8; + break; + case DSPF_RGB332: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB332 | DITHER_ENABLE; + break; + case DSPF_ARGB2554: + rdev->gui_master_cntl = GMC_DST_16BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB565; + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + rdev->gui_master_cntl = GMC_DST_16BPP; + rdev->rb3d_cntl = COLOR_FORMAT_ARGB4444 | DITHER_ENABLE; + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + rdev->gui_master_cntl = GMC_DST_15BPP; + rdev->rb3d_cntl = COLOR_FORMAT_ARGB1555 | DITHER_ENABLE; + break; + case DSPF_RGB16: + rdev->gui_master_cntl = GMC_DST_16BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB565 | DITHER_ENABLE; + break; + case DSPF_RGB32: + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + rdev->gui_master_cntl = GMC_DST_32BPP; + rdev->rb3d_cntl = COLOR_FORMAT_ARGB8888; + break; + case DSPF_UYVY: + rdev->gui_master_cntl = GMC_DST_YVYU; + rdev->rb3d_cntl = COLOR_FORMAT_YUV422_YVYU; + dst_422 = true; + break; + case DSPF_YUY2: + rdev->gui_master_cntl = GMC_DST_VYUY; + rdev->rb3d_cntl = COLOR_FORMAT_YUV422_VYUY; + dst_422 = true; + break; + case DSPF_I420: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB8; + rdev->dst_offset_cb = offset + pitch * surface->config.size.h; + rdev->dst_offset_cr = rdev->dst_offset_cb + + pitch/2 * surface->config.size.h/2; + break; + case DSPF_YV12: + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->rb3d_cntl = COLOR_FORMAT_RGB8; + rdev->dst_offset_cr = offset + pitch * surface->config.size.h; + rdev->dst_offset_cb = rdev->dst_offset_cr + + pitch/2 * surface->config.size.h/2; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + rdev->gui_master_cntl |= GMC_DP_SRC_SOURCE_MEMORY | + GMC_WR_MSK_DIS | + GMC_SRC_PITCH_OFFSET_CNTL | + GMC_DST_PITCH_OFFSET_CNTL | + GMC_DST_CLIPPING; + + radeon_waitfifo( rdrv, rdev, 4 ); + radeon_out32( mmio, DST_OFFSET, offset ); + radeon_out32( mmio, DST_PITCH, pitch ); + radeon_out32( mmio, RB3D_COLOROFFSET, offset ); + radeon_out32( mmio, RB3D_COLORPITCH, + pitch / DFB_BYTES_PER_PIXEL(buffer->format) ); + + if (rdev->dst_format != buffer->format) { + if (dst_422 && !rdev->dst_422) { + RADEON_UNSET( SOURCE ); + RADEON_UNSET( CLIP ); + } + + RADEON_UNSET( COLOR ); + RADEON_UNSET( DST_BLEND ); + } + + rdev->dst_format = buffer->format; + rdev->dst_offset = offset; + rdev->dst_pitch = pitch; + rdev->dst_422 = dst_422; + } + + RADEON_SET( DESTINATION ); +} + +void r200_set_source( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->source; + CoreSurfaceBuffer *buffer = state->src.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 txformat = R200_TXFORMAT_NON_POWER2; + u32 txfilter = R200_MAG_FILTER_LINEAR | + R200_MIN_FILTER_LINEAR | + R200_CLAMP_S_CLAMP_LAST | + R200_CLAMP_T_CLAMP_LAST; + + if (RADEON_IS_SET( SOURCE )) { + if ((state->blittingflags & DSBLIT_DEINTERLACE) == + (rdev->blittingflags & DSBLIT_DEINTERLACE)) + return; + } + + D_ASSERT( (state->src.offset % 32) == 0 ); + D_ASSERT( (state->src.pitch % 32) == 0 ); + + rdev->src_offset = radeon_buffer_offset( rdev, &state->src ); + rdev->src_pitch = state->src.pitch; + rdev->src_width = surface->config.size.w; + rdev->src_height = surface->config.size.h; + + switch (buffer->format) { + case DSPF_LUT8: + txformat |= R200_TXFORMAT_I8; + txfilter &= ~(R200_MAG_FILTER_LINEAR | + R200_MIN_FILTER_LINEAR); + rdev->src_mask = 0x000000ff; + break; + case DSPF_ALUT44: + txformat |= R200_TXFORMAT_I8; + txfilter &= ~(R200_MAG_FILTER_LINEAR | + R200_MIN_FILTER_LINEAR); + rdev->src_mask = 0x0000000f; + break; + case DSPF_A8: + txformat |= R200_TXFORMAT_I8 | + R200_TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0; + break; + case DSPF_RGB332: + txformat |= R200_TXFORMAT_RGB332; + rdev->src_mask = 0x000000ff; + break; + case DSPF_ARGB2554: + txformat |= R200_TXFORMAT_RGB565; + txfilter &= ~(R200_MAG_FILTER_LINEAR | + R200_MIN_FILTER_LINEAR); + rdev->src_mask = 0x00003fff; + break; + case DSPF_RGB444: + txformat |= R200_TXFORMAT_ARGB4444; + rdev->src_mask = 0x00000fff; + break; + case DSPF_ARGB4444: + txformat |= R200_TXFORMAT_ARGB4444 | + R200_TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0x00000fff; + break; + case DSPF_RGB555: + txformat |= R200_TXFORMAT_ARGB1555; + rdev->src_mask = 0x00007fff; + break; + case DSPF_ARGB1555: + txformat |= R200_TXFORMAT_ARGB1555 | + R200_TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0x00007fff; + break; + case DSPF_RGB16: + txformat |= R200_TXFORMAT_RGB565; + rdev->src_mask = 0x0000ffff; + break; + case DSPF_RGB32: + txformat |= R200_TXFORMAT_ARGB8888; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + txformat |= R200_TXFORMAT_ARGB8888 | + R200_TXFORMAT_ALPHA_IN_MAP; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_UYVY: + txformat |= R200_TXFORMAT_YVYU422; + if (!rdev->dst_422) + txfilter |= R200_YUV_TO_RGB; + rdev->src_mask = 0xffffffff; + break; + case DSPF_YUY2: + txformat |= R200_TXFORMAT_VYUY422; + if (!rdev->dst_422) + txfilter |= R200_YUV_TO_RGB; + rdev->src_mask = 0xffffffff; + break; + case DSPF_I420: + txformat |= R200_TXFORMAT_I8; + rdev->src_offset_cb = rdev->src_offset + + rdev->src_pitch * rdev->src_height; + rdev->src_offset_cr = rdev->src_offset_cb + + rdev->src_pitch/2 * rdev->src_height/2; + rdev->src_mask = 0x000000ff; + break; + case DSPF_YV12: + txformat |= R200_TXFORMAT_I8; + rdev->src_offset_cr = rdev->src_offset + + rdev->src_pitch * rdev->src_height; + rdev->src_offset_cb = rdev->src_offset_cr + + rdev->src_pitch/2 * rdev->src_height/2; + rdev->src_mask = 0x000000ff; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + rdev->src_height /= 2; + if (surface->config.caps & DSCAPS_SEPARATED) { + if (surface->field) { + rdev->src_offset += rdev->src_height * rdev->src_pitch; + rdev->src_offset_cr += rdev->src_height * rdev->src_pitch/4; + rdev->src_offset_cb += rdev->src_height * rdev->src_pitch/4; + } + } else { + if (surface->field) { + rdev->src_offset += rdev->src_pitch; + rdev->src_offset_cr += rdev->src_pitch/2; + rdev->src_offset_cb += rdev->src_pitch/2; + } + rdev->src_pitch *= 2; + } + } + + radeon_waitfifo( rdrv, rdev, 7 ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch ); + radeon_out32( mmio, R200_PP_TXFILTER_0, txfilter ); + radeon_out32( mmio, R200_PP_TXFORMAT_0, txformat ); + radeon_out32( mmio, R200_PP_TXSIZE_0, ((rdev->src_height-1) << 16) | + ((rdev->src_width-1) & 0xffff) ); + radeon_out32( mmio, R200_PP_TXPITCH_0, rdev->src_pitch - 32 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset ); + + if (rdev->src_format != buffer->format) + RADEON_UNSET( BLITTING_FLAGS ); + rdev->src_format = buffer->format; + + RADEON_SET( SOURCE ); +} + +void r200_set_source_mask( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->source_mask; + CoreSurfaceBuffer *buffer = state->src_mask.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 txformat = R200_TXFORMAT_NON_POWER2; + u32 txfilter = R200_MAG_FILTER_LINEAR | + R200_MIN_FILTER_LINEAR | + R200_CLAMP_S_CLAMP_LAST | + R200_CLAMP_T_CLAMP_LAST; + + if (RADEON_IS_SET( SOURCE_MASK )) { + if ((state->blittingflags & DSBLIT_DEINTERLACE) == + (rdev->blittingflags & DSBLIT_DEINTERLACE)) + return; + } + + D_ASSERT( (state->src_mask.offset % 32) == 0 ); + D_ASSERT( (state->src_mask.pitch % 32) == 0 ); + + rdev->msk_format = buffer->format; + rdev->msk_offset = radeon_buffer_offset( rdev, &state->src_mask ); + rdev->msk_pitch = state->src_mask.pitch; + rdev->msk_width = surface->config.size.w; + rdev->msk_height = surface->config.size.h; + + switch (buffer->format) { + case DSPF_A8: + txformat |= R200_TXFORMAT_I8 | + R200_TXFORMAT_ALPHA_IN_MAP; + break; + case DSPF_RGB332: + txformat |= R200_TXFORMAT_RGB332; + break; + case DSPF_RGB444: + txformat |= R200_TXFORMAT_ARGB4444; + break; + case DSPF_ARGB4444: + txformat |= R200_TXFORMAT_ARGB4444 | + R200_TXFORMAT_ALPHA_IN_MAP; + break; + case DSPF_RGB555: + txformat |= R200_TXFORMAT_ARGB1555; + break; + case DSPF_ARGB1555: + txformat |= R200_TXFORMAT_ARGB1555 | + R200_TXFORMAT_ALPHA_IN_MAP; + break; + case DSPF_RGB16: + txformat |= R200_TXFORMAT_RGB565; + break; + case DSPF_RGB32: + txformat |= R200_TXFORMAT_ARGB8888; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + txformat |= R200_TXFORMAT_ARGB8888 | + R200_TXFORMAT_ALPHA_IN_MAP; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + rdev->msk_height /= 2; + if (surface->config.caps & DSCAPS_SEPARATED) { + if (surface->field) + rdev->msk_offset += rdev->msk_height * rdev->msk_pitch; + } else { + if (surface->field) + rdev->msk_offset += rdev->msk_pitch; + rdev->msk_pitch *= 2; + } + } + + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R200_PP_TXFILTER_1, txfilter ); + radeon_out32( mmio, R200_PP_TXFORMAT_1, txformat ); + radeon_out32( mmio, R200_PP_TXSIZE_1, ((rdev->msk_height-1) << 16) | + ((rdev->msk_width-1) & 0xffff) ); + radeon_out32( mmio, R200_PP_TXPITCH_1, rdev->msk_pitch - 32 ); + radeon_out32( mmio, R200_PP_TXOFFSET_1, rdev->msk_offset ); + + RADEON_SET( SOURCE_MASK ); +} + +void r200_set_clip( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBRegion *clip = &state->clip; + volatile u8 *mmio = rdrv->mmio_base; + + if (RADEON_IS_SET( CLIP )) + return; + + /* 2d clip */ + radeon_waitfifo( rdrv, rdev, 2 ); + if (rdev->dst_422) { + radeon_out32( mmio, SC_TOP_LEFT, + (clip->y1 << 16) | (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, + ((clip->y2+1) << 16) | ((clip->x2+1)/2 & 0xffff) ); + } else { + radeon_out32( mmio, SC_TOP_LEFT, + (clip->y1 << 16) | (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, + ((clip->y2+1) << 16) | ((clip->x2+1) & 0xffff) ); + } + + /* 3d clip */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, RE_TOP_LEFT, + (clip->y1 << 16) | (clip->x1 & 0xffff) ); + radeon_out32( mmio, RE_BOTTOM_RIGHT, + (clip->y2 << 16) | (clip->x2 & 0xffff) ); + + rdev->clip = state->clip; + + RADEON_SET( CLIP ); +} + +#define R200_SET_YUV422_COLOR( rdrv, rdev, y, u, v ) { \ + radeon_out32( (rdrv)->fb_base, (rdev)->yuv422_buffer, \ + PIXEL_YUY2( y, u, v ) ); \ + radeon_in8( (rdrv)->fb_base, (rdev)->yuv422_buffer ); \ + radeon_waitfifo( rdrv, rdev, 3 ); \ + radeon_out32( (rdrv)->mmio_base, R200_PP_TXOFFSET_1, \ + (rdev)->fb_offset + (rdev)->yuv422_buffer ); \ + radeon_out32( (rdrv)->mmio_base, R200_PP_TXFORMAT_1, \ + R200_TXFORMAT_VYUY422 ); \ + radeon_out32( (rdrv)->mmio_base, R200_PP_TXFILTER_1, 0 ); \ +} + +void r200_set_drawing_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + int index = state->color_index; + u32 color2d; + u32 color3d; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) { + color.r = ((long) color.r * color.a / 255L); + color.g = ((long) color.g * color.a / 255L); + color.b = ((long) color.b * color.a / 255L); + } + + color3d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + + switch (rdev->dst_format) { + case DSPF_ALUT44: + index |= (color.a & 0xf0); + case DSPF_LUT8: + color2d = index; + color3d = PIXEL_RGB32( index, index, index ); + break; + case DSPF_A8: + color2d = color.a; + color3d = (color.a << 24) | 0x00ffffff; + break; + case DSPF_RGB332: + color2d = PIXEL_RGB332( color.r, color.g, color.b ); + break; + case DSPF_ARGB2554: + color2d = PIXEL_ARGB2554( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + color2d = PIXEL_ARGB4444( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + color2d = PIXEL_ARGB1555( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB16: + color2d = PIXEL_RGB16( color.r, color.g, color.b ); + break; + case DSPF_RGB32: + color2d = PIXEL_RGB32( color.r, color.g, color.b ); + break; + case DSPF_ARGB: + color2d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + break; + case DSPF_AiRGB: + color2d = PIXEL_AiRGB( color.a, color.r, + color.g, color.b ); + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color3d = color2d = PIXEL_AYUV( color.a, y, u, v ); + break; + case DSPF_UYVY: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_UYVY( y, u, v ); + R200_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + break; + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_YUY2( y, u, v ); + R200_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + break; + case DSPF_I420: + case DSPF_YV12: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + rdev->y_cop = PIXEL_ARGB( color.a, y, y, y ); + rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u ); + rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v ); + color3d = color2d = rdev->y_cop; + break; + default: + D_BUG( "unexpected pixelformat" ); + color2d = 0; + break; + } + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( rdrv->mmio_base, DP_BRUSH_FRGD_CLR, color2d ); + radeon_out32( rdrv->mmio_base, R200_PP_TFACTOR_1, color3d ); + + RADEON_SET( COLOR ); +} + +void r200_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + u32 color3d; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( BLITTING_FLAGS )) + return; + + if (state->blittingflags & DSBLIT_COLORIZE && + state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { + color.r = color.r * color.a / 255; + color.g = color.g * color.a / 255; + color.b = color.b * color.a / 255; + } + + switch (rdev->dst_format) { + case DSPF_A8: + color3d = (color.a << 24) | 0x00ffffff; + break; + case DSPF_I420: + case DSPF_YV12: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + rdev->y_cop = PIXEL_ARGB( color.a, y, y, y ); + rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u ); + rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v ); + color3d = rdev->y_cop; + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color3d = PIXEL_AYUV( color.a, y, u, v ); + break; + case DSPF_UYVY: + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + R200_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + default: + color3d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + break; + } + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, R200_PP_TFACTOR_0, color3d ); + + RADEON_SET( COLOR ); +} + +void r200_set_src_colorkey( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + if (RADEON_IS_SET( SRC_COLORKEY )) + return; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, CLR_CMP_CLR_SRC, state->src_colorkey ); + radeon_out32( mmio, CLR_CMP_MASK, rdev->src_mask ); + + RADEON_SET( SRC_COLORKEY ); +} + +void r200_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 sblend; + u32 dblend; + + if (RADEON_IS_SET( SRC_BLEND ) && RADEON_IS_SET( DST_BLEND )) + return; + + sblend = r200SrcBlend[state->src_blend-1]; + dblend = r200DstBlend[state->dst_blend-1]; + + if (!DFB_PIXELFORMAT_HAS_ALPHA(rdev->dst_format)) { + if (sblend == SRC_BLEND_GL_DST_ALPHA) + sblend = SRC_BLEND_GL_ONE; + else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA) + sblend = SRC_BLEND_GL_ZERO; + + if (dblend == DST_BLEND_GL_DST_ALPHA) + dblend = DST_BLEND_GL_ONE; + else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA) + dblend = DST_BLEND_GL_ZERO; + } + else if (rdev->dst_format == DSPF_A8) { + if (sblend == SRC_BLEND_GL_DST_ALPHA) + sblend = SRC_BLEND_GL_DST_COLOR; + else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA) + sblend = SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + + if (dblend == DST_BLEND_GL_DST_ALPHA) + dblend = DST_BLEND_GL_DST_COLOR; + else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA) + dblend = DST_BLEND_GL_ONE_MINUS_DST_COLOR; + } + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, RB3D_BLENDCNTL, sblend | dblend ); + + RADEON_SET( SRC_BLEND ); + RADEON_SET( DST_BLEND ); +} + +void r200_set_render_options( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + if (RADEON_IS_SET( RENDER_OPTIONS )) + return; + + if (state->render_options & DSRO_MATRIX && + (!state->affine_matrix || + state->matrix[0] != (1<<16) || state->matrix[1] != 0 || state->matrix[2] != 0 || + state->matrix[3] != 0 || state->matrix[4] != (1<<16) || state->matrix[5] != 0)) { + rdev->matrix = state->matrix; + rdev->affine_matrix = state->affine_matrix; + } + else { + rdev->matrix = NULL; + } + + if ((rdev->render_options & DSRO_ANTIALIAS) != (state->render_options & DSRO_ANTIALIAS)) { + RADEON_UNSET( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); + } + rdev->render_options = state->render_options; + + RADEON_SET( RENDER_OPTIONS ); +} + +/* NOTES: + * - We use texture unit 0 for blitting functions, + * texture unit 1 for drawing functions + * - Default blend equation is ADD_CLAMP (A * B + C) + */ + +void r200_set_drawingflags( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 master_cntl = rdev->gui_master_cntl | + GMC_SRC_DATATYPE_MONO_FG_LA | + GMC_BRUSH_SOLID_COLOR | + GMC_CLR_CMP_CNTL_DIS; + u32 rb3d_cntl = rdev->rb3d_cntl & ~DITHER_ENABLE; + u32 pp_cntl = TEX_BLEND_1_ENABLE; + u32 cblend = R200_TXC_ARG_C_TFACTOR_COLOR; + + if (RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (rdev->dst_422) { + pp_cntl |= TEX_1_ENABLE; + cblend = R200_TXC_ARG_C_R1_COLOR; + } + else if (rdev->dst_format == DSPF_A8) { + cblend = R200_TXC_ARG_C_TFACTOR_ALPHA; + } + + if (state->drawingflags & DSDRAW_BLEND) + rb3d_cntl |= ALPHA_BLEND_ENABLE; + + if (state->drawingflags & DSDRAW_XOR) { + rb3d_cntl |= ROP_ENABLE; + master_cntl |= GMC_ROP3_PATXOR; + } + else { + master_cntl |= GMC_ROP3_PATCOPY; + } + + if (state->render_options & DSRO_ANTIALIAS) + pp_cntl |= ANTI_ALIAS_LINE_POLY; + + radeon_waitfifo( rdrv, rdev, 11 ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + radeon_out32( mmio, DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM ); + radeon_out32( mmio, RB3D_CNTL, rb3d_cntl ); + radeon_out32( mmio, SE_CNTL, DIFFUSE_SHADE_FLAT | + ALPHA_SHADE_FLAT | + BFACE_SOLID | + FFACE_SOLID | + VTX_PIX_CENTER_OGL | + ROUND_MODE_ROUND | + ROUND_PREC_4TH_PIX ); + radeon_out32( mmio, PP_CNTL, pp_cntl ); + radeon_out32( mmio, R200_PP_TXCBLEND_1, cblend ); + radeon_out32( mmio, R200_PP_TXCBLEND2_1, (1 << R200_TXC_TFACTOR_SEL_SHIFT) | + R200_TXC_OUTPUT_REG_R0 | + R200_TXC_CLAMP_0_1 ); + radeon_out32( mmio, R200_PP_TXABLEND_1, R200_TXA_ARG_C_TFACTOR_ALPHA ); + radeon_out32( mmio, R200_PP_TXABLEND2_1, (1 << R200_TXA_TFACTOR_SEL_SHIFT) | + R200_TXA_OUTPUT_REG_R0 | + R200_TXA_CLAMP_0_1 ); + radeon_out32( mmio, R200_SE_VTX_FMT_0, R200_VTX_XY ); + radeon_out32( mmio, R200_SE_VTX_FMT_1, 0 ); + + rdev->drawingflags = state->drawingflags; + + RADEON_SET ( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); +} + +void r200_set_blittingflags( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 master_cntl = rdev->gui_master_cntl | + GMC_BRUSH_NONE | + GMC_SRC_DATATYPE_COLOR; + u32 cmp_cntl = 0; + u32 rb3d_cntl = rdev->rb3d_cntl; + u32 se_cntl = BFACE_SOLID | + FFACE_SOLID | + VTX_PIX_CENTER_OGL | + ROUND_MODE_ROUND; + u32 pp_cntl = TEX_0_ENABLE; + u32 cblend = R200_TXC_ARG_C_R0_COLOR; + u32 ablend = R200_TXA_ARG_C_R0_ALPHA; + u32 vtx_fmt = R200_VTX_XY; + u32 vte_cntl; + + if (RADEON_IS_SET( BLITTING_FLAGS )) + return; + + if (rdev->accel == DFXL_TEXTRIANGLES) { + se_cntl |= DIFFUSE_SHADE_GOURAUD | + ALPHA_SHADE_GOURAUD | + SPECULAR_SHADE_GOURAUD | + FLAT_SHADE_VTX_LAST | + ROUND_PREC_8TH_PIX; + vtx_fmt |= R200_VTX_Z0 | R200_VTX_W0; + vte_cntl = 0; + } + else { + se_cntl |= DIFFUSE_SHADE_FLAT | + ALPHA_SHADE_FLAT | + ROUND_PREC_4TH_PIX; + vte_cntl = R200_VTX_ST_DENORMALIZED; + } + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_BLEND_ALPHACHANNEL)) { + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + ablend = R200_TXA_ARG_A_R0_ALPHA | R200_TXA_ARG_B_TFACTOR_ALPHA; + else + ablend = R200_TXA_ARG_C_TFACTOR_ALPHA; + + pp_cntl |= TEX_BLEND_0_ENABLE; + } + + rb3d_cntl |= ALPHA_BLEND_ENABLE; + } + + if (rdev->dst_format != DSPF_A8) { + if (state->blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR)) { + if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) + ablend = R200_TXA_ARG_A_R0_ALPHA | R200_TXA_ARG_B_R1_ALPHA; + + if (state->blittingflags & DSBLIT_SRC_MASK_COLOR) + cblend = R200_TXC_ARG_A_R0_COLOR | R200_TXC_ARG_B_R1_COLOR; + + pp_cntl |= TEX_1_ENABLE | TEX_BLEND_0_ENABLE; + } + else if (state->blittingflags & DSBLIT_COLORIZE) { + if (rdev->dst_422) { + cblend = (rdev->src_format == DSPF_A8) + ? (R200_TXC_ARG_C_R1_COLOR) + : (R200_TXC_ARG_A_R0_COLOR | R200_TXC_ARG_B_R1_COLOR); + + pp_cntl |= TEX_1_ENABLE; + } + else { + cblend = (rdev->src_format == DSPF_A8) + ? (R200_TXC_ARG_C_TFACTOR_COLOR) + : (R200_TXC_ARG_A_R0_COLOR | R200_TXC_ARG_B_TFACTOR_COLOR); + } + + pp_cntl |= TEX_BLEND_0_ENABLE; + } + else if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { + cblend = (rdev->src_format == DSPF_A8) + ? (R200_TXC_ARG_C_R0_ALPHA) + : (R200_TXC_ARG_A_R0_COLOR | R200_TXC_ARG_B_TFACTOR_ALPHA); + + pp_cntl |= TEX_BLEND_0_ENABLE; + } + else if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + cblend = (rdev->src_format == DSPF_A8) + ? (R200_TXC_ARG_C_R0_ALPHA) + : (R200_TXC_ARG_A_R0_COLOR | R200_TXC_ARG_B_R0_ALPHA); + + pp_cntl |= TEX_BLEND_0_ENABLE; + } + } /* DSPF_A8 */ + else { + if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) { + ablend = R200_TXA_ARG_A_R0_ALPHA | R200_TXA_ARG_B_R1_ALPHA; + cblend = R200_TXC_ARG_A_R0_ALPHA | R200_TXC_ARG_B_R1_ALPHA; + pp_cntl |= TEX_1_ENABLE; + } + else if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + cblend = R200_TXC_ARG_A_R0_ALPHA | R200_TXC_ARG_B_TFACTOR_ALPHA; + else + cblend = R200_TXC_ARG_C_TFACTOR_ALPHA; + } + else { + cblend = R200_TXC_ARG_C_R0_ALPHA; + } + + pp_cntl |= TEX_BLEND_0_ENABLE; + } + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + cmp_cntl = SRC_CMP_EQ_COLOR | CLR_CMP_SRC_SOURCE; + else + master_cntl |= GMC_CLR_CMP_CNTL_DIS; + + if (state->blittingflags & DSBLIT_XOR) { + master_cntl |= GMC_ROP3_XOR; + rb3d_cntl |= ROP_ENABLE; + } + else { + master_cntl |= GMC_ROP3_SRCCOPY; + } + + if (state->render_options & DSRO_ANTIALIAS) + pp_cntl |= ANTI_ALIAS_POLY; + + radeon_waitfifo( rdrv, rdev, 12 ); + radeon_out32( mmio, CLR_CMP_CNTL, cmp_cntl ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + radeon_out32( mmio, RB3D_CNTL, rb3d_cntl ); + radeon_out32( mmio, SE_CNTL, se_cntl ); + radeon_out32( mmio, PP_CNTL, pp_cntl ); + radeon_out32( mmio, R200_PP_TXCBLEND_0, cblend ); + radeon_out32( mmio, R200_PP_TXCBLEND2_0, R200_TXC_OUTPUT_REG_R0 | + R200_TXC_CLAMP_0_1 ); + radeon_out32( mmio, R200_PP_TXABLEND_0, ablend ); + radeon_out32( mmio, R200_PP_TXABLEND2_0, R200_TXA_OUTPUT_REG_R0 | + R200_TXA_CLAMP_0_1 ); + radeon_out32( mmio, R200_SE_VTX_FMT_0, vtx_fmt ); + radeon_out32( mmio, R200_SE_VTX_FMT_1, 2 << R200_VTX_TEX0_COMP_CNT_SHIFT ); + radeon_out32( mmio, R200_SE_VTE_CNTL, vte_cntl ); + + rdev->blittingflags = state->blittingflags; + + RADEON_SET ( BLITTING_FLAGS ); + RADEON_UNSET( DRAWING_FLAGS ); +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/r300_3d.c b/Source/DirectFB/gfxdrivers/radeon/r300_3d.c new file mode 100755 index 0000000..c8a1b8c --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r300_3d.c @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <dfb_types.h> +#include <directfb.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/state.h> +#include <core/gfxcard.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_state.h" +#include "radeon_3d.h" + + +#define EMIT_VERTICES( rdrv, rdev, mmio ) { \ + u32 *_v = (rdev)->vb; \ + u32 _s = (rdev)->vb_size; \ + radeon_waitfifo( rdrv, rdev, 1 ); \ + radeon_out32( mmio, SE_VF_CNTL, rdev->vb_type | VF_PRIM_WALK_DATA | \ + (rdev->vb_count << VF_NUM_VERTICES_SHIFT) ); \ + do { \ + u32 _n = MIN(_s, 64); \ + _s -= _n; \ + radeon_waitfifo( rdrv, rdev, _n ); \ + while (_n--) \ + radeon_out32( mmio, SE_PORT_DATA0, *_v++ ); \ + } while (_s); \ + radeon_waitfifo( rdrv, rdev, 2 ); \ + radeon_out32( mmio, R300_RB3D_DSTCACHE_CTLSTAT, 0xa ); \ + radeon_out32( mmio, 0x4f18, 0x3 ); \ +} + +static void +r300_flush_vb( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + EMIT_VERTICES( rdrv, rdev, mmio ); + + if (DFB_PLANAR_PIXELFORMAT(rdev->dst_format)) { + DFBRegion clip; + int i; + + for (i = 0; i < rdev->vb_size; i += 8) { + rdev->vb[i+0] = f2d(d2f(rdev->vb[i+0])*0.5f); + rdev->vb[i+1] = f2d(d2f(rdev->vb[i+1])*0.5f); + } + + clip.x1 = rdev->clip.x1 >> 1; + clip.y1 = rdev->clip.y1 >> 1; + clip.x2 = rdev->clip.x2 >> 1; + clip.y2 = rdev->clip.y2 >> 1; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, rdev->dst_offset_cb ); + radeon_out32( mmio, R300_RB3D_COLORPITCH0, (rdev->dst_pitch>>1) | + R300_COLOR_FORMAT_RGB8 ); + radeon_out32( mmio, R300_TX_SIZE_0, ((rdev->src_width/2 -1) << R300_TX_WIDTH_SHIFT) | + ((rdev->src_height/2-1) << R300_TX_HEIGHT_SHIFT) | + R300_TX_SIZE_TXPITCH_EN ); + radeon_out32( mmio, R300_TX_PITCH_0, (rdev->src_pitch>>1) - 8 ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset_cb ); + r300_set_clip3d( rdrv, rdev, &clip ); + + /* Fill Cb plane */ + EMIT_VERTICES( rdrv, rdev, mmio ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, rdev->dst_offset_cr ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset_cr ); + + /* Fill Cr plane */ + EMIT_VERTICES( rdrv, rdev, mmio ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, rdev->dst_offset ); + radeon_out32( mmio, R300_RB3D_COLORPITCH0, rdev->dst_pitch | + R300_COLOR_FORMAT_RGB8 ); + radeon_out32( mmio, R300_TX_SIZE_0, ((rdev->src_width -1) << R300_TX_WIDTH_SHIFT) | + ((rdev->src_height-1) << R300_TX_HEIGHT_SHIFT) | + R300_TX_SIZE_TXPITCH_EN ); + radeon_out32( mmio, R300_TX_PITCH_0, rdev->src_pitch - 8 ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset ); + r300_set_clip3d( rdrv, rdev, &rdev->clip ); + } + + rdev->vb_size = 0; + rdev->vb_count = 0; +} + +static inline u32* +r300_init_vb( RadeonDriverData *rdrv, RadeonDeviceData *rdev, u32 type, u32 count, u32 size ) +{ + u32 *vb; + + if ((rdev->vb_size && rdev->vb_type != type) || + rdev->vb_size+size > D_ARRAY_SIZE(rdev->vb)) + r300_flush_vb( rdrv, rdev ); + + vb = &rdev->vb[rdev->vb_size]; + rdev->vb_type = type; + rdev->vb_size += size; + rdev->vb_count += count; + + return vb; +} + + +#define VTX(v, x, y, c) \ + *(v)++ = f2d(x); \ + *(v)++ = f2d(y); \ + *(v)++ = f2d(0); \ + *(v)++ = f2d(1); \ + *(v)++ = f2d(c[0]); \ + *(v)++ = f2d(c[1]); \ + *(v)++ = f2d(c[2]); \ + *(v)++ = f2d(c[3]) + +bool r300FillRectangle3D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + if (rect->w == 1 && rect->h == 1) { + x1 = rect->x+1; y1 = rect->y+1; + if (rdev->matrix) + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_POINT_LIST, 1, 8 ); + VTX( v, x1, y1, rdev->color ); + + return true; + } + + x1 = rect->x; y1 = rect->y; + x2 = rect->x+rect->w; y2 = rect->y+rect->h; + if (rdev->matrix) { + float x, y; + + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_QUAD_LIST, 4, 32 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + } + else { + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_QUAD_LIST, 4, 32 ); + VTX( v, x1, y1, rdev->color ); + VTX( v, x2, y1, rdev->color ); + VTX( v, x2, y2, rdev->color ); + VTX( v, x1, y2, rdev->color ); + } + + return true; +} + +bool r300FillTriangle( void *drv, void *dev, DFBTriangle *tri ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + float x3, y3; + u32 *v; + + x1 = tri->x1; y1 = tri->y1; + x2 = tri->x2; y2 = tri->y2; + x3 = tri->x3; y3 = tri->y3; + if (rdev->matrix) { + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, x2, y2, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x3, y3, x3, y3, rdev->matrix, rdev->affine_matrix ); + } + + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_TRIANGLE_LIST, 3, 24 ); + VTX( v, x1, y1, rdev->color ); + VTX( v, x2, y2, rdev->color ); + VTX( v, x3, y3, rdev->color ); + + return true; +} + +bool r300DrawRectangle3D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + x1 = rect->x; y1 = rect->y; + x2 = rect->x+rect->w; y2 = rect->y+rect->h; + if (rdev->matrix) { + float x, y; + + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LOOP, 4, 32 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, rdev->color ); + } + else { + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LOOP, 4, 32 ); + VTX( v, x1, y1, rdev->color ); + VTX( v, x2, y1, rdev->color ); + VTX( v, x2, y2, rdev->color ); + VTX( v, x1, y2, rdev->color ); + } + + return true; +} + +bool r300DrawLine3D( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + u32 *v; + + x1 = line->x1; y1 = line->y1; + x2 = line->x2; y2 = line->y2; + if (rdev->matrix) { + RADEON_TRANSFORM( x1, y1, x1, y1, rdev->matrix, rdev->affine_matrix ); + RADEON_TRANSFORM( x2, y2, x2, y2, rdev->matrix, rdev->affine_matrix ); + } + + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_LINE_LIST, 2, 16 ); + VTX( v, x1, y1, rdev->color ); + VTX( v, x2, y2, rdev->color ); + + return true; +} + +#undef VTX +#define VTX( v, x, y, s, t ) \ + *(v)++ = f2d(x); \ + *(v)++ = f2d(y); \ + *(v)++ = f2d(0); \ + *(v)++ = f2d(1); \ + *(v)++ = f2d(s); \ + *(v)++ = f2d(t); \ + *(v)++ = f2d(0); \ + *(v)++ = f2d(1) + +bool r300Blit3D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + DFBRectangle dr = { dx, dy, sr->w, sr->h }; + + return r300StretchBlit( drv, dev, sr, &dr ); +} + +bool r300StretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + float x1, y1; + float x2, y2; + float s1, t1; + float s2, t2; + u32 *v; + + if (rdev->blittingflags & DSBLIT_DEINTERLACE) { + sr->y /= 2; + sr->h /= 2; + } + + s1 = (float)sr->x / rdev->src_width; t1 = (float)sr->y / rdev->src_height; + s2 = (float)(sr->x+sr->w) / rdev->src_width; t2 = (float)(sr->y+sr->h) / rdev->src_height; + if (rdev->blittingflags & DSBLIT_ROTATE180) { + float tmp; + tmp = s2; s2 = s1; s1 = tmp; + tmp = t2; t2 = t1; t1 = tmp; + } + + x1 = dr->x; y1 = dr->y; + x2 = dr->x+dr->w; y2 = dr->y+dr->h; + if (rdev->matrix) { + float x, y; + + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_QUAD_LIST, 4, 32 ); + RADEON_TRANSFORM( x1, y1, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, s1, t1 ); + RADEON_TRANSFORM( x2, y1, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, s2, t1 ); + RADEON_TRANSFORM( x2, y2, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, s2, t2 ); + RADEON_TRANSFORM( x1, y2, x, y, rdev->matrix, rdev->affine_matrix ); + VTX( v, x, y, s1, t2 ); + } + else { + v = r300_init_vb( rdrv, rdev, VF_PRIM_TYPE_QUAD_LIST, 4, 32 ); + VTX( v, x1, y1, s1, t1 ); + VTX( v, x2, y1, s2, t1 ); + VTX( v, x2, y2, s2, t2 ); + VTX( v, x1, y2, s1, t2 ); + } + + return true; +} + +static void +r300DoTextureTriangles( RadeonDriverData *rdrv, RadeonDeviceData *rdev, + DFBVertex *ve, int num, u32 primitive ) +{ + volatile u8 *mmio = rdrv->mmio_base; + int i; + + radeon_waitfifo( rdrv, rdev, 1 ); + + radeon_out32( mmio, SE_VF_CNTL, primitive | VF_PRIM_WALK_DATA | + (num << VF_NUM_VERTICES_SHIFT) ); + + for (; num >= 8; num -= 8) { + radeon_waitfifo( rdrv, rdev, 64 ); + for (i = 0; i < 8; i++) { + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].x) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].y) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].z) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(1) ); // FIXME + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].s) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].t) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(0) ); // r + radeon_out32( mmio, SE_PORT_DATA0, f2d(1) ); // q + } + ve += 8; + } + + if (num > 0) { + radeon_waitfifo( rdrv, rdev, num*8 ); + for (i = 0; i < num; i++) { + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].x) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].y) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].z) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(1) ); // FIXME + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].s) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(ve[i].t) ); + radeon_out32( mmio, SE_PORT_DATA0, f2d(0) ); // r + radeon_out32( mmio, SE_PORT_DATA0, f2d(1) ); // q + } + } + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, R300_RB3D_DSTCACHE_CTLSTAT, 0xa ); + radeon_out32( mmio, 0x4f18, 0x3 ); +} + +bool r300TextureTriangles( void *drv, void *dev, DFBVertex *ve, + int num, DFBTriangleFormation formation ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + u32 prim = 0; + int i; + + if (num > 65535) { + D_WARN( "R300 supports maximum 65535 vertices" ); + return false; + } + + switch (formation) { + case DTTF_LIST: + prim = VF_PRIM_TYPE_TRIANGLE_LIST; + break; + case DTTF_STRIP: + prim = VF_PRIM_TYPE_TRIANGLE_STRIP; + break; + case DTTF_FAN: + prim = VF_PRIM_TYPE_TRIANGLE_FAN; + break; + default: + D_BUG( "unexpected triangle formation" ); + return false; + } + + if (rdev->matrix) { + for (i = 0; i < num; i++) + RADEON_TRANSFORM( ve[i].x, ve[i].y, ve[i].x, ve[i].y, rdev->matrix, rdev->affine_matrix ); + } + + r300DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + if (DFB_PLANAR_PIXELFORMAT(rdev->dst_format)) { + volatile u8 *mmio = rdrv->mmio_base; + DFBRegion clip; + int i; + + /* Scale coordinates */ + for (i = 0; i < num; i++) { + ve[i].x *= 0.5; + ve[i].y *= 0.5; + } + clip.x1 = rdev->clip.x1 >> 1; + clip.y1 = rdev->clip.y1 >> 1; + clip.x2 = rdev->clip.x2 >> 1; + clip.y2 = rdev->clip.y2 >> 1; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, rdev->dst_offset_cb ); + radeon_out32( mmio, R300_RB3D_COLORPITCH0, (rdev->dst_pitch>>1) | + R300_COLOR_FORMAT_RGB8 ); + radeon_out32( mmio, R300_TX_SIZE_0, ((rdev->src_width/2 -1) << R300_TX_WIDTH_SHIFT) | + ((rdev->src_height/2-1) << R300_TX_HEIGHT_SHIFT) | + R300_TX_SIZE_TXPITCH_EN ); + radeon_out32( mmio, R300_TX_PITCH_0, (rdev->src_pitch>>1) - 8 ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset_cb ); + r300_set_clip3d( rdrv, rdev, &clip ); + + /* Blit Cb plane */ + r300DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, rdev->dst_offset_cr ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset_cr ); + + /* Blit Cr plane */ + r300DoTextureTriangles( rdrv, rdev, ve, num, prim ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, rdev->dst_offset ); + radeon_out32( mmio, R300_RB3D_COLORPITCH0, rdev->dst_pitch | + R300_COLOR_FORMAT_RGB8 ); + radeon_out32( mmio, R300_TX_SIZE_0, ((rdev->src_width -1) << R300_TX_WIDTH_SHIFT) | + ((rdev->src_height-1) << R300_TX_HEIGHT_SHIFT) | + R300_TX_SIZE_TXPITCH_EN ); + radeon_out32( mmio, R300_TX_PITCH_0, rdev->src_pitch - 8 ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset ); + r300_set_clip3d( rdrv, rdev, &rdev->clip ); + } + + return true; +} + +void r300EmitCommands3D( void *drv, void *dev ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->vb_count) + r300_flush_vb( rdrv, rdev ); +} diff --git a/Source/DirectFB/gfxdrivers/radeon/r300_program.h b/Source/DirectFB/gfxdrivers/radeon/r300_program.h new file mode 100755 index 0000000..b2bc0dd --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r300_program.h @@ -0,0 +1,151 @@ +/* +Copyright (C) 2004 Nicolai Haehnle. All Rights Reserved. + +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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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: + * Nicolai Haehnle <prefect_@gmx.net> + */ + +#ifndef __R300_PROGRAM_H__ +#define __R300_PROGRAM_H__ + +#include "radeon_regs.h" + +/** + * Vertex program helper macros + */ + +/* Produce out dword */ +#define VP_OUTCLASS_TMP R300_VPI_OUT_REG_CLASS_TEMPORARY +#define VP_OUTCLASS_OUT R300_VPI_OUT_REG_CLASS_RESULT + +#define VP_OUTMASK_X R300_VPI_OUT_WRITE_X +#define VP_OUTMASK_Y R300_VPI_OUT_WRITE_Y +#define VP_OUTMASK_Z R300_VPI_OUT_WRITE_Z +#define VP_OUTMASK_W R300_VPI_OUT_WRITE_W +#define VP_OUTMASK_XY (VP_OUTMASK_X|VP_OUTMASK_Y) +#define VP_OUTMASK_XZ (VP_OUTMASK_X|VP_OUTMASK_Z) +#define VP_OUTMASK_XW (VP_OUTMASK_X|VP_OUTMASK_W) +#define VP_OUTMASK_XYZ (VP_OUTMASK_XY|VP_OUTMASK_Z) +#define VP_OUTMASK_XYW (VP_OUTMASK_XY|VP_OUTMASK_W) +#define VP_OUTMASK_XZW (VP_OUTMASK_XZ|VP_OUTMASK_W) +#define VP_OUTMASK_XYZW (VP_OUTMASK_XYZ|VP_OUTMASK_W) +#define VP_OUTMASK_YZ (VP_OUTMASK_Y|VP_OUTMASK_Z) +#define VP_OUTMASK_YW (VP_OUTMASK_Y|VP_OUTMASK_W) +#define VP_OUTMASK_YZW (VP_OUTMASK_YZ|VP_OUTMASK_W) +#define VP_OUTMASK_ZW (VP_OUTMASK_Z|VP_OUTMASK_W) + +#define VP_OUT(instr,outclass,outidx,outmask) \ + (R300_VPI_OUT_OP_##instr | \ + ((outidx) << R300_VPI_OUT_REG_INDEX_SHIFT) | \ + VP_OUTCLASS_##outclass | \ + VP_OUTMASK_##outmask) + +/* Produce in dword */ +#define VP_INCLASS_TMP R300_VPI_IN_REG_CLASS_TEMPORARY +#define VP_INCLASS_IN R300_VPI_IN_REG_CLASS_ATTRIBUTE +#define VP_INCLASS_CONST R300_VPI_IN_REG_CLASS_PARAMETER + +#define VP_IN(class,idx) \ + (((idx) << R300_VPI_IN_REG_INDEX_SHIFT) | \ + VP_INCLASS_##class | \ + (R300_VPI_IN_SELECT_X << R300_VPI_IN_X_SHIFT) | \ + (R300_VPI_IN_SELECT_Y << R300_VPI_IN_Y_SHIFT) | \ + (R300_VPI_IN_SELECT_Z << R300_VPI_IN_Z_SHIFT) | \ + (R300_VPI_IN_SELECT_W << R300_VPI_IN_W_SHIFT)) +#define VP_ZERO() \ + ((R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_X_SHIFT) | \ + (R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_Y_SHIFT) | \ + (R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_Z_SHIFT) | \ + (R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_W_SHIFT)) +#define VP_ONE() \ + ((R300_VPI_IN_SELECT_ONE << R300_VPI_IN_X_SHIFT) | \ + (R300_VPI_IN_SELECT_ONE << R300_VPI_IN_Y_SHIFT) | \ + (R300_VPI_IN_SELECT_ONE << R300_VPI_IN_Z_SHIFT) | \ + (R300_VPI_IN_SELECT_ONE << R300_VPI_IN_W_SHIFT)) + +#define VP_NEG(in,comp) ((in) ^ (R300_VPI_IN_NEG_##comp)) +#define VP_NEGALL(in,comp) VP_NEG(VP_NEG(VP_NEG(VP_NEG((in),X),Y),Z),W) + +/** + * Fragment program helper macros + */ + +/* Produce unshifted source selectors */ +#define FP_TMP(idx) (idx) +#define FP_CONST(idx) ((idx) | (1 << 5)) + +/* Produce source/dest selector dword */ +#define FP_SELC_MASK_NO 0 +#define FP_SELC_MASK_X 1 +#define FP_SELC_MASK_Y 2 +#define FP_SELC_MASK_XY 3 +#define FP_SELC_MASK_Z 4 +#define FP_SELC_MASK_XZ 5 +#define FP_SELC_MASK_YZ 6 +#define FP_SELC_MASK_XYZ 7 + +#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \ + (((destidx) << R300_FPI1_DSTC_SHIFT) | \ + (FP_SELC_MASK_##regmask << 23) | \ + (FP_SELC_MASK_##outmask << 26) | \ + ((src0) << R300_FPI1_SRC0C_SHIFT) | \ + ((src1) << R300_FPI1_SRC1C_SHIFT) | \ + ((src2) << R300_FPI1_SRC2C_SHIFT)) + +#define FP_SELA_MASK_NO 0 +#define FP_SELA_MASK_W 1 + +#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \ + (((destidx) << R300_FPI3_DSTA_SHIFT) | \ + (FP_SELA_MASK_##regmask << 23) | \ + (FP_SELA_MASK_##outmask << 24) | \ + ((src0) << R300_FPI3_SRC0A_SHIFT) | \ + ((src1) << R300_FPI3_SRC1A_SHIFT) | \ + ((src2) << R300_FPI3_SRC2A_SHIFT)) + +/* Produce unshifted argument selectors */ +#define FP_ARGC(source) R300_FPI0_ARGC_##source +#define FP_ARGA(source) R300_FPI2_ARGA_##source +#define FP_ABS(arg) ((arg) | (1 << 6)) +#define FP_NEG(arg) ((arg) ^ (1 << 5)) + +/* Produce instruction dword */ +#define FP_INSTRC(opcode,arg0,arg1,arg2) \ + (R300_FPI0_OUTC_##opcode | \ + ((arg0) << R300_FPI0_ARG0C_SHIFT) | \ + ((arg1) << R300_FPI0_ARG1C_SHIFT) | \ + ((arg2) << R300_FPI0_ARG2C_SHIFT)) + +#define FP_INSTRA(opcode,arg0,arg1,arg2) \ + (R300_FPI2_OUTA_##opcode | \ + ((arg0) << R300_FPI2_ARG0A_SHIFT) | \ + ((arg1) << R300_FPI2_ARG1A_SHIFT) | \ + ((arg2) << R300_FPI2_ARG2A_SHIFT)) + + +#include "vertex_shader.h" + +#endif /* __R300_PROGRAM_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/r300_state.c b/Source/DirectFB/gfxdrivers/radeon/r300_state.c new file mode 100755 index 0000000..97bfd6a --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r300_state.c @@ -0,0 +1,1103 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <directfb.h> + +#include <direct/messages.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/state.h> +#include <core/gfxcard.h> +#include <core/surface.h> + +#include <gfx/convert.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_state.h" + +#include "r300_program.h" + + +#define R300_HAS_3DREGS() (rdrv->mmio_size > 0x4000) + + +static const u32 r300SrcBlend[] = { + SRC_BLEND_GL_ZERO, // DSBF_ZERO + SRC_BLEND_GL_ONE, // DSBF_ONE + SRC_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR + SRC_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR + SRC_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA + SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA + SRC_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA + SRC_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA + SRC_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR + SRC_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR + SRC_BLEND_GL_SRC_ALPHA_SATURATE // DSBF_SRCALPHASAT +}; + +static const u32 r300DstBlend[] = { + DST_BLEND_GL_ZERO, // DSBF_ZERO + DST_BLEND_GL_ONE, // DSBF_ONE + DST_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR + DST_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR + DST_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA + DST_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA + DST_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA + DST_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA + DST_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR + DST_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR + DST_BLEND_GL_ZERO // DSBF_SRCALPHASAT +}; + + +void r300_restore( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + const u32 rs_magic[8] = { 0x00, 0x44, 0x84, 0xc4, + 0x04, 0x04, 0x04, 0x04 }; + volatile u8 *mmio = rdrv->mmio_base; + int i; + + /* enable caches */ + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, RB2D_DSTCACHE_MODE, RB2D_DC_2D_CACHE_AUTOFLUSH | + R300_RB2D_DC_ENABLE ); + + if (!R300_HAS_3DREGS()) + return; + + /* restore 3d engine state */ + radeon_waitfifo( rdrv, rdev, 50 ); + radeon_out32( mmio, 0x2080, 0x0030045a ); + radeon_out32( mmio, R300_SE_VTE_CNTL, R300_VTX_W0_FMT ); + radeon_out32( mmio, R300_SE_VTE_CNTL+4, 0x00000008 ); + radeon_out32( mmio, 0x2134, 0x00FFFFFF ); + radeon_out32( mmio, 0x2138, 0x00000000 ); +#ifdef WORDS_BIGENDIAN + radeon_out32( mmio, 0x2140, 0x00000002 ); +#else + radeon_out32( mmio, 0x2140, 0x00000000 ); +#endif + radeon_out32( mmio, 0x21dc, 0xaaaaaaaa ); + radeon_out32( mmio, 0x2220, f2d(1.0) ); + radeon_out32( mmio, 0x2224, f2d(1.0) ); + radeon_out32( mmio, 0x2228, f2d(1.0) ); + radeon_out32( mmio, 0x222c, f2d(1.0) ); + if (rdev->chipset >= CHIP_RV350) + radeon_out32( mmio, R300_VAP_UNKNOWN_2288, R300_2288_RV350 ); + else + radeon_out32( mmio, R300_VAP_UNKNOWN_2288, R300_2288_R300 ); + radeon_out32( mmio, R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | + R300_GB_LINE_STUFF_ENABLE | + R300_GB_TRIANGLE_STUFF_ENABLE ); + radeon_out32( mmio, R300_GB_MSPOS0, 0x66666666 ); + radeon_out32( mmio, R300_GB_MSPOS1, 0x06666666 ); + if (rdev->chipset == CHIP_R300 || rdev->chipset == CHIP_R350 || rdev->chipset == CHIP_RV410) { + radeon_out32( mmio, R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | + R300_GB_TILE_PIPE_COUNT_R300 | + R300_GB_TILE_SIZE_16 ); + } + else if (rdev->chipset == CHIP_R420) { + radeon_out32( mmio, R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | + R300_GB_TILE_PIPE_COUNT_R420 | + R300_GB_TILE_SIZE_16 ); + } + else { + radeon_out32( mmio, R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | + R300_GB_TILE_PIPE_COUNT_RV300 | + R300_GB_TILE_SIZE_16 ); + } + radeon_out32( mmio, R300_GB_SELECT, 0 ); + radeon_out32( mmio, R300_GB_AA_CONFIG, 0 ); + radeon_out32( mmio, 0x4200, f2d(0.0) ); + radeon_out32( mmio, 0x4204, f2d(0.0) ); + radeon_out32( mmio, 0x4208, f2d(1.0) ); + radeon_out32( mmio, 0x420c, f2d(1.0) ); + radeon_out32( mmio, 0x4214, 0x00050005 ); + radeon_out32( mmio, R300_RE_POINTSIZE, (6 << R300_POINTSIZE_X_SHIFT) | + (6 << R300_POINTSIZE_Y_SHIFT) ); + radeon_out32( mmio, 0x4230, 0x18000006 ); + radeon_out32( mmio, R300_RE_LINE_CNT, (6 << R300_LINESIZE_SHIFT) | + R300_LINE_CNT_VE ); + radeon_out32( mmio, R300_RE_UNK4238, f2d(1.0/192.0) ); + radeon_out32( mmio, 0x4260, 0x00000000 ); + radeon_out32( mmio, 0x4264, f2d(0.0) ); + radeon_out32( mmio, 0x4268, f2d(1.0) ); + radeon_out32( mmio, 0x4274, 0x00000002 ); + radeon_out32( mmio, 0x427c, 0x00000000 ); + radeon_out32( mmio, 0x4280, 0x00000000 ); + radeon_out32( mmio, R300_RE_POLYGON_MODE, 0 ); + radeon_out32( mmio, 0x428c, 0x00000001 ); + radeon_out32( mmio, 0x4290, 0x00000000 ); + radeon_out32( mmio, 0x4294, 0x00000000 ); + radeon_out32( mmio, 0x4298, 0x00000000 ); + radeon_out32( mmio, 0x42a0, 0x00000000 ); + radeon_out32( mmio, R300_RE_ZBIAS_T_FACTOR, 0 ); + radeon_out32( mmio, R300_RE_ZBIAS_T_CONSTANT, 0 ); + radeon_out32( mmio, R300_RE_ZBIAS_W_FACTOR, 0 ); + radeon_out32( mmio, R300_RE_ZBIAS_W_CONSTANT, 0 ); + radeon_out32( mmio, R300_RE_OCCLUSION_CNTL, 0 ); + radeon_out32( mmio, R300_RE_CULL_CNTL, 0 ); + radeon_out32( mmio, 0x42c0, 0x4b7fffff ); + radeon_out32( mmio, 0x42c4, 0x00000000 ); + + radeon_waitfifo( rdrv, rdev, 16 ); + for (i = 0; i < 8; i++) { + radeon_out32( mmio, R300_RS_INTERP_0+i*4, R300_RS_INTERP_USED | rs_magic[i] ); + //radeon_out32( mmio, R300_RS_ROUTE_0+i*4, 0 ); + } + + radeon_waitfifo( rdrv, rdev, 43 ); + radeon_out32( mmio, 0x43a4, 0x0000001c ); + radeon_out32( mmio, 0x43a8, 0x2da49525 ); + radeon_out32( mmio, 0x43e8, 0x00ffffff ); + radeon_out32( mmio, 0x46a4, 0x00001b01 ); + radeon_out32( mmio, 0x46a8, 0x00001b0f ); + radeon_out32( mmio, 0x46ac, 0x00001b0f ); + radeon_out32( mmio, 0x46b0, 0x00001b0f ); + radeon_out32( mmio, 0x46b4, 0x00000001 ); + radeon_out32( mmio, 0x4bc0, 0x00000000 ); + radeon_out32( mmio, 0x4bc8, 0x00000000 ); + radeon_out32( mmio, 0x4bcc, 0x00000000 ); + radeon_out32( mmio, 0x4bd0, 0x00000000 ); + radeon_out32( mmio, R300_PP_ALPHA_TEST, R300_ALPHA_TEST_PASS ); + radeon_out32( mmio, 0x4bd8, 0x00000000 ); + radeon_out32( mmio, 0x4e00, 0x00000000 ); + radeon_out32( mmio, R300_RB3D_COLORMASK, R300_COLORMASK0_B | + R300_COLORMASK0_G | + R300_COLORMASK0_R | + R300_COLORMASK0_A ); + radeon_out32( mmio, R300_RB3D_BLENDCOLOR, 0xffffffff ); + radeon_out32( mmio, 0x4e14, 0x00000000 ); + radeon_out32( mmio, 0x4e18, 0x00000000 ); + radeon_out32( mmio, 0x4e50, 0x00000000 ); + radeon_out32( mmio, 0x4e54, 0x00000000 ); + radeon_out32( mmio, 0x4e58, 0x00000000 ); + radeon_out32( mmio, 0x4e5c, 0x00000000 ); + radeon_out32( mmio, 0x4e60, 0x00000000 ); + radeon_out32( mmio, 0x4e64, 0x00000000 ); + radeon_out32( mmio, 0x4e68, 0x00000000 ); + radeon_out32( mmio, 0x4e6c, 0x00000000 ); + radeon_out32( mmio, 0x4e70, 0x00000000 ); + radeon_out32( mmio, 0x4e88, 0x00000000 ); + radeon_out32( mmio, 0x4ea0, 0x00000000 ); + radeon_out32( mmio, 0x4ea4, 0xffffffff ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_CNTL_0, R300_RB3D_Z_DISABLED_1 ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_CNTL_1, R300_ZS_ALWAYS ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_CNTL_2, 0xffffff00 ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_FORMAT, R300_DEPTH_FORMAT_16BIT_INT_Z ); + radeon_out32( mmio, 0x4f14, 0x00000000 ); + radeon_out32( mmio, 0x4f18, 0x00000003 ); + radeon_out32( mmio, 0x4f1c, 0x00000000 ); + radeon_out32( mmio, 0x4f28, 0x00000000 ); + radeon_out32( mmio, 0x4f30, 0x00000000 ); + radeon_out32( mmio, 0x4f34, 0x00000000 ); + radeon_out32( mmio, 0x4f44, 0x00000000 ); + radeon_out32( mmio, 0x4f54, 0x00000000 ); + + /* upload vertex program */ + radeon_waitfifo( rdrv, rdev, 50 ); + radeon_out32( mmio, R300_VAP_PVS_CNTL_1, + (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | + (4 << R300_PVS_CNTL_1_POS_END_SHIFT) | + (4 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT) ); + radeon_out32( mmio, R300_VAP_PVS_CNTL_2, + (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | + (4 << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT) ); + radeon_out32( mmio, R300_VAP_PVS_CNTL_3, + (4 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | + (4 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT) ); + radeon_out32( mmio, R300_VAP_PVS_WAITIDLE, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_ADDRESS, R300_PVS_UPLOAD_POINTSIZE ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_WAITIDLE, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_ADDRESS, R300_PVS_UPLOAD_PROGRAM ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, TMP) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_X(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_SOURCE(0, ZERO, ZERO, ZERO, ZERO, PARAM, NONE) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, TMP) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_Y(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(1) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_TMP(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, TMP) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_Z(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(2) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_TMP(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, RESULT) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_W(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(3) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_TMP(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(ADD, 1, ALL, RESULT) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_REG(1) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_SOURCE(1, ZERO, ZERO, ZERO, ZERO, ATTR, NONE) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_SOURCE(1, ZERO, ZERO, ZERO, ZERO, ATTR, NONE) ); + radeon_out32( mmio, R300_VAP_PVS_WAITIDLE, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_ADDRESS, R300_PVS_UPLOAD_PARAMETERS ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + +#if 0 + /* set YUV422 color buffer */ + radeon_waitfifo( rdrv, rdev, 4 ); + radeon_out32( mmio, R300_TX_FILTER_1, R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST ); + radeon_out32( mmio, R300_TX_FILTER1_0, 0 ); + radeon_out32( mmio, R300_TX_SIZE_1, (1 << R300_TX_WIDTHMASK_SHIFT) | + (1 << R300_TX_HEIGHTMASK_SHIFT) ); + radeon_out32( mmio, R300_TX_FORMAT_1, R300_TXFORMAT_VYUY422 ); +#endif +} + +void r300_set_destination( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->destination; + CoreSurfaceBuffer *buffer = state->dst.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 offset; + u32 pitch; + u32 format = 0; + bool dst_422 = false; + + if (RADEON_IS_SET( DESTINATION )) + return; + + D_ASSERT( (state->dst.offset % 32) == 0 ); + D_ASSERT( (state->dst.pitch % 64) == 0 ); + + offset = radeon_buffer_offset( rdev, &state->dst ); + pitch = state->dst.pitch; + + if (rdev->dst_offset != offset || + rdev->dst_pitch != pitch || + rdev->dst_format != buffer->format) + { + switch (buffer->format) { + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_A8: + case DSPF_RGB332: + format = R300_COLOR_FORMAT_RGB8; + rdev->gui_master_cntl = GMC_DST_8BPP; + break; + case DSPF_ARGB2554: + rdev->gui_master_cntl = GMC_DST_16BPP; + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + rdev->gui_master_cntl = GMC_DST_16BPP; + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + rdev->gui_master_cntl = GMC_DST_15BPP; + break; + case DSPF_RGB16: + format = R300_COLOR_FORMAT_RGB565; + rdev->gui_master_cntl = GMC_DST_16BPP; + break; + case DSPF_RGB32: + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + format = R300_COLOR_FORMAT_ARGB8888; + rdev->gui_master_cntl = GMC_DST_32BPP; + break; + case DSPF_UYVY: + rdev->gui_master_cntl = GMC_DST_YVYU; + dst_422 = true; + break; + case DSPF_YUY2: + rdev->gui_master_cntl = GMC_DST_VYUY; + dst_422 = true; + break; + case DSPF_I420: + format = R300_COLOR_FORMAT_RGB8; + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->dst_offset_cb = offset + pitch * surface->config.size.h; + rdev->dst_offset_cr = rdev->dst_offset_cb + + pitch/2 * surface->config.size.h/2; + break; + case DSPF_YV12: + format = R300_COLOR_FORMAT_RGB8; + rdev->gui_master_cntl = GMC_DST_8BPP; + rdev->dst_offset_cr = offset + pitch * surface->config.size.h; + rdev->dst_offset_cb = rdev->dst_offset_cr + + pitch/2 * surface->config.size.h/2; + break; + default: + D_BUG( "unexpected pixelformat" ); + break; + } + + rdev->gui_master_cntl |= GMC_DP_SRC_SOURCE_MEMORY | + GMC_WR_MSK_DIS | + GMC_SRC_PITCH_OFFSET_CNTL | + GMC_DST_PITCH_OFFSET_CNTL | + GMC_DST_CLIPPING; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, offset ); + radeon_out32( mmio, DST_PITCH, pitch ); + + if (R300_HAS_3DREGS() && format) { + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, offset ); + radeon_out32( mmio, R300_RB3D_COLORPITCH0, + ((pitch / DFB_BYTES_PER_PIXEL(buffer->format)) + & R300_COLORPITCH_MASK) | format ); + } + + if (rdev->dst_format != buffer->format) { + if (dst_422 && !rdev->dst_422) { + RADEON_UNSET( CLIP ); + RADEON_UNSET( SOURCE ); + rdev->src_format = DSPF_UNKNOWN; + } + + RADEON_UNSET( COLOR ); + RADEON_UNSET( DST_BLEND ); + } + + rdev->dst_format = buffer->format; + rdev->dst_offset = offset; + rdev->dst_pitch = pitch; + rdev->dst_422 = dst_422; + } + + RADEON_SET( DESTINATION ); +} + +void r300_set_source( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + CoreSurface *surface = state->source; + CoreSurfaceBuffer *buffer = state->src.buffer; + volatile u8 *mmio = rdrv->mmio_base; + u32 txformat = 0; + u32 txfilter = (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT) | + (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) | + (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT) | + R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR; + + if (RADEON_IS_SET( SOURCE )) { + if ((state->blittingflags & DSBLIT_DEINTERLACE) == + (rdev->blittingflags & DSBLIT_DEINTERLACE)) + return; + } + + D_ASSERT( (state->src.offset % 32) == 0 ); + D_ASSERT( (state->src.pitch % 64) == 0 ); + + rdev->src_offset = radeon_buffer_offset( rdev, &state->src ); + rdev->src_pitch = state->src.pitch; + rdev->src_width = surface->config.size.w; + rdev->src_height = surface->config.size.h; + + switch (buffer->format) { + case DSPF_LUT8: + txformat = R300_TXFORMAT_I8; + txfilter &= ~(R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR); + txfilter |= R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST; + rdev->src_mask = 0x000000ff; + break; + case DSPF_ALUT44: + txformat = R300_TXFORMAT_I8; + txfilter &= ~(R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR); + txfilter |= R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST; + rdev->src_mask = 0x0000000f; + break; + case DSPF_A8: + txformat = R300_TXFORMAT_A8; + rdev->src_mask = 0; + break; + case DSPF_RGB332: + txformat = R300_TXFORMAT_RGB332; + rdev->src_mask = 0x000000ff; + break; + case DSPF_ARGB2554: + txformat = R300_TXFORMAT_RGB565; + txfilter &= ~(R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR); + txfilter |= R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST; + rdev->src_mask = 0x00003fff; + break; + case DSPF_RGB444: + txformat = R300_TXFORMAT_RGB444; + rdev->src_mask = 0x00000fff; + break; + case DSPF_ARGB4444: + txformat = R300_TXFORMAT_ARGB4444; + rdev->src_mask = 0x00000fff; + break; + case DSPF_RGB555: + txformat = R300_TXFORMAT_RGB555; + rdev->src_mask = 0x00007fff; + break; + case DSPF_ARGB1555: + txformat = R300_TXFORMAT_ARGB1555; + rdev->src_mask = 0x00007fff; + break; + case DSPF_RGB16: + txformat = R300_TXFORMAT_RGB565; + rdev->src_mask = 0x0000ffff; + break; + case DSPF_RGB32: + txformat = R300_TXFORMAT_XRGB8888; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + txformat = R300_TXFORMAT_ARGB8888; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_UYVY: + txformat = R300_TXFORMAT_YVYU422; + rdev->src_mask = 0xffffffff; + break; + case DSPF_YUY2: + txformat = R300_TXFORMAT_VYUY422; + rdev->src_mask = 0xffffffff; + break; + case DSPF_I420: + txformat = R300_TXFORMAT_I8; + rdev->src_offset_cb = rdev->src_offset + + rdev->src_pitch * rdev->src_height; + rdev->src_offset_cr = rdev->src_offset_cb + + rdev->src_pitch/2 * rdev->src_height/2; + rdev->src_mask = 0x000000ff; + break; + case DSPF_YV12: + txformat = R300_TXFORMAT_I8; + rdev->src_offset_cr = rdev->src_offset + + rdev->src_pitch * rdev->src_height; + rdev->src_offset_cb = rdev->src_offset_cr + + rdev->src_pitch/2 * rdev->src_height/2; + rdev->src_mask = 0x000000ff; + break; + default: + D_BUG( "unexpected pixelformat" ); + break; + } + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + rdev->src_height /= 2; + if (surface->config.caps & DSCAPS_SEPARATED) { + if (surface->field) { + rdev->src_offset += rdev->src_height * rdev->src_pitch; + rdev->src_offset_cr += rdev->src_height * rdev->src_pitch/4; + rdev->src_offset_cb += rdev->src_height * rdev->src_pitch/4; + } + } else { + if (surface->field) { + rdev->src_offset += rdev->src_pitch; + rdev->src_offset_cr += rdev->src_pitch/2; + rdev->src_offset_cb += rdev->src_pitch/2; + } + rdev->src_pitch *= 2; + } + } + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch ); + + if (R300_HAS_3DREGS()) { + radeon_waitfifo( rdrv, rdev, 6 ); + radeon_out32( mmio, R300_TX_CNTL, 0 ); + radeon_out32( mmio, R300_TX_FILTER_0, txfilter ); + radeon_out32( mmio, R300_TX_FORMAT_0, txformat ); + radeon_out32( mmio, R300_TX_SIZE_0, ((rdev->src_width -1) << R300_TX_WIDTH_SHIFT) | + ((rdev->src_height-1) << R300_TX_HEIGHT_SHIFT) | + R300_TX_SIZE_TXPITCH_EN ); + radeon_out32( mmio, R300_TX_PITCH_0, rdev->src_pitch / + DFB_BYTES_PER_PIXEL(buffer->format) - 8 ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset ); + } + + if (rdev->src_format != buffer->format) + RADEON_UNSET( BLITTING_FLAGS ); + rdev->src_format = buffer->format; + + RADEON_SET( SOURCE ); +} + +void r300_set_clip3d( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + const DFBRegion *clip ) +{ + volatile u8 *mmio = rdrv->mmio_base; + int x1, y1, x2, y2; + + x1 = clip->x1 + R300_CLIPRECT_OFFSET; + y1 = clip->y1 + R300_CLIPRECT_OFFSET; + x2 = clip->x2 + R300_CLIPRECT_OFFSET; + y2 = clip->y2 + R300_CLIPRECT_OFFSET; + + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R300_RE_CLIPRECT_TL_0, + ((y1 << R300_CLIPRECT_Y_SHIFT) & R300_CLIPRECT_Y_MASK) | + ((x1 << R300_CLIPRECT_X_SHIFT) & R300_CLIPRECT_X_MASK) ); + radeon_out32( mmio, R300_RE_CLIPRECT_BR_0, + ((y2 << R300_CLIPRECT_Y_SHIFT) & R300_CLIPRECT_Y_MASK) | + ((x2 << R300_CLIPRECT_X_SHIFT) & R300_CLIPRECT_X_MASK) ); + radeon_out32( mmio, R300_RE_CLIPRECT_CNTL, 0x0000aaaa ); + radeon_out32( mmio, R300_RE_SCISSORS_TL, + ((y1 << R300_SCISSORS_Y_SHIFT) & R300_SCISSORS_Y_MASK) | + ((x1 << R300_SCISSORS_X_SHIFT) & R300_SCISSORS_X_MASK) ); + radeon_out32( mmio, R300_RE_SCISSORS_BR, + ((y2 << R300_SCISSORS_Y_SHIFT) & R300_SCISSORS_Y_MASK) | + ((x2 << R300_SCISSORS_X_SHIFT) & R300_SCISSORS_X_MASK) ); +} + +void r300_set_clip( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBRegion *clip = &state->clip; + volatile u8 *mmio = rdrv->mmio_base; + + if (RADEON_IS_SET( CLIP )) + return; + + /* 2d clip */ + radeon_waitfifo( rdrv, rdev, 2 ); + if (rdev->dst_422) { + radeon_out32( mmio, SC_TOP_LEFT, + (clip->y1 << 16) | (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, + ((clip->y2+1) << 16) | ((clip->x2+1)/2 & 0xffff) ); + } else { + radeon_out32( mmio, SC_TOP_LEFT, + (clip->y1 << 16) | (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, + ((clip->y2+1) << 16) | ((clip->x2+1) & 0xffff) ); + } + + /* 3d clip */ + if (R300_HAS_3DREGS()) + r300_set_clip3d( rdrv, rdev, clip ); + + rdev->clip = state->clip; + + RADEON_SET( CLIP ); +} + +#define R300_SET_YUV422_COLOR( rdrv, rdev, y, u, v ) \ + if (R300_HAS_3DREGS()) { \ + radeon_out32( (rdrv)->fb_base, \ + (rdev)->yuv422_buffer, PIXEL_YUY2( y, u, v ) ); \ + radeon_in8( (rdrv)->fb_base, (rdev)->yuv422_buffer ); \ + radeon_waitfifo( rdrv, rdev, 1 ); \ + radeon_out32( (rdrv)->mmio_base, R300_TX_OFFSET_1, \ + ((rdev)->fb_offset + (rdev)->yuv422_buffer) ); \ + } + +void r300_set_drawing_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + int index = state->color_index; + u32 color2d; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) { + color.r = ((long) color.r * color.a / 255L); + color.g = ((long) color.g * color.a / 255L); + color.b = ((long) color.b * color.a / 255L); + } + + switch (rdev->dst_format) { + case DSPF_ALUT44: + index |= (color.a & 0xf0); + case DSPF_LUT8: + color2d = index; + break; + case DSPF_A8: + color2d = color.a; + break; + case DSPF_RGB332: + color2d = PIXEL_RGB332( color.r, color.g, color.b ); + break; + case DSPF_ARGB2554: + color2d = PIXEL_ARGB2554( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + color2d = PIXEL_ARGB4444( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + color2d = PIXEL_ARGB1555( color.a, color.r, + color.g, color.b ); + break; + case DSPF_RGB16: + color2d = PIXEL_RGB16( color.r, color.g, color.b ); + break; + case DSPF_RGB32: + color2d = PIXEL_RGB32( color.r, color.g, color.b ); + break; + case DSPF_ARGB: + color2d = PIXEL_ARGB( color.a, color.r, + color.g, color.b ); + break; + case DSPF_AiRGB: + color2d = PIXEL_AiRGB( color.a, color.r, + color.g, color.b ); + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_AYUV( color.a, y, u, v ); + break; + case DSPF_UYVY: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_UYVY( y, u, v ); + //R300_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + break; + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color2d = PIXEL_YUY2( y, u, v ); + //R300_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + break; + case DSPF_I420: + case DSPF_YV12: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + rdev->y_cop = PIXEL_ARGB( color.a, y, y, y ); + rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u ); + rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v ); + color2d = rdev->y_cop; + break; + default: + D_BUG( "unexpected pixelformat" ); + color2d = 0; + break; + } + + rdev->color[0] = (float)color.r/255.0; + rdev->color[1] = (float)color.g/255.0; + rdev->color[2] = (float)color.b/255.0; + rdev->color[3] = (float)color.a/255.0; + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, DP_BRUSH_FRGD_CLR, color2d ); + + RADEON_SET( COLOR ); +} + +void r300_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( BLITTING_FLAGS )) + return; + + switch (rdev->dst_format) { + case DSPF_A8: + color.r = color.g = color.b = 0xff; + break; + case DSPF_I420: + case DSPF_YV12: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + rdev->y_cop = PIXEL_ARGB( color.a, y, y, y ); + rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u ); + rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v ); + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color.r = y; + color.g = u; + color.b = v; + break; + case DSPF_UYVY: + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + //R300_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + default: + break; + } + + /*rdev->color[0] = (float)color.r/255.0; + rdev->color[1] = (float)color.g/255.0; + rdev->color[2] = (float)color.b/255.0; + rdev->color[3] = (float)color.a/255.0;*/ + + if (R300_HAS_3DREGS()) { + u32 argb; + + argb = (state->blittingflags & DSBLIT_BLEND_COLORALPHA) ? (color.a << 24) : 0xff000000; + if (state->blittingflags & DSBLIT_COLORIZE && + state->blittingflags & (DSBLIT_SRC_PREMULTCOLOR | DSBLIT_BLEND_COLORALPHA)) { + argb |= PIXEL_RGB32( (long)color.r * color.a / 255L, + (long)color.g * color.a / 255L, + (long)color.b * color.a / 255L ); + } + else { + argb |= (state->blittingflags & DSBLIT_COLORIZE) + ? PIXEL_RGB32( color.r, color.g, color.b ) + : PIXEL_RGB32( color.a, color.a, color.a ); + } + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, R300_RB3D_BLENDCOLOR, argb ); + } + + RADEON_SET( COLOR ); +} + +void r300_set_src_colorkey( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 key = state->src_colorkey; + + if (RADEON_IS_SET( SRC_COLORKEY )) + return; + + switch (rdev->src_format) { + case DSPF_ARGB4444: + key |= 0xf000; + break; + case DSPF_ARGB2554: + key |= 0xc000; + break; + case DSPF_ARGB1555: + key |= 0x8000; + break; + case DSPF_ARGB: + case DSPF_AYUV: + key |= 0xff000000; + break; + default: + break; + } + + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, CLR_CMP_CLR_SRC, key ); + /* XXX: R300 seems to ignore CLR_CMP_MASK. */ + radeon_out32( mmio, CLR_CMP_MASK, rdev->src_mask ); + if (R300_HAS_3DREGS()) + radeon_out32( mmio, R300_TX_CHROMA_KEY_0, state->src_colorkey ); + + RADEON_SET( SRC_COLORKEY ); +} + +void +r300_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + u32 sblend, dblend; + + if (RADEON_IS_SET( SRC_BLEND ) && RADEON_IS_SET( DST_BLEND )) + return; + + sblend = r300SrcBlend[state->src_blend-1]; + dblend = r300DstBlend[state->dst_blend-1]; + + if (!DFB_PIXELFORMAT_HAS_ALPHA(rdev->dst_format)) { + if (sblend == SRC_BLEND_GL_DST_ALPHA) + sblend = SRC_BLEND_GL_ONE; + else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA) + sblend = SRC_BLEND_GL_ZERO; + + if (dblend == DST_BLEND_GL_DST_ALPHA) + dblend = DST_BLEND_GL_ONE; + else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA) + dblend = DST_BLEND_GL_ZERO; + } + + rdev->rb3d_blend = sblend | dblend; + + RADEON_UNSET( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); + RADEON_SET( SRC_BLEND ); + RADEON_SET( DST_BLEND ); +} + +void r300_set_render_options( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + if (RADEON_IS_SET( RENDER_OPTIONS )) + return; + + if (state->render_options & DSRO_MATRIX && + (!state->affine_matrix || + state->matrix[0] != (1<<16) || state->matrix[1] != 0 || state->matrix[2] != 0 || + state->matrix[3] != 0 || state->matrix[4] != (1<<16) || state->matrix[5] != 0)) { + rdev->matrix = state->matrix; + rdev->affine_matrix = state->affine_matrix; + } + else { + rdev->matrix = NULL; + } + + /* TODO: antialiasing */ +#if 0 + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, R300_GB_AA_CONFIG, + (state->render_options & DSRO_ANTIALIAS) ? R300_AA_ENABLE : 0 ); +#endif + rdev->render_options = state->render_options & ~DSRO_ANTIALIAS; + + RADEON_SET( RENDER_OPTIONS ); +} + +void r300_set_drawingflags( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 master_cntl = rdev->gui_master_cntl | + GMC_SRC_DATATYPE_MONO_FG_LA | + GMC_BRUSH_SOLID_COLOR | + GMC_CLR_CMP_CNTL_DIS; + u32 rb3d_blend; + + if (RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (state->drawingflags & DSDRAW_BLEND) { + rb3d_blend = R300_BLEND_ENABLE | R300_BLEND_UNKNOWN | + R300_BLEND_NO_SEPARATE | rdev->rb3d_blend; + } + else { + rb3d_blend = R300_SRC_BLEND_GL_ONE | R300_DST_BLEND_GL_ZERO; + } + + if (state->drawingflags & DSDRAW_XOR) + master_cntl |= GMC_ROP3_PATXOR; + else + master_cntl |= GMC_ROP3_PATCOPY; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + radeon_out32( mmio, DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM ); + + if (R300_HAS_3DREGS()) { + radeon_waitfifo( rdrv, rdev, 27 ); + radeon_out32( mmio, R300_TX_ENABLE, 0 ); + radeon_out32( mmio, R300_RE_SHADE_MODEL, R300_RE_SHADE_MODEL_FLAT ); + /* fragment program */ + radeon_out32( mmio, R300_PFS_CNTL_0, 0 ); + radeon_out32( mmio, R300_PFS_CNTL_1, 0 ); + radeon_out32( mmio, R300_PFS_CNTL_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_0, 0 ); + radeon_out32( mmio, R300_PFS_NODE_1, 0 ); + radeon_out32( mmio, R300_PFS_NODE_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_3, R300_PFS_NODE_OUTPUT_COLOR ); + radeon_out32( mmio, R300_PFS_INSTR0_0, + FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR1_0, + FP_SELC(0,NO,XYZ,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + radeon_out32( mmio, R300_PFS_INSTR2_0, + FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR3_0, + FP_SELA(0,NO,W,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + /* blend functions */ + radeon_out32( mmio, R300_RB3D_CBLEND, rb3d_blend ); + radeon_out32( mmio, R300_RB3D_ABLEND, rb3d_blend & 0xfffffff0 ); + /* routing */ + radeon_out32( mmio, R300_RS_CNTL_0, (0 << R300_RS_CNTL_TC_CNT_SHIFT) | + (1 << R300_RS_CNTL_CI_CNT_SHIFT) | + R300_RS_CNTL_0_UNKNOWN_18 ); + radeon_out32( mmio, R300_RS_CNTL_1, 0x000000c0 ); + radeon_out32( mmio, R300_RS_ROUTE_0, R300_RS_ROUTE_0_COLOR ); + /* input */ + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_0_0, 0x21030003 ); + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_1_0, 0xf688f688 ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_0, R300_INPUT_CNTL_0_COLOR ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_1, R300_INPUT_CNTL_POS | + R300_INPUT_CNTL_COLOR ); + /* output */ + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT ); + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_1, 0 ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_0, + R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT | + R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_1, 0 ); + radeon_out32( mmio, R300_VAP_UNKNOWN_221C, R300_221C_CLEAR ); + } + + rdev->drawingflags = state->drawingflags; + + RADEON_SET ( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); +} + +void r300_set_blittingflags( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 master_cntl = rdev->gui_master_cntl | + GMC_BRUSH_NONE | + GMC_SRC_DATATYPE_COLOR; + u32 txfilter1 = R300_TX_TRI_PERF_0_8; + u32 cmp_cntl = 0; + u32 rb3d_blend; + + if (RADEON_IS_SET( BLITTING_FLAGS )) + return; + + if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA | + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) { + rb3d_blend = R300_BLEND_ENABLE | R300_BLEND_UNKNOWN | R300_BLEND_NO_SEPARATE; + + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + rb3d_blend |= rdev->rb3d_blend; + else + rb3d_blend |= R300_SRC_BLEND_GL_ONE | R300_DST_BLEND_GL_ZERO; + + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + rb3d_blend &= ~(R300_SRC_BLEND_MASK | R300_DST_BLEND_MASK); + rb3d_blend |= R300_SRC_BLEND_GL_CONST_ALPHA | + R300_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA; + } + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) { + rb3d_blend &= ~R300_SRC_BLEND_MASK; + rb3d_blend |= R300_SRC_BLEND_GL_CONST_COLOR; + } + } + else { + rb3d_blend = R300_SRC_BLEND_GL_ONE | R300_DST_BLEND_GL_ZERO; + } + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + txfilter1 |= R300_CHROMA_KEY_FORCE; + cmp_cntl = SRC_CMP_EQ_COLOR | CLR_CMP_SRC_SOURCE; + } + else { + master_cntl |= GMC_CLR_CMP_CNTL_DIS; + } + + if (state->blittingflags & DSBLIT_XOR) + master_cntl |= GMC_ROP3_XOR; + else + master_cntl |= GMC_ROP3_SRCCOPY; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, CLR_CMP_CNTL, cmp_cntl ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + + if (R300_HAS_3DREGS()) { + radeon_waitfifo( rdrv, rdev, 29 ); + radeon_out32( mmio, R300_TX_FILTER1_0, txfilter1 ); + radeon_out32( mmio, R300_TX_ENABLE, R300_TX_ENABLE_0 ); + if (rdev->accel == DFXL_TEXTRIANGLES) + radeon_out32( mmio, R300_RE_SHADE_MODEL, R300_RE_SHADE_MODEL_SMOOTH ); + else + radeon_out32( mmio, R300_RE_SHADE_MODEL, R300_RE_SHADE_MODEL_FLAT ); + /* fragment program */ + radeon_out32( mmio, R300_PFS_CNTL_0, R300_PFS_CNTL_FIRST_NODE_HAS_TEX ); + radeon_out32( mmio, R300_PFS_CNTL_1, 0 ); + radeon_out32( mmio, R300_PFS_CNTL_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_0, 0 ); + radeon_out32( mmio, R300_PFS_NODE_1, 0 ); + radeon_out32( mmio, R300_PFS_NODE_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_3, R300_PFS_NODE_OUTPUT_COLOR ); + radeon_out32( mmio, R300_PFS_TEXI_0, R300_FPITX_OP_TXP ); + radeon_out32( mmio, R300_PFS_INSTR0_0, + FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR1_0, + FP_SELC(0,NO,XYZ,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + radeon_out32( mmio, R300_PFS_INSTR2_0, + FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR3_0, + FP_SELA(0,NO,W,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + /* blend functions */ + radeon_out32( mmio, R300_RB3D_CBLEND, rb3d_blend ); + radeon_out32( mmio, R300_RB3D_ABLEND, rb3d_blend & 0xfffffff0 ); + /* routing */ + radeon_out32( mmio, R300_RS_CNTL_0, (1 << R300_RS_CNTL_TC_CNT_SHIFT) | + (0 << R300_RS_CNTL_CI_CNT_SHIFT) | + R300_RS_CNTL_0_UNKNOWN_18 ); + radeon_out32( mmio, R300_RS_CNTL_1, 0x000000c0 ); + radeon_out32( mmio, R300_RS_ROUTE_0, R300_RS_ROUTE_ENABLE ); + /* input routing */ + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_0_0, 0x21030003 ); + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_1_0, 0xf688f688 ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_0, 0x5555 ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_1, R300_INPUT_CNTL_POS | + R300_INPUT_CNTL_TC0 ); + /* output routing */ + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT ); + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_1, 4 ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_0, + R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_1, 4 ); + radeon_out32( mmio, R300_VAP_UNKNOWN_221C, R300_221C_CLEAR ); + } + + rdev->blittingflags = state->blittingflags; + + RADEON_SET ( BLITTING_FLAGS ); + RADEON_UNSET( DRAWING_FLAGS ); +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon.c b/Source/DirectFB/gfxdrivers/radeon/radeon.c new file mode 100755 index 0000000..19f8c49 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon.c @@ -0,0 +1,1753 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +#include <dfb_types.h> +#include <directfb.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/state.h> +#include <core/gfxcard.h> +#include <core/screens.h> +#include <core/surface.h> +#include <core/palette.h> +#include <core/system.h> + +#include <fbdev/fb.h> + +#include <gfx/convert.h> + +#include <misc/conf.h> +#include <misc/util.h> + +#include <core/graphics_driver.h> + +DFB_GRAPHICS_DRIVER( radeon ) + + +#include "radeon.h" +#include "radeon_chipsets.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_state.h" +#include "radeon_2d.h" +#include "radeon_3d.h" + + +/* Enable the following option if you see strange behaviours */ +#define RESET_AFTER_SETVAR 0 + + +/* Driver capability flags */ +#define RADEON_SUPPORTED_2D_DRAWINGFLAGS \ + ( DSDRAW_XOR ) + +#define RADEON_SUPPORTED_2D_DRAWINGFUNCS \ + ( DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | DFXL_DRAWLINE ) + +#define RADEON_SUPPORTED_2D_BLITTINGFLAGS \ + ( DSBLIT_XOR | DSBLIT_SRC_COLORKEY ) + +#define RADEON_SUPPORTED_2D_BLITTINGFUNCS \ + ( DFXL_BLIT ) + + +#define R100_SUPPORTED_DRAWINGFLAGS \ + ( RADEON_SUPPORTED_2D_DRAWINGFLAGS | DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY ) + +#define R100_SUPPORTED_DRAWINGFUNCS \ + ( RADEON_SUPPORTED_2D_DRAWINGFUNCS | DFXL_FILLTRIANGLE ) + +#define R100_SUPPORTED_BLITTINGFLAGS \ + ( RADEON_SUPPORTED_2D_BLITTINGFLAGS | \ + DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA | \ + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR | \ + DSBLIT_DEINTERLACE | DSBLIT_ROTATE180 | \ + DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR | \ + DSBLIT_SRC_PREMULTIPLY ) + +#define R100_SUPPORTED_BLITTINGFUNCS \ + ( RADEON_SUPPORTED_2D_BLITTINGFUNCS | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES ) + + +#define R200_SUPPORTED_DRAWINGFLAGS \ + ( RADEON_SUPPORTED_2D_DRAWINGFLAGS | DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY ) + +#define R200_SUPPORTED_DRAWINGFUNCS \ + ( RADEON_SUPPORTED_2D_DRAWINGFUNCS | DFXL_FILLTRIANGLE ) + +#define R200_SUPPORTED_BLITTINGFLAGS \ + ( RADEON_SUPPORTED_2D_BLITTINGFLAGS | \ + DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA | \ + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR | \ + DSBLIT_DEINTERLACE | DSBLIT_ROTATE180 | \ + DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR | \ + DSBLIT_SRC_PREMULTIPLY ) + +#define R200_SUPPORTED_BLITTINGFUNCS \ + ( RADEON_SUPPORTED_2D_BLITTINGFUNCS | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES ) + + +#define R300_SUPPORTED_DRAWINGFLAGS \ + ( RADEON_SUPPORTED_2D_DRAWINGFLAGS | DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY ) + +#define R300_SUPPORTED_DRAWINGFUNCS \ + ( RADEON_SUPPORTED_2D_DRAWINGFUNCS | DFXL_FILLTRIANGLE ) + +#define R300_SUPPORTED_BLITTINGFLAGS \ + ( RADEON_SUPPORTED_2D_BLITTINGFLAGS | \ + DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA | \ + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR | \ + DSBLIT_DEINTERLACE | DSBLIT_ROTATE180 ) + +#define R300_SUPPORTED_BLITTINGFUNCS \ + ( RADEON_SUPPORTED_2D_BLITTINGFUNCS | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES ) + + +#define DSBLIT_MODULATE_ALPHA ( DSBLIT_BLEND_ALPHACHANNEL | \ + DSBLIT_BLEND_COLORALPHA ) +#define DSBLIT_MODULATE_COLOR ( DSBLIT_BLEND_COLORALPHA | \ + DSBLIT_COLORIZE | \ + DSBLIT_SRC_PREMULTCOLOR ) +#define DSBLIT_MODULATE ( DSBLIT_MODULATE_ALPHA | \ + DSBLIT_MODULATE_COLOR | \ + DSBLIT_SRC_PREMULTIPLY ) +#define DSBLIT_MASK ( DSBLIT_SRC_MASK_ALPHA | \ + DSBLIT_SRC_MASK_COLOR ) + +#define RADEON_DRAW_3D() ( rdev->accel & DFXL_FILLTRIANGLE || \ + rdev->drawingflags & ~DSDRAW_XOR || \ + rdev->matrix != NULL || \ + (rdev->render_options & DSRO_ANTIALIAS && \ + rdev->accel & DFXL_DRAWLINE) ) + +#define RADEON_BLIT_3D() ( rdev->accel & ~DFXL_BLIT ||\ + rdev->blittingflags & ~(DSBLIT_XOR | \ + DSBLIT_SRC_COLORKEY) || \ + rdev->matrix != NULL || \ + (rdev->dst_format != rdev->src_format && \ + !(DFB_PLANAR_PIXELFORMAT(rdev->dst_format) && \ + DFB_PLANAR_PIXELFORMAT(rdev->src_format) ))) + +#define RADEON_FUNC( f ) DFB_PLANAR_PIXELFORMAT(rdev->dst_format) ? f##_420 : f + + +static inline bool +radeon_compatible_format( RadeonDriverData *rdrv, DFBSurfacePixelFormat format ) +{ +#ifdef WORDS_BIGENDIAN + u32 tmp, bpp; + + bpp = DFB_BYTES_PER_PIXEL( format ); + tmp = radeon_in32( rdrv->mmio_base, CRTC_GEN_CNTL ); + switch ((tmp >> 8) & 0xf) { + case DST_8BPP: + case DST_24BPP: + if (bpp == 2 || bpp == 4) + return false; + break; + case DST_15BPP: + case DST_16BPP: + if (bpp != 2) + return false; + break; + default: + if (bpp != 4) + return false; + break; + } +#endif + return true; +} + +static void +radeon_get_monitors( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + RadeonMonitorType *ret_monitor1, + RadeonMonitorType *ret_monitor2 ) +{ + RadeonMonitorType dvimon = MT_NONE; + RadeonMonitorType vgamon = MT_NONE; +#if D_DEBUG_ENABLED + const char *name[] = { "NONE", "CRT", "DFP", + "LCD", "CTV", "STV" }; +#endif + u32 tmp; + + if (rdev->chipset != CHIP_R100) { + if (rdev->chipset >= CHIP_R300 || + rdev->chipset == CHIP_UNKNOWN) + tmp = radeon_in32( rdrv->mmio_base, BIOS_0_SCRATCH ); + else + tmp = radeon_in32( rdrv->mmio_base, BIOS_4_SCRATCH ); + + /* DVI/TVO port */ + if (tmp & 0x08) + dvimon = MT_DFP; + else if (tmp & 0x4) + dvimon = MT_LCD; + else if (tmp & 0x200) + dvimon = MT_CRT; + else if (tmp & 0x10) + dvimon = MT_CTV; + else if (tmp & 0x20) + dvimon = MT_STV; + + /* VGA port */ + if (tmp & 0x2) + vgamon = MT_CRT; + else if (tmp & 0x800) + vgamon = MT_DFP; + else if (tmp & 0x400) + vgamon = MT_LCD; + else if (tmp & 0x1000) + vgamon = MT_CTV; + else if (tmp & 0x2000) + vgamon = MT_STV; + } + else { + tmp = radeon_in32( rdrv->mmio_base, FP_GEN_CNTL ); + + if (tmp & FP_EN_TMDS) + vgamon = MT_DFP; + else + vgamon = MT_CRT; + } + + D_DEBUG( "DirectFB/Radeon: " + "DVI/TVO Port -> %s, VGA Port -> %s.\n", + name[dvimon], name[vgamon] ); + + if (dvimon) { + /* If DVI port is connected, then + * DVI port is the primary head and + * CRT port is the secondary head. + */ + if (ret_monitor1) + *ret_monitor1 = dvimon; + if (ret_monitor2) + *ret_monitor2 = vgamon; + } + else { + if (ret_monitor1) + *ret_monitor1 = vgamon; + if (ret_monitor2) + *ret_monitor2 = MT_NONE; + } +} + +void +radeon_reset( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 clock_cntl_index; + u32 mclk_cntl; + u32 rbbm_soft_reset; + u32 host_path_cntl; + + clock_cntl_index = radeon_in32( mmio, CLOCK_CNTL_INDEX ); + + mclk_cntl = radeon_inpll( mmio, MCLK_CNTL ); + radeon_outpll( mmio, MCLK_CNTL, mclk_cntl | + FORCEON_MCLKA | + FORCEON_MCLKB | + FORCEON_YCLKA | + FORCEON_YCLKB | + FORCEON_MC | + FORCEON_AIC ); + + host_path_cntl = radeon_in32( mmio, HOST_PATH_CNTL ); + rbbm_soft_reset = radeon_in32( mmio, RBBM_SOFT_RESET ); + + radeon_out32( mmio, RBBM_SOFT_RESET, rbbm_soft_reset | + SOFT_RESET_CP | SOFT_RESET_HI | + SOFT_RESET_SE | SOFT_RESET_RE | + SOFT_RESET_PP | SOFT_RESET_E2 | + SOFT_RESET_RB ); + radeon_in32( mmio, RBBM_SOFT_RESET ); + + radeon_out32( mmio, RBBM_SOFT_RESET, rbbm_soft_reset & + ~(SOFT_RESET_CP | SOFT_RESET_HI | + SOFT_RESET_SE | SOFT_RESET_RE | + SOFT_RESET_PP | SOFT_RESET_E2 | + SOFT_RESET_RB) ); + radeon_in32( mmio, RBBM_SOFT_RESET ); + + radeon_out32( mmio, HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET ); + radeon_in32( mmio, HOST_PATH_CNTL ); + radeon_out32( mmio, HOST_PATH_CNTL, host_path_cntl ); + + radeon_out32( mmio, RBBM_SOFT_RESET, rbbm_soft_reset ); + + radeon_out32( mmio, CLOCK_CNTL_INDEX, clock_cntl_index ); + radeon_outpll( mmio, MCLK_CNTL, mclk_cntl ); + + rdev->set = 0; + rdev->src_format = DSPF_UNKNOWN; + rdev->dst_format = DSPF_UNKNOWN; + rdev->fifo_space = 0; +} + +static void radeonAfterSetVar( void *drv, void *dev ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + volatile u8 *mmio = rdrv->mmio_base; + + rdev->surface_cntl = + rdev->surface_cntl_c = + rdev->surface_cntl_p = radeon_in32( mmio, SURFACE_CNTL ); + + radeon_out32( mmio, CRTC_OFFSET_CNTL, + (radeon_in32( mmio, CRTC_OFFSET_CNTL ) & ~CRTC_TILE_EN) | CRTC_HSYNC_EN ); + +#if RESET_AFTER_SETVAR + radeon_waitidle( rdrv, rdev ); + radeon_reset( rdrv, rdev ); +#endif +} + +static void radeonEngineReset( void *drv, void *dev ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + volatile u8 *mmio = rdrv->mmio_base; + + rdev->fifo_space = 0; + + radeon_out32( mmio, SURFACE_CNTL, rdev->surface_cntl_c ); + + radeon_waitfifo( rdrv, rdev, 3 ); +#ifdef WORDS_BIGENDIAN + radeon_out32( mmio, DP_DATATYPE, + radeon_in32( mmio, DP_DATATYPE ) | HOST_BIG_ENDIAN_EN ); +#else + radeon_out32( mmio, DP_DATATYPE, + radeon_in32( mmio, DP_DATATYPE ) & ~HOST_BIG_ENDIAN_EN ); +#endif + radeon_out32( mmio, DEFAULT_SC_BOTTOM_RIGHT, DEFAULT_SC_RIGHT_MAX | + DEFAULT_SC_BOTTOM_MAX ); + radeon_out32( mmio, AUX_SC_CNTL, 0 ); + + if (rdev->chipset >= CHIP_R300) { + r300_restore( rdrv, rdev ); + } + else if (rdev->chipset >= CHIP_R200) { + r200_restore( rdrv, rdev ); + } + else if (rdev->chipset >= CHIP_R100) { + r100_restore( rdrv, rdev ); + } + + /* sync 2d and 3d engines */ + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, ISYNC_CNTL, ISYNC_ANY2D_IDLE3D | + ISYNC_ANY3D_IDLE2D ); +} + +static DFBResult radeonEngineSync( void *drv, void *dev ) +{ + if (!radeon_waitidle( (RadeonDriverData*)drv, (RadeonDeviceData*)dev )) + return DFB_IO; /* DFB_TIMEOUT !? */ + + return DFB_OK; +} + +static void radeonInvalidateState( void *drv, void *dev ) +{ + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + rdev->set = 0; + rdev->dst_format = DSPF_UNKNOWN; + rdev->src_format = DSPF_UNKNOWN; + rdev->msk_format = DSPF_UNKNOWN; +} + +static void radeonFlushTextureCache( void *drv, void *dev ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + volatile u8 *mmio = rdrv->mmio_base; + + if (rdev->chipset >= CHIP_R300) { + if (rdrv->mmio_size > 0x4000) { + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, R300_TX_CNTL, 0 ); + } + } + else if (rdev->chipset >= CHIP_R200) { + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, R200_PP_TXOFFSET_0, rdev->src_offset ); + radeon_out32( mmio, R200_PP_TXOFFSET_1, rdev->msk_offset ); + } + else if (rdev->chipset >= CHIP_R100) { + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset ); + radeon_out32( mmio, PP_TXOFFSET_1, rdev->msk_offset ); + } +} + +#ifdef WORDS_BIGENDIAN +static void radeonSurfaceEnter( void *drv, void *dev, + CoreSurfaceBuffer *buffer, DFBSurfaceLockFlags flags ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + volatile u8 *mmio = rdrv->mmio_base; + u32 tmp; + + if (!(flags & DSLF_WRITE)) + return; + + rdev->surface_cntl_p = radeon_in32( mmio, SURFACE_CNTL ); + + tmp = rdev->surface_cntl_p & ~SURF_TRANSLATION_DIS; + tmp &= ~(NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP | + NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP); + + switch (DFB_BITS_PER_PIXEL( buffer->format )) { + case 16: + tmp |= NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP; + break; + case 32: + tmp |= NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP; + break; + default: + break; + } + + radeon_out32( mmio, SURFACE_CNTL, tmp ); + rdev->surface_cntl_c = tmp; +} + +static void radeonSurfaceLeave( void *drv, void *dev, CoreSurfaceBuffer *buffer ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + volatile u8 *mmio = rdrv->mmio_base; + + if (rdev->surface_cntl_p != rdev->surface_cntl_c) { + radeon_out32( mmio, SURFACE_CNTL, rdev->surface_cntl_p ); + rdev->surface_cntl_c = rdev->surface_cntl_p; + } +} +#endif + +static void r100CheckState( void *drv, void *dev, + CardState *state, DFBAccelerationMask accel ) +{ + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + CoreSurface *destination = state->destination; + CoreSurface *source = state->source; + + int supported_drawingfuncs = R100_SUPPORTED_DRAWINGFUNCS; + int supported_drawingflags = R100_SUPPORTED_DRAWINGFLAGS; + int supported_blittingfuncs = R100_SUPPORTED_BLITTINGFUNCS; + int supported_blittingflags = R100_SUPPORTED_BLITTINGFLAGS; + + if (!radeon_compatible_format( drv, destination->config.format )) + return; + + switch (destination->config.format) { + case DSPF_A8: + if (state->src_blend == DSBF_SRCALPHASAT) { + supported_drawingflags &= ~DSDRAW_BLEND; + supported_blittingflags &= ~DSBLIT_MODULATE_ALPHA; + } + break; + + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + break; + + case DSPF_LUT8: + case DSPF_ALUT44: + if (DFB_BLITTING_FUNCTION( accel ) && + source->config.format != destination->config.format) + return; + supported_drawingflags = DSDRAW_NOFX; + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + supported_blittingflags = ~(DSBLIT_MODULATE | DSBLIT_MASK); + break; + + case DSPF_ARGB2554: + if (DFB_BLITTING_FUNCTION( accel ) && + source->config.format != destination->config.format) + return; + supported_drawingfuncs &= ~DFXL_FILLTRIANGLE; + supported_drawingflags = DSDRAW_XOR; + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + supported_blittingflags &= ~(DSBLIT_MODULATE | DSBLIT_MASK); + break; + + case DSPF_AiRGB: + supported_drawingflags &= ~DSDRAW_BLEND; + supported_blittingflags &= ~DSBLIT_MODULATE_ALPHA; + break; + + case DSPF_I420: + case DSPF_YV12: + if (DFB_BLITTING_FUNCTION( accel ) && + source->config.format != DSPF_A8 && + source->config.format != DSPF_I420 && + source->config.format != DSPF_YV12) + return; + case DSPF_YUY2: + case DSPF_UYVY: + if (source && source->config.format != DSPF_A8) + supported_blittingflags &= ~(DSBLIT_COLORIZE | DSBLIT_SRC_COLORKEY | DSBLIT_MASK); + break; + + case DSPF_AYUV: + if (DFB_BLITTING_FUNCTION( accel ) && source->config.format != DSPF_A8) { + if (source->config.format != DSPF_AYUV) + return; + supported_blittingflags &= ~(DSBLIT_COLORIZE | DSBLIT_MASK); + } + break; + + default: + return; + } + + if (DFB_BLITTING_FUNCTION( accel )) { + if (state->blittingflags & DSBLIT_MASK || + state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + if (state->blittingflags & DSBLIT_MASK && + state->blittingflags & DSBLIT_SRC_PREMULTIPLY) + return; + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) + return; + } + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + if (destination->config.format != source->config.format) + return; + supported_blittingfuncs = DFXL_BLIT; + supported_blittingflags &= DSBLIT_SRC_COLORKEY | DSBLIT_XOR; + } + + if (state->blittingflags & DSBLIT_ROTATE180) + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + + if (accel & ~supported_blittingfuncs || + state->blittingflags & ~supported_blittingflags) + return; + + if (source->config.size.w > 2048 || source->config.size.h > 2048) + return; + + if (state->blittingflags & DSBLIT_MODULATE_ALPHA && + state->dst_blend == DSBF_SRCALPHASAT) + return; + + if (!radeon_compatible_format( drv, source->config.format )) + return; + + switch (source->config.format) { + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + if (destination->config.format == DSPF_UYVY || + destination->config.format == DSPF_YUY2) + return; + case DSPF_A8: + case DSPF_YUY2: + case DSPF_UYVY: + break; + + case DSPF_AiRGB: + if (destination->config.format != source->config.format && + (DFB_PIXELFORMAT_HAS_ALPHA(destination->config.format) || + destination->config.format == DSPF_UYVY || + destination->config.format == DSPF_YUY2)) + return; + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) + return; + break; + + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_ARGB2554: + case DSPF_AYUV: + if (destination->config.format != source->config.format) + return; + break; + + case DSPF_I420: + case DSPF_YV12: + if (source->config.size.w < 2 || source->config.size.h < 2) + return; + if (destination->config.format != DSPF_I420 && + destination->config.format != DSPF_YV12) + return; + break; + + default: + return; + } + + if (state->blittingflags & DSBLIT_MASK) { + CoreSurface *mask = state->source_mask; + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) + return; + + if (state->src_mask_flags & DSMF_STENCIL || + state->src_mask_offset.x || state->src_mask_offset.y) + return; + + if (mask->config.size.w > 2048 || mask->config.size.h > 2048) + return; + + if (!radeon_compatible_format( drv, mask->config.format )) + return; + + switch (mask->config.format) { + case DSPF_A8: + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + break; + + case DSPF_AiRGB: + if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA && + DFB_PIXELFORMAT_HAS_ALPHA(source->config.format) && + source->config.format != DSPF_AiRGB) + return; + break; + + default: + return; + } + } + + state->accel |= supported_blittingfuncs; + rdev->blitting_mask = supported_blittingfuncs; + } + else { + if (accel & ~supported_drawingfuncs || + state->drawingflags & ~supported_drawingflags) + return; + + if (state->drawingflags & DSDRAW_BLEND && + state->dst_blend == DSBF_SRCALPHASAT) + return; + + state->accel |= supported_drawingfuncs; + rdev->drawing_mask = supported_drawingfuncs; + } +} + +static void r200CheckState( void *drv, void *dev, + CardState *state, DFBAccelerationMask accel ) +{ + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + CoreSurface *destination = state->destination; + CoreSurface *source = state->source; + + int supported_drawingfuncs = R200_SUPPORTED_DRAWINGFUNCS; + int supported_drawingflags = R200_SUPPORTED_DRAWINGFLAGS; + int supported_blittingfuncs = R200_SUPPORTED_BLITTINGFUNCS; + int supported_blittingflags = R200_SUPPORTED_BLITTINGFLAGS; + + if (!radeon_compatible_format( drv, destination->config.format )) + return; + + switch (destination->config.format) { + case DSPF_A8: + if (state->src_blend == DSBF_SRCALPHASAT) { + supported_drawingflags &= ~DSDRAW_BLEND; + supported_blittingflags &= ~DSBLIT_MODULATE_ALPHA; + } + break; + + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + break; + + case DSPF_LUT8: + case DSPF_ALUT44: + if (DFB_BLITTING_FUNCTION( accel ) && + source->config.format != destination->config.format) + return; + supported_drawingflags = DSDRAW_NOFX; + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + supported_blittingflags &= ~(DSBLIT_MODULATE | DSBLIT_MASK); + break; + + case DSPF_ARGB2554: + if (DFB_BLITTING_FUNCTION( accel ) && + source->config.format != destination->config.format) + return; + supported_drawingfuncs &= ~DFXL_FILLTRIANGLE; + supported_drawingflags = DSDRAW_XOR; + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + supported_blittingflags &= ~(DSBLIT_MODULATE | DSBLIT_MASK); + break; + + case DSPF_AiRGB: + supported_drawingflags &= ~DSDRAW_BLEND; + supported_blittingflags &= ~DSBLIT_MODULATE_ALPHA; + break; + + case DSPF_I420: + case DSPF_YV12: + if (DFB_BLITTING_FUNCTION( accel ) && + source->config.format != DSPF_A8 && + source->config.format != DSPF_I420 && + source->config.format != DSPF_YV12) + return; + case DSPF_YUY2: + case DSPF_UYVY: + if (source && source->config.format != DSPF_A8) + supported_blittingflags &= ~(DSBLIT_COLORIZE | DSBLIT_SRC_COLORKEY | DSBLIT_MASK); + break; + + case DSPF_AYUV: + if (DFB_BLITTING_FUNCTION( accel ) && source->config.format != DSPF_A8) { + if (source->config.format != DSPF_AYUV) + return; + supported_blittingflags &= ~(DSBLIT_COLORIZE | DSBLIT_MASK); + } + break; + + default: + return; + } + + if (DFB_BLITTING_FUNCTION( accel )) { + if (state->blittingflags & DSBLIT_MASK || + state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + if (state->blittingflags & DSBLIT_MASK && + state->blittingflags & DSBLIT_SRC_PREMULTIPLY) + return; + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) + return; + } + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + if (destination->config.format != source->config.format) + return; + supported_blittingfuncs = DFXL_BLIT; + supported_blittingflags &= DSBLIT_SRC_COLORKEY | DSBLIT_XOR; + } + + if (state->blittingflags & DSBLIT_ROTATE180) + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + + if (accel & ~supported_blittingfuncs || + state->blittingflags & ~supported_blittingflags) + return; + + if (source->config.size.w > 2048 || source->config.size.h > 2048) + return; + + if (state->blittingflags & DSBLIT_MODULATE_ALPHA && + state->dst_blend == DSBF_SRCALPHASAT) + return; + + if (!radeon_compatible_format( drv, source->config.format )) + return; + + switch (source->config.format) { + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + if (destination->config.format == DSPF_UYVY || + destination->config.format == DSPF_YUY2) + return; + case DSPF_A8: + break; + + case DSPF_AiRGB: + if (destination->config.format != source->config.format && + (DFB_PIXELFORMAT_HAS_ALPHA(destination->config.format) || + destination->config.format == DSPF_UYVY || + destination->config.format == DSPF_YUY2)) + return; + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) + return; + break; + + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_ARGB2554: + case DSPF_AYUV: + if (destination->config.format != source->config.format) + return; + break; + + case DSPF_YUY2: + case DSPF_UYVY: + if (rdev->chipset == CHIP_RV250 && + destination->config.format != DSPF_YUY2 && + destination->config.format != DSPF_UYVY) + return; + break; + + case DSPF_I420: + case DSPF_YV12: + if (source->config.size.w < 2 || source->config.size.h < 2) + return; + if (destination->config.format != DSPF_I420 && + destination->config.format != DSPF_YV12) + return; + break; + + default: + return; + } + + if (state->blittingflags & DSBLIT_MASK) { + CoreSurface *mask = state->source_mask; + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) + return; + + if (state->src_mask_flags & DSMF_STENCIL || + state->src_mask_offset.x || state->src_mask_offset.y) + return; + + if (mask->config.size.w > 2048 || mask->config.size.h > 2048) + return; + + if (!radeon_compatible_format( drv, mask->config.format )) + return; + + switch (mask->config.format) { + case DSPF_A8: + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + break; + + case DSPF_AiRGB: + if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA && + DFB_PIXELFORMAT_HAS_ALPHA(source->config.format) && + source->config.format != DSPF_AiRGB) + return; + break; + + default: + return; + } + } + + state->accel |= supported_blittingfuncs; + rdev->blitting_mask = supported_blittingfuncs; + } + else { + if (accel & ~supported_drawingfuncs || + state->drawingflags & ~supported_drawingflags) + return; + + if (state->drawingflags & DSDRAW_BLEND && + state->dst_blend == DSBF_SRCALPHASAT) + return; + + state->accel |= supported_drawingfuncs; + rdev->drawing_mask = supported_drawingfuncs; + } +} + +static void r300CheckState( void *drv, void *dev, + CardState *state, DFBAccelerationMask accel ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + CoreSurface *destination = state->destination; + CoreSurface *source = state->source; + bool can_convert = true; + + int supported_drawingfuncs = R300_SUPPORTED_DRAWINGFUNCS; + int supported_drawingflags = R300_SUPPORTED_DRAWINGFLAGS; + int supported_blittingfuncs = R300_SUPPORTED_BLITTINGFUNCS; + int supported_blittingflags = R300_SUPPORTED_BLITTINGFLAGS; + if (rdrv->mmio_size <= 0x4000) { + supported_drawingfuncs = RADEON_SUPPORTED_2D_DRAWINGFUNCS; + supported_drawingflags = RADEON_SUPPORTED_2D_DRAWINGFLAGS; + supported_blittingfuncs = RADEON_SUPPORTED_2D_BLITTINGFUNCS; + supported_blittingflags = RADEON_SUPPORTED_2D_BLITTINGFLAGS; + can_convert = false; + } + + if (!radeon_compatible_format( drv, destination->config.format )) + return; + + switch (destination->config.format) { + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + break; + + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_A8: + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_ARGB2554: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_AiRGB: + case DSPF_AYUV: + case DSPF_YUY2: + case DSPF_UYVY: + if (DFB_BLITTING_FUNCTION( accel )) { + if (source->config.format != destination->config.format) + return; + } + supported_drawingfuncs &= ~DFXL_FILLTRIANGLE; + supported_drawingflags = DSDRAW_NOFX; + supported_blittingfuncs = DFXL_BLIT; + supported_blittingflags = DSBLIT_NOFX; + break; + + case DSPF_I420: + case DSPF_YV12: + if (DFB_BLITTING_FUNCTION( accel )) { + if (source->config.format != DSPF_I420 && + source->config.format != DSPF_YV12) + return; + } + supported_drawingfuncs &= ~DFXL_FILLTRIANGLE; + supported_drawingflags = DSDRAW_XOR; + supported_blittingflags = DSBLIT_DEINTERLACE; + break; + + default: + return; + } + + if (DFB_BLITTING_FUNCTION( accel )) { + if (state->blittingflags & DSBLIT_XOR) { + can_convert = false; + supported_blittingfuncs = DFXL_BLIT; + supported_blittingflags &= DSBLIT_SRC_COLORKEY | DSBLIT_XOR; + } + + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) { + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) + return; + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) { + if (state->src_blend != DSBF_ONE) + return; + } + } + + if (state->blittingflags & DSBLIT_ROTATE180) + supported_blittingfuncs &= ~DFXL_TEXTRIANGLES; + + if (accel & ~supported_blittingfuncs || + state->blittingflags & ~supported_blittingflags) + return; + + if (source->config.size.w > 2048 || source->config.size.h > 2048) + return; + + if (state->blittingflags & DSBLIT_MODULATE_ALPHA && + state->dst_blend == DSBF_SRCALPHASAT) + return; + + if (!radeon_compatible_format( drv, source->config.format )) + return; + + switch (source->config.format) { + case DSPF_A8: + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_ARGB4444: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + if (!can_convert && + destination->config.format != source->config.format) + return; + break; + + case DSPF_LUT8: + case DSPF_ALUT44: + if (destination->config.format != source->config.format) + return; + break; + + case DSPF_ARGB2554: + case DSPF_AiRGB: + case DSPF_AYUV: + case DSPF_YUY2: + case DSPF_UYVY: + if (destination->config.format != source->config.format) + return; + break; + + case DSPF_I420: + case DSPF_YV12: + if (source->config.size.w < 2 || source->config.size.h < 2) + return; + if (destination->config.format != DSPF_I420 && + destination->config.format != DSPF_YV12) + return; + break; + + default: + return; + } + + state->accel |= supported_blittingfuncs; + rdev->blitting_mask = supported_blittingfuncs; + } + else { + if (state->drawingflags & DSDRAW_XOR) { + supported_drawingfuncs &= ~DFXL_FILLTRIANGLE; + supported_drawingflags &= DSDRAW_XOR; + } + + if (accel & ~supported_drawingfuncs || + state->drawingflags & ~supported_drawingflags) + return; + + if (state->drawingflags & DSDRAW_BLEND && + state->dst_blend == DSBF_SRCALPHASAT) + return; + + state->accel |= supported_drawingfuncs; + rdev->drawing_mask = supported_drawingfuncs; + } +} + +static void r100SetState( void *drv, void *dev, + GraphicsDeviceFuncs *funcs, + CardState *state, DFBAccelerationMask accel ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + rdev->set &= ~state->mod_hw; + if (DFB_BLITTING_FUNCTION( accel )) { + if ((rdev->accel ^ accel) & DFXL_TEXTRIANGLES) + rdev->set &= ~SMF_BLITTING_FLAGS; + } + + rdev->accel = accel; + + r100_set_destination( rdrv, rdev, state ); + r100_set_clip( rdrv, rdev, state ); + r100_set_render_options( rdrv, rdev, state ); + + switch (accel) { + case DFXL_FILLRECTANGLE: + case DFXL_FILLTRIANGLE: + case DFXL_DRAWRECTANGLE: + case DFXL_DRAWLINE: + r100_set_drawing_color( rdrv, rdev, state ); + + if (state->drawingflags & DSDRAW_BLEND) + r100_set_blend_function( rdrv, rdev, state ); + + r100_set_drawingflags( rdrv, rdev, state ); + + if (RADEON_DRAW_3D()) { + funcs->FillRectangle = r100FillRectangle3D; + funcs->FillTriangle = r100FillTriangle; + funcs->DrawRectangle = r100DrawRectangle3D; + funcs->DrawLine = r100DrawLine3D; + funcs->EmitCommands = r100EmitCommands3D; + } else { + funcs->FillRectangle = RADEON_FUNC(radeonFillRectangle2D); + funcs->FillTriangle = NULL; + funcs->DrawRectangle = RADEON_FUNC(radeonDrawRectangle2D); + funcs->DrawLine = RADEON_FUNC(radeonDrawLine2D); + funcs->EmitCommands = NULL; + } + + state->set = rdev->drawing_mask; + break; + + case DFXL_BLIT: + case DFXL_STRETCHBLIT: + case DFXL_TEXTRIANGLES: + r100_set_source( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MASK) + r100_set_source_mask( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MODULATE_ALPHA) + r100_set_blend_function( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MODULATE_COLOR) + r100_set_blitting_color( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + r100_set_src_colorkey( rdrv, rdev, state ); + + r100_set_blittingflags( rdrv, rdev, state ); + + if (RADEON_BLIT_3D()) { + funcs->Blit = r100Blit3D; + funcs->StretchBlit = r100StretchBlit; + funcs->TextureTriangles = r100TextureTriangles; + funcs->EmitCommands = r100EmitCommands3D; + } else { + funcs->Blit = RADEON_FUNC(radeonBlit2D); + funcs->StretchBlit = NULL; + funcs->TextureTriangles = NULL; + funcs->EmitCommands = NULL; + } + + state->set = (accel & DFXL_TEXTRIANGLES) + ? : (rdev->blitting_mask & ~DFXL_TEXTRIANGLES); + break; + + default: + D_BUG( "unexpected drawing/blitting function" ); + break; + } + + state->mod_hw = 0; +} + +static void r200SetState( void *drv, void *dev, + GraphicsDeviceFuncs *funcs, + CardState *state, DFBAccelerationMask accel ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + rdev->set &= ~state->mod_hw; + if (DFB_BLITTING_FUNCTION( accel )) { + if ((rdev->accel ^ accel) & DFXL_TEXTRIANGLES) + rdev->set &= ~SMF_BLITTING_FLAGS; + } + + rdev->accel = accel; + + r200_set_destination( rdrv, rdev, state ); + r200_set_clip( rdrv, rdev, state ); + r200_set_render_options( rdrv, rdev, state ); + + switch (accel) { + case DFXL_FILLRECTANGLE: + case DFXL_FILLTRIANGLE: + case DFXL_DRAWRECTANGLE: + case DFXL_DRAWLINE: + r200_set_drawing_color( rdrv, rdev, state ); + + if (state->drawingflags & DSDRAW_BLEND) + r200_set_blend_function( rdrv, rdev, state ); + + r200_set_drawingflags( rdrv, rdev, state ); + + if (RADEON_DRAW_3D()) { + funcs->FillRectangle = r200FillRectangle3D; + funcs->FillTriangle = r200FillTriangle; + funcs->DrawRectangle = r200DrawRectangle3D; + funcs->DrawLine = r200DrawLine3D; + funcs->EmitCommands = r200EmitCommands3D; + } else { + funcs->FillRectangle = RADEON_FUNC(radeonFillRectangle2D); + funcs->FillTriangle = NULL; + funcs->DrawRectangle = RADEON_FUNC(radeonDrawRectangle2D); + funcs->DrawLine = RADEON_FUNC(radeonDrawLine2D); + funcs->EmitCommands = NULL; + } + + state->set = rdev->drawing_mask; + break; + + case DFXL_BLIT: + case DFXL_STRETCHBLIT: + case DFXL_TEXTRIANGLES: + r200_set_source( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MASK) + r200_set_source_mask( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MODULATE_ALPHA) + r200_set_blend_function( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MODULATE_COLOR) + r200_set_blitting_color( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + r200_set_src_colorkey( rdrv, rdev, state ); + + r200_set_blittingflags( rdrv, rdev, state ); + + if (RADEON_BLIT_3D()) { + funcs->Blit = r200Blit3D; + funcs->StretchBlit = r200StretchBlit; + funcs->TextureTriangles = r200TextureTriangles; + funcs->EmitCommands = r200EmitCommands3D; + } else { + funcs->Blit = RADEON_FUNC(radeonBlit2D); + funcs->StretchBlit = NULL; + funcs->TextureTriangles = NULL; + funcs->EmitCommands = NULL; + } + + state->set = (accel & DFXL_TEXTRIANGLES) + ? : (rdev->blitting_mask & ~DFXL_TEXTRIANGLES); + break; + + default: + D_BUG( "unexpected drawing/blitting function" ); + break; + } + + state->mod_hw = 0; +} + +static void r300SetState( void *drv, void *dev, + GraphicsDeviceFuncs *funcs, + CardState *state, DFBAccelerationMask accel ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + rdev->set &= ~state->mod_hw; + if (DFB_BLITTING_FUNCTION( accel )) { + if ((rdev->accel ^ accel) & DFXL_TEXTRIANGLES) + rdev->set &= ~SMF_BLITTING_FLAGS; + } + + rdev->accel = accel; + + r300_set_destination( rdrv, rdev, state ); + r300_set_clip( rdrv, rdev, state ); + r300_set_render_options( rdrv, rdev, state ); + + switch (accel) { + case DFXL_FILLRECTANGLE: + case DFXL_FILLTRIANGLE: + case DFXL_DRAWRECTANGLE: + case DFXL_DRAWLINE: + r300_set_drawing_color( rdrv, rdev, state ); + + if (state->drawingflags & DSDRAW_BLEND) + r300_set_blend_function( rdrv, rdev, state ); + + r300_set_drawingflags( rdrv, rdev, state ); + + if (RADEON_DRAW_3D()) { + funcs->FillRectangle = r300FillRectangle3D; + funcs->FillTriangle = r300FillTriangle; + funcs->DrawRectangle = r300DrawRectangle3D; + funcs->DrawLine = r300DrawLine3D; + funcs->EmitCommands = r300EmitCommands3D; + } else { + funcs->FillRectangle = RADEON_FUNC(radeonFillRectangle2D); + funcs->FillTriangle = NULL; + funcs->DrawRectangle = RADEON_FUNC(radeonDrawRectangle2D); + funcs->DrawLine = RADEON_FUNC(radeonDrawLine2D); + funcs->EmitCommands = NULL; + } + + state->set = rdev->drawing_mask; + break; + + case DFXL_BLIT: + case DFXL_STRETCHBLIT: + case DFXL_TEXTRIANGLES: + r300_set_source( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MODULATE_ALPHA) + r300_set_blend_function( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_MODULATE_COLOR) + r300_set_blitting_color( rdrv, rdev, state ); + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + r300_set_src_colorkey( rdrv, rdev, state ); + + r300_set_blittingflags( rdrv, rdev, state ); + + if (RADEON_BLIT_3D()) { + funcs->Blit = r300Blit3D; + funcs->StretchBlit = r300StretchBlit; + funcs->TextureTriangles = r300TextureTriangles; + funcs->EmitCommands = r300EmitCommands3D; + } else { + funcs->Blit = RADEON_FUNC(radeonBlit2D); + funcs->StretchBlit = NULL; + funcs->TextureTriangles = NULL; + funcs->EmitCommands = NULL; + } + + state->set = (accel & DFXL_TEXTRIANGLES) + ? : (rdev->blitting_mask & ~DFXL_TEXTRIANGLES); + break; + + default: + D_BUG( "unexpected drawing/blitting function" ); + break; + } + + state->mod_hw = 0; +} + + +/* chipset detection */ + +static int +radeon_find_chipset( RadeonDriverData *rdrv, int *ret_devid, int *ret_index ) +{ + volatile u8 *mmio = rdrv->mmio_base; + unsigned int vendor_id; + unsigned int device_id; + int i; + + vendor_id = radeon_in16( mmio, CONFIG_VENDOR_ID ); + device_id = radeon_in16( mmio, CONFIG_DEVICE_ID ); + if (vendor_id != 0x1002 || !device_id) + dfb_system_get_deviceid( &vendor_id, &device_id ); + + if (vendor_id == 0x1002) { + if (ret_devid) + *ret_devid = device_id; + + for (i = 0; i < D_ARRAY_SIZE( dev_table ); i++) { + if ((unsigned int)dev_table[i].id == device_id) { + if (ret_index) + *ret_index = i; + return 1; + } + } + } + + return 0; +} + +/* exported symbols */ + +static int +driver_probe( CoreGraphicsDevice *device ) +{ + switch (dfb_gfxcard_get_accelerator( device )) { + case FB_ACCEL_ATI_RADEON: + return 1; + default: + break; + } + + return 0; +} + +static void +driver_get_info( CoreGraphicsDevice *device, + GraphicsDriverInfo *info ) +{ + /* fill driver info structure */ + snprintf( info->name, + DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, + "ATI Radeon Driver" ); + + snprintf( info->vendor, + DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH, + "Claudio Ciccani" ); + + snprintf( info->license, + DFB_GRAPHICS_DRIVER_INFO_LICENSE_LENGTH, + "LGPL" ); + + snprintf( info->url, + DFB_GRAPHICS_DRIVER_INFO_URL_LENGTH, + "http://www.directfb.org" ); + + info->version.major = 1; + info->version.minor = 2; + + info->driver_data_size = sizeof(RadeonDriverData); + info->device_data_size = sizeof(RadeonDeviceData); +} + +static DFBResult +driver_init_driver( CoreGraphicsDevice *device, + GraphicsDeviceFuncs *funcs, + void *driver_data, + void *device_data, + CoreDFB *core ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonChipsetFamily chip = CHIP_UNKNOWN; + int idx; + + rdrv->device_data = (RadeonDeviceData*) device_data; + + /* gain access to memory mapped registers */ + rdrv->mmio_base = (volatile u8*) dfb_gfxcard_map_mmio( device, 0, 0x4000 ); + if (!rdrv->mmio_base) + return DFB_IO; + rdrv->mmio_size = 0x4000; + + rdrv->fb_base = dfb_gfxcard_memory_virtual( device, 0 ); + + if (radeon_find_chipset( rdrv, NULL, &idx )) + chip = dev_table[idx].chip; + + if (chip >= CHIP_R300 && !getenv( "R300_DISABLE_3D" )) { + volatile void *base; + /* increase amount of memory mapped registers */ + base = dfb_gfxcard_map_mmio( device, 0, 0x8000 ); + if (!base) { + D_ERROR( "DirectFB/Radeon: You are running a buggy version of radeonfb!\n" + " -> Please, apply the kernel patch named radeonfb-r300fix.\n" ); + D_INFO( "DirectFB/Radeon: 3D Acceleration will be disabled.\n" ); + } + else { + rdrv->mmio_base = base; + rdrv->mmio_size = 0x8000; + } + } + + /* fill function table */ + funcs->AfterSetVar = radeonAfterSetVar; + funcs->EngineReset = radeonEngineReset; + funcs->EngineSync = radeonEngineSync; + funcs->InvalidateState = radeonInvalidateState; + funcs->FlushTextureCache = radeonFlushTextureCache; +#ifdef WORDS_BIGENDIAN + funcs->SurfaceEnter = radeonSurfaceEnter; + funcs->SurfaceLeave = radeonSurfaceLeave; +#endif + + if (chip >= CHIP_R300) { + funcs->CheckState = r300CheckState; + funcs->SetState = r300SetState; + } + else if (chip >= CHIP_R200) { + funcs->CheckState = r200CheckState; + funcs->SetState = r200SetState; + } + else if (chip >= CHIP_R100) { + funcs->CheckState = r100CheckState; + funcs->SetState = r100SetState; + } + + /* primary screen */ + dfb_screens_hook_primary( device, driver_data, + &RadeonCrtc1ScreenFuncs, + &OldPrimaryScreenFuncs, + &OldPrimaryScreenDriverData ); + + /* primary layer */ + dfb_layers_hook_primary( device, driver_data, + &RadeonCrtc1LayerFuncs, + &OldPrimaryLayerFuncs, + &OldPrimaryLayerDriverData ); + + /* overlay support */ + dfb_layers_register( dfb_screens_at( DSCID_PRIMARY ), + driver_data, &RadeonOverlayFuncs ); + + if (chip != CHIP_R100) { + CoreScreen *screen; + + /* secondary screen support */ + screen = dfb_screens_register( device, driver_data, + &RadeonCrtc2ScreenFuncs ); + + /* secondary underlay support */ + dfb_layers_register( screen, driver_data, + &RadeonCrtc2LayerFuncs ); + + /* secondary overlay support */ + dfb_layers_register( screen, driver_data, + &RadeonOverlayFuncs ); + } + + return DFB_OK; +} + +static DFBResult +driver_init_device( CoreGraphicsDevice *device, + GraphicsDeviceInfo *device_info, + void *driver_data, + void *device_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonDeviceData *rdev = (RadeonDeviceData*) device_data; + volatile void *mmio = rdrv->mmio_base; + int dev = 0; + int idx = 0; + const char *name = "Unknown"; + + if (radeon_find_chipset( rdrv, &dev, &idx )) { + rdev->chipset = dev_table[idx].chip; + rdev->igp = dev_table[idx].igp; + name = dev_table[idx].name; + } + else { + if (!dev) { + D_ERROR( "DirectFB/Radeon: Could not detect device id!\n" + " -> Please, specify the bus location of" + " the card by using the 'busid' option.\n" ); + } + D_INFO( "DirectFB/Radeon: " + "Unknown chipset, disabling acceleration!\n" ); + } + + /* fill device info */ + snprintf( device_info->name, + DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, + "%s (%04x)", name, dev ); + + snprintf( device_info->vendor, + DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "ATI" ); + + device_info->caps.flags = CCF_CLIPPING | CCF_AUXMEMORY | CCF_RENDEROPTS; + + if (rdev->chipset >= CHIP_R300) { + if (rdrv->mmio_size > 0x4000) { + device_info->caps.accel = R300_SUPPORTED_DRAWINGFUNCS | + R300_SUPPORTED_BLITTINGFUNCS; + device_info->caps.drawing = R300_SUPPORTED_DRAWINGFLAGS; + device_info->caps.blitting = R300_SUPPORTED_BLITTINGFLAGS; + } else { + device_info->caps.accel = RADEON_SUPPORTED_2D_DRAWINGFUNCS | + RADEON_SUPPORTED_2D_BLITTINGFUNCS; + device_info->caps.drawing = RADEON_SUPPORTED_2D_DRAWINGFLAGS; + device_info->caps.blitting = RADEON_SUPPORTED_2D_BLITTINGFLAGS; + } + } + else if (rdev->chipset >= CHIP_R200) { + device_info->caps.accel = R200_SUPPORTED_DRAWINGFUNCS | + R200_SUPPORTED_BLITTINGFUNCS; + device_info->caps.drawing = R200_SUPPORTED_DRAWINGFLAGS; + device_info->caps.blitting = R200_SUPPORTED_BLITTINGFLAGS; + } + else if (rdev->chipset >= CHIP_R100) { + device_info->caps.accel = R100_SUPPORTED_DRAWINGFUNCS | + R100_SUPPORTED_BLITTINGFUNCS; + device_info->caps.drawing = R100_SUPPORTED_DRAWINGFLAGS; + device_info->caps.blitting = R100_SUPPORTED_BLITTINGFLAGS; + } + + device_info->limits.surface_byteoffset_alignment = 32; + device_info->limits.surface_pixelpitch_alignment = 64; + device_info->limits.surface_bytepitch_alignment = 128; + + dfb_config->pollvsync_after = 1; + + /* reserve memory for YUV422 color buffer */ + rdev->yuv422_buffer = dfb_gfxcard_reserve_memory( device, 128 ); + if (rdev->yuv422_buffer == (u32)-1) { + D_ERROR( "DirectFB/Radeon: " + "couldn't reserve 128 bytes of video memory!\n" ); + return DFB_NOVIDEOMEMORY; + } + + rdev->fb_phys = dfb_gfxcard_memory_physical( device, 0 ); + + radeon_waitidle( rdrv, rdev ); + + /* get connected monitors */ + radeon_get_monitors( rdrv, rdev, &rdev->monitor1, &rdev->monitor2 ); + + /* save the following regs */ + rdev->mc_fb_location = radeon_in32( mmio, MC_FB_LOCATION ); + rdev->mc_agp_location = radeon_in32( mmio, MC_AGP_LOCATION ); + rdev->crtc_base_addr = radeon_in32( mmio, CRTC_BASE_ADDR ); + rdev->crtc2_base_addr = radeon_in32( mmio, CRTC2_BASE_ADDR ); + rdev->agp_base = radeon_in32( mmio, AGP_BASE ); + rdev->agp_cntl = radeon_in32( mmio, AGP_CNTL ); + rdev->aic_cntl = radeon_in32( mmio, AIC_CNTL ); + rdev->bus_cntl = radeon_in32( mmio, BUS_CNTL ); + rdev->fcp_cntl = radeon_in32( mmio, FCP_CNTL ); + rdev->cap0_trig_cntl = radeon_in32( mmio, CAP0_TRIG_CNTL ); + rdev->vid_buffer_control = radeon_in32( mmio, VID_BUFFER_CONTROL ); + rdev->display_test_debug_cntl = radeon_in32( mmio, DISPLAY_TEST_DEBUG_CNTL ); + rdev->surface_cntl = radeon_in32( mmio, SURFACE_CNTL ); + rdev->dp_gui_master_cntl = radeon_in32( mmio, DP_GUI_MASTER_CNTL ); + + rdev->surface_cntl_p = + rdev->surface_cntl_c = rdev->surface_cntl; + + if (rdev->igp) { + u32 tom; + /* force MC_FB_LOCATION to NB_TOM */ + tom = radeon_in32( mmio, NB_TOM ); + rdev->fb_offset = tom << 16; + rdev->fb_size = ((tom >> 16) - (tom & 0xffff) + 1) << 16; + } + else { + if (rdev->chipset >= CHIP_R300) { + rdev->fb_offset = 0; + rdev->fb_size = radeon_in32( mmio, CONFIG_MEMSIZE ); + } else { + rdev->fb_offset = radeon_in32( mmio, CONFIG_APER_0_BASE ); + rdev->fb_size = radeon_in32( mmio, CONFIG_APER_SIZE ); + } + } + + radeon_out32( mmio, MC_FB_LOCATION, (rdev->fb_offset>>16) | + ((rdev->fb_offset + rdev->fb_size - 1) & 0xffff0000) ); + + D_DEBUG( "DirectFB/Radeon: " + "Framebuffer located at 0x%08x:0x%08x.\n", + rdev->fb_offset, rdev->fb_offset + rdev->fb_size - 1 ); + + if (dfb_system_auxram_length()) { + rdev->agp_offset = (rdev->fb_offset + rdev->fb_size) & 0xffc00000; + rdev->agp_size = dfb_system_auxram_length(); + + /* enable AGP support */ + radeon_out32( mmio, AIC_CNTL, rdev->aic_cntl & ~PCIGART_TRANSLATE_EN ); + radeon_out32( mmio, AGP_BASE, dfb_system_aux_memory_physical( 0 ) ); + radeon_out32( mmio, AGP_CNTL, rdev->agp_cntl | 0x000e0000 ); + radeon_out32( mmio, BUS_CNTL, rdev->bus_cntl & ~BUS_MASTER_DIS ); + + radeon_out32( mmio, MC_AGP_LOCATION, (rdev->agp_offset>>16) | + ((rdev->agp_offset + rdev->agp_size - 1) & 0xffff0000) ); + + D_DEBUG( "DirectFB/Radeon: " + "AGP Aperture located at 0x%08x:0x%08x.\n", + rdev->agp_offset, rdev->agp_offset + rdev->agp_size - 1 ); + } + + radeon_out32( mmio, CRTC_BASE_ADDR, rdev->fb_offset ); + radeon_out32( mmio, DISP_MERGE_CNTL, 0xffff0000 ); + if (rdev->chipset != CHIP_R100) { + radeon_out32( mmio, CRTC2_BASE_ADDR, rdev->fb_offset ); + radeon_out32( mmio, DISP2_MERGE_CNTL, 0xffff0000 ); + } + + radeon_out32( mmio, FCP_CNTL, FCP0_SRC_GND ); + radeon_out32( mmio, CAP0_TRIG_CNTL, 0 ); + radeon_out32( mmio, VID_BUFFER_CONTROL, 0x00010001 ); + radeon_out32( mmio, DISPLAY_TEST_DEBUG_CNTL, 0 ); + + radeon_reset( rdrv, rdev ); + + return DFB_OK; +} + +static void +driver_close_device( CoreGraphicsDevice *device, + void *driver_data, + void *device_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonDeviceData *rdev = (RadeonDeviceData*) device_data; + volatile u8 *mmio = rdrv->mmio_base; + + D_DEBUG( "DirectFB/Radeon: FIFO Performance Monitoring:\n" ); + D_DEBUG( "DirectFB/Radeon: %9d radeon_waitfifo calls\n", + rdev->waitfifo_calls ); + D_DEBUG( "DirectFB/Radeon: %9d register writes (radeon_waitfifo sum)\n", + rdev->waitfifo_sum ); + D_DEBUG( "DirectFB/Radeon: %9d FIFO wait cycles (depends on CPU)\n", + rdev->fifo_waitcycles ); + D_DEBUG( "DirectFB/Radeon: %9d IDLE wait cycles (depends on CPU)\n", + rdev->idle_waitcycles ); + D_DEBUG( "DirectFB/Radeon: %9d FIFO space cache hits(depends on CPU)\n", + rdev->fifo_cache_hits ); + D_DEBUG( "DirectFB/Radeon: Conclusion:\n" ); + D_DEBUG( "DirectFB/Radeon: Average register writes/radeon_waitfifo call:%.2f\n", + rdev->waitfifo_sum / (float)rdev->waitfifo_calls ); + D_DEBUG( "DirectFB/Radeon: Average wait cycles/radeon_waitfifo call: %.2f\n", + rdev->fifo_waitcycles / (float)rdev->waitfifo_calls ); + D_DEBUG( "DirectFB/Radeon: Average fifo space cache hits: %02d%%\n", + (int)(100 * rdev->fifo_cache_hits / (float)rdev->waitfifo_calls) ); + + radeon_reset( rdrv, rdev ); + + /* restore previously saved regs */ + radeon_out32( mmio, MC_FB_LOCATION, rdev->mc_fb_location ); + radeon_out32( mmio, MC_AGP_LOCATION, rdev->mc_agp_location ); + radeon_out32( mmio, CRTC_BASE_ADDR, rdev->crtc_base_addr ); + radeon_out32( mmio, CRTC2_BASE_ADDR, rdev->crtc2_base_addr ); + radeon_out32( mmio, AGP_CNTL, rdev->agp_cntl ); + radeon_out32( mmio, AGP_BASE, rdev->agp_base ); + radeon_out32( mmio, AIC_CNTL, rdev->aic_cntl ); + radeon_out32( mmio, BUS_CNTL, rdev->bus_cntl ); + radeon_out32( mmio, FCP_CNTL, rdev->fcp_cntl ); + radeon_out32( mmio, CAP0_TRIG_CNTL, rdev->cap0_trig_cntl ); + radeon_out32( mmio, VID_BUFFER_CONTROL, rdev->vid_buffer_control ); + radeon_out32( mmio, DISPLAY_TEST_DEBUG_CNTL, rdev->display_test_debug_cntl ); + radeon_out32( mmio, SURFACE_CNTL, rdev->surface_cntl ); + + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, SC_TOP_LEFT, 0 ); + radeon_out32( mmio, DEFAULT_SC_BOTTOM_RIGHT, DEFAULT_SC_RIGHT_MAX | + DEFAULT_SC_BOTTOM_MAX ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, rdev->dp_gui_master_cntl ); +} + +static void +driver_close_driver( CoreGraphicsDevice *device, + void *driver_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + + dfb_gfxcard_unmap_mmio( device, rdrv->mmio_base, rdrv->mmio_size ); +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon.h b/Source/DirectFB/gfxdrivers/radeon/radeon.h new file mode 100755 index 0000000..037c892 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __RADEON_H__ +#define __RADEON_H__ + +#include <dfb_types.h> + +#include <core/coretypes.h> +#include <core/state.h> +#include <core/screens.h> +#include <core/layers.h> + + +typedef enum { + CHIP_UNKNOWN = 0, + CHIP_R100, + CHIP_RV100, + CHIP_RS100, + CHIP_RV200, + CHIP_RS200, + CHIP_RS250, + CHIP_R200, + CHIP_RV250, + CHIP_RV280, + CHIP_RS300, + CHIP_RS350, + CHIP_R300, + CHIP_R350, + CHIP_RV350, + CHIP_RV380, + CHIP_R420, + CHIP_RV410, + CHIP_RS400, +} RadeonChipsetFamily; + +typedef enum { + MT_NONE = 0, + MT_CRT = 1, + MT_DFP = 2, + MT_LCD = 3, + MT_CTV = 4, + MT_STV = 5 +} RadeonMonitorType; + +typedef struct { + /* validated flags */ + StateModificationFlags set; + /* current function */ + DFBAccelerationMask accel; + /* mask of currently supported drawing functions */ + DFBAccelerationMask drawing_mask; + /* mask of currently supported blitting functions */ + DFBAccelerationMask blitting_mask; + + unsigned long fb_phys; + u32 fb_offset; + u32 fb_size; + u32 agp_offset; + u32 agp_size; + + DFBSurfacePixelFormat dst_format; + u32 dst_offset; + u32 dst_offset_cb; + u32 dst_offset_cr; + u32 dst_pitch; + DFBBoolean dst_422; + + DFBSurfacePixelFormat src_format; + u32 src_offset; + u32 src_offset_cb; + u32 src_offset_cr; + u32 src_pitch; + u32 src_width; + u32 src_height; + u32 src_mask; + + DFBSurfacePixelFormat msk_format; + u32 msk_offset; + u32 msk_pitch; + u32 msk_width; + u32 msk_height; + + DFBRegion clip; + + float color[4]; + u32 y_cop; + u32 cb_cop; + u32 cr_cop; + + DFBSurfaceRenderOptions render_options; + DFBSurfaceDrawingFlags drawingflags; + DFBSurfaceBlittingFlags blittingflags; + + const s32 *matrix; + DFBBoolean affine_matrix; + + /* chipset identified */ + RadeonChipsetFamily chipset; + DFBBoolean igp; + + /* connected monitors */ + RadeonMonitorType monitor1; + RadeonMonitorType monitor2; + + /* saved registers */ + u32 mc_fb_location; + u32 mc_agp_location; + u32 crtc_base_addr; + u32 crtc2_base_addr; + u32 agp_base; + u32 agp_cntl; + u32 aic_cntl; + u32 bus_cntl; + u32 fcp_cntl; + u32 cap0_trig_cntl; + u32 vid_buffer_control; + u32 display_test_debug_cntl; + u32 surface_cntl; + u32 dp_gui_master_cntl; + + /* recorded registers */ + u32 surface_cntl_p; + u32 surface_cntl_c; + u32 gui_master_cntl; + u32 rb3d_cntl; + u32 rb3d_blend; + + /* faked texture for YUV422 drawing functions */ + u32 yuv422_buffer; + + /* vertex buffer */ + u32 vb[1024]; + u32 vb_size; + u32 vb_count; + u32 vb_type; + + /* for fifo/performance monitoring */ + unsigned int fifo_space; + + unsigned int waitfifo_sum; + unsigned int waitfifo_calls; + unsigned int fifo_waitcycles; + unsigned int idle_waitcycles; + unsigned int fifo_cache_hits; +} RadeonDeviceData; + +typedef struct { + RadeonDeviceData *device_data; + + u8 *fb_base; + volatile u8 *mmio_base; + unsigned int mmio_size; +} RadeonDriverData; + + +extern void radeon_reset( RadeonDriverData *rdrv, RadeonDeviceData *rdev ); + +extern ScreenFuncs RadeonCrtc1ScreenFuncs; +extern ScreenFuncs OldPrimaryScreenFuncs; +extern void *OldPrimaryScreenDriverData; + +extern DisplayLayerFuncs RadeonCrtc1LayerFuncs; +extern DisplayLayerFuncs OldPrimaryLayerFuncs; +extern void *OldPrimaryLayerDriverData; + +extern DisplayLayerFuncs RadeonOverlayFuncs; + +extern ScreenFuncs RadeonCrtc2ScreenFuncs; + +extern DisplayLayerFuncs RadeonCrtc2LayerFuncs; + + +/* utility function */ +static __inline__ u32 f2d( float f ) +{ + union { float f; u32 d; } tmp; + tmp.f = f; + return tmp.d; +} + +static __inline__ float d2f( u32 d ) +{ + union { float f; u32 d; } tmp; + tmp.d = d; + return tmp.f; +} + +#define RADEON_TRANSFORM(x, y, retx, rety, m, affine) \ + do { \ + float _x, _y, _w; \ + if (affine) { \ + _x = ((x) * m[0] + (y) * m[1] + m[2]) / 65536.f; \ + _y = ((x) * m[3] + (y) * m[4] + m[5]) / 65536.f; \ + } \ + else { \ + _w = ((x) * m[6] + (y) * m[7] + m[8]); \ + _x = ((x) * m[0] + (y) * m[1] + m[2]) / _w; \ + _y = ((x) * m[3] + (y) * m[4] + m[5]) / _w; \ + } \ + retx = _x; rety = _y; \ + } while(0) + + +#endif /* __RADEON_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_2d.c b/Source/DirectFB/gfxdrivers/radeon/radeon_2d.c new file mode 100755 index 0000000..acee7aa --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_2d.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <dfb_types.h> +#include <directfb.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/state.h> +#include <core/gfxcard.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_2d.h" + + +static void +radeonDoFillRectangle2D( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + DFBRectangle *rect ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 2 ); + + radeon_out32( mmio, DST_Y_X, (rect->y << 16) | + (rect->x & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (rect->h << 16) | + (rect->w & 0x3fff) ); +} + +bool radeonFillRectangle2D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + rect->x /= 2; + rect->w = (rect->w+1) >> 1; + } + + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + return true; +} + +bool radeonFillRectangle2D_420( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + /* Fill Luma plane */ + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + /* Scale coordinates */ + rect->x /= 2; + rect->y /= 2; + rect->w = (rect->w+1) >> 1; + rect->h = (rect->h+1) >> 1; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1)/2 << 16) | + ((clip->x2+1)/2 & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cb_cop ); + + /* Fill Cb plane */ + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cr_cop ); + + /* Fill Cr plane */ + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->y_cop ); + + return true; +} + +static void +radeonDoDrawRectangle2D( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + DFBRectangle *rect ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 7 ); + + /* left line */ + radeon_out32( mmio, DST_Y_X, (rect->y << 16) | (rect->x & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (rect->h << 16) | 1 ); + /* top line */ + radeon_out32( mmio, DST_HEIGHT_WIDTH, (1 << 16) | (rect->w & 0xffff) ); + /* bottom line */ + radeon_out32( mmio, DST_Y_X, ((rect->y+rect->h-1) << 16) | (rect->x & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (1 << 16) | (rect->w & 0xffff) ); + /* right line */ + radeon_out32( mmio, DST_Y_X, (rect->y << 16) | ((rect->x+rect->w-1) & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (rect->h << 16) | 1 ); +} + +bool radeonDrawRectangle2D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + rect->x /= 2; + rect->w = (rect->w+1) >> 1; + } + + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + return true; +} + +bool radeonDrawRectangle2D_420( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + /* Fill Luma plane */ + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + /* Scale coordinates */ + rect->x /= 2; + rect->y /= 2; + rect->w >>= 1; + rect->h >>= 1; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1)/2 << 16) | + ((clip->x2+1)/2 & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cb_cop ); + + /* Fill Cb plane */ + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cr_cop ); + + /* Fill Cr plane */ + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->y_cop ); + + return true; +} + +static void +radeonDoDrawLine2D( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + DFBRegion *line ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 2 ); + + radeon_out32( mmio, DST_LINE_START, (line->y1 << 16) | + (line->x1 & 0xffff) ); + radeon_out32( mmio, DST_LINE_END, (line->y2 << 16) | + (line->x2 & 0xffff) ); +} + +bool radeonDrawLine2D( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + line->x1 /= 2; + line->x2 = (line->x2+1) / 2; + } + + radeonDoDrawLine2D( rdrv, rdev, line ); + + return true; +} + +bool radeonDrawLine2D_420( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + line->x1 &= ~1; + line->y1 &= ~1; + line->x2 &= ~1; + line->y2 &= ~1; + + /* Fill Luma plane */ + radeonDoDrawLine2D( rdrv, rdev, line ); + + /* Scale coordinates */ + line->x1 /= 2; + line->y1 /= 2; + line->x2 /= 2; + line->y2 /= 2; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1)/2 << 16) | + ((clip->x2+1)/2 & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cb_cop ); + + /* Fill Cb plane */ + radeonDoDrawLine2D( rdrv, rdev, line ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cr_cop ); + + /* Fill Cr plane */ + radeonDoDrawLine2D( rdrv, rdev, line ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->y_cop ); + + return true; +} + +static void +radeonDoBlit2D( RadeonDriverData *rdrv, RadeonDeviceData *rdev, + int sx, int sy, int dx, int dy, int w, int h ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 dir = 0; + + /* check which blitting direction should be used */ + if (sx <= dx) { + sx += w-1; + dx += w-1; + } else + dir |= DST_X_LEFT_TO_RIGHT; + + if (sy <= dy) { + sy += h-1; + dy += h-1; + } else + dir |= DST_Y_TOP_TO_BOTTOM; + + radeon_waitfifo( rdrv, rdev, 4 ); + + radeon_out32( mmio, DP_CNTL, dir ); + radeon_out32( mmio, SRC_Y_X, (sy << 16) | (sx & 0x3fff) ); + radeon_out32( mmio, DST_Y_X, (dy << 16) | (dx & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (h << 16) | (w & 0x3fff) ); +} + +bool radeonBlit2D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + sr->x /= 2; + sr->w = (sr->w+1) >> 1; + dx /= 2; + } + + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + return true; +} + +bool radeonBlit2D_420( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + /* Blit Luma plane */ + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + /* Scale coordinates */ + sr->x /= 2; + sr->y /= 2; + sr->w = (sr->w+1) >> 1; + sr->h = (sr->h+1) >> 1; + dx /= 2; + dy /= 2; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 6 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset_cb ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1/2) << 16) | + ((clip->x2+1/2) & 0xffff) ); + + /* Blit Cb plane */ + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset_cr ); + + /* Blit Cr plane */ + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 6 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + + return true; +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_2d.h b/Source/DirectFB/gfxdrivers/radeon/radeon_2d.h new file mode 100755 index 0000000..9277f85 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_2d.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __RADEON_2D_H__ +#define __RADEON_2D_H__ + +bool radeonFillRectangle2D( void *drv, void *dev, DFBRectangle *rect ); +bool radeonFillRectangle2D_420( void *drv, void *dev, DFBRectangle *rect ); + +bool radeonDrawRectangle2D( void *drv, void *dev, DFBRectangle *rect ); +bool radeonDrawRectangle2D_420( void *drv, void *dev, DFBRectangle *rect ); + +bool radeonDrawLine2D( void *drv, void *dev, DFBRegion *line ); +bool radeonDrawLine2D_420( void *drv, void *dev, DFBRegion *line ); + +bool radeonBlit2D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ); +bool radeonBlit2D_420( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ); + +#endif /* __RADEON_2D_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_3d.h b/Source/DirectFB/gfxdrivers/radeon/radeon_3d.h new file mode 100755 index 0000000..0504dbc --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_3d.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __RADEON_3D_H__ +#define __RADEON_3D_H__ + +/* R100 Functions */ +bool r100FillRectangle3D( void *drv, void *dev, DFBRectangle *rect ); + +bool r100FillTriangle( void *drv, void *dev, DFBTriangle *tri ); + +bool r100DrawRectangle3D( void *drv, void *dev, DFBRectangle *rect ); + +bool r100DrawLine3D( void *drv, void *dev, DFBRegion *line ); + +bool r100Blit3D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ); + +bool r100StretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr ); + +bool r100TextureTriangles( void *drv, void *dev, DFBVertex *ve, + int num, DFBTriangleFormation formation ); + +void r100EmitCommands3D( void *drv, void *dev ); + +/* R200 Functions */ +bool r200FillRectangle3D( void *drv, void *dev, DFBRectangle *rect ); + +bool r200FillTriangle( void *drv, void *dev, DFBTriangle *tri ); + +bool r200DrawRectangle3D( void *drv, void *dev, DFBRectangle *rect ); + +bool r200DrawLine3D( void *drv, void *dev, DFBRegion *line ); + +bool r200Blit3D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ); + +bool r200StretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr ); + +bool r200TextureTriangles( void *drv, void *dev, DFBVertex *ve, + int num, DFBTriangleFormation formation ); + +void r200EmitCommands3D( void *drv, void *dev ); + +/* R300 Functions */ +bool r300FillRectangle3D( void *drv, void *dev, DFBRectangle *rect ); + +bool r300FillTriangle( void *drv, void *dev, DFBTriangle *tri ); + +bool r300DrawRectangle3D( void *drv, void *dev, DFBRectangle *rect ); + +bool r300DrawLine3D( void *drv, void *dev, DFBRegion *line ); + +bool r300Blit3D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ); + +bool r300StretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr ); + +bool r300TextureTriangles( void *drv, void *dev, DFBVertex *ve, + int num, DFBTriangleFormation formation ); + +void r300EmitCommands3D( void *drv, void *dev ); + + +#endif /* __RADEON_3D_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_chipsets.h b/Source/DirectFB/gfxdrivers/radeon/radeon_chipsets.h new file mode 100755 index 0000000..52f38f1 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_chipsets.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __RADEON_CHIPSETS_H__ +#define __RADEON_CHIPSETS_H__ + +static const struct { + u16 id; + u16 chip; + bool igp; + const char *name; +} dev_table[] = { + { 0x5144, CHIP_R100 , false, "Radeon" }, + { 0x5145, CHIP_R100 , false, "Radeon" }, + { 0x5146, CHIP_R100 , false, "Radeon" }, + { 0x5147, CHIP_R100 , false, "Radeon" }, + { 0x5159, CHIP_RV100, false, "Radeon VE/7000" }, + { 0x515a, CHIP_RV100, false, "Radeon VE/7000" }, + { 0x4c59, CHIP_RV100, false, "Radeon Mobility M6" }, + { 0x4c5a, CHIP_RV100, false, "Radeon Mobility M6" }, + { 0x4c57, CHIP_RV200, false, "Radeon Mobility M7" }, + { 0x4c58, CHIP_RV200, false, "FireGL Mobility 7800 M7" }, + { 0x5157, CHIP_RV200, false, "Radeon 7500" }, + { 0x5158, CHIP_RV200, false, "Radeon 7500" }, + { 0x4136, CHIP_RS100, true , "Radeon IGP320" }, + { 0x4336, CHIP_RS100, true , "Radeon IGP320M" }, + { 0x4137, CHIP_RS200, true , "Radeon IGP330/340/350" }, + { 0x4337, CHIP_RS200, true , "Radeon IGP330M/340M/350M" }, + { 0x4237, CHIP_RS250, true , "Radeon 7000 IGP" }, + { 0x4437, CHIP_RS250, true , "Radeon Mobility 7000 IGP" }, + { 0x514c, CHIP_R200 , false, "Radeon 8500" }, + { 0x4242, CHIP_R200 , false, "Radeon 8500 AIW" }, + { 0x4243, CHIP_R200 , false, "Radeon 8500 AIW" }, + { 0x514d, CHIP_R200 , false, "Radeon 9100" }, + { 0x5148, CHIP_R200 , false, "FireGL 8700/8800" }, + { 0x4966, CHIP_RV250, false, "Radeon 9000 PRO" }, + { 0x4967, CHIP_RV250, false, "Radeon 9000" }, + { 0x4c66, CHIP_RV250, false, "Radeon Mobility 9000 M9" }, + { 0x4c67, CHIP_RV250, false, "Radeon Mobility 9000 M9" }, + { 0x4c64, CHIP_RV250, false, "FireGL Mobility 9000 M9" }, + { 0x5960, CHIP_RV280, false, "Radeon 9200 PRO" }, + { 0x5961, CHIP_RV280, false, "Radeon 9200" }, + { 0x5962, CHIP_RV280, false, "Radeon 9200" }, + { 0x5964, CHIP_RV280, false, "Radeon 9200 SE" }, + { 0x5c61, CHIP_RV280, false, "Radeon Mobility 9200 M9+" }, + { 0x5c63, CHIP_RV280, false, "Radeon Mobility 9200 M9+" }, + { 0x5834, CHIP_RS300, true , "Radeon 9100 IGP" }, + { 0x5835, CHIP_RS300, true , "Radeon Mobility 9100 IGP" }, + { 0x7834, CHIP_RS350, true , "Radeon 9100 PRO IGP" }, + { 0x7835, CHIP_RS350, true , "Radeon Mobility 9200 IGP" }, + { 0x4144, CHIP_R300 , false, "Radeon 9500" }, + { 0x4145, CHIP_R300 , false, "Radeon 9500" }, + { 0x4146, CHIP_R300 , false, "Radeon 9600 TX" }, + { 0x4147, CHIP_R300 , false, "FireGL Z1" }, + { 0x4e44, CHIP_R300 , false, "Radeon 9700 PRO" }, + { 0x4e45, CHIP_R300 , false, "Radeon 9700/9500PRO" }, + { 0x4e46, CHIP_R300 , false, "Radeon 9600 TX" }, + { 0x4e47, CHIP_R300 , false, "FireGL X1" }, + { 0x4150, CHIP_RV350, false, "Radeon 9600" }, + { 0x4151, CHIP_RV350, false, "Radeon 9600 SE" }, + { 0x4152, CHIP_RV350, false, "Radeon 9600 XT" }, + { 0x4153, CHIP_RV350, false, "Radeon 9600" }, + { 0x4154, CHIP_RV350, false, "FireGL T2" }, + { 0x4156, CHIP_RV350, false, "FireGL RV360" }, + { 0x4e50, CHIP_RV350, false, "Radeon Mobility 9600/9700 M10/M11" }, + { 0x4e51, CHIP_RV350, false, "Radeon Mobility 9600 M10" }, + { 0x4e52, CHIP_RV350, false, "Radeon Mobility 9600 M11" }, + { 0x4e53, CHIP_RV350, false, "Radeon Mobility 9600 M10" }, + { 0x4e54, CHIP_RV350, false, "FireGL Mobility T2 M10" }, + { 0x4e56, CHIP_RV350, false, "FireGL Mobility T2e M11" }, + { 0x4155, CHIP_RV350, false, "Radeon 9650" }, + { 0x4148, CHIP_R350 , false, "Radeon 9800 SE" }, + { 0x4149, CHIP_R350 , false, "Radeon 9800" }, + { 0x414a, CHIP_R350 , false, "Radeon 9800" }, + { 0x414b, CHIP_R350 , false, "FireGL X2" }, + { 0x4e48, CHIP_R350 , false, "Radeon 9800 PRO" }, + { 0x4e49, CHIP_R350 , false, "Radeon 9800" }, + { 0x4e4b, CHIP_R350 , false, "FireGL X2" }, + { 0x4e4a, CHIP_R350 , false, "Radeon 9800 XT" }, + { 0x3e50, CHIP_RV380, false, "Radeon X600" }, + { 0x3e54, CHIP_RV380, false, "FireGL V3200" }, + { 0x3150, CHIP_RV380, false, "Radeon Mobility X600 M24" }, + { 0x3152, CHIP_RV380, false, "Radeon Mobility X300 M24" }, + { 0x3154, CHIP_RV380, false, "FireGL M24 GL" }, + { 0x5b60, CHIP_RV380, false, "Radeon X300" }, + { 0x5b62, CHIP_RV380, false, "Radeon X600" }, + { 0x5b63, CHIP_RV380, false, "Radeon X550" }, + { 0x5b64, CHIP_RV380, false, "FireGL V3100" }, + { 0x5b65, CHIP_RV380, false, "FireMV 2200 PCIE" }, + { 0x5460, CHIP_RV380, false, "Radeon Mobility X300 M22" }, + { 0x5462, CHIP_RV380, false, "Radeon Mobility X600 SE M24C" }, + { 0x5464, CHIP_RV380, false, "FireGL M22 GL" }, + { 0x5a41, CHIP_RS400, false, "Radeon XPRESS 200" }, + { 0x5a42, CHIP_RS400, false, "Radeon XPRESS 200M" }, + { 0x5a61, CHIP_RS400, false, "Radeon XPRESS 200" }, + { 0x5a62, CHIP_RS400, false, "Radeon XPRESS 200M" }, + { 0x5954, CHIP_RS400, false, "Radeon XPRESS 200" }, + { 0x5955, CHIP_RS400, false, "Radeon XPRESS 200M" }, + { 0x5974, CHIP_RS400, false, "Radeon XPRESS 200" }, + { 0x5975, CHIP_RS400, false, "Radeon XPRESS 200M" }, + { 0x5e48, CHIP_RV410, false, "FireGL V5000" }, + { 0x564a, CHIP_RV410, false, "Mobility FireGL V5000 M26" }, + { 0x564b, CHIP_RV410, false, "Mobility FireGL V5000 M26" }, + { 0x564f, CHIP_RV410, false, "Mobility Radeon X700 XL M26" }, + { 0x5652, CHIP_RV410, false, "Mobility Radeon X700 M26" }, + { 0x5653, CHIP_RV410, false, "Mobility Radeon X700 M26" }, + { 0x5e4b, CHIP_RV410, false, "Radeon X700 PRO" }, + { 0x5e4a, CHIP_RV410, false, "Radeon X700 XT" }, + { 0x5e4d, CHIP_RV410, false, "Radeon X700" }, + { 0x5e4c, CHIP_RV410, false, "Radeon X700 SE" }, + { 0x5e4f, CHIP_RV410, false, "Radeon X700 SE" }, + { 0x4a48, CHIP_R420 , false, "Radeon X800" }, + { 0x4a49, CHIP_R420 , false, "Radeon X800 PRO" }, + { 0x4a4a, CHIP_R420 , false, "Radeon X800 SE" }, + { 0x4a4b, CHIP_R420 , false, "Radeon X800" }, + { 0x4a4c, CHIP_R420 , false, "Radeon X800" }, + { 0x4a4d, CHIP_R420 , false, "FireGL X3" }, + { 0x4a4e, CHIP_R420 , false, "Radeon Mobility 9800 M18" }, + { 0x4a50, CHIP_R420 , false, "Radeon X800 XT" }, + { 0x4a4f, CHIP_R420 , false, "Radeon X800 SE" }, + { 0x4a54, CHIP_R420 , false, "Radeon AIW X800" }, + { 0x5548, CHIP_R420 , false, "Radeon X800" }, + { 0x5549, CHIP_R420 , false, "Radeon X800 PRO" }, + { 0x554a, CHIP_R420 , false, "Radeon X800 LE" }, + { 0x554b, CHIP_R420 , false, "Radeon X800 SE" }, + { 0x5551, CHIP_R420 , false, "FireGL V5100" }, + { 0x5552, CHIP_R420 , false, "FireGL Unknown" }, + { 0x5554, CHIP_R420 , false, "FireGL Unknown" }, + { 0x5d57, CHIP_R420 , false, "Radeon X800 XT" }, + { 0x5550, CHIP_R420 , false, "FireGL V7100" }, + { 0x5d49, CHIP_R420 , false, "Mobility FireGL V5100 M28" }, + { 0x5d4a, CHIP_R420 , false, "Mobility Radeon X800 M28" }, + { 0x5d48, CHIP_R420 , false, "Mobility Radeon X800 XT M28" }, + { 0x554f, CHIP_R420 , false, "Radeon X800" }, + { 0x554d, CHIP_R420 , false, "Radeon X800 XL" }, + { 0x554e, CHIP_R420 , false, "Radeon X800 SE" }, + { 0x554c, CHIP_R420 , false, "Radeon X800 XTP" }, + { 0x5d4c, CHIP_R420 , false, "Radeon X850" }, + { 0x5d50, CHIP_R420 , false, "Radeon Unknown R480" }, + { 0x5d4e, CHIP_R420 , false, "Radeon X850 SE" }, + { 0x5d4f, CHIP_R420 , false, "Radeon X850 PRO" }, + { 0x5d52, CHIP_R420 , false, "Radeon X850 XT" }, + { 0x5d4d, CHIP_R420 , false, "Radeon X850 XT PE" }, + { 0x4b4b, CHIP_R420 , false, "Radeon X850 PRO" }, + { 0x4b4a, CHIP_R420 , false, "Radeon X850 SE" }, + { 0x4b49, CHIP_R420 , false, "Radeon X850 XT" }, + { 0x4b4c, CHIP_R420 , false, "Radeon X850 XT PE" } +}; + +#endif /* __RADEON_CHIPSETS_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_crtc1.c b/Source/DirectFB/gfxdrivers/radeon/radeon_crtc1.c new file mode 100755 index 0000000..c4b1610 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_crtc1.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <directfb.h> + +#include <core/coredefs.h> +#include <core/screen.h> +#include <core/screens.h> +#include <core/layers.h> +#include <core/layer_context.h> +#include <core/layer_region.h> +#include <core/layer_control.h> +#include <core/layers_internal.h> +#include <core/surface.h> +#include <core/system.h> + +#include <misc/conf.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" + + + +/*************************** CRTC1 Screen functions **************************/ + +static DFBResult +crtc1WaitVSync( CoreScreen *screen, + void *driver_data, + void *screen_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + volatile u8 *mmio = rdrv->mmio_base; + int i; + + if (dfb_config->pollvsync_none) + return DFB_OK; + + radeon_out32( mmio, GEN_INT_STATUS, + (radeon_in32( mmio, GEN_INT_STATUS ) & ~VSYNC_INT) | VSYNC_INT_AK ); + + for (i = 0; i < 2000000; i++) { + struct timespec t = { 0, 10000 }; + + if (radeon_in32( mmio, GEN_INT_STATUS ) & VSYNC_INT) + break; + nanosleep( &t, NULL ); + } + + return DFB_OK; +} + +ScreenFuncs RadeonCrtc1ScreenFuncs = { + .WaitVSync = crtc1WaitVSync +}; + +ScreenFuncs OldPrimaryScreenFuncs; +void *OldPrimaryScreenDriverData; + + +/*************************** CRTC1 Layer functions **************************/ + +#define CRTC1_SUPPORTED_OPTIONS ( DLOP_ALPHACHANNEL ) + +static DFBResult +crtc1InitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + DFBResult ret; + + ret = OldPrimaryLayerFuncs.InitLayer( layer, + OldPrimaryLayerDriverData, + layer_data, description, + config, adjustment ); + + description->caps |= DLCAPS_ALPHACHANNEL; + + return ret; +} + +static DFBResult +crtc1TestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + CoreLayerRegionConfig layer_config; + CoreLayerRegionConfigFlags fail = 0; + DFBResult ret; + + layer_config = *config; + layer_config.options &= ~CRTC1_SUPPORTED_OPTIONS; + + ret = OldPrimaryLayerFuncs.TestRegion( layer, + OldPrimaryLayerDriverData, + layer_data, &layer_config, &fail ); + + if (config->options & ~CRTC1_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + if (config->options & DLOP_ALPHACHANNEL && config->format != DSPF_ARGB) + fail |= CLRCF_OPTIONS; + + if (failed) + *failed = fail; + + return fail ? DFB_UNSUPPORTED : DFB_OK; +} + +static DFBResult +crtc1SetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + + if (updated & ~CLRCF_OPTIONS) { + return OldPrimaryLayerFuncs.SetRegion( layer, + OldPrimaryLayerDriverData, + layer_data, region_data, + config, updated, surface, palette, lock ); + } + + return DFB_OK; +} + +DisplayLayerFuncs RadeonCrtc1LayerFuncs = { + .InitLayer = crtc1InitLayer, + .TestRegion = crtc1TestRegion, + .SetRegion = crtc1SetRegion +}; + +DisplayLayerFuncs OldPrimaryLayerFuncs; +void *OldPrimaryLayerDriverData; + diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_crtc2.c b/Source/DirectFB/gfxdrivers/radeon/radeon_crtc2.c new file mode 100755 index 0000000..bcae981 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_crtc2.c @@ -0,0 +1,1011 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> + +#include <directfb.h> + +#include <core/coredefs.h> +#include <core/gfxcard.h> +#include <core/screens.h> +#include <core/layers.h> +#include <core/layer_context.h> +#include <core/layer_region.h> +#include <core/layer_control.h> +#include <core/layers_internal.h> +#include <core/palette.h> +#include <core/surface.h> +#include <core/system.h> + +#include <misc/conf.h> + +#include <gfx/convert.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" + + +typedef struct { + CoreLayerRegionConfig config; + CorePalette *palette; + DFBColorAdjustment adjustment; + + unsigned int pll_max_freq; + unsigned int pll_min_freq; + unsigned int pll_ref_div; + unsigned int pll_ref_clk; + + struct { + unsigned int size; + u8 r[256]; + u8 g[256]; + u8 b[256]; + } lut; + + struct { + u32 rCRTC2_GEN_CNTL; + u32 rFP2_GEN_CNTL; + u32 rDAC_CNTL2; + u32 rTV_DAC_CNTL; + u32 rDISP_OUTPUT_CNTL; + u32 rDISP_HW_DEBUG; + u32 rCRTC2_OFFSET_CNTL; + } save; + + struct { + u32 rCRTC2_GEN_CNTL; + u32 rDAC_CNTL2; + u32 rTV_DAC_CNTL; + u32 rDISP_OUTPUT_CNTL; + u32 rDISP_HW_DEBUG; + u32 rCRTC2_H_TOTAL_DISP; + u32 rCRTC2_H_SYNC_STRT_WID; + u32 rCRTC2_V_TOTAL_DISP; + u32 rCRTC2_V_SYNC_STRT_WID; + u32 rCRTC2_BASE_ADDR; + u32 rCRTC2_OFFSET; + u32 rCRTC2_OFFSET_CNTL; + u32 rCRTC2_PITCH; + u32 rFP2_GEN_CNTL; + u32 rFP2_H_SYNC_STRT_WID; + u32 rFP2_V_SYNC_STRT_WID; + u32 rP2PLL_REF_DIV; + u32 rP2PLL_DIV_0; + u32 rHTOTAL2_CNTL; + } regs; +} RadeonCrtc2LayerData; + +static VideoMode* crtc2_find_mode ( RadeonDriverData *drv, + int xres, + int yres ); +static bool crtc2_calc_regs ( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ); +static void crtc2_set_regs ( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2 ); +static void crtc2_calc_palette ( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2, + CoreLayerRegionConfig *config, + DFBColorAdjustment *adjustment, + CorePalette *palette ); +static void crtc2_set_palette ( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2 ); + +/*************************** CRTC2 Screen functions **************************/ + +static DFBResult +crtc2InitScreen( CoreScreen *screen, + CoreGraphicsDevice *device, + void *driver_data, + void *screen_data, + DFBScreenDescription *description ) +{ + /* Set the screen capabilities. */ + description->caps = DSCCAPS_VSYNC | DSCCAPS_POWER_MANAGEMENT; + + /* Set the screen name. */ + snprintf( description->name, + DFB_SCREEN_DESC_NAME_LENGTH, "Radeon CRTC2" ); + + return DFB_OK; +} + +static DFBResult +crtc2SetPowerMode( CoreScreen *screen, + void *driver_data, + void *screen_data, + DFBScreenPowerMode mode ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + volatile u8 *mmio = rdrv->mmio_base; + u32 crtc2_gen_cntl; + + crtc2_gen_cntl = radeon_in32( mmio, CRTC2_GEN_CNTL ); + crtc2_gen_cntl &= ~(CRTC2_HSYNC_DIS | CRTC2_VSYNC_DIS | CRTC2_DISP_DIS); + + switch (mode) { + case DSPM_OFF: + crtc2_gen_cntl |= CRTC2_HSYNC_DIS | + CRTC2_VSYNC_DIS | + CRTC2_DISP_DIS; + break; + case DSPM_SUSPEND: + crtc2_gen_cntl |= CRTC2_VSYNC_DIS | + CRTC2_DISP_DIS; + break; + case DSPM_STANDBY: + crtc2_gen_cntl |= CRTC2_HSYNC_DIS | + CRTC2_DISP_DIS; + break; + case DSPM_ON: + break; + default: + D_DEBUG( "unknown power mode" ); + return DFB_INVARG; + } + + radeon_out32( mmio, CRTC2_GEN_CNTL, crtc2_gen_cntl ); + + return DFB_OK; +} + +static DFBResult +crtc2WaitVSync( CoreScreen *screen, + void *driver_data, + void *screen_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + volatile u8 *mmio = rdrv->mmio_base; + int i; + + if (dfb_config->pollvsync_none) + return DFB_OK; + + radeon_out32( mmio, GEN_INT_STATUS, + (radeon_in32( mmio, GEN_INT_STATUS ) & ~VSYNC2_INT) | VSYNC2_INT_AK ); + + for (i = 0; i < 2000000; i++) { + struct timespec t = { 0, 10000 }; + + if (radeon_in32( mmio, GEN_INT_STATUS ) & VSYNC2_INT) + break; + nanosleep( &t, NULL ); + } + + return DFB_OK; +} + +static DFBResult +crtc2GetScreenSize( CoreScreen *screen, + void *driver_data, + void *screen_data, + int *ret_width, + int *ret_height ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + volatile u8 *mmio = rdrv->mmio_base; + unsigned int xres; + unsigned int yres; + + xres = ((radeon_in32( mmio, CRTC2_H_TOTAL_DISP ) >> 16) + 1) * 8; + yres = ((radeon_in32( mmio, CRTC2_V_TOTAL_DISP ) >> 16) + 1); + + D_DEBUG( "DirectFB/Radeon/CRTC2: " + "detected screen size %dx%d.\n", xres, yres ); + + if (xres <= 1 || yres <= 1) { + VideoMode *mode = dfb_system_modes(); + + if (!mode) { + D_WARN( "no default video mode" ); + return DFB_UNSUPPORTED; + } + xres = mode->xres; + yres = mode->yres; + } + + *ret_width = xres; + *ret_height = yres; + + return DFB_OK; +} + +ScreenFuncs RadeonCrtc2ScreenFuncs = { + .InitScreen = crtc2InitScreen, + .SetPowerMode = crtc2SetPowerMode, + .WaitVSync = crtc2WaitVSync, + .GetScreenSize = crtc2GetScreenSize +}; + +/**************************** CRTC2 Layer functions **************************/ + +#define CRTC2_SUPPORTED_OPTIONS ( DLOP_ALPHACHANNEL ) + +static int +crtc2LayerDataSize( void ) +{ + return sizeof(RadeonCrtc2LayerData); +} + +static DFBResult +crtc2InitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonCrtc2LayerData *rcrtc2 = (RadeonCrtc2LayerData*) layer_data; + volatile u8 *mmio = rdrv->mmio_base; + VideoMode *mode; + + mode = dfb_system_modes(); + if (!mode) { + D_BUG( "no default video mode" ); + return DFB_FAILURE; + } + + /* Fill layer description. */ + description->caps = DLCAPS_SURFACE | DLCAPS_BRIGHTNESS | + DLCAPS_CONTRAST | DLCAPS_SATURATION | + DLCAPS_ALPHACHANNEL; + + description->type = DLTF_GRAPHICS; + + snprintf( description->name, + DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Radeon CRTC2's Underlay" ); + + /* Set default configuration. */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | + DLCONF_OPTIONS; + config->width = mode->xres; + config->height = mode->yres; + config->pixelformat = DSPF_RGB16; + config->buffermode = DLBM_FRONTONLY; + config->options = DLOP_NONE; + + /* Set default color adjustment. */ + adjustment->flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | + DCAF_SATURATION; + adjustment->brightness = 0x8000; + adjustment->contrast = 0x8000; + adjustment->saturation = 0x8000; + + /* Set PLL coefficients (should be done by reading the BIOS). */ + rcrtc2->pll_max_freq = 35000; + rcrtc2->pll_min_freq = 12000; + rcrtc2->pll_ref_div = 60; + rcrtc2->pll_ref_clk = 2700; + + /* Save common registers. */ + rcrtc2->save.rCRTC2_GEN_CNTL = radeon_in32( mmio, CRTC2_GEN_CNTL ); + rcrtc2->save.rFP2_GEN_CNTL = radeon_in32( mmio, FP2_GEN_CNTL ); + rcrtc2->save.rDAC_CNTL2 = radeon_in32( mmio, DAC_CNTL2 ); + rcrtc2->save.rTV_DAC_CNTL = radeon_in32( mmio, TV_DAC_CNTL ); + rcrtc2->save.rDISP_OUTPUT_CNTL = radeon_in32( mmio, DISP_OUTPUT_CNTL ); + rcrtc2->save.rDISP_HW_DEBUG = radeon_in32( mmio, DISP_HW_DEBUG ); + rcrtc2->save.rCRTC2_OFFSET_CNTL = radeon_in32( mmio, CRTC2_OFFSET_CNTL ); + + return DFB_OK; +} + +static DFBResult +crtc2TestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + CoreLayerRegionConfigFlags fail = 0; + + /* check for unsupported options */ + if (config->options & ~CRTC2_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + if (config->options & DLOP_ALPHACHANNEL && config->format != DSPF_ARGB) + fail |= CLRCF_OPTIONS; + + /* check for unsupported buffermode */ + switch (config->buffermode) { + case DLBM_FRONTONLY: + case DLBM_BACKSYSTEM: + case DLBM_BACKVIDEO: + case DLBM_TRIPLE: + break; + + default: + fail |= CLRCF_BUFFERMODE; + break; + } + + /* check for unsupported pixelformat */ + switch (config->format) { + case DSPF_LUT8: + case DSPF_RGB332: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB24: + case DSPF_RGB32: + case DSPF_ARGB: + break; + + default: + fail |= CLRCF_FORMAT; + break; + } + + /* check for unsupported size */ + if (!crtc2_find_mode( rdrv, config->width, config->height )) + fail |= CLRCF_WIDTH | CLRCF_HEIGHT; + + if (failed) + *failed = fail; + + return fail ? DFB_UNSUPPORTED : DFB_OK; +} + +static DFBResult +crtc2AddRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonDeviceData *rdev = rdrv->device_data; + + if (!rdev->monitor2) { + D_ERROR( "DirectFB/Radeon/CRTC2: " + "no secondary monitor connected!\n" ); + return DFB_IO; + } + + return DFB_OK; +} + +static DFBResult +crtc2SetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonCrtc2LayerData *rcrtc2 = (RadeonCrtc2LayerData*) layer_data; + + rcrtc2->config = *config; + rcrtc2->palette = palette; + + updated &= CLRCF_WIDTH | CLRCF_HEIGHT | + CLRCF_FORMAT | CLRCF_SURFACE | CLRCF_PALETTE; + + if (updated & ~CLRCF_PALETTE) { + if (!crtc2_calc_regs( rdrv, rcrtc2, &rcrtc2->config, surface, lock )) + return DFB_UNSUPPORTED; + + crtc2_set_regs( rdrv, rcrtc2 ); + } + + if (updated) { + crtc2_calc_palette( rdrv, rcrtc2, &rcrtc2->config, + &rcrtc2->adjustment, rcrtc2->palette ); + crtc2_set_palette( rdrv, rcrtc2 ); + } + + return DFB_OK; +} + +static DFBResult +crtc2RemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonCrtc2LayerData *rcrtc2 = (RadeonCrtc2LayerData*) layer_data; + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitidle( rdrv, rdrv->device_data ); + + radeon_out32( mmio, CRTC2_GEN_CNTL, rcrtc2->save.rCRTC2_GEN_CNTL ); + radeon_out32( mmio, FP2_GEN_CNTL, rcrtc2->save.rFP2_GEN_CNTL ); + radeon_out32( mmio, DAC_CNTL2, rcrtc2->save.rDAC_CNTL2 ); + radeon_out32( mmio, TV_DAC_CNTL, rcrtc2->save.rTV_DAC_CNTL ); + radeon_out32( mmio, DISP_OUTPUT_CNTL, rcrtc2->save.rDISP_OUTPUT_CNTL ); + radeon_out32( mmio, DISP_HW_DEBUG, rcrtc2->save.rDISP_HW_DEBUG ); + radeon_out32( mmio, CRTC2_OFFSET_CNTL, rcrtc2->save.rCRTC2_OFFSET_CNTL ); + + return DFB_OK; +} + +static DFBResult +crtc2FlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonDeviceData *rdev = rdrv->device_data; + RadeonCrtc2LayerData *rcrtc2 = (RadeonCrtc2LayerData*) layer_data; + volatile u8 *mmio = rdrv->mmio_base; + + if (lock->phys - lock->offset == rdev->fb_phys) + rcrtc2->regs.rCRTC2_BASE_ADDR = rdev->fb_offset; + else + rcrtc2->regs.rCRTC2_BASE_ADDR = rdev->agp_offset; + + rcrtc2->regs.rCRTC2_OFFSET = lock->offset; + + radeon_waitidle( rdrv, rdrv->device_data ); + + radeon_out32( mmio, CRTC2_BASE_ADDR, rcrtc2->regs.rCRTC2_BASE_ADDR ); + radeon_out32( mmio, CRTC2_OFFSET, rcrtc2->regs.rCRTC2_OFFSET ); + + dfb_surface_flip( surface, false ); + + if (flags & DSFLIP_WAIT) + dfb_layer_wait_vsync( layer ); + + return DFB_OK; +} + +static DFBResult +crtc2SetColorAdjustment( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBColorAdjustment *adj ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonCrtc2LayerData *rcrtc2 = (RadeonCrtc2LayerData*) layer_data; + + if (adj->flags & DCAF_BRIGHTNESS) { + if (adj->brightness == 0x8000) { + rcrtc2->adjustment.flags &= ~DCAF_BRIGHTNESS; + } else { + rcrtc2->adjustment.flags |= DCAF_BRIGHTNESS; + rcrtc2->adjustment.brightness = adj->brightness; + } + } + if (adj->flags & DCAF_CONTRAST) { + if (adj->contrast == 0x8000) { + rcrtc2->adjustment.flags &= ~DCAF_CONTRAST; + } else { + rcrtc2->adjustment.flags |= DCAF_CONTRAST; + rcrtc2->adjustment.contrast = adj->contrast; + } + } + if (adj->flags & DCAF_SATURATION) { + if (adj->saturation == 0x8000) { + rcrtc2->adjustment.flags &= ~DCAF_SATURATION; + } else { + rcrtc2->adjustment.flags |= DCAF_SATURATION; + rcrtc2->adjustment.saturation = adj->saturation; + } + } + + crtc2_calc_palette( rdrv, rcrtc2, &rcrtc2->config, + &rcrtc2->adjustment, rcrtc2->palette ); + crtc2_set_palette( rdrv, rcrtc2 ); + + return DFB_OK; +} + +DisplayLayerFuncs RadeonCrtc2LayerFuncs = { + .LayerDataSize = crtc2LayerDataSize, + .InitLayer = crtc2InitLayer, + .TestRegion = crtc2TestRegion, + .AddRegion = crtc2AddRegion, + .SetRegion = crtc2SetRegion, + .RemoveRegion = crtc2RemoveRegion, + .FlipRegion = crtc2FlipRegion, + .SetColorAdjustment = crtc2SetColorAdjustment +}; + +/************************** CRTC2 internal functions *************************/ + +static VideoMode* +crtc2_find_mode( RadeonDriverData *rdrv, + int xres, + int yres ) +{ + VideoMode *modes = dfb_system_modes(); + VideoMode *mode; + + for (mode = modes; mode; mode = mode->next) { + if (mode->xres == xres && mode->yres == yres) + return mode; + } + + return NULL; +} + +static void +crtc2_calc_pllregs( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2, + unsigned int freq ) +{ + struct { + int divider; + int bitvalue; + } *post_div, post_divs[] = { + { 1, 0 }, /* VCLK_SRC */ + { 2, 1 }, /* VCLK_SRC/2 */ + { 4, 2 }, /* VCLK_SRC/4 */ + { 8, 3 }, /* VCLK_SRC/8 */ + { 3, 4 }, /* VCLK_SRC/3 */ + { 6, 6 }, /* VCLK_SRC/6 */ + { 12, 7 }, /* VCLK_SRC/12 */ + { 0, 0 } + }; + u32 pll_output_freq_2 = 0; + u32 feedback_div_2; + + if (freq > rcrtc2->pll_max_freq) + freq = rcrtc2->pll_max_freq; + if (freq*12 < rcrtc2->pll_min_freq) + freq = rcrtc2->pll_min_freq/12; + + for (post_div = &post_divs[0]; post_div->divider; ++post_div) { + pll_output_freq_2 = post_div->divider * freq; + if (pll_output_freq_2 >= rcrtc2->pll_min_freq && + pll_output_freq_2 <= rcrtc2->pll_max_freq) + break; + } + + if (!post_div->divider) { + pll_output_freq_2 = freq; + post_div = &post_divs[0]; + } + + feedback_div_2 = rcrtc2->pll_ref_div * pll_output_freq_2; + feedback_div_2 += rcrtc2->pll_ref_clk/2; + feedback_div_2 /= rcrtc2->pll_ref_clk; + + D_DEBUG( "DirectFB/Radeon/CRTC2: " + "DotCLock=%d OutputFreq=%d FeedbackDiv=%d PostDiv=%d.\n", + freq, pll_output_freq_2, feedback_div_2, post_div->divider ); + + rcrtc2->regs.rP2PLL_REF_DIV = rcrtc2->pll_ref_div; + rcrtc2->regs.rP2PLL_DIV_0 = feedback_div_2 | (post_div->bitvalue << 16); + rcrtc2->regs.rHTOTAL2_CNTL = 0; +} + +static bool +crtc2_calc_regs( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ) +{ + RadeonDeviceData *rdev = rdrv->device_data; + VideoMode *mode; + u32 format = 0; + + int h_total, h_sync_start, h_sync_end, h_sync_wid; + int v_total, v_sync_start, v_sync_end, v_sync_wid; + + + mode = crtc2_find_mode( rdrv, config->width, config->height ); + if (!mode) { + D_BUG( "unexpected error while searching video mode" ); + return false; + } + + switch (config->format) { + case DSPF_LUT8: + case DSPF_RGB332: + format = DST_8BPP; + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + format = DST_15BPP; + break; + case DSPF_RGB16: + format = DST_16BPP; + break; + case DSPF_RGB24: + format = DST_24BPP; + break; + case DSPF_RGB32: + case DSPF_ARGB: + format = DST_32BPP; + break; + default: + D_BUG( "unexpected pixelformat" ); + return false; + } + + h_sync_start = mode->xres + mode->right_margin; + h_sync_end = h_sync_start + mode->hsync_len; + h_total = h_sync_end + mode->left_margin; + h_sync_wid = (h_sync_end - h_sync_start) / 8; + h_sync_wid = CLAMP( h_sync_wid, 1, 0x3f ); + h_sync_start = h_sync_start - 8; + + v_sync_start = mode->yres + mode->lower_margin; + v_sync_end = v_sync_start + mode->vsync_len; + v_total = v_sync_end + mode->upper_margin; + v_sync_wid = v_sync_end - v_sync_start; + v_sync_wid = CLAMP( v_sync_wid, 1, 0x1f ); + + D_DEBUG( "DirectFB/Radeon/CRTC2: \n" + "\t\thSyncStart:%d hSyncEnd:%d hTotal:%d hSyncWid:%d\n" + "\t\tvSyncStart:%d vSyncEnd:%d vTotal:%d vSyncWid:%d\n", + h_sync_start, h_sync_end, h_total, h_sync_wid, + v_sync_start, v_sync_end, v_total, v_sync_wid ); + + rcrtc2->regs.rCRTC2_GEN_CNTL = CRTC2_EN | CRTC2_CRT2_ON | (format << 8); + if (mode->laced) + rcrtc2->regs.rCRTC2_GEN_CNTL |= CRTC2_INTERLACE_EN; + if (mode->doubled) + rcrtc2->regs.rCRTC2_GEN_CNTL |= CRTC2_DBL_SCAN_EN; + if (mode->sync_on_green) + rcrtc2->regs.rCRTC2_GEN_CNTL |= CRTC2_CSYNC_EN; + + rcrtc2->regs.rDAC_CNTL2 = rcrtc2->save.rDAC_CNTL2 | DAC2_DAC2_CLK_SEL; + rcrtc2->regs.rTV_DAC_CNTL = 0x00280203; + rcrtc2->regs.rDISP_OUTPUT_CNTL = rcrtc2->save.rDISP_OUTPUT_CNTL; + rcrtc2->regs.rDISP_HW_DEBUG = rcrtc2->save.rDISP_HW_DEBUG; + + if (rdev->chipset == CHIP_UNKNOWN || + rdev->chipset == CHIP_R200 || + rdev->chipset >= CHIP_R300) + { + rcrtc2->regs.rDISP_OUTPUT_CNTL &= ~(DISP_DAC_SOURCE_MASK | + DISP_DAC2_SOURCE_MASK); + + /* If primary monitor is a TV monitor, + * reverse the DAC source to control it using the CRTC2. */ + if (rdev->monitor1 == MT_CTV || rdev->monitor1 == MT_STV) + rcrtc2->regs.rDISP_OUTPUT_CNTL |= DISP_DAC2_SOURCE_CRTC2; + else + rcrtc2->regs.rDISP_OUTPUT_CNTL |= DISP_DAC_SOURCE_CRTC2; + } + else { + if (rdev->monitor1 == MT_CTV || rdev->monitor1 == MT_STV) { + rcrtc2->regs.rDISP_HW_DEBUG &= ~CRT2_DISP1_SEL; + rcrtc2->regs.rDAC_CNTL2 &= ~DAC2_DAC_CLK_SEL; + } + else { + rcrtc2->regs.rDISP_HW_DEBUG |= CRT2_DISP1_SEL; + rcrtc2->regs.rDAC_CNTL2 |= DAC2_DAC_CLK_SEL; + } + } + + rcrtc2->regs.rCRTC2_H_TOTAL_DISP = ((h_total/8 - 1) & 0x3ff) | + ((mode->xres/8 - 1) << 16); + rcrtc2->regs.rCRTC2_H_SYNC_STRT_WID = (h_sync_start & 0x1fff) | + ((h_sync_wid & 0x3f) << 16); + if (!mode->hsync_high) + rcrtc2->regs.rCRTC2_H_SYNC_STRT_WID |= CRTC2_H_SYNC_POL; + + rcrtc2->regs.rCRTC2_V_TOTAL_DISP = ((v_total - 1) & 0xffff) | + ((mode->yres - 1) << 16); + rcrtc2->regs.rCRTC2_V_SYNC_STRT_WID = ((v_sync_start - 1) & 0xfff) | + ((v_sync_wid & 0x1f) << 16); + if (!mode->vsync_high) + rcrtc2->regs.rCRTC2_V_SYNC_STRT_WID |= CRTC2_V_SYNC_POL; + + if (lock->phys - lock->offset == rdev->fb_phys) + rcrtc2->regs.rCRTC2_BASE_ADDR = rdev->fb_offset; + else + rcrtc2->regs.rCRTC2_BASE_ADDR = rdev->agp_offset; + + rcrtc2->regs.rCRTC2_OFFSET = lock->offset; + + rcrtc2->regs.rCRTC2_OFFSET_CNTL = rcrtc2->save.rCRTC2_OFFSET_CNTL; + rcrtc2->regs.rCRTC2_OFFSET_CNTL &= ~CRTC_TILE_EN; + rcrtc2->regs.rCRTC2_OFFSET_CNTL |= CRTC_HSYNC_EN; + + rcrtc2->regs.rCRTC2_PITCH = (lock->pitch / + DFB_BYTES_PER_PIXEL(surface->config.format)) >> 3; + rcrtc2->regs.rCRTC2_PITCH |= rcrtc2->regs.rCRTC2_PITCH << 16; + + if (rdev->monitor2 == MT_DFP) { + rcrtc2->regs.rCRTC2_GEN_CNTL &= ~CRTC2_CRT2_ON; + rcrtc2->regs.rFP2_GEN_CNTL = rcrtc2->save.rFP2_GEN_CNTL | FP2_ON; + + if (rdev->chipset == CHIP_UNKNOWN || + rdev->chipset == CHIP_R200 || + rdev->chipset >= CHIP_R300) + { + rcrtc2->regs.rFP2_GEN_CNTL &= ~(R200_FP2_SOURCE_SEL_MASK | + FP2_DVO_RATE_SEL_SDR); + rcrtc2->regs.rFP2_GEN_CNTL |= R200_FP2_SOURCE_SEL_CRTC2 | FP2_DVO_EN; + } + else { + rcrtc2->regs.rFP2_GEN_CNTL &= ~FP2_SRC_SEL_MASK; + rcrtc2->regs.rFP2_GEN_CNTL |= FP2_SRC_SEL_CRTC2; + } + + rcrtc2->regs.rFP2_H_SYNC_STRT_WID = rcrtc2->regs.rCRTC2_H_SYNC_STRT_WID; + rcrtc2->regs.rFP2_V_SYNC_STRT_WID = rcrtc2->regs.rCRTC2_V_SYNC_STRT_WID; + } + else { + rcrtc2->regs.rFP2_GEN_CNTL = rcrtc2->save.rFP2_GEN_CNTL; + rcrtc2->regs.rFP2_H_SYNC_STRT_WID = 0; + rcrtc2->regs.rFP2_V_SYNC_STRT_WID = 0; + } + + crtc2_calc_pllregs( rdrv, rcrtc2, 100000000 / mode->pixclock ); + + return true; +} + +static void +crtc2_set_regs ( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2 ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 tmp; + + /* Lock the card during mode switching. */ + dfb_gfxcard_lock( GDLF_WAIT | GDLF_SYNC ); + + radeon_out32( mmio, CRTC2_GEN_CNTL, + rcrtc2->regs.rCRTC2_GEN_CNTL | CRTC2_DISP_DIS ); + + radeon_out32( mmio, DAC_CNTL2, rcrtc2->regs.rDAC_CNTL2 ); + radeon_out32( mmio, TV_DAC_CNTL, rcrtc2->regs.rTV_DAC_CNTL ); + radeon_out32( mmio, DISP_OUTPUT_CNTL, rcrtc2->regs.rDISP_OUTPUT_CNTL ); + radeon_out32( mmio, DISP_HW_DEBUG, rcrtc2->regs.rDISP_HW_DEBUG ); + + radeon_out32( mmio, CRTC2_H_TOTAL_DISP, rcrtc2->regs.rCRTC2_H_TOTAL_DISP ); + radeon_out32( mmio, CRTC2_H_SYNC_STRT_WID, rcrtc2->regs.rCRTC2_H_SYNC_STRT_WID ); + + radeon_out32( mmio, CRTC2_V_TOTAL_DISP, rcrtc2->regs.rCRTC2_V_TOTAL_DISP ); + radeon_out32( mmio, CRTC2_V_SYNC_STRT_WID, rcrtc2->regs.rCRTC2_V_SYNC_STRT_WID ); + + radeon_out32( mmio, CRTC2_BASE_ADDR, rcrtc2->regs.rCRTC2_BASE_ADDR ); + radeon_out32( mmio, CRTC2_OFFSET, rcrtc2->regs.rCRTC2_OFFSET ); + radeon_out32( mmio, CRTC2_OFFSET_CNTL, rcrtc2->regs.rCRTC2_OFFSET_CNTL ); + radeon_out32( mmio, CRTC2_PITCH, rcrtc2->regs.rCRTC2_PITCH ); + + radeon_out32( mmio, FP2_GEN_CNTL, rcrtc2->regs.rFP2_GEN_CNTL ); + radeon_out32( mmio, FP2_H_SYNC_STRT_WID, rcrtc2->regs.rFP2_H_SYNC_STRT_WID ); + radeon_out32( mmio, FP2_V_SYNC_STRT_WID, rcrtc2->regs.rFP2_V_SYNC_STRT_WID ); + + tmp = radeon_inpll( mmio, PIXCLKS_CNTL) & ~PIX2CLK_SRC_SEL_MASK; + radeon_outpll( mmio, PIXCLKS_CNTL, tmp | PIX2CLK_SRC_SEL_CPUCLK ); + + tmp = radeon_inpll( mmio, P2PLL_CNTL ); + radeon_outpll( mmio, P2PLL_CNTL, tmp | P2PLL_RESET | + P2PLL_ATOMIC_UPDATE_EN | + P2PLL_VGA_ATOMIC_UPDATE_EN ); + + tmp = radeon_inpll( mmio, P2PLL_REF_DIV ) & ~P2PLL_REF_DIV_MASK; + radeon_outpll( mmio, P2PLL_REF_DIV, tmp | rcrtc2->regs.rP2PLL_REF_DIV ); + + tmp = radeon_inpll( mmio, P2PLL_DIV_0 ) & ~P2PLL_FB0_DIV_MASK; + radeon_outpll( mmio, P2PLL_DIV_0, tmp | rcrtc2->regs.rP2PLL_DIV_0 ); + + tmp = radeon_inpll( mmio, P2PLL_DIV_0 ) & ~P2PLL_POST0_DIV_MASK; + radeon_outpll( mmio, P2PLL_DIV_0, tmp | rcrtc2->regs.rP2PLL_DIV_0 ); + + while (radeon_inpll( mmio, P2PLL_REF_DIV ) & P2PLL_ATOMIC_UPDATE_R); + + radeon_outpll( mmio, P2PLL_REF_DIV, + radeon_inpll( mmio, P2PLL_REF_DIV ) | P2PLL_ATOMIC_UPDATE_W ); + + for (tmp = 0; tmp < 1000; tmp++) { + if (!(radeon_inpll( mmio, P2PLL_REF_DIV ) & P2PLL_ATOMIC_UPDATE_R)) + break; + } + + radeon_outpll( mmio, HTOTAL2_CNTL, rcrtc2->regs.rHTOTAL2_CNTL ); + + tmp = radeon_inpll( mmio, P2PLL_CNTL ); + radeon_outpll( mmio, P2PLL_CNTL, tmp & ~(P2PLL_RESET | P2PLL_SLEEP | + P2PLL_ATOMIC_UPDATE_EN | + P2PLL_VGA_ATOMIC_UPDATE_EN) ); + + usleep( 5000 ); + + tmp = radeon_inpll( mmio, PIXCLKS_CNTL ) & ~PIX2CLK_SRC_SEL_MASK; + radeon_outpll( mmio, PIXCLKS_CNTL, tmp | PIX2CLK_SRC_SEL_P2PLLCLK ); + + radeon_out32( mmio, CRTC2_GEN_CNTL, rcrtc2->regs.rCRTC2_GEN_CNTL ); + + dfb_gfxcard_unlock(); +} + +static inline u8 +calc_gamma( float n, float d ) +{ + int ret; + + ret = 255.0 * n / d + 0.5; + if (ret > 255) + ret = 255; + else if (ret < 0) + ret = 0; + + return ret; +} + +static void +crtc2_calc_palette( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2, + CoreLayerRegionConfig *config, + DFBColorAdjustment *adjustment, + CorePalette *palette ) +{ + unsigned int i; + int r, g, b; + + switch (config->format) { + case DSPF_LUT8: + rcrtc2->lut.size = MAX( palette->num_entries, 256 ); + for (i = 0; i < rcrtc2->lut.size; i++) { + rcrtc2->lut.r[i] = palette->entries[i].r; + rcrtc2->lut.g[i] = palette->entries[i].g; + rcrtc2->lut.b[i] = palette->entries[i].b; + } + break; + case DSPF_RGB332: + rcrtc2->lut.size = 256; + for (i = 0, r = 0; r < 8; r++) { + for (g = 0; g < 8; g++) { + for (b = 0; b < 4; b++) { + rcrtc2->lut.r[i] = calc_gamma( r, 7 ); + rcrtc2->lut.g[i] = calc_gamma( g, 7 ); + rcrtc2->lut.b[i] = calc_gamma( b, 3 ); + i++; + } + } + } + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + rcrtc2->lut.size = 32; + for (i = 0; i < 32; i++) { + rcrtc2->lut.r[i] = + rcrtc2->lut.g[i] = + rcrtc2->lut.b[i] = calc_gamma( i, 31 ); + } + break; + case DSPF_RGB16: + rcrtc2->lut.size = 64; + for (i = 0; i < 64; i++) { + rcrtc2->lut.r[i] = + rcrtc2->lut.b[i] = calc_gamma( i/2, 31 ); + rcrtc2->lut.g[i] = calc_gamma( i, 63 ); + } + break; + default: + rcrtc2->lut.size = 256; + for (i = 0; i < 256; i++) { + rcrtc2->lut.r[i] = + rcrtc2->lut.b[i] = + rcrtc2->lut.g[i] = i; + } + break; + } + + if (adjustment->flags & DCAF_BRIGHTNESS) { + int brightness = (adjustment->brightness >> 8) - 128; + + for (i = 0; i < rcrtc2->lut.size; i++) { + r = rcrtc2->lut.r[i] + brightness; + g = rcrtc2->lut.g[i] + brightness; + b = rcrtc2->lut.b[i] + brightness; + rcrtc2->lut.r[i] = CLAMP( r, 0, 255 ); + rcrtc2->lut.g[i] = CLAMP( g, 0, 255 ); + rcrtc2->lut.b[i] = CLAMP( b, 0, 255 ); + } + } + + if (adjustment->flags & DCAF_CONTRAST) { + int contrast = adjustment->contrast; + + for (i = 0; i < rcrtc2->lut.size; i++) { + r = rcrtc2->lut.r[i] * contrast / 0x8000; + g = rcrtc2->lut.g[i] * contrast / 0x8000; + b = rcrtc2->lut.b[i] * contrast / 0x8000; + rcrtc2->lut.r[i] = CLAMP( r, 0, 255 ); + rcrtc2->lut.g[i] = CLAMP( g, 0, 255 ); + rcrtc2->lut.b[i] = CLAMP( b, 0, 255 ); + } + } + + if (adjustment->flags & DCAF_SATURATION) { + int saturation = adjustment->saturation >> 8; + + for (i = 0; i < rcrtc2->lut.size; i++) { + if (saturation > 128) { + float gray = ((float)saturation - 128.0)/128.0; + float color = 1.0 - gray; + + r = (((float)rcrtc2->lut.r[i] - 128.0 * gray)/color); + g = (((float)rcrtc2->lut.g[i] - 128.0 * gray)/color); + b = (((float)rcrtc2->lut.b[i] - 128.0 * gray)/color); + } + else { + float color = (float)saturation/128.0; + float gray = 1.0 - color; + + r = (((float)rcrtc2->lut.r[i] * color) + (128.0 * gray)); + g = (((float)rcrtc2->lut.g[i] * color) + (128.0 * gray)); + b = (((float)rcrtc2->lut.b[i] * color) + (128.0 * gray)); + } + rcrtc2->lut.r[i] = CLAMP( r, 0, 255 ); + rcrtc2->lut.g[i] = CLAMP( g, 0, 255 ); + rcrtc2->lut.b[i] = CLAMP( b, 0, 255 ); + } + } +} + +static void +crtc2_set_palette( RadeonDriverData *rdrv, + RadeonCrtc2LayerData *rcrtc2 ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 tmp; + int i, j; + + if (!rcrtc2->lut.size) { + D_WARN( "palette is empty" ); + return; + } + + dfb_gfxcard_lock( GDLF_WAIT | GDLF_SYNC ); + + tmp = radeon_in32( mmio, DAC_CNTL2 ); + radeon_out32( mmio, DAC_CNTL2, tmp | DAC2_PALETTE_ACC_CTL ); + + j = 256 / rcrtc2->lut.size; + for (i = 0; i < rcrtc2->lut.size; i++) { + radeon_out32( mmio, PALETTE_INDEX, i*j ); + radeon_out32( mmio, PALETTE_DATA, (rcrtc2->lut.b[i] ) | + (rcrtc2->lut.g[i] << 8) | + (rcrtc2->lut.r[i] << 16) ); + } + + radeon_out32( mmio, DAC_CNTL2, tmp ); + + dfb_gfxcard_unlock(); +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_mmio.h b/Source/DirectFB/gfxdrivers/radeon/radeon_mmio.h new file mode 100755 index 0000000..cdfa1f7 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_mmio.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __RADEON_MMIO_H__ +#define __RADEON_MMIO_H__ + +#include <unistd.h> +#include <dfb_types.h> + +#include "radeon.h" + + +static __inline__ void +radeon_out8( volatile u8 *mmioaddr, u32 reg, u8 value ) +{ + *((volatile u8*)(mmioaddr+reg)) = value; +} + +static __inline__ void +radeon_out16( volatile u8 *mmioaddr, u32 reg, u32 value ) +{ +#ifdef __powerpc__ + asm volatile( "sthbrx %0,%1,%2;eieio" + :: "r" (value), "b"(reg), "r" (mmioaddr) : "memory" ); +#else + *((volatile u16*)(mmioaddr+reg)) = value; +#endif +} + +static __inline__ void +radeon_out32( volatile u8 *mmioaddr, u32 reg, u32 value ) +{ +#ifdef __powerpc__ + asm volatile( "stwbrx %0,%1,%2;eieio" + :: "r" (value), "b"(reg), "r" (mmioaddr) : "memory" ); +#else + *((volatile u32*)(mmioaddr+reg)) = value; +#endif +} + +static __inline__ u8 +radeon_in8( volatile u8 *mmioaddr, u32 reg ) +{ + return *((volatile u8*)(mmioaddr+reg)); +} + +static __inline__ u16 +radeon_in16( volatile u8 *mmioaddr, u32 reg ) +{ +#ifdef __powerpc__ + u32 value; + asm volatile( "lhbrx %0,%1,%2;eieio" + : "=r" (value) : "b" (reg), "r" (mmioaddr) ); + return value; +#else + return *((volatile u16*)(mmioaddr+reg)); +#endif +} + +static __inline__ u32 +radeon_in32( volatile u8 *mmioaddr, u32 reg ) +{ +#ifdef __powerpc__ + u32 value; + asm volatile( "lwbrx %0,%1,%2;eieio" + : "=r" (value) : "b" (reg), "r" (mmioaddr) ); + return value; +#else + return *((volatile u32*)(mmioaddr+reg)); +#endif +} + + +static __inline__ void +radeon_outpll( volatile u8 *mmioaddr, u32 addr, u32 value ) +{ + radeon_out8( mmioaddr, CLOCK_CNTL_INDEX, (addr & 0x3f) | PLL_WR_EN ); + radeon_out32( mmioaddr, CLOCK_CNTL_DATA, value ); +} + +static __inline__ u32 +radeon_inpll( volatile u8 *mmioaddr, u32 addr ) +{ + radeon_out8( mmioaddr, CLOCK_CNTL_INDEX, addr & 0x3f ); + return radeon_in32( mmioaddr, CLOCK_CNTL_DATA ); +} + + +static inline bool +radeon_waitfifo( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + unsigned int space ) +{ + int waitcycles = 0; + + rdev->waitfifo_sum += space; + rdev->waitfifo_calls++; + + if (rdev->fifo_space < space ) { + do { + rdev->fifo_space = radeon_in32( rdrv->mmio_base, RBBM_STATUS ); + rdev->fifo_space &= RBBM_FIFOCNT_MASK; + if (++waitcycles > 10000000) { + radeon_reset( rdrv, rdev ); + D_BREAK( "FIFO timed out" ); + return false; + } + } while (rdev->fifo_space < space); + + rdev->fifo_waitcycles += waitcycles; + } else + rdev->fifo_cache_hits++; + + rdev->fifo_space -= space; + + return true; +} + +static inline bool +radeon_waitidle( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + int waitcycles = 0; + int status; + + if (!radeon_waitfifo( rdrv, rdev, 64 )) + return false; + + do { + status = radeon_in32( rdrv->mmio_base, RBBM_STATUS ); + if (++waitcycles > 10000000) { + radeon_reset( rdrv, rdev ); + D_BREAK( "Engine timed out" ); + return false; + } + } while (status & RBBM_ACTIVE); + + rdev->fifo_space = status & RBBM_FIFOCNT_MASK; + rdev->idle_waitcycles += waitcycles; + + return true; +} + + +#endif /* __RADEON_MMIO_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_overlay.c b/Source/DirectFB/gfxdrivers/radeon/radeon_overlay.c new file mode 100755 index 0000000..bdcaabe --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_overlay.c @@ -0,0 +1,983 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include <directfb.h> + +#include <core/coredefs.h> +#include <core/screen.h> +#include <core/screens.h> +#include <core/layers.h> +#include <core/layer_context.h> +#include <core/layer_region.h> +#include <core/layer_control.h> +#include <core/layers_internal.h> +#include <core/surface.h> +#include <core/system.h> + +#include <gfx/convert.h> + +#include <misc/conf.h> + +#include <direct/types.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" + + +typedef struct { + CoreLayerRegionConfig config; + float brightness; + float contrast; + float saturation; + float hue; + int field; + int level; + + CoreScreen *screen; + int crtc2; + + CoreSurface *surface; + CoreSurfaceBufferLock *lock; + + /* overlay registers */ + struct { + u32 H_INC; + u32 STEP_BY; + u32 Y_X_START; + u32 Y_X_END; + u32 V_INC; + u32 P1_BLANK_LINES_AT_TOP; + u32 P23_BLANK_LINES_AT_TOP; + u32 VID_BUF_PITCH0_VALUE; + u32 VID_BUF_PITCH1_VALUE; + u32 P1_X_START_END; + u32 P2_X_START_END; + u32 P3_X_START_END; + u32 BASE_ADDR; + u32 VID_BUF0_BASE_ADRS; + u32 VID_BUF1_BASE_ADRS; + u32 VID_BUF2_BASE_ADRS; + u32 VID_BUF3_BASE_ADRS; + u32 VID_BUF4_BASE_ADRS; + u32 VID_BUF5_BASE_ADRS; + u32 P1_V_ACCUM_INIT; + u32 P23_V_ACCUM_INIT; + u32 P1_H_ACCUM_INIT; + u32 P23_H_ACCUM_INIT; + u32 VID_KEY_CLR_LOW; + u32 VID_KEY_CLR_HIGH; + u32 GRPH_KEY_CLR_LOW; + u32 GRPH_KEY_CLR_HIGH; + u32 KEY_CNTL; + u32 MERGE_CNTL; + u32 SCALE_CNTL; + } regs; +} RadeonOverlayLayerData; + +static void ovl_calc_regs ( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreSurface *surface, + CoreLayerRegionConfig *config, + CoreSurfaceBufferLock *lock ); +static void ovl_set_regs ( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl ); +static void ovl_calc_buffers ( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreSurface *surface, + CoreLayerRegionConfig *config, + CoreSurfaceBufferLock *lock ); +static void ovl_set_buffers ( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl ); +static void ovl_set_colorkey ( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreLayerRegionConfig *config ); +static void ovl_set_adjustment( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + float brightness, + float contrast, + float saturation, + float hue ); + +#define OVL_SUPPORTED_OPTIONS \ + ( DLOP_DST_COLORKEY | DLOP_OPACITY | DLOP_DEINTERLACING ) + +/**********************/ + +static int +ovlLayerDataSize( void ) +{ + return sizeof(RadeonOverlayLayerData); +} + +static DFBResult +ovlInitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + volatile u8 *mmio = rdrv->mmio_base; + DFBScreenDescription dsc; + + dfb_screen_get_info( layer->screen, NULL, &dsc ); + if (strstr( dsc.name, "CRTC2" )) + rovl->crtc2 = 1; + + rovl->level = 1; + + /* fill layer description */ + description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE; + description->caps = DLCAPS_SURFACE | DLCAPS_SCREEN_LOCATION | + DLCAPS_BRIGHTNESS | DLCAPS_CONTRAST | + DLCAPS_SATURATION | DLCAPS_HUE | + DLCAPS_DST_COLORKEY | DLCAPS_OPACITY | + DLCAPS_DEINTERLACING | DLCAPS_LEVELS; + + snprintf( description->name, + DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, + "Radeon CRTC%c's Overlay", rovl->crtc2 ? '2' : '1' ); + + /* set default configuration */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | + DLCONF_OPTIONS; + config->width = 640; + config->height = 480; + config->pixelformat = DSPF_YUY2; + config->buffermode = DLBM_FRONTONLY; + config->options = DLOP_NONE; + + /* set default color adjustment */ + adjustment->flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | + DCAF_SATURATION | DCAF_HUE; + adjustment->brightness = 0x8000; + adjustment->contrast = 0x8000; + adjustment->saturation = 0x8000; + adjustment->hue = 0x8000; + + /* reset overlay */ + radeon_out32( mmio, OV0_SCALE_CNTL, SCALER_SOFT_RESET ); + radeon_out32( mmio, OV0_AUTO_FLIP_CNTL, 0 ); + radeon_out32( mmio, OV0_DEINTERLACE_PATTERN, 0 ); + radeon_out32( mmio, OV0_EXCLUSIVE_HORZ, 0 ); + radeon_out32( mmio, OV0_FILTER_CNTL, FILTER_HARDCODED_COEF ); + radeon_out32( mmio, OV0_TEST, 0 ); + + /* reset color adjustments */ + ovl_set_adjustment( rdrv, rovl, 0, 0, 0, 0 ); + + return DFB_OK; +} + +static DFBResult +ovlTestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + CoreLayerRegionConfigFlags fail = 0; + + /* check for unsupported options */ + if (config->options & ~OVL_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + if (rovl->level == -1) { + if (config->options & ~DLOP_DEINTERLACING) + fail |= CLRCF_OPTIONS; + } + else { + if (config->options & DLOP_OPACITY && + config->options & (DLOP_SRC_COLORKEY | DLOP_DST_COLORKEY)) + fail |= CLRCF_OPTIONS; + } + + /* check buffermode */ + switch (config->buffermode) { + case DLBM_FRONTONLY: + case DLBM_BACKSYSTEM: + case DLBM_BACKVIDEO: + case DLBM_TRIPLE: + break; + + default: + fail |= CLRCF_BUFFERMODE; + break; + } + + /* check pixel format */ + switch (config->format) { + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + case DSPF_YUY2: + case DSPF_UYVY: + case DSPF_I420: + case DSPF_YV12: + break; + + default: + fail |= CLRCF_FORMAT; + break; + } + + /* check width */ + if (config->width > 2048 || config->width < 1) + fail |= CLRCF_WIDTH; + + /* check height */ + if (config->height > 2048 || config->height < 1) + fail |= CLRCF_HEIGHT; + + /* write back failing fields */ + if (failed) + *failed = fail; + + /* return failure if any field failed */ + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +ovlAddRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonDeviceData *rdev = rdrv->device_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + if (rovl->crtc2 && !rdev->monitor2) { + D_ERROR( "DirectFB/Radeon/Overlay: " + "no secondary monitor connected!\n" ); + return DFB_IO; + } + + return DFB_OK; +} + +static DFBResult +ovlSetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + /* save configuration */ + rovl->config = *config; + rovl->surface = surface; + rovl->screen = layer->screen; + + if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT | + CLRCF_SOURCE | CLRCF_DEST | CLRCF_OPTIONS | CLRCF_OPACITY)) + { + ovl_calc_regs( rdrv, rovl, surface, &rovl->config, lock ); + ovl_set_regs( rdrv, rovl ); + } + + if (updated & (CLRCF_SRCKEY | CLRCF_DSTKEY)) + ovl_set_colorkey( rdrv, rovl, &rovl->config ); + + rovl->lock = lock; + + return DFB_OK; +} + +static DFBResult +ovlFlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + dfb_surface_flip( surface, false ); + + ovl_calc_buffers( rdrv, rovl, surface, &rovl->config, lock ); + ovl_set_buffers( rdrv, rovl ); + + if (flags & DSFLIP_WAIT) + dfb_layer_wait_vsync( layer ); + + rovl->lock = lock; + + return DFB_OK; +} + +static DFBResult +ovlSetColorAdjustment( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBColorAdjustment *adj ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + if (adj->flags & DCAF_BRIGHTNESS) + rovl->brightness = (float)(adj->brightness-0x8000) / 65535.0; + + if (adj->flags & DCAF_CONTRAST) + rovl->contrast = (float)adj->contrast / 32768.0; + + if (adj->flags & DCAF_SATURATION) + rovl->saturation = (float)adj->saturation / 32768.0; + + if (adj->flags & DCAF_HUE) + rovl->hue = (float)(adj->hue-0x8000) * 3.1416 / 65535.0; + + ovl_set_adjustment( rdrv, rovl, rovl->brightness, rovl->contrast, + rovl->saturation, rovl->hue ); + + return DFB_OK; +} + +static DFBResult +ovlSetInputField( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + int field ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + rovl->field = field; + + if (rovl->surface) { + ovl_calc_buffers( rdrv, rovl, rovl->surface, &rovl->config, rovl->lock ); + ovl_set_buffers( rdrv, rovl ); + } + + return DFB_OK; +} + +static DFBResult +ovlGetLevel( CoreLayer *layer, + void *driver_data, + void *layer_data, + int *level ) +{ + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + *level = rovl->level; + + return DFB_OK; +} + +static DFBResult +ovlSetLevel( CoreLayer *layer, + void *driver_data, + void *layer_data, + int level ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonOverlayLayerData *rovl = (RadeonOverlayLayerData*) layer_data; + + if (!rovl->surface) + return DFB_UNSUPPORTED; + + switch (level) { + case -1: + case 1: + rovl->level = level; + ovl_calc_regs( rdrv, rovl, rovl->surface, &rovl->config, rovl->lock ); + ovl_set_regs( rdrv, rovl ); + break; + default: + return DFB_UNSUPPORTED; + } + + return DFB_OK; +} + +static DFBResult +ovlRemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) driver_data; + RadeonDeviceData *rdev = rdrv->device_data; + + /* disable overlay */ + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, OV0_SCALE_CNTL, 0 ); + + return DFB_OK; +} + + +DisplayLayerFuncs RadeonOverlayFuncs = { + .LayerDataSize = ovlLayerDataSize, + .InitLayer = ovlInitLayer, + .TestRegion = ovlTestRegion, + .AddRegion = ovlAddRegion, + .SetRegion = ovlSetRegion, + .RemoveRegion = ovlRemoveRegion, + .FlipRegion = ovlFlipRegion, + .SetColorAdjustment = ovlSetColorAdjustment, + .SetInputField = ovlSetInputField, + .GetLevel = ovlGetLevel, + .SetLevel = ovlSetLevel +}; + + +/*** Internal Functions ***/ + +static void +ovl_calc_coordinates( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreSurface *surface, + CoreLayerRegionConfig *config ) +{ + RadeonDeviceData *rdev = rdrv->device_data; + DFBRectangle source = config->source; + DFBRectangle dest = config->dest; + u32 ecp_div = 0; + u32 h_inc; + u32 h_inc2; + u32 v_inc; + u32 step_by; + u32 tmp; + int xres; + int yres; + + dfb_screen_get_screen_size( rovl->screen, &xres, &yres ); + + if (dest.w > (source.w << 4)) + dest.w = source.w << 4; + + if (dest.h > (source.h << 4)) + dest.h = source.h << 4; + + if (dest.x < 0) { + source.w += dest.x * source.w / dest.w; + dest.w += dest.x; + dest.x = 0; + } + + if (dest.y < 0) { + source.h += dest.y * source.h / dest.h; + dest.h += dest.y; + dest.y = 0; + } + + if ((dest.x + dest.w) > xres) { + source.w = (xres - dest.x) * source.w / dest.w; + dest.w = xres - dest.x; + } + + if ((dest.y + dest.h) > yres) { + source.h = (yres - dest.y) * source.h / dest.h; + dest.h = yres - dest.y; + } + + if (dest.w < 1 || dest.h < 1 || source.w < 1 || source.h < 1) { + config->opacity = 0; + return; + } + + if (config->options & DLOP_DEINTERLACING) + source.h /= 2; + + tmp = radeon_in32( rdrv->mmio_base, + rovl->crtc2 ? CRTC2_GEN_CNTL : CRTC_GEN_CNTL ); + + if (tmp & CRTC_DBL_SCAN_EN) { + dest.y *= 2; + dest.h *= 2; + } + + if (tmp & CRTC_INTERLACE_EN) { + dest.y /= 2; + dest.h /= 2; + } + + /* FIXME: We need to know the VideoMode of the current screen. */ +#if 0 + if ((100000000 / mode->pixclock) >= 17500) + ecp_div = 1; +#endif + + h_inc = (source.w << (12 + ecp_div)) / dest.w; + v_inc = (source.h << 20) / dest.h; + + for (step_by = 1; h_inc >= (2 << 12);) { + step_by++; + h_inc >>= 1; + } + + switch (surface->config.format) { + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + h_inc2 = h_inc; + break; + default: + h_inc2 = h_inc >> 1; + break; + } + + rovl->regs.V_INC = v_inc; + rovl->regs.H_INC = h_inc | (h_inc2 << 16); + rovl->regs.STEP_BY = step_by | (step_by << 8); + + /* compute values for horizontal accumulators */ + tmp = 0x00028000 + (h_inc << 3); + rovl->regs.P1_H_ACCUM_INIT = ((tmp << 4) & 0x000f8000) | + ((tmp << 12) & 0xf0000000); + tmp = 0x00028000 + (h_inc2 << 3); + rovl->regs.P23_H_ACCUM_INIT = ((tmp << 4) & 0x000f8000) | + ((tmp << 12) & 0x70000000); + + /* compute values for vertical accumulators */ + tmp = 0x00018000; + rovl->regs.P1_V_ACCUM_INIT = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK) | + (OV0_P1_MAX_LN_IN_PER_LN_OUT & 1); + tmp = 0x00018000; + rovl->regs.P23_V_ACCUM_INIT = ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) | + (OV0_P23_MAX_LN_IN_PER_LN_OUT & 1); + + if (!rovl->crtc2) { + if (rdev->chipset < CHIP_R300 && + rdev->chipset != CHIP_R200 && + rdev->chipset != CHIP_UNKNOWN) + dest.x += 8; + } + + /* compute destination coordinates */ + rovl->regs.Y_X_START = (dest.x & 0xffff) | (dest.y << 16); + rovl->regs.Y_X_END = ((dest.x + dest.w - 1) & 0xffff) | + ((dest.y + dest.h - 1) << 16); + + /* compute source coordinates */ + rovl->regs.P1_BLANK_LINES_AT_TOP = P1_BLNK_LN_AT_TOP_M1_MASK | + ((source.h - 1) << 16); + rovl->regs.P1_X_START_END = (source.w - 1) & 0xffff; + + if (DFB_PLANAR_PIXELFORMAT( surface->config.format )) { + rovl->regs.P23_BLANK_LINES_AT_TOP = P23_BLNK_LN_AT_TOP_M1_MASK | + ((source.h/2 - 1) << 16); + rovl->regs.P2_X_START_END = (source.w/2 - 1) & 0xffff; + rovl->regs.P3_X_START_END = rovl->regs.P2_X_START_END; + } + else { + rovl->regs.P23_BLANK_LINES_AT_TOP = P23_BLNK_LN_AT_TOP_M1_MASK | + ((source.h - 1) << 16); + rovl->regs.P2_X_START_END = rovl->regs.P1_X_START_END; + rovl->regs.P3_X_START_END = rovl->regs.P1_X_START_END; + } +} + +static void +ovl_calc_buffers( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreSurface *surface, + CoreLayerRegionConfig *config, + CoreSurfaceBufferLock *lock ) +{ + RadeonDeviceData *rdev = rdrv->device_data; + DFBRectangle source = config->source; + u32 offsets[3] = { 0, 0, 0 }; + u32 pitch = lock->pitch; + int even = 0; + int cropleft; + int croptop; + + if (config->options & DLOP_DEINTERLACING) { + source.y /= 2; + source.h /= 2; + pitch *= 2; + even = rovl->field; + } + + cropleft = source.x; + croptop = source.y; + + if (config->dest.x < 0) + cropleft += -config->dest.x * source.w / config->dest.w; + + if (config->dest.y < 0) + croptop += -config->dest.y * source.h / config->dest.h; + + if (DFB_PLANAR_PIXELFORMAT( surface->config.format )) { + cropleft &= ~31; + croptop &= ~1; + + offsets[0] = lock->offset; + offsets[1] = offsets[0] + surface->config.size.h * lock->pitch; + offsets[2] = offsets[1] + surface->config.size.h/2 * lock->pitch/2; + offsets[0] += croptop * pitch + cropleft; + offsets[1] += croptop/2 * pitch/2 + cropleft/2; + offsets[2] += croptop/2 * pitch/2 + cropleft/2; + + if (even) { + offsets[0] += lock->pitch; + offsets[1] += lock->pitch/2; + offsets[2] += lock->pitch/2; + } + + if (surface->config.format == DSPF_YV12) { + u32 tmp = offsets[1]; + offsets[1] = offsets[2]; + offsets[2] = tmp; + } + } + else { + offsets[0] = lock->offset + croptop * pitch + + cropleft * DFB_BYTES_PER_PIXEL( surface->config.format ); + if (even) + offsets[0] += lock->pitch; + + offsets[1] = + offsets[2] = offsets[0]; + } + + if (lock->phys - lock->offset == rdev->fb_phys) + rovl->regs.BASE_ADDR = rdev->fb_offset; + else + rovl->regs.BASE_ADDR = rdev->agp_offset; + + rovl->regs.VID_BUF0_BASE_ADRS = (offsets[0] & VIF_BUF0_BASE_ADRS_MASK); + rovl->regs.VID_BUF1_BASE_ADRS = (offsets[1] & VIF_BUF1_BASE_ADRS_MASK) | + VIF_BUF1_PITCH_SEL; + rovl->regs.VID_BUF2_BASE_ADRS = (offsets[2] & VIF_BUF2_BASE_ADRS_MASK) | + VIF_BUF2_PITCH_SEL; + rovl->regs.VID_BUF3_BASE_ADRS = (offsets[0] & VIF_BUF3_BASE_ADRS_MASK); + rovl->regs.VID_BUF4_BASE_ADRS = (offsets[1] & VIF_BUF4_BASE_ADRS_MASK) | + VIF_BUF4_PITCH_SEL; + rovl->regs.VID_BUF5_BASE_ADRS = (offsets[2] & VIF_BUF5_BASE_ADRS_MASK) | + VIF_BUF5_PITCH_SEL; + rovl->regs.VID_BUF_PITCH0_VALUE = pitch; + rovl->regs.VID_BUF_PITCH1_VALUE = pitch/2; +} + +static void +ovl_calc_regs( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreSurface *surface, + CoreLayerRegionConfig *config, + CoreSurfaceBufferLock *lock ) +{ + rovl->regs.SCALE_CNTL = 0; + + /* Configure coordinates */ + ovl_calc_coordinates( rdrv, rovl, surface, config ); + + /* Configure buffers */ + ovl_calc_buffers( rdrv, rovl, surface, config, lock ); + + /* Configure scaler */ + if (rovl->level == -1) { + rovl->regs.KEY_CNTL = GRAPHIC_KEY_FN_FALSE | + VIDEO_KEY_FN_FALSE | + CMP_MIX_AND; + rovl->regs.MERGE_CNTL = DISP_ALPHA_MODE_PER_PIXEL | + 0x00ff0000 | /* graphic alpha */ + 0xff000000; /* overlay alpha */ + } + else if (config->options & DLOP_OPACITY) { + rovl->regs.KEY_CNTL = GRAPHIC_KEY_FN_TRUE | + VIDEO_KEY_FN_TRUE | + CMP_MIX_AND; + rovl->regs.MERGE_CNTL = DISP_ALPHA_MODE_GLOBAL | + 0x00ff0000 | + (config->opacity << 24); + } + else { + rovl->regs.KEY_CNTL = CMP_MIX_AND; + + if (config->options & DLOP_SRC_COLORKEY) + rovl->regs.KEY_CNTL |= VIDEO_KEY_FN_NE; + else + rovl->regs.KEY_CNTL |= VIDEO_KEY_FN_TRUE; + + if (config->options & DLOP_DST_COLORKEY) + rovl->regs.KEY_CNTL |= GRAPHIC_KEY_FN_EQ; + else + rovl->regs.KEY_CNTL |= GRAPHIC_KEY_FN_TRUE; + + rovl->regs.MERGE_CNTL = 0xffff0000; + } + + if (config->opacity) { + rovl->regs.SCALE_CNTL = SCALER_SMART_SWITCH | + SCALER_DOUBLE_BUFFER | + SCALER_ADAPTIVE_DEINT | + (rovl->crtc2 << 14); + + if (config->source.w == config->dest.w) + rovl->regs.SCALE_CNTL |= SCALER_HORZ_PICK_NEAREST; + if (config->source.h == config->dest.h) + rovl->regs.SCALE_CNTL |= SCALER_VERT_PICK_NEAREST; + + switch (surface->config.format) { + case DSPF_RGB555: + case DSPF_ARGB1555: + rovl->regs.SCALE_CNTL |= SCALER_SOURCE_15BPP | + SCALER_PRG_LOAD_START; + break; + case DSPF_RGB16: + rovl->regs.SCALE_CNTL |= SCALER_SOURCE_16BPP | + SCALER_PRG_LOAD_START; + break; + case DSPF_RGB32: + case DSPF_ARGB: + rovl->regs.SCALE_CNTL |= SCALER_SOURCE_32BPP | + SCALER_PRG_LOAD_START; + break; + case DSPF_UYVY: + rovl->regs.SCALE_CNTL |= SCALER_SOURCE_YVYU422; + break; + case DSPF_YUY2: + rovl->regs.SCALE_CNTL |= SCALER_SOURCE_VYUY422; + break; + case DSPF_YV12: + case DSPF_I420: + rovl->regs.SCALE_CNTL |= SCALER_SOURCE_YUV12; + break; + default: + D_BUG( "unexpected pixelformat" ); + config->opacity = 0; + return; + } + + rovl->regs.SCALE_CNTL |= SCALER_ENABLE; + } +} + +static void +ovl_set_regs( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl ) +{ + RadeonDeviceData *rdev = rdrv->device_data; + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK ); + while(!(radeon_in32( mmio, OV0_REG_LOAD_CNTL ) & REG_LD_CTL_LOCK_READBACK)); + + radeon_waitfifo( rdrv, rdev, 17 ); + radeon_out32( mmio, OV0_H_INC, rovl->regs.H_INC ); + radeon_out32( mmio, OV0_STEP_BY, rovl->regs.STEP_BY ); + if (rovl->crtc2) { + radeon_out32( mmio, OV1_Y_X_START, rovl->regs.Y_X_START ); + radeon_out32( mmio, OV1_Y_X_END, rovl->regs.Y_X_END ); + } else { + radeon_out32( mmio, OV0_Y_X_START, rovl->regs.Y_X_START ); + radeon_out32( mmio, OV0_Y_X_END, rovl->regs.Y_X_END ); + } + radeon_out32( mmio, OV0_V_INC, rovl->regs.V_INC ); + radeon_out32( mmio, OV0_P1_BLANK_LINES_AT_TOP, rovl->regs.P1_BLANK_LINES_AT_TOP ); + radeon_out32( mmio, OV0_P23_BLANK_LINES_AT_TOP, rovl->regs.P23_BLANK_LINES_AT_TOP ); + radeon_out32( mmio, OV0_VID_BUF_PITCH0_VALUE, rovl->regs.VID_BUF_PITCH0_VALUE ); + radeon_out32( mmio, OV0_VID_BUF_PITCH1_VALUE, rovl->regs.VID_BUF_PITCH1_VALUE ); + radeon_out32( mmio, OV0_P1_X_START_END, rovl->regs.P1_X_START_END ); + radeon_out32( mmio, OV0_P2_X_START_END, rovl->regs.P2_X_START_END ); + radeon_out32( mmio, OV0_P3_X_START_END, rovl->regs.P3_X_START_END ); + radeon_out32( mmio, OV0_P1_V_ACCUM_INIT, rovl->regs.P1_V_ACCUM_INIT ); + radeon_out32( mmio, OV0_BASE_ADDR, rovl->regs.BASE_ADDR ); + radeon_out32( mmio, OV0_VID_BUF0_BASE_ADRS, rovl->regs.VID_BUF0_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF1_BASE_ADRS, rovl->regs.VID_BUF1_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF2_BASE_ADRS, rovl->regs.VID_BUF2_BASE_ADRS ); + + radeon_waitfifo( rdrv, rdev, 10 ); + radeon_out32( mmio, OV0_VID_BUF3_BASE_ADRS, rovl->regs.VID_BUF3_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF4_BASE_ADRS, rovl->regs.VID_BUF4_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF5_BASE_ADRS, rovl->regs.VID_BUF5_BASE_ADRS ); + radeon_out32( mmio, OV0_P1_H_ACCUM_INIT, rovl->regs.P1_H_ACCUM_INIT ); + radeon_out32( mmio, OV0_P23_V_ACCUM_INIT, rovl->regs.P23_V_ACCUM_INIT ); + radeon_out32( mmio, OV0_P23_H_ACCUM_INIT, rovl->regs.P23_H_ACCUM_INIT ); + + radeon_out32( mmio, DISP_MERGE_CNTL, rovl->regs.MERGE_CNTL ); + radeon_out32( mmio, OV0_KEY_CNTL, rovl->regs.KEY_CNTL ); + radeon_out32( mmio, OV0_SCALE_CNTL, rovl->regs.SCALE_CNTL ); + + radeon_out32( mmio, OV0_REG_LOAD_CNTL, 0 ); +} + +static void +ovl_set_buffers( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl ) +{ + RadeonDeviceData *rdev = rdrv->device_data; + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK ); + while(!(radeon_in32( mmio, OV0_REG_LOAD_CNTL ) & REG_LD_CTL_LOCK_READBACK)); + + radeon_waitfifo( rdrv, rdev, 8 ); + radeon_out32( mmio, OV0_BASE_ADDR, rovl->regs.BASE_ADDR ); + radeon_out32( mmio, OV0_VID_BUF0_BASE_ADRS, rovl->regs.VID_BUF0_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF1_BASE_ADRS, rovl->regs.VID_BUF1_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF2_BASE_ADRS, rovl->regs.VID_BUF2_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF3_BASE_ADRS, rovl->regs.VID_BUF3_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF4_BASE_ADRS, rovl->regs.VID_BUF4_BASE_ADRS ); + radeon_out32( mmio, OV0_VID_BUF5_BASE_ADRS, rovl->regs.VID_BUF5_BASE_ADRS ); + + radeon_out32( mmio, OV0_REG_LOAD_CNTL, 0 ); +} + +static void +ovl_set_colorkey( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + CoreLayerRegionConfig *config ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 SkeyLow, SkeyHigh; + u32 DkeyLow, DkeyHigh; + u32 tmp; + + SkeyLow = PIXEL_RGB32( config->src_key.r, + config->src_key.g, + config->src_key.b ); + SkeyHigh = SkeyLow | 0xff000000; + + tmp = radeon_in32( mmio, rovl->crtc2 ? CRTC2_GEN_CNTL : CRTC_GEN_CNTL ); + switch ((tmp >> 8) & 0xf) { + case DST_8BPP: + case DST_8BPP_RGB332: + DkeyLow = ((MAX( config->dst_key.r - 0x20, 0 ) & 0xe0) << 16) | + ((MAX( config->dst_key.g - 0x20, 0 ) & 0xe0) << 8) | + ((MAX( config->dst_key.b - 0x40, 0 ) & 0xc0) ); + break; + case DST_15BPP: + DkeyLow = ((MAX( config->dst_key.r - 0x08, 0 ) & 0xf8) << 16) | + ((MAX( config->dst_key.g - 0x08, 0 ) & 0xf8) << 8) | + ((MAX( config->dst_key.b - 0x08, 0 ) & 0xf8) ); + break; + case DST_16BPP: + DkeyLow = ((MAX( config->dst_key.r - 0x08, 0 ) & 0xf8) << 16) | + ((MAX( config->dst_key.g - 0x04, 0 ) & 0xfc) << 8) | + ((MAX( config->dst_key.b - 0x08, 0 ) & 0xf8) ); + break; + default: + DkeyLow = PIXEL_RGB32( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ); + break; + } + + DkeyHigh = PIXEL_RGB32( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ) | 0xff000000; + + radeon_waitfifo( rdrv, rdrv->device_data, 4 ); + radeon_out32( mmio, OV0_VID_KEY_CLR_LOW, SkeyLow ); + radeon_out32( mmio, OV0_VID_KEY_CLR_HIGH, SkeyHigh ); + radeon_out32( mmio, OV0_GRPH_KEY_CLR_LOW, DkeyLow ); + radeon_out32( mmio, OV0_GRPH_KEY_CLR_HIGH, DkeyHigh ); +} + +static void +ovl_set_adjustment( RadeonDriverData *rdrv, + RadeonOverlayLayerData *rovl, + float brightness, + float contrast, + float saturation, + float hue ) +{ + volatile u8 *mmio = rdrv->mmio_base; + float HueSin, HueCos; + float Luma; + float RCb, RCr; + float GCb, GCr; + float BCb, BCr; + float AdjOff, ROff, GOff, BOff; + u32 dwLuma, dwROff, dwGOff, dwBOff; + u32 dwRCb, dwRCr; + u32 dwGCb, dwGCr; + u32 dwBCb, dwBCr; + + HueSin = sin( hue ); + HueCos = cos( hue ); + + Luma = contrast * +1.1678; + RCb = saturation * -HueSin * +1.6007; + RCr = saturation * HueCos * +1.6007; + GCb = saturation * (HueCos * -0.3929 - HueSin * -0.8154); + GCr = saturation * (HueCos * -0.3929 + HueCos * -0.8154); + BCb = saturation * HueCos * +2.0232; + BCr = saturation * HueSin * +2.0232; + + AdjOff = contrast * 1.1678 * brightness * 1023.0; + ROff = AdjOff - Luma * 64.0 - (RCb + RCr) * 512.0; + GOff = AdjOff - Luma * 64.0 - (GCb + GCr) * 512.0; + BOff = AdjOff - Luma * 64.0 - (BCb + BCr) * 512.0; + ROff = CLAMP( ROff, -2048.0, 2047.5 ); + GOff = CLAMP( GOff, -2048.0, 2047.5 ); + BOff = CLAMP( BOff, -2048.0, 2047.5 ); + dwROff = ((u32)(ROff * 2.0)) & 0x1fff; + dwGOff = ((u32)(GOff * 2.0)) & 0x1fff; + dwBOff = ((u32)(BOff * 2.0)) & 0x1fff; + + dwLuma = (((u32)(Luma * 256.0)) & 0xfff) << 20; + dwRCb = (((u32)(RCb * 256.0)) & 0xfff) << 4; + dwRCr = (((u32)(RCr * 256.0)) & 0xfff) << 20; + dwGCb = (((u32)(GCb * 256.0)) & 0xfff) << 4; + dwGCr = (((u32)(GCr * 256.0)) & 0xfff) << 20; + dwBCb = (((u32)(BCb * 256.0)) & 0xfff) << 4; + dwBCr = (((u32)(BCr * 256.0)) & 0xfff) << 20; + + radeon_waitfifo( rdrv, rdrv->device_data, 6 ); + radeon_out32( mmio, OV0_LIN_TRANS_A, dwRCb | dwLuma ); + radeon_out32( mmio, OV0_LIN_TRANS_B, dwROff | dwRCr ); + radeon_out32( mmio, OV0_LIN_TRANS_C, dwGCb | dwLuma ); + radeon_out32( mmio, OV0_LIN_TRANS_D, dwGOff | dwGCr ); + radeon_out32( mmio, OV0_LIN_TRANS_E, dwBCb | dwLuma ); + radeon_out32( mmio, OV0_LIN_TRANS_F, dwBOff | dwBCr ); +} + diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_regs.h b/Source/DirectFB/gfxdrivers/radeon/radeon_regs.h new file mode 100755 index 0000000..03e5952 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_regs.h @@ -0,0 +1,4364 @@ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and + * VA Linux Systems Inc., Fremont, California. + * + * All Rights Reserved. + * + * 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 on 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + * THEIR SUPPLIERS 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: + * Kevin E. Martin <martin@xfree86.org> + * Rickard E. Faith <faith@valinux.com> + * Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * !!!! FIXME !!!! + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h + * AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT + * ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */ + +#ifndef __RADEON_REGS_H__ +#define __RADEON_REGS_H__ + +#ifdef ROP_XOR +#undef ROP_XOR +#endif + +#ifdef ROP_COPY +#undef ROP_COPY +#endif + + + /* Registers for 2D/Video/Overlay */ +#define CONFIG_VENDOR_ID 0x0f00 /* PCI */ +#define CONFIG_DEVICE_ID 0x0f02 /* PCI */ +#define CONFIG_ADAPTER_ID 0x0f2c /* PCI */ + +#define AGP_BASE 0x0170 +#define AGP_CNTL 0x0174 +# define AGP_APER_SIZE_256MB (0x00 << 0) +# define AGP_APER_SIZE_128MB (0x20 << 0) +# define AGP_APER_SIZE_64MB (0x30 << 0) +# define AGP_APER_SIZE_32MB (0x38 << 0) +# define AGP_APER_SIZE_16MB (0x3c << 0) +# define AGP_APER_SIZE_8MB (0x3e << 0) +# define AGP_APER_SIZE_4MB (0x3f << 0) +# define AGP_APER_SIZE_MASK (0x3f << 0) +#define AGP_COMMAND 0x0f60 /* PCI */ +#define AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config*/ +# define AGP_ENABLE (1<<8) +#define AGP_PLL_CNTL 0x000b /* PLL */ +#define AGP_STATUS 0x0f5c /* PCI */ +# define AGP_1X_MODE 0x01 +# define AGP_2X_MODE 0x02 +# define AGP_4X_MODE 0x04 +# define AGP_FW_MODE 0x10 +# define AGP_MODE_MASK 0x17 +#define ATTRDR 0x03c1 /* VGA */ +#define ATTRDW 0x03c0 /* VGA */ +#define ATTRX 0x03c0 /* VGA */ +#define AUX_SC_CNTL 0x1660 +# define AUX1_SC_EN (1 << 0) +# define AUX1_SC_MODE_OR (0 << 1) +# define AUX1_SC_MODE_NAND (1 << 1) +# define AUX2_SC_EN (1 << 2) +# define AUX2_SC_MODE_OR (0 << 3) +# define AUX2_SC_MODE_NAND (1 << 3) +# define AUX3_SC_EN (1 << 4) +# define AUX3_SC_MODE_OR (0 << 5) +# define AUX3_SC_MODE_NAND (1 << 5) +#define AUX1_SC_BOTTOM 0x1670 +#define AUX1_SC_LEFT 0x1664 +#define AUX1_SC_RIGHT 0x1668 +#define AUX1_SC_TOP 0x166c +#define AUX2_SC_BOTTOM 0x1680 +#define AUX2_SC_LEFT 0x1674 +#define AUX2_SC_RIGHT 0x1678 +#define AUX2_SC_TOP 0x167c +#define AUX3_SC_BOTTOM 0x1690 +#define AUX3_SC_LEFT 0x1684 +#define AUX3_SC_RIGHT 0x1688 +#define AUX3_SC_TOP 0x168c +#define AUX_WINDOW_HORZ_CNTL 0x02d8 +#define AUX_WINDOW_VERT_CNTL 0x02dc + +#define BASE_CODE 0x0f0b +#define BIOS_0_SCRATCH 0x0010 +#define BIOS_1_SCRATCH 0x0014 +#define BIOS_2_SCRATCH 0x0018 +#define BIOS_3_SCRATCH 0x001c +#define BIOS_4_SCRATCH 0x0020 +#define BIOS_5_SCRATCH 0x0024 +#define BIOS_6_SCRATCH 0x0028 +#define BIOS_7_SCRATCH 0x002c +#define BIOS_ROM 0x0f30 /* PCI */ +#define BIST 0x0f0f /* PCI */ +#define BRUSH_DATA0 0x1480 +#define BRUSH_DATA1 0x1484 +#define BRUSH_DATA10 0x14a8 +#define BRUSH_DATA11 0x14ac +#define BRUSH_DATA12 0x14b0 +#define BRUSH_DATA13 0x14b4 +#define BRUSH_DATA14 0x14b8 +#define BRUSH_DATA15 0x14bc +#define BRUSH_DATA16 0x14c0 +#define BRUSH_DATA17 0x14c4 +#define BRUSH_DATA18 0x14c8 +#define BRUSH_DATA19 0x14cc +#define BRUSH_DATA2 0x1488 +#define BRUSH_DATA20 0x14d0 +#define BRUSH_DATA21 0x14d4 +#define BRUSH_DATA22 0x14d8 +#define BRUSH_DATA23 0x14dc +#define BRUSH_DATA24 0x14e0 +#define BRUSH_DATA25 0x14e4 +#define BRUSH_DATA26 0x14e8 +#define BRUSH_DATA27 0x14ec +#define BRUSH_DATA28 0x14f0 +#define BRUSH_DATA29 0x14f4 +#define BRUSH_DATA3 0x148c +#define BRUSH_DATA30 0x14f8 +#define BRUSH_DATA31 0x14fc +#define BRUSH_DATA32 0x1500 +#define BRUSH_DATA33 0x1504 +#define BRUSH_DATA34 0x1508 +#define BRUSH_DATA35 0x150c +#define BRUSH_DATA36 0x1510 +#define BRUSH_DATA37 0x1514 +#define BRUSH_DATA38 0x1518 +#define BRUSH_DATA39 0x151c +#define BRUSH_DATA4 0x1490 +#define BRUSH_DATA40 0x1520 +#define BRUSH_DATA41 0x1524 +#define BRUSH_DATA42 0x1528 +#define BRUSH_DATA43 0x152c +#define BRUSH_DATA44 0x1530 +#define BRUSH_DATA45 0x1534 +#define BRUSH_DATA46 0x1538 +#define BRUSH_DATA47 0x153c +#define BRUSH_DATA48 0x1540 +#define BRUSH_DATA49 0x1544 +#define BRUSH_DATA5 0x1494 +#define BRUSH_DATA50 0x1548 +#define BRUSH_DATA51 0x154c +#define BRUSH_DATA52 0x1550 +#define BRUSH_DATA53 0x1554 +#define BRUSH_DATA54 0x1558 +#define BRUSH_DATA55 0x155c +#define BRUSH_DATA56 0x1560 +#define BRUSH_DATA57 0x1564 +#define BRUSH_DATA58 0x1568 +#define BRUSH_DATA59 0x156c +#define BRUSH_DATA6 0x1498 +#define BRUSH_DATA60 0x1570 +#define BRUSH_DATA61 0x1574 +#define BRUSH_DATA62 0x1578 +#define BRUSH_DATA63 0x157c +#define BRUSH_DATA7 0x149c +#define BRUSH_DATA8 0x14a0 +#define BRUSH_DATA9 0x14a4 +#define BRUSH_SCALE 0x1470 +#define BRUSH_Y_X 0x1474 +#define BUS_CNTL 0x0030 +# define BUS_MASTER_DIS (1 << 6) +# define BUS_RD_DISCARD_EN (1 << 24) +# define BUS_RD_ABORT_EN (1 << 25) +# define BUS_MSTR_DISCONNECT_EN (1 << 28) +# define BUS_WRT_BURST (1 << 29) +# define BUS_READ_BURST (1 << 30) +#define BUS_CNTL1 0x0034 +# define BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define CACHE_CNTL 0x1724 +#define CACHE_LINE 0x0f0c /* PCI */ +#define CAP0_TRIG_CNTL 0x0950 /* ? */ +#define CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define CAPABILITIES_ID 0x0f50 /* PCI */ +#define CAPABILITIES_PTR 0x0f34 /* PCI */ +#define CLK_PIN_CNTL 0x0001 /* PLL */ +# define SCLK_DYN_START_CNTL (1 << 15) +#define CLOCK_CNTL_DATA 0x000c +#define CLOCK_CNTL_INDEX 0x0008 +# define PLL_WR_EN (1 << 7) +# define PLL_DIV_SEL (3 << 8) +# define PLL2_DIV_SEL_MASK ~(3 << 8) +#define CLK_PWRMGT_CNTL 0x0014 +# define ENGIN_DYNCLK_MODE (1 << 12) +# define ACTIVE_HILO_LAT_MASK (3 << 13) +# define ACTIVE_HILO_LAT_SHIFT 13 +# define DISP_DYN_STOP_LAT_MASK (1 << 12) +# define DYN_STOP_MODE_MASK (7 << 21) +#define PLL_PWRMGT_CNTL 0x0015 +# define TCL_BYPASS_DISABLE (1 << 20) +#define CLR_CMP_CLR_3D 0x1a24 +#define CLR_CMP_CLR_DST 0x15c8 +#define CLR_CMP_CLR_SRC 0x15c4 +#define CLR_CMP_CNTL 0x15c0 +# define SRC_CMP_EQ_COLOR (4 << 0) +# define SRC_CMP_NEQ_COLOR (5 << 0) +# define CLR_CMP_SRC_SOURCE (1 << 24) +#define CLR_CMP_MASK 0x15cc +# define CLR_CMP_MSK 0xffffffff +#define CLR_CMP_MASK_3D 0x1A28 +#define COMMAND 0x0f04 /* PCI */ +#define COMPOSITE_SHADOW_ID 0x1a0c +#define CONFIG_APER_0_BASE 0x0100 +#define CONFIG_APER_1_BASE 0x0104 +#define CONFIG_APER_SIZE 0x0108 +#define CONFIG_BONDS 0x00e8 +#define CONFIG_CNTL 0x00e0 +# define CFG_ATI_REV_A11 (0 << 16) +# define CFG_ATI_REV_A12 (1 << 16) +# define CFG_ATI_REV_A13 (2 << 16) +# define CFG_ATI_REV_ID_MASK (0xf << 16) +#define CONFIG_MEMSIZE 0x00f8 +#define CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define CONFIG_REG_1_BASE 0x010c +#define CONFIG_REG_APER_SIZE 0x0110 +#define CONFIG_XSTRAP 0x00e4 +#define CONSTANT_COLOR_C 0x1d34 +# define CONSTANT_COLOR_MASK 0x00ffffff +# define CONSTANT_COLOR_ONE 0x00ffffff +# define CONSTANT_COLOR_ZERO 0x00000000 +#define CRC_CMDFIFO_ADDR 0x0740 +#define CRC_CMDFIFO_DOUT 0x0744 +#define GRPH_BUFFER_CNTL 0x02f0 +# define GRPH_START_REQ_MASK (0x7f) +# define GRPH_START_REQ_SHIFT 0 +# define GRPH_STOP_REQ_MASK (0x7f<<8) +# define GRPH_STOP_REQ_SHIFT 8 +# define GRPH_CRITICAL_POINT_MASK (0x7f<<16) +# define GRPH_CRITICAL_POINT_SHIFT 16 +# define GRPH_CRITICAL_CNTL (1<<28) +# define GRPH_BUFFER_SIZE (1<<29) +# define GRPH_CRITICAL_AT_SOF (1<<30) +# define GRPH_STOP_CNTL (1<<31) +#define GRPH2_BUFFER_CNTL 0x03f0 +# define GRPH2_START_REQ_MASK (0x7f) +# define GRPH2_START_REQ_SHIFT 0 +# define GRPH2_STOP_REQ_MASK (0x7f<<8) +# define GRPH2_STOP_REQ_SHIFT 8 +# define GRPH2_CRITICAL_POINT_MASK (0x7f<<16) +# define GRPH2_CRITICAL_POINT_SHIFT 16 +# define GRPH2_CRITICAL_CNTL (1<<28) +# define GRPH2_BUFFER_SIZE (1<<29) +# define GRPH2_CRITICAL_AT_SOF (1<<30) +# define GRPH2_STOP_CNTL (1<<31) +#define CRTC_CRNT_FRAME 0x0214 +#define CRTC_EXT_CNTL 0x0054 +# define CRTC_VGA_XOVERSCAN (1 << 0) +# define VGA_ATI_LINEAR (1 << 3) +# define XCRT_CNT_EN (1 << 6) +# define CRTC_HSYNC_DIS (1 << 8) +# define CRTC_VSYNC_DIS (1 << 9) +# define CRTC_DISPLAY_DIS (1 << 10) +# define CRTC_SYNC_TRISTAT (1 << 11) +# define CRTC_CRT_ON (1 << 15) +#define CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define CRTC_HSYNC_DIS_BYTE (1 << 0) +# define CRTC_VSYNC_DIS_BYTE (1 << 1) +# define CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define CRTC_GEN_CNTL 0x0050 +# define CRTC_DBL_SCAN_EN (1 << 0) +# define CRTC_INTERLACE_EN (1 << 1) +# define CRTC_CSYNC_EN (1 << 4) +# define CRTC_CUR_EN (1 << 16) +# define CRTC_CUR_MODE_MASK (7 << 17) +# define CRTC_ICON_EN (1 << 20) +# define CRTC_EXT_DISP_EN (1 << 24) +# define CRTC_EN (1 << 25) +# define CRTC_DISP_REQ_EN_B (1 << 26) +#define CRTC2_GEN_CNTL 0x03f8 +# define CRTC2_DBL_SCAN_EN (1 << 0) +# define CRTC2_INTERLACE_EN (1 << 1) +# define CRTC2_SYNC_TRISTAT (1 << 4) +# define CRTC2_HSYNC_TRISTAT (1 << 5) +# define CRTC2_VSYNC_TRISTAT (1 << 6) +# define CRTC2_CRT2_ON (1 << 7) +# define CRTC2_ICON_EN (1 << 15) +# define CRTC2_CUR_EN (1 << 16) +# define CRTC2_CUR_MODE_MASK (7 << 20) +# define CRTC2_DISP_DIS (1 << 23) +# define CRTC2_EN (1 << 25) +# define CRTC2_DISP_REQ_EN_B (1 << 26) +# define CRTC2_CSYNC_EN (1 << 27) +# define CRTC2_HSYNC_DIS (1 << 28) +# define CRTC2_VSYNC_DIS (1 << 29) +#define CRTC_MORE_CNTL 0x27c +# define CRTC_H_CUTOFF_ACTIVE_EN (1<<4) +# define CRTC_V_CUTOFF_ACTIVE_EN (1<<5) +#define CRTC_GUI_TRIG_VLINE 0x0218 +#define CRTC_H_SYNC_STRT_WID 0x0204 +# define CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define CRTC_H_SYNC_STRT_CHAR (0x3ff << 3) +# define CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define CRTC_H_SYNC_WID (0x3f << 16) +# define CRTC_H_SYNC_WID_SHIFT 16 +# define CRTC_H_SYNC_POL (1 << 23) +#define CRTC2_H_SYNC_STRT_WID 0x0304 +# define CRTC2_H_SYNC_STRT_PIX (0x07 << 0) +# define CRTC2_H_SYNC_STRT_CHAR (0x3ff << 3) +# define CRTC2_H_SYNC_STRT_CHAR_SHIFT 3 +# define CRTC2_H_SYNC_WID (0x3f << 16) +# define CRTC2_H_SYNC_WID_SHIFT 16 +# define CRTC2_H_SYNC_POL (1 << 23) +#define CRTC_H_TOTAL_DISP 0x0200 +# define CRTC_H_TOTAL (0x03ff << 0) +# define CRTC_H_TOTAL_SHIFT 0 +# define CRTC_H_DISP (0x01ff << 16) +# define CRTC_H_DISP_SHIFT 16 +#define CRTC2_H_TOTAL_DISP 0x0300 +# define CRTC2_H_TOTAL (0x03ff << 0) +# define CRTC2_H_TOTAL_SHIFT 0 +# define CRTC2_H_DISP (0x01ff << 16) +# define CRTC2_H_DISP_SHIFT 16 +#define CRTC_OFFSET 0x0224 +#define CRTC2_OFFSET 0x0324 +#define CRTC_OFFSET_CNTL 0x0228 +# define CRTC_TILE_EN (1 << 15) +# define CRTC_HSYNC_EN (1 << 16) +#define CRTC2_OFFSET_CNTL 0x0328 +# define CRTC2_TILE_EN (1 << 15) +#define CRTC_PITCH 0x022c +#define CRTC2_PITCH 0x032c +#define CRTC_STATUS 0x005c +# define CRTC_VBLANK_SAVE (1 << 1) +# define CRTC_VBLANK_SAVE_CLEAR (1 << 1) +#define CRTC2_STATUS 0x03fc +# define CRTC2_VBLANK_SAVE (1 << 1) +# define CRTC2_VBLANK_SAVE_CLEAR (1 << 1) +#define CRTC_V_SYNC_STRT_WID 0x020c +# define CRTC_V_SYNC_STRT (0x7ff << 0) +# define CRTC_V_SYNC_STRT_SHIFT 0 +# define CRTC_V_SYNC_WID (0x1f << 16) +# define CRTC_V_SYNC_WID_SHIFT 16 +# define CRTC_V_SYNC_POL (1 << 23) +#define CRTC2_V_SYNC_STRT_WID 0x030c +# define CRTC2_V_SYNC_STRT (0x7ff << 0) +# define CRTC2_V_SYNC_STRT_SHIFT 0 +# define CRTC2_V_SYNC_WID (0x1f << 16) +# define CRTC2_V_SYNC_WID_SHIFT 16 +# define CRTC2_V_SYNC_POL (1 << 23) +#define CRTC_V_TOTAL_DISP 0x0208 +# define CRTC_V_TOTAL (0x07ff << 0) +# define CRTC_V_TOTAL_SHIFT 0 +# define CRTC_V_DISP (0x07ff << 16) +# define CRTC_V_DISP_SHIFT 16 +#define CRTC2_V_TOTAL_DISP 0x0308 +# define CRTC2_V_TOTAL (0x07ff << 0) +# define CRTC2_V_TOTAL_SHIFT 0 +# define CRTC2_V_DISP (0x07ff << 16) +# define CRTC2_V_DISP_SHIFT 16 +#define CRTC_VLINE_CRNT_VLINE 0x0210 +# define CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define CRTC2_CRNT_FRAME 0x0314 +#define CRTC2_GUI_TRIG_VLINE 0x0318 +#define CRTC2_STATUS 0x03fc +#define CRTC2_VLINE_CRNT_VLINE 0x0310 +#define CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define CUR_CLR0 0x026c +#define CUR_CLR1 0x0270 +#define CUR_HORZ_VERT_OFF 0x0268 +#define CUR_HORZ_VERT_POSN 0x0264 +#define CUR_OFFSET 0x0260 +# define CUR_LOCK (1 << 31) +#define CUR2_CLR0 0x036c +#define CUR2_CLR1 0x0370 +#define CUR2_HORZ_VERT_OFF 0x0368 +#define CUR2_HORZ_VERT_POSN 0x0364 +#define CUR2_OFFSET 0x0360 +# define CUR2_LOCK (1 << 31) + +#define DAC_CNTL 0x0058 +# define DAC_RANGE_CNTL (3 << 0) +# define DAC_RANGE_CNTL_MASK 0x03 +# define DAC_BLANKING (1 << 2) +# define DAC_CMP_EN (1 << 3) +# define DAC_CMP_OUTPUT (1 << 7) +# define DAC_8BIT_EN (1 << 8) +# define DAC_TVO_EN (1 << 10) +# define DAC_VGA_ADR_EN (1 << 13) +# define DAC_PDWN (1 << 15) +# define DAC_MASK_ALL (0xff << 24) +#define DAC_CNTL2 0x007c +# define DAC2_DAC_CLK_SEL (1 << 0) +# define DAC2_DAC2_CLK_SEL (1 << 1) +# define DAC2_PALETTE_ACC_CTL (1 << 5) +#define DAC_EXT_CNTL 0x0280 +# define DAC_FORCE_BLANK_OFF_EN (1 << 4) +# define DAC_FORCE_DATA_EN (1 << 5) +# define DAC_FORCE_DATA_SEL_MASK (3 << 6) +# define DAC_FORCE_DATA_MASK 0x0003ff00 +# define DAC_FORCE_DATA_SHIFT 8 +#define DAC_MACRO_CNTL 0x0d04 +# define DAC_PDWN_R (1 << 16) +# define DAC_PDWN_G (1 << 17) +# define DAC_PDWN_B (1 << 18) +#define DISP_HW_DEBUG 0x0d14 +# define CRT2_DISP1_SEL (1 << 5) +#define DISP_OUTPUT_CNTL 0x0d64 +# define DISP_DAC_SOURCE_MASK 0x03 +# define DISP_DAC2_SOURCE_MASK 0x0c +# define DISP_DAC_SOURCE_CRTC2 0x01 +# define DISP_DAC2_SOURCE_CRTC2 0x04 +# define DISP_TV_SOURCE (1 << 16) +# define DISP_TV_MODE_MASK (3 << 17) +# define DISP_TV_MODE_888 (0 << 17) +# define DISP_TV_MODE_565 (1 << 17) +# define DISP_TV_YG_DITH_EN (1 << 19) +# define DISP_TV_CBB_CRR_DITH_EN (1 << 20) +# define DISP_TV_BIT_WIDTH (1 << 21) +# define DISP_TV_SYNC_MODE_MASK (3 << 22) +# define DISP_TV_SYNC_COLOR_MASK (3 << 25) +#define DAC_CRC_SIG 0x02cc +#define DAC_DATA 0x03c9 /* VGA */ +#define DAC_MASK 0x03c6 /* VGA */ +#define DAC_R_INDEX 0x03c7 /* VGA */ +#define DAC_W_INDEX 0x03c8 /* VGA */ +#define DDA_CONFIG 0x02e0 +#define DDA_ON_OFF 0x02e4 +#define DEFAULT_OFFSET 0x16e0 +#define DEFAULT_PITCH 0x16e4 +#define DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define DISP_MISC_CNTL 0x0d00 +# define SOFT_RESET_GRPH_PP (1 << 0) +#define DISP_MERGE_CNTL 0x0d60 +# define DISP_ALPHA_MODE_MASK 0x03 +# define DISP_ALPHA_MODE_KEY 0 +# define DISP_ALPHA_MODE_PER_PIXEL 1 +# define DISP_ALPHA_MODE_GLOBAL 2 +# define DISP_RGB_OFFSET_EN (1<<8) +# define DISP_GRPH_ALPHA_MASK (0xff << 16) +# define DISP_OV0_ALPHA_MASK (0xff << 24) +# define DISP_LIN_TRANS_BYPASS (0x01 << 9) +#define DISP2_MERGE_CNTL 0x0d68 +# define DISP2_RGB_OFFSET_EN (1<<8) +#define DISP_LIN_TRANS_GRPH_A 0x0d80 +#define DISP_LIN_TRANS_GRPH_B 0x0d84 +#define DISP_LIN_TRANS_GRPH_C 0x0d88 +#define DISP_LIN_TRANS_GRPH_D 0x0d8c +#define DISP_LIN_TRANS_GRPH_E 0x0d90 +#define DISP_LIN_TRANS_GRPH_F 0x0d98 +#define DP_BRUSH_BKGD_CLR 0x1478 +#define DP_BRUSH_FRGD_CLR 0x147c +#define DP_CNTL 0x16c0 +# define DST_X_LEFT_TO_RIGHT (1 << 0) +# define DST_Y_TOP_TO_BOTTOM (1 << 1) +#define DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define DST_Y_MAJOR (1 << 2) +# define DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define DP_DATATYPE 0x16c4 +# define DST_8BPP 0x00000002 +# define DST_15BPP 0x00000003 +# define DST_16BPP 0x00000004 +# define DST_24BPP 0x00000005 +# define DST_32BPP 0x00000006 +# define DST_8BPP_RGB332 0x00000007 +# define DST_8BPP_Y8 0x00000008 +# define DST_8BPP_RGB8 0x00000009 +# define DST_16BPP_VYUY422 0x0000000b +# define DST_16BPP_YVYU422 0x0000000c +# define DST_32BPP_AYUV444 0x0000000e +# define DST_16BPP_ARGB4444 0x0000000f +# define BRUSH_SOLIDCOLOR 0x00000d00 +# define SRC_MONO 0x00000000 +# define SRC_MONO_LBKGD 0x00010000 +# define SRC_DSTCOLOR 0x00030000 +# define BYTE_ORDER_MSB_TO_LSB 0x00000000 +# define BYTE_ORDER_LSB_TO_MSB 0x40000000 +# define DP_CONVERSION_TEMP 0x80000000 +# define HOST_BIG_ENDIAN_EN (1 << 29) +#define DP_GUI_MASTER_CNTL 0x146c +# define GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define GMC_SRC_CLIPPING (1 << 2) +# define GMC_DST_CLIPPING (1 << 3) +# define GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define GMC_BRUSH_32x32_MONO_FG_BG (8 << 4) +# define GMC_BRUSH_32x32_MONO_FG_LA (9 << 4) +# define GMC_BRUSH_8x8_COLOR (10 << 4) +# define GMC_BRUSH_1X8_COLOR (12 << 4) +# define GMC_BRUSH_SOLID_COLOR (13 << 4) +# define GMC_BRUSH_NONE (15 << 4) +# define GMC_DST_8BPP (2 << 8) +# define GMC_DST_15BPP (3 << 8) +# define GMC_DST_16BPP (4 << 8) +# define GMC_DST_24BPP (5 << 8) +# define GMC_DST_32BPP (6 << 8) +# define GMC_DST_8BPP_RGB (7 << 8) +# define GMC_DST_Y8 (8 << 8) +# define GMC_DST_RGB8 (9 << 8) +# define GMC_DST_VYUY (11 << 8) +# define GMC_DST_YVYU (12 << 8) +# define GMC_DST_AYUV444 (14 << 8) +# define GMC_DST_ARGB4444 (15 << 8) +# define GMC_DST_DATATYPE_MASK (0x0f << 8) +# define GMC_DST_DATATYPE_SHIFT 8 +# define GMC_SRC_DATATYPE_MASK (3 << 12) +# define GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define GMC_SRC_DATATYPE_COLOR (3 << 12) +# define GMC_BYTE_PIX_ORDER (1 << 14) +# define GMC_BYTE_MSB_TO_LSB (0 << 14) +# define GMC_BYTE_LSB_TO_MSB (1 << 14) +# define GMC_CONVERSION_TEMP (1 << 15) +# define GMC_CONVERSION_TEMP_6500 (0 << 15) +# define GMC_CONVERSION_TEMP_9300 (1 << 15) +# define GMC_ROP3_MASK (0xff << 16) +# define GMC_ROP3_PATCOPY 0x00f00000 +# define GMC_ROP3_SRCCOPY 0x00cc0000 +# define GMC_ROP3_PATXOR 0x005a0000 +# define GMC_ROP3_XOR 0x00660000 +# define GMC_DP_SRC_SOURCE_MASK (7 << 24) +# define GMC_DP_SRC_SOURCE_MEMORY (2 << 24) +# define GMC_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define GMC_3D_FCN_EN (1 << 27) +# define GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define GMC_AUX_CLIP_DIS (1 << 29) +# define GMC_WR_MSK_DIS (1 << 30) +# define GMC_LD_BRUSH_Y_X (1 << 31) +#define DP_GUI_MASTER_CNTL_C 0x1c84 +#define DP_MIX 0x16c8 +#define DP_SRC_BKGD_CLR 0x15dc +#define DP_SRC_FRGD_CLR 0x15d8 +#define DP_WRITE_MASK 0x16cc +#define DST_BRES_DEC 0x1630 +#define DST_BRES_ERR 0x1628 +#define DST_BRES_INC 0x162c +#define DST_BRES_LNTH 0x1634 +#define DST_BRES_LNTH_SUB 0x1638 +#define DST_HEIGHT 0x1410 +#define DST_HEIGHT_WIDTH 0x143c +#define DST_HEIGHT_WIDTH_8 0x158c +#define DST_HEIGHT_WIDTH_BW 0x15b4 +#define DST_HEIGHT_Y 0x15a0 +#define DST_LINE_START 0x1600 +#define DST_LINE_END 0x1604 +#define DST_LINE_PATCOUNT 0x1608 +# define BRES_CNTL_SHIFT 8 +#define DST_OFFSET 0x1404 +#define DST_PITCH 0x1408 +#define DST_PITCH_OFFSET 0x142c +#define DST_PITCH_OFFSET_C 0x1c80 +# define PITCH_SHIFT 21 +# define DST_TILE_LINEAR (0 << 30) +# define DST_TILE_MACRO (1 << 30) +# define DST_TILE_MICRO (2 << 30) +# define DST_TILE_BOTH (3 << 30) +#define DST_WIDTH 0x140c +#define DST_WIDTH_HEIGHT 0x1598 +#define DST_WIDTH_X 0x1588 +#define DST_WIDTH_X_INCY 0x159c +#define DST_X 0x141c +#define DST_X_SUB 0x15a4 +#define DST_X_Y 0x1594 +#define DST_Y 0x1420 +#define DST_Y_SUB 0x15a8 +#define DST_Y_X 0x1438 + +#define FCP_CNTL 0x0910 +# define FCP0_SRC_PCICLK 0 +# define FCP0_SRC_PCLK 1 +# define FCP0_SRC_PCLKb 2 +# define FCP0_SRC_HREF 3 +# define FCP0_SRC_GND 4 +# define FCP0_SRC_HREFb 5 +#define FLUSH_1 0x1704 +#define FLUSH_2 0x1708 +#define FLUSH_3 0x170c +#define FLUSH_4 0x1710 +#define FLUSH_5 0x1714 +#define FLUSH_6 0x1718 +#define FLUSH_7 0x171c +#define FOG_3D_TABLE_START 0x1810 +#define FOG_3D_TABLE_END 0x1814 +#define FOG_3D_TABLE_DENSITY 0x181c +#define FOG_TABLE_INDEX 0x1a14 +#define FOG_TABLE_DATA 0x1a18 +#define FP_CRTC_H_TOTAL_DISP 0x0250 +#define FP_CRTC_V_TOTAL_DISP 0x0254 +#define FP_CRTC2_H_TOTAL_DISP 0x0350 +#define FP_CRTC2_V_TOTAL_DISP 0x0354 +# define FP_CRTC_H_TOTAL_MASK 0x000003ff +# define FP_CRTC_H_DISP_MASK 0x01ff0000 +# define FP_CRTC_V_TOTAL_MASK 0x00000fff +# define FP_CRTC_V_DISP_MASK 0x0fff0000 +# define FP_H_SYNC_STRT_CHAR_MASK 0x00001ff8 +# define FP_H_SYNC_WID_MASK 0x003f0000 +# define FP_V_SYNC_STRT_MASK 0x00000fff +# define FP_V_SYNC_WID_MASK 0x001f0000 +# define FP_CRTC_H_TOTAL_SHIFT 0x00000000 +# define FP_CRTC_H_DISP_SHIFT 0x00000010 +# define FP_CRTC_V_TOTAL_SHIFT 0x00000000 +# define FP_CRTC_V_DISP_SHIFT 0x00000010 +# define FP_H_SYNC_STRT_CHAR_SHIFT 0x00000003 +# define FP_H_SYNC_WID_SHIFT 0x00000010 +# define FP_V_SYNC_STRT_SHIFT 0x00000000 +# define FP_V_SYNC_WID_SHIFT 0x00000010 +#define FP_GEN_CNTL 0x0284 +# define FP_FPON (1 << 0) +# define FP_BLANK_EN (1 << 1) +# define FP_TMDS_EN (1 << 2) +# define FP_PANEL_FORMAT (1 << 3) +# define FP_EN_TMDS (1 << 7) +# define FP_DETECT_SENSE (1 << 8) +# define R200_FP_SOURCE_SEL_MASK (3 << 10) +# define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) +# define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) +# define R200_FP_SOURCE_SEL_RMX (2 << 10) +# define R200_FP_SOURCE_SEL_TRANS (3 << 10) +# define FP_SEL_CRTC1 (0 << 13) +# define FP_SEL_CRTC2 (1 << 13) +# define FP_CRTC_DONT_SHADOW_HPAR (1 << 15) +# define FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define FP_CRTC_DONT_SHADOW_HEND (1 << 17) +# define FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define FP_RMX_HVSYNC_CONTROL_EN (1 << 20) +# define FP_DFP_SYNC_SEL (1 << 21) +# define FP_CRTC_LOCK_8DOT (1 << 22) +# define FP_CRT_SYNC_SEL (1 << 23) +# define FP_USE_SHADOW_EN (1 << 24) +# define FP_CRT_SYNC_ALT (1 << 26) +#define FP2_GEN_CNTL 0x0288 +# define FP2_BLANK_EN (1 << 1) +# define FP2_ON (1 << 2) +# define FP2_PANEL_FORMAT (1 << 3) +# define R200_FP2_SOURCE_SEL_MASK (3 << 10) +# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) +# define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) +# define R200_FP2_SOURCE_SEL_RMX (2 << 10) +# define FP2_SRC_SEL_MASK (3 << 13) +# define FP2_SRC_SEL_CRTC2 (1 << 13) +# define FP2_FP_POL (1 << 16) +# define FP2_LP_POL (1 << 17) +# define FP2_SCK_POL (1 << 18) +# define FP2_LCD_CNTL_MASK (7 << 19) +# define FP2_PAD_FLOP_EN (1 << 22) +# define FP2_CRC_EN (1 << 23) +# define FP2_CRC_READ_EN (1 << 24) +# define FP2_DVO_EN (1 << 25) +# define FP2_DVO_RATE_SEL_SDR (1 << 26) +#define FP_H_SYNC_STRT_WID 0x02c4 +#define FP2_H_SYNC_STRT_WID 0x03c4 +#define FP_HORZ_STRETCH 0x028c +#define FP_HORZ2_STRETCH 0x038c +# define HORZ_STRETCH_RATIO_MASK 0xffff +# define HORZ_STRETCH_RATIO_MAX 4096 +# define HORZ_PANEL_SIZE (0x1ff << 16) +# define HORZ_PANEL_SHIFT 16 +# define HORZ_STRETCH_PIXREP (0 << 25) +# define HORZ_STRETCH_BLEND (1 << 26) +# define HORZ_STRETCH_ENABLE (1 << 25) +# define HORZ_AUTO_RATIO (1 << 27) +# define HORZ_FP_LOOP_STRETCH (0x7 << 28) +# define HORZ_AUTO_RATIO_INC (1 << 31) +#define FP_V_SYNC_STRT_WID 0x02c8 +#define FP_VERT_STRETCH 0x0290 +#define FP2_V_SYNC_STRT_WID 0x03c8 +#define FP_VERT2_STRETCH 0x0390 +# define VERT_PANEL_SIZE (0xfff << 12) +# define VERT_PANEL_SHIFT 12 +# define VERT_STRETCH_RATIO_MASK 0xfff +# define VERT_STRETCH_RATIO_SHIFT 0 +# define VERT_STRETCH_RATIO_MAX 4096 +# define VERT_STRETCH_ENABLE (1 << 25) +# define VERT_STRETCH_LINEREP (0 << 26) +# define VERT_STRETCH_BLEND (1 << 26) +# define VERT_AUTO_RATIO_EN (1 << 27) +# define VERT_STRETCH_RESERVED 0xf1000000 + +#define GEN_INT_CNTL 0x0040 +#define GEN_INT_STATUS 0x0044 +# define VSYNC_INT_AK (1 << 2) +# define VSYNC_INT (1 << 2) +# define VSYNC2_INT_AK (1 << 6) +# define VSYNC2_INT (1 << 6) +#define GENENB 0x03c3 /* VGA */ +#define GENFC_RD 0x03ca /* VGA */ +#define GENFC_WT 0x03da /* VGA, 0x03ba */ +#define GENMO_RD 0x03cc /* VGA */ +#define GENMO_WT 0x03c2 /* VGA */ +#define GENS0 0x03c2 /* VGA */ +#define GENS1 0x03da /* VGA, 0x03ba */ +#define GPIO_MONID 0x0068 /* DDC interface via I2C */ +#define GPIO_MONIDB 0x006c +#define GPIO_CRT2_DDC 0x006c +#define GPIO_DVI_DDC 0x0064 +#define GPIO_VGA_DDC 0x0060 +# define GPIO_A_0 (1 << 0) +# define GPIO_A_1 (1 << 1) +# define GPIO_Y_0 (1 << 8) +# define GPIO_Y_1 (1 << 9) +# define GPIO_Y_SHIFT_0 8 +# define GPIO_Y_SHIFT_1 9 +# define GPIO_EN_0 (1 << 16) +# define GPIO_EN_1 (1 << 17) +# define GPIO_MASK_0 (1 << 24) /*??*/ +# define GPIO_MASK_1 (1 << 25) /*??*/ +#define GRPH8_DATA 0x03cf /* VGA */ +#define GRPH8_IDX 0x03ce /* VGA */ +#define GUI_SCRATCH_REG0 0x15e0 +#define GUI_SCRATCH_REG1 0x15e4 +#define GUI_SCRATCH_REG2 0x15e8 +#define GUI_SCRATCH_REG3 0x15ec +#define GUI_SCRATCH_REG4 0x15f0 +#define GUI_SCRATCH_REG5 0x15f4 + +#define HEADER 0x0f0e /* PCI */ +#define HOST_DATA0 0x17c0 +#define HOST_DATA1 0x17c4 +#define HOST_DATA2 0x17c8 +#define HOST_DATA3 0x17cc +#define HOST_DATA4 0x17d0 +#define HOST_DATA5 0x17d4 +#define HOST_DATA6 0x17d8 +#define HOST_DATA7 0x17dc +#define HOST_DATA_LAST 0x17e0 +#define HOST_PATH_CNTL 0x0130 +# define HDP_SOFT_RESET (1 << 26) +#define HTOTAL_CNTL 0x0009 /* PLL */ +#define HTOTAL2_CNTL 0x002e /* PLL */ + +#define I2C_CNTL_1 0x0094 /* ? */ +#define DVI_I2C_CNTL_1 0x02e4 /* ? */ +#define INTERRUPT_LINE 0x0f3c /* PCI */ +#define INTERRUPT_PIN 0x0f3d /* PCI */ +#define IO_BASE 0x0f14 /* PCI */ + +#define LATENCY 0x0f0d /* PCI */ +#define LEAD_BRES_DEC 0x1608 +#define LEAD_BRES_LNTH 0x161c +#define LEAD_BRES_LNTH_SUB 0x1624 +#define LVDS_GEN_CNTL 0x02d0 +# define LVDS_ON (1 << 0) +# define LVDS_DISPLAY_DIS (1 << 1) +# define LVDS_PANEL_TYPE (1 << 2) +# define LVDS_PANEL_FORMAT (1 << 3) +# define LVDS_EN (1 << 7) +# define LVDS_DIGON (1 << 18) +# define LVDS_BLON (1 << 19) +# define LVDS_SEL_CRTC2 (1 << 23) +#define LVDS_PLL_CNTL 0x02d4 +# define HSYNC_DELAY_SHIFT 28 +# define HSYNC_DELAY_MASK (0xf << 28) + +#define MAX_LATENCY 0x0f3f /* PCI */ +#define MC_AGP_LOCATION 0x014c +#define MC_FB_LOCATION 0x0148 +#define CRTC_BASE_ADDR 0x023c +#define CRTC2_BASE_ADDR 0x033c +#define DISPLAY_TEST_DEBUG_CNTL 0x0d10 +#define NB_TOM 0x015c +#define MCLK_CNTL 0x0012 /* PLL */ +# define FORCEON_MCLKA (1 << 16) +# define FORCEON_MCLKB (1 << 17) +# define FORCEON_YCLKA (1 << 18) +# define FORCEON_YCLKB (1 << 19) +# define FORCEON_MC (1 << 20) +# define FORCEON_AIC (1 << 21) +# define R300_DISABLE_MC_MCLKA (1 << 21) +# define R300_DISABLE_MC_MCLKB (1 << 21) +#define MCLK_MISC 0x001f /* PLL */ +# define MC_MCLK_MAX_DYN_STOP_LAT (1<<12) +# define IO_MCLK_MAX_DYN_STOP_LAT (1<<13) +# define MC_MCLK_DYN_ENABLE (1 << 14) +# define IO_MCLK_DYN_ENABLE (1 << 14) +#define MDGPIO_A_REG 0x01ac +#define MDGPIO_EN_REG 0x01b0 +#define MDGPIO_MASK 0x0198 +#define MDGPIO_Y_REG 0x01b4 +#define MEM_ADDR_CONFIG 0x0148 +#define MEM_BASE 0x0f10 /* PCI */ +#define MEM_CNTL 0x0140 +# define MEM_NUM_CHANNELS_MASK 0x01 +# define MEM_USE_B_CH_ONLY (1<<1) +# define RV100_HALF_MODE (1<<3) +# define R300_MEM_NUM_CHANNELS_MASK 0x03 +# define R300_MEM_USE_CD_CH_ONLY (1<<2) +#define MEM_TIMING_CNTL 0x0144 /* EXT_MEM_CNTL */ +#define MEM_INIT_LAT_TIMER 0x0154 +#define MEM_INTF_CNTL 0x014c +#define MEM_SDRAM_MODE_REG 0x0158 +#define MEM_STR_CNTL 0x0150 +#define MEM_VGA_RP_SEL 0x003c +#define MEM_VGA_WP_SEL 0x0038 +#define MIN_GRANT 0x0f3e /* PCI */ +#define MM_DATA 0x0004 +#define MM_INDEX 0x0000 +#define MPLL_CNTL 0x000e /* PLL */ +#define MPP_TB_CONFIG 0x01c0 /* ? */ +#define MPP_GP_CONFIG 0x01c8 /* ? */ +#define R300_MC_IND_INDEX 0x01f8 +# define R300_MC_IND_ADDR_MASK 0x3f +#define R300_MC_IND_DATA 0x01fc +#define R300_MC_READ_CNTL_AB 0x017c +# define R300_MEM_RBS_POSITION_A_MASK 0x03 +#define R300_MC_READ_CNTL_CD_mcind 0x24 +# define R300_MEM_RBS_POSITION_C_MASK 0x03 + +#define N_VIF_COUNT 0x0248 + +/* overlay */ +#define OV0_Y_X_START 0x0400 +#define OV0_Y_X_END 0x0404 +#define OV0_PIPELINE_CNTL 0x0408 +#define OV0_EXCLUSIVE_HORZ 0x0408 +# define EXCL_HORZ_START_MASK 0x000000ff +# define EXCL_HORZ_END_MASK 0x0000ff00 +# define EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define OV0_EXCLUSIVE_VERT 0x040C +# define EXCL_VERT_START_MASK 0x000003ff +# define EXCL_VERT_END_MASK 0x03ff0000 +#define OV0_REG_LOAD_CNTL 0x0410 +# define REG_LD_CTL_LOCK 0x00000001 +# define REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002 +# define REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004 +# define REG_LD_CTL_LOCK_READBACK 0x00000008 +#define OV0_SCALE_CNTL 0x0420 +# define SCALER_PIX_EXPAND 0x00000001 +# define SCALER_Y2R_TEMP 0x00000002 +# define SCALER_HORZ_PICK_NEAREST 0x00000004 +# define SCALER_VERT_PICK_NEAREST 0x00000008 +# define SCALER_SIGNED_UV 0x00000010 +# define SCALER_GAMMA_SEL_MASK 0x00000060 +# define SCALER_GAMMA_SEL_BRIGHT 0x00000000 +# define SCALER_GAMMA_SEL_G22 0x00000020 +# define SCALER_GAMMA_SEL_G18 0x00000040 +# define SCALER_GAMMA_SEL_G14 0x00000060 +# define SCALER_COMCORE_SHIFT_UP_ONE 0x00000080 +# define SCALER_SURFAC_FORMAT 0x00000f00 +# define SCALER_SOURCE_UNK0 0x00000000 /* 2 bpp ??? */ +# define SCALER_SOURCE_UNK1 0x00000100 /* 4 bpp ??? */ +# define SCALER_SOURCE_UNK2 0x00000200 /* 8 bpp ??? */ +# define SCALER_SOURCE_15BPP 0x00000300 +# define SCALER_SOURCE_16BPP 0x00000400 +/*# define SCALER_SOURCE_24BPP 0x00000500*/ +# define SCALER_SOURCE_32BPP 0x00000600 +# define SCALER_SOURCE_UNK3 0x00000700 /* 8BPP_RGB332 ??? */ +# define SCALER_SOURCE_UNK4 0x00000800 /* 8BPP_Y8 ??? */ +# define SCALER_SOURCE_YUV9 0x00000900 /* 8BPP_RGB8 */ +# define SCALER_SOURCE_YUV12 0x00000A00 +# define SCALER_SOURCE_VYUY422 0x00000B00 +# define SCALER_SOURCE_YVYU422 0x00000C00 +# define SCALER_SOURCE_UNK5 0x00000D00 /* ??? */ +# define SCALER_SOURCE_UNK6 0x00000E00 /* 32BPP_AYUV444 */ +# define SCALER_SOURCE_UNK7 0x00000F00 /* 16BPP_ARGB4444 */ +# define SCALER_ADAPTIVE_DEINT 0x00001000 +# define R200_SCALER_TEMPORAL_DEINT 0x00002000 +# define SCALER_UNKNOWN_FLAG1 0x00004000 /* ??? */ +# define SCALER_SMART_SWITCH 0x00008000 +# define SCALER_BURST_PER_PLANE 0x007f0000 +# define SCALER_DOUBLE_BUFFER 0x01000000 +# define SCALER_UNKNOWN_FLAG3 0x02000000 /* ??? */ +# define SCALER_UNKNOWN_FLAG4 0x04000000 /* ??? */ +# define SCALER_DIS_LIMIT 0x08000000 +# define SCALER_PRG_LOAD_START 0x10000000 +# define SCALER_INT_EMU 0x20000000 +# define SCALER_ENABLE 0x40000000 +# define SCALER_SOFT_RESET 0x80000000 +#define OV0_V_INC 0x0424 +#define OV0_P1_V_ACCUM_INIT 0x0428 +# define OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003 +# define OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000 +#define OV0_P23_V_ACCUM_INIT 0x042C +# define OV0_P23_MAX_LN_IN_PER_LN_OUT 0x00000003 +# define OV0_P23_V_ACCUM_INIT_MASK 0x01ff8000 +#define OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fff +# define P1_ACTIVE_LINES_M1 0x0fff0000 +#define OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ff +# define P23_ACTIVE_LINES_M1 0x07ff0000 +#define OV0_BASE_ADDR 0x043C +#define OV0_VID_BUF0_BASE_ADRS 0x0440 +# define VIF_BUF0_PITCH_SEL 0x00000001 +# define VIF_BUF0_TILE_ADRS 0x00000002 +# define VIF_BUF0_BASE_ADRS_MASK 0xfffffff0 +# define VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000 +#define OV0_VID_BUF1_BASE_ADRS 0x0444 +# define VIF_BUF1_PITCH_SEL 0x00000001 +# define VIF_BUF1_TILE_ADRS 0x00000002 +# define VIF_BUF1_BASE_ADRS_MASK 0xfffffff0 +# define VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000 +#define OV0_VID_BUF2_BASE_ADRS 0x0448 +# define VIF_BUF2_PITCH_SEL 0x00000001 +# define VIF_BUF2_TILE_ADRS 0x00000002 +# define VIF_BUF2_BASE_ADRS_MASK 0xfffffff0 +# define VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000 +#define OV0_VID_BUF3_BASE_ADRS 0x044C +# define VIF_BUF3_PITCH_SEL 0x00000001 +# define VIF_BUF3_TILE_ADRS 0x00000002 +# define VIF_BUF3_BASE_ADRS_MASK 0xfffffff0 +# define VIF_BUF3_1ST_LINE_LSBS_MASK 0x48000000 +#define OV0_VID_BUF4_BASE_ADRS 0x0450 +# define VIF_BUF4_PITCH_SEL 0x00000001 +# define VIF_BUF4_TILE_ADRS 0x00000002 +# define VIF_BUF4_BASE_ADRS_MASK 0xfffffff0 +# define VIF_BUF4_1ST_LINE_LSBS_MASK 0x48000000 +#define OV0_VID_BUF5_BASE_ADRS 0x0454 +# define VIF_BUF5_PITCH_SEL 0x00000001 +# define VIF_BUF5_TILE_ADRS 0x00000002 +# define VIF_BUF5_BASE_ADRS_MASK 0xfffffff0 +# define VIF_BUF5_1ST_LINE_LSBS_MASK 0x48000000 +#define OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define OV0_AUTO_FLIP_CNTL 0x0470 +# define OV0_AUTO_FLIP_CNTL_SOFT_BUF_NUM 0x00000007 +# define OV0_AUTO_FLIP_CNTL_SOFT_REPEAT_FIELD 0x00000008 +# define OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 0x00000010 +# define OV0_AUTO_FLIP_CNTL_IGNORE_REPEAT_FIELD 0x00000020 +# define OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE 0x00000040 +# define OV0_AUTO_FLIP_CNTL_VID_PORT_SELECT 0x00000300 +# define OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 0x00010000 +# define OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN 0x00040000 +# define OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN 0x00080000 +# define OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE 0x00800000 +#define OV0_DEINTERLACE_PATTERN 0x0474 +#define OV0_SUBMIT_HISTORY 0x0478 +#define OV0_H_INC 0x0480 +#define OV0_STEP_BY 0x0484 +#define OV0_P1_H_ACCUM_INIT 0x0488 +#define OV0_P23_H_ACCUM_INIT 0x048C +#define OV0_P1_X_START_END 0x0494 +#define OV0_P2_X_START_END 0x0498 +#define OV0_P3_X_START_END 0x049C +#define OV0_FILTER_CNTL 0x04A0 +# define FILTER_PROGRAMMABLE_COEF 0x00000000 +# define FILTER_HARD_SCALE_HORZ_Y 0x00000001 +# define FILTER_HARD_SCALE_HORZ_UV 0x00000002 +# define FILTER_HARD_SCALE_VERT_Y 0x00000004 +# define FILTER_HARD_SCALE_VERT_UV 0x00000008 +# define FILTER_HARDCODED_COEF 0x0000000F +# define FILTER_COEF_MASK 0x0000000F +#define OV0_FOUR_TAP_COEF_0 0x04B0 +# define OV0_FOUR_TAP_PHASE_0_TAP_0 0x0000000F +# define OV0_FOUR_TAP_PHASE_0_TAP_1 0x00007F00 +# define OV0_FOUR_TAP_PHASE_0_TAP_2 0x007F0000 +# define OV0_FOUR_TAP_PHASE_0_TAP_3 0x0F000000 +#define OV0_FOUR_TAP_COEF_1 0x04B4 +# define OV0_FOUR_TAP_PHASE_1_5_TAP_0 0x0000000F +# define OV0_FOUR_TAP_PHASE_1_5_TAP_1 0x00007F00 +# define OV0_FOUR_TAP_PHASE_1_5_TAP_2 0x007F0000 +# define OV0_FOUR_TAP_PHASE_1_5_TAP_3 0x0F000000 +#define OV0_FOUR_TAP_COEF_2 0x04B8 +# define OV0_FOUR_TAP_PHASE_2_6_TAP_0 0x0000000F +# define OV0_FOUR_TAP_PHASE_2_6_TAP_1 0x00007F00 +# define OV0_FOUR_TAP_PHASE_2_6_TAP_2 0x007F0000 +# define OV0_FOUR_TAP_PHASE_2_6_TAP_3 0x0F000000 +#define OV0_FOUR_TAP_COEF_3 0x04BC +# define OV0_FOUR_TAP_PHASE_3_7_TAP_0 0x0000000F +# define OV0_FOUR_TAP_PHASE_3_7_TAP_1 0x00007F00 +# define OV0_FOUR_TAP_PHASE_3_7_TAP_2 0x007F0000 +# define OV0_FOUR_TAP_PHASE_3_7_TAP_3 0x0F000000 +#define OV0_FOUR_TAP_COEF_4 0x04C0 +# define OV0_FOUR_TAP_PHASE_4_TAP_0 0x0000000F +# define OV0_FOUR_TAP_PHASE_4_TAP_1 0x00007F00 +# define OV0_FOUR_TAP_PHASE_4_TAP_2 0x007F0000 +# define OV0_FOUR_TAP_PHASE_4_TAP_3 0x0F000000 +#define OV0_FLAG_CNTL 0x04DC +#define OV0_SLICE_CNTL 0x04E0 +# define SLICE_CNTL_DISABLE 0x40000000 +#define OV0_VID_KEY_CLR_LOW 0x04E4 +#define OV0_VID_KEY_CLR_HIGH 0x04E8 +#define OV0_GRPH_KEY_CLR_LOW 0x04EC +#define OV0_GRPH_KEY_CLR_HIGH 0x04F0 +#define OV0_KEY_CNTL 0x04F4 +# define VIDEO_KEY_FN_MASK 0x00000003 +# define VIDEO_KEY_FN_FALSE 0x00000000 +# define VIDEO_KEY_FN_TRUE 0x00000001 +# define VIDEO_KEY_FN_EQ 0x00000002 +# define VIDEO_KEY_FN_NE 0x00000003 +# define GRAPHIC_KEY_FN_MASK 0x00000030 +# define GRAPHIC_KEY_FN_FALSE 0x00000000 +# define GRAPHIC_KEY_FN_TRUE 0x00000010 +# define GRAPHIC_KEY_FN_EQ 0x00000020 +# define GRAPHIC_KEY_FN_NE 0x00000030 +# define CMP_MIX_MASK 0x00000100 +# define CMP_MIX_OR 0x00000000 +# define CMP_MIX_AND 0x00000100 +#define OV0_TEST 0x04F8 +# define OV0_SCALER_Y2R_DISABLE 0x00000001 +# define OV0_SUBPIC_ONLY 0x00000008 +# define OV0_EXTENSE 0x00000010 +# define OV0_SWAP_UV 0x00000020 +#define OV0_COL_CONV 0x04FC +# define OV0_CB_TO_B 0x0000007F +# define OV0_CB_TO_G 0x0000FF00 +# define OV0_CR_TO_G 0x00FF0000 +# define OV0_CR_TO_R 0x7F000000 +# define OV0_NEW_COL_CONV 0x80000000 +#define OV1_Y_X_START 0x0600 +#define OV1_Y_X_END 0x0604 +#define OV0_LIN_TRANS_A 0x0D20 +#define OV0_LIN_TRANS_B 0x0D24 +#define OV0_LIN_TRANS_C 0x0D28 +#define OV0_LIN_TRANS_D 0x0D2C +#define OV0_LIN_TRANS_E 0x0D30 +#define OV0_LIN_TRANS_F 0x0D34 +#define OV0_GAMMA_000_00F 0x0d40 +#define OV0_GAMMA_010_01F 0x0d44 +#define OV0_GAMMA_020_03F 0x0d48 +#define OV0_GAMMA_040_07F 0x0d4c +#define OV0_GAMMA_080_0BF 0x0e00 +#define OV0_GAMMA_0C0_0FF 0x0e04 +#define OV0_GAMMA_100_13F 0x0e08 +#define OV0_GAMMA_140_17F 0x0e0c +#define OV0_GAMMA_180_1BF 0x0e10 +#define OV0_GAMMA_1C0_1FF 0x0e14 +#define OV0_GAMMA_200_23F 0x0e18 +#define OV0_GAMMA_240_27F 0x0e1c +#define OV0_GAMMA_280_2BF 0x0e20 +#define OV0_GAMMA_2C0_2FF 0x0e24 +#define OV0_GAMMA_300_33F 0x0e28 +#define OV0_GAMMA_340_37F 0x0e2c +#define OV0_GAMMA_380_3BF 0x0d50 +#define OV0_GAMMA_3C0_3FF 0x0d54 + +#define OVR_CLR 0x0230 +#define OVR_WID_LEFT_RIGHT 0x0234 +#define OVR_WID_TOP_BOTTOM 0x0238 + +/* subpicture */ +#define SUBPIC_CNTL 0x0540 +#define SUBPIC_DEFCOLCON 0x0544 +#define SUBPIC_Y_X_START 0x054C +#define SUBPIC_Y_X_END 0x0550 +#define SUBPIC_V_INC 0x0554 +#define SUBPIC_H_INC 0x0558 +#define SUBPIC_BUF0_OFFSET 0x055C +#define SUBPIC_BUF1_OFFSET 0x0560 +#define SUBPIC_LC0_OFFSET 0x0564 +#define SUBPIC_LC1_OFFSET 0x0568 +#define SUBPIC_PITCH 0x056C +#define SUBPIC_BTN_HLI_COLCON 0x0570 +#define SUBPIC_BTN_HLI_Y_X_START 0x0574 +#define SUBPIC_BTN_HLI_Y_X_END 0x0578 +#define SUBPIC_PALETTE_INDEX 0x057C +#define SUBPIC_PALETTE_DATA 0x0580 +#define SUBPIC_H_ACCUM_INIT 0x0584 +#define SUBPIC_V_ACCUM_INIT 0x0588 + +#define P2PLL_CNTL 0x002a /* P2PLL */ +# define P2PLL_RESET (1 << 0) +# define P2PLL_SLEEP (1 << 1) +# define P2PLL_ATOMIC_UPDATE_EN (1 << 16) +# define P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +# define P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18) +#define P2PLL_DIV_0 0x002c +# define P2PLL_FB0_DIV_MASK 0x07ff +# define P2PLL_POST0_DIV_MASK 0x00070000 +#define P2PLL_REF_DIV 0x002B /* PLL */ +# define P2PLL_REF_DIV_MASK 0x03ff +# define P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +# define R300_PPLL_REF_DIV_ACC_MASK (0x3ff << 18) +# define R300_PPLL_REF_DIV_ACC_SHIFT 18 +#define PALETTE_DATA 0x00b4 +#define PALETTE_30_DATA 0x00b8 +#define PALETTE_INDEX 0x00b0 +#define PCI_GART_PAGE 0x017c +#define PIXCLKS_CNTL 0x002d +# define PIX2CLK_SRC_SEL_MASK 0x03 +# define PIX2CLK_SRC_SEL_CPUCLK 0x00 +# define PIX2CLK_SRC_SEL_PSCANCLK 0x01 +# define PIX2CLK_SRC_SEL_BYTECLK 0x02 +# define PIX2CLK_SRC_SEL_P2PLLCLK 0x03 +# define PIX2CLK_ALWAYS_ONb (1<<6) +# define PIX2CLK_DAC_ALWAYS_ONb (1<<7) +# define PIXCLK_TV_SRC_SEL (1 << 8) +# define DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb (1 << 9) +# define R300_DVOCLK_ALWAYS_ONb (1 << 10) +# define PIXCLK_BLEND_ALWAYS_ONb (1 << 11) +# define PIXCLK_GV_ALWAYS_ONb (1 << 12) +# define PIXCLK_DIG_TMDS_ALWAYS_ONb (1 << 13) +# define R300_PIXCLK_DVO_ALWAYS_ONb (1 << 13) +# define PIXCLK_LVDS_ALWAYS_ONb (1 << 14) +# define PIXCLK_TMDS_ALWAYS_ONb (1 << 15) +# define R300_PIXCLK_TRANS_ALWAYS_ONb (1 << 16) +# define R300_PIXCLK_TVO_ALWAYS_ONb (1 << 17) +# define R300_P2G2CLK_ALWAYS_ONb (1 << 18) +# define R300_P2G2CLK_DAC_ALWAYS_ONb (1 << 19) +# define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23) +#define PLANE_3D_MASK_C 0x1d44 +#define PLL_TEST_CNTL 0x0013 /* PLL */ +#define PMI_CAP_ID 0x0f5c /* PCI */ +#define PMI_DATA 0x0f63 /* PCI */ +#define PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define PMI_PMC_REG 0x0f5e /* PCI */ +#define PMI_PMCSR_REG 0x0f60 /* PCI */ +#define PMI_REGISTER 0x0f5c /* PCI */ +#define PPLL_CNTL 0x0002 /* PLL */ +# define PPLL_RESET (1 << 0) +# define PPLL_SLEEP (1 << 1) +# define PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +# define PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) +#define PPLL_DIV_0 0x0004 /* PLL */ +#define PPLL_DIV_1 0x0005 /* PLL */ +#define PPLL_DIV_2 0x0006 /* PLL */ +#define PPLL_DIV_3 0x0007 /* PLL */ +# define PPLL_FB3_DIV_MASK 0x07ff +# define PPLL_POST3_DIV_MASK 0x00070000 +#define PPLL_REF_DIV 0x0003 /* PLL */ +# define PPLL_REF_DIV_MASK 0x03ff +# define PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ + +/* ERT registers */ +#define TV_MASTER_CNTL 0x0800 +# define TV_MASTER_TVCLK_ALWAYS_ONb (1 << 30) +# define TV_MASTER_TV_ON (1 << 31) +#define TV_RGB_CNTL 0x0804 +# define TV_RGB_CNTL_INI 0x007b0004 +#define TV_SYNC_CNTL 0x0808 +#define TV_HTOTAL 0x080c +#define TV_HDISP 0x0810 +#define TV_HSTART 0x0818 +#define TV_HCOUNT 0x081c +#define TV_VTOTAL 0x0820 +#define TV_VDISP 0x0824 +#define TV_VCOUNT 0x0828 +#define TV_FTOTAL 0x082c +#define TV_FCOUNT 0x0830 +#define TV_FRESTART 0x0834 +#define TV_HRESTART 0x0838 +#define TV_VRESTART 0x083c +#define TV_HOST_READ_DATA 0x0840 +#define TV_HOST_WRITE_DATA 0x0844 +#define TV_HOST_RD_WT_CNTL 0x0848 +#define TV_VSCALER_CNTL1 0x084c +# define TV_VSCALER_RESTART_FIELD (1 << 29) +#define TV_TIMING_CNTL 0x0850 +#define TV_VSCALER_CNTL2 0x0854 +#define TV_Y_FALL_CNTL 0x0858 +#define TV_Y_RISE_CNTL 0x085c +#define TV_Y_SAWTOOTH_CNTL 0x0860 +#define TV_UPSAMP_AND_GAIN_CNTL 0x0864 +#define TV_GAIN_LIMIT_SETTINGS 0x0868 +#define TV_LINEAR_GAIN_SETTINGS 0x086c +#define TV_MODULATOR_CNTL1 0x0870 +#define TV_MODULATOR_CNTL2 0x0874 +#define TV_PRE_DAC_MUX_CNTL 0x0888 +# define TV_PRE_DAC_Y_RED_EN (1 << 0) +# define TV_PRE_DAC_C_GRN_EN (1 << 1) +# define TV_PRE_DAC_CMP_BLU_EN (1 << 2) +# define TV_PRE_DAC_RED_MX_FORCE_DAC_DATA (6 << 4) +# define TV_PRE_DAC_GRN_MX_FORCE_DAC_DATA (6 << 8) +# define TV_PRE_DAC_BLU_MX_FORCE_DAC_DATA (6 << 12) +# define TV_FORCE_DAC_DATA_SHIFT 16 +#define TV_DAC_CNTL 0x088c +# define TV_DAC_NBLANK (1 << 0) +# define TV_DAC_NHOLD (1 << 1) +# define TV_DAC_CMPOUT (1 << 5) +# define TV_DAC_BGSLEEP (1 << 6) +# define TV_DAC_RDACPD (1 << 24) +# define TV_DAC_GDACPD (1 << 25) +# define TV_DAC_BDACPD (1 << 26) +#define TV_CRC_CNTL 0x0890 +#define TV_UV_ADR 0x08ac +/* ERT PLL registers */ +#define TV_PLL_CNTL 0x21 +#define TV_PLL_CNTL1 0x22 +# define TV_PLL_CNTL1_TVPLL_RESET (1 << 1) +# define TV_PLL_CNTL1_TVPLL_SLEEP (1 << 3) +# define TV_PLL_CNTL1_TVPDC_SHIFT 14 +# define TV_PLL_CNTL1_TVPDC_MASK (3 << 14) +# define TV_PLL_CNTL1_TVCLK_SRC_SEL (1 << 30) + + +#define RBBM_GUICNTL 0x172c +# define HOST_DATA_SWAP_NONE (0 << 0) +# define HOST_DATA_SWAP_16BIT (1 << 0) +# define HOST_DATA_SWAP_32BIT (2 << 0) +# define HOST_DATA_SWAP_HDW (3 << 0) +#define RBBM_SOFT_RESET 0x00f0 +# define SOFT_RESET_CP (1 << 0) +# define SOFT_RESET_HI (1 << 1) +# define SOFT_RESET_SE (1 << 2) +# define SOFT_RESET_RE (1 << 3) +# define SOFT_RESET_PP (1 << 4) +# define SOFT_RESET_E2 (1 << 5) +# define SOFT_RESET_RB (1 << 6) +# define SOFT_RESET_HDP (1 << 7) +#define RBBM_STATUS 0x0e40 +# define RBBM_FIFOCNT_MASK 0x007f +# define RBBM_ACTIVE (1 << 31) +#define RB2D_DSTCACHE_MODE 0x3428 +# define RB2D_DC_CACHE_ENABLE (0) +# define RB2D_DC_2D_CACHE_DISABLE (1) +# define RB2D_DC_3D_CACHE_DISABLE (2) +# define RB2D_DC_CACHE_DISABLE (3) +# define RB2D_DC_2D_CACHE_LINESIZE_128 (1 << 2) +# define RB2D_DC_3D_CACHE_LINESIZE_128 (2 << 2) +# define RB2D_DC_2D_CACHE_AUTOFLUSH (1 << 8) +# define RB2D_DC_3D_CACHE_AUTOFLUSH (2 << 8) +# define R200_RB2D_DC_2D_CACHE_AUTOFREE (1 << 10) +# define R200_RB2D_DC_3D_CACHE_AUTOFREE (2 << 10) +# define RB2D_DC_FORCE_RMW (1 << 16) +# define R300_RB2D_DC_ENABLE (1 << 17) +# define RB2D_DC_DISABLE_RI_FILL (1 << 24) +# define RB2D_DC_DISABLE_RI_READ (1 << 25) +# define RB2D_DC_DISABLE_MASK_CHK (1 << 26) +#define RB2D_DSTCACHE_CTLSTAT 0x342c +# define RB2D_DC_FLUSH (3 << 0) +# define RB2D_DC_FREE (3 << 2) +# define RB2D_DC_FLUSH_ALL 0xf +# define RB2D_DC_BUSY (1 << 31) +#define RB3D_DSTCACHE_MODE 0x3258 +# define RB3D_DC_CACHE_ENABLE (0) +# define RB3D_DC_2D_CACHE_DISABLE (1) +# define RB3D_DC_3D_CACHE_DISABLE (2) +# define RB3D_DC_CACHE_DISABLE (3) +# define RB3D_DC_2D_CACHE_LINESIZE_128 (1 << 2) +# define RB3D_DC_3D_CACHE_LINESIZE_128 (2 << 2) +# define RB3D_DC_2D_CACHE_AUTOFLUSH (1 << 8) +# define RB3D_DC_3D_CACHE_AUTOFLUSH (2 << 8) +# define R200_RB3D_DC_2D_CACHE_AUTOFREE (1 << 10) +# define R200_RB3D_DC_3D_CACHE_AUTOFREE (2 << 10) +# define RB3D_DC_FORCE_RMW (1 << 16) +# define R300_RB3D_DC_ENABLE (1 << 17) +# define RB3D_DC_DISABLE_RI_FILL (1 << 24) +# define RB3D_DC_DISABLE_RI_READ (1 << 25) +# define RB3D_DC_DISABLE_MASK_CHK (1 << 26) +#define RB3D_DSTCACHE_CTLSTAT 0x325C +# define RB3D_DC_FLUSH (3 << 0) +# define RB3D_DC_FREE (3 << 2) +# define RB3D_DC_FLUSH_ALL 0xf +# define RB3D_DC_BUSY (1 << 31) +#define REG_BASE 0x0f18 /* PCI */ +#define REGPROG_INF 0x0f09 /* PCI */ +#define REVISION_ID 0x0f08 /* PCI */ + +#define SC_BOTTOM 0x164c +#define SC_BOTTOM_RIGHT 0x16f0 +#define SC_BOTTOM_RIGHT_C 0x1c8c +#define SC_LEFT 0x1640 +#define SC_RIGHT 0x1644 +#define SC_TOP 0x1648 +#define SC_TOP_LEFT 0x16ec +#define SC_TOP_LEFT_C 0x1c88 +# define SC_SIGN_MASK_LO 0x8000 +# define SC_SIGN_MASK_HI 0x80000000 +#define SCLK_CNTL 0x000d /* PLL */ +# define SCLK_SRC_SEL_MASK 0x0007 +# define DYN_STOP_LAT_MASK 0x00007ff8 +# define CP_MAX_DYN_STOP_LAT 0x0008 +# define SCLK_FORCEON_MASK 0xffff8000 +# define SCLK_FORCE_DISP2 (1<<15) +# define SCLK_FORCE_CP (1<<16) +# define SCLK_FORCE_HDP (1<<17) +# define SCLK_FORCE_DISP1 (1<<18) +# define SCLK_FORCE_TOP (1<<19) +# define SCLK_FORCE_E2 (1<<20) +# define SCLK_FORCE_SE (1<<21) +# define SCLK_FORCE_IDCT (1<<22) +# define SCLK_FORCE_VIP (1<<23) +# define SCLK_FORCE_RE (1<<24) +# define SCLK_FORCE_PB (1<<25) +# define SCLK_FORCE_TAM (1<<26) +# define SCLK_FORCE_TDM (1<<27) +# define SCLK_FORCE_RB (1<<28) +# define SCLK_FORCE_TV_SCLK (1<<29) +# define SCLK_FORCE_SUBPIC (1<<30) +# define SCLK_FORCE_OV0 (1<<31) +# define R300_SCLK_FORCE_VAP (1<<21) +# define R300_SCLK_FORCE_SR (1<<25) +# define R300_SCLK_FORCE_PX (1<<26) +# define R300_SCLK_FORCE_TX (1<<27) +# define R300_SCLK_FORCE_US (1<<28) +# define R300_SCLK_FORCE_SU (1<<30) +#define R300_SCLK_CNTL2 0x1e /* PLL */ +# define R300_SCLK_TCL_MAX_DYN_STOP_LAT (1<<10) +# define R300_SCLK_GA_MAX_DYN_STOP_LAT (1<<11) +# define R300_SCLK_CBA_MAX_DYN_STOP_LAT (1<<12) +# define R300_SCLK_FORCE_TCL (1<<13) +# define R300_SCLK_FORCE_CBA (1<<14) +# define R300_SCLK_FORCE_GA (1<<15) +#define SCLK_MORE_CNTL 0x0035 /* PLL */ +# define SCLK_MORE_MAX_DYN_STOP_LAT 0x0007 +# define SCLK_MORE_FORCEON 0x0700 +#define SDRAM_MODE_REG 0x0158 +#define SEQ8_DATA 0x03c5 /* VGA */ +#define SEQ8_IDX 0x03c4 /* VGA */ +#define SNAPSHOT_F_COUNT 0x0244 +#define SNAPSHOT_VH_COUNTS 0x0240 +#define SNAPSHOT_VIF_COUNT 0x024c +#define SRC_OFFSET 0x15ac +#define SRC_PITCH 0x15b0 +#define SRC_PITCH_OFFSET 0x1428 +#define SRC_SC_BOTTOM 0x165c +#define SRC_SC_BOTTOM_RIGHT 0x16f4 +#define SRC_SC_RIGHT 0x1654 +#define SRC_X 0x1414 +#define SRC_X_Y 0x1590 +#define SRC_Y 0x1418 +#define SRC_Y_X 0x1434 +#define STATUS 0x0f06 /* PCI */ +#define SUB_CLASS 0x0f0a /* PCI */ +#define SURFACE_CNTL 0x0b00 +# define SURF_TRANSLATION_DIS (1 << 8) +# define NONSURF_AP0_SWP_16BPP (1 << 20) +# define NONSURF_AP0_SWP_32BPP (1 << 21) +# define NONSURF_AP1_SWP_16BPP (1 << 22) +# define NONSURF_AP1_SWP_32BPP (1 << 23) +#define SURFACE0_INFO 0x0b0c +#define SURFACE0_LOWER_BOUND 0x0b04 +#define SURFACE0_UPPER_BOUND 0x0b08 +#define SURFACE1_INFO 0x0b1c +#define SURFACE1_LOWER_BOUND 0x0b14 +#define SURFACE1_UPPER_BOUND 0x0b18 +#define SURFACE2_INFO 0x0b2c +#define SURFACE2_LOWER_BOUND 0x0b24 +#define SURFACE2_UPPER_BOUND 0x0b28 +#define SURFACE3_INFO 0x0b3c +#define SURFACE3_LOWER_BOUND 0x0b34 +#define SURFACE3_UPPER_BOUND 0x0b38 +#define SURFACE4_INFO 0x0b4c +#define SURFACE4_LOWER_BOUND 0x0b44 +#define SURFACE4_UPPER_BOUND 0x0b48 +#define SURFACE5_INFO 0x0b5c +#define SURFACE5_LOWER_BOUND 0x0b54 +#define SURFACE5_UPPER_BOUND 0x0b58 +#define SURFACE6_INFO 0x0b6c +#define SURFACE6_LOWER_BOUND 0x0b64 +#define SURFACE6_UPPER_BOUND 0x0b68 +#define SURFACE7_INFO 0x0b7c +#define SURFACE7_LOWER_BOUND 0x0b74 +#define SURFACE7_UPPER_BOUND 0x0b78 +#define SW_SEMAPHORE 0x013c + +#define TEST_DEBUG_CNTL 0x0120 +#define TEST_DEBUG_MUX 0x0124 +#define TEST_DEBUG_OUT 0x012c +#define TMDS_PLL_CNTL 0x02a8 +#define TMDS_TRANSMITTER_CNTL 0x02a4 +# define TMDS_TRANSMITTER_PLLEN 1 +# define TMDS_TRANSMITTER_PLLRST 2 +#define TRAIL_BRES_DEC 0x1614 +#define TRAIL_BRES_ERR 0x160c +#define TRAIL_BRES_INC 0x1610 +#define TRAIL_X 0x1618 +#define TRAIL_X_SUB 0x1620 + +#define VCLK_ECP_CNTL 0x0008 /* PLL */ +# define VCLK_SRC_SEL_MASK 0x03 +# define VCLK_SRC_SEL_CPUCLK 0x00 +# define VCLK_SRC_SEL_PSCANCLK 0x01 +# define VCLK_SRC_SEL_BYTECLK 0x02 +# define VCLK_SRC_SEL_PPLLCLK 0x03 +# define PIXCLK_ALWAYS_ONb (1<<6) +# define PIXCLK_DAC_ALWAYS_ONb (1<<7) +# define R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF (1<<23) + +#define VGA_DDA_CONFIG 0x02e8 +#define VGA_DDA_ON_OFF 0x02ec +#define VID_BUFFER_CONTROL 0x0900 +#define VIDEOMUX_CNTL 0x0190 +#define VIPH_CONTROL 0x0c40 /* ? */ + +#define WAIT_UNTIL 0x1720 +# define WAIT_CRTC_PFLIP (1 << 0) +# define R300_WAIT_2D_IDLE (1 << 0) +# define R300_WAIT_3D_IDLE (2 << 0) +# define R300_WAIT_2D_IDLECLEAN (3 << 0) +# define R300_WAIT_3D_IDLECLEAN (4 << 0) +# define WAIT_2D_IDLE (1 << 14) +# define WAIT_3D_IDLE (1 << 15) +# define WAIT_2D_IDLECLEAN (1 << 16) +# define WAIT_3D_IDLECLEAN (1 << 17) +# define WAIT_HOST_IDLECLEAN (1 << 18) + +#define ISYNC_CNTL 0x1724 +# define ISYNC_ANY2D_IDLE3D (1 << 0) +# define ISYNC_ANY3D_IDLE2D (1 << 1) +# define ISYNC_TRIG2D_IDLE3D (1 << 2) +# define ISYNC_TRIG3D_IDLE2D (1 << 3) +# define ISYNC_WAIT_IDLEGUI (1 << 4) +# define ISYNC_CPSCRATCH_IDLEGUI (1 << 5) + +#define X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define XCLK_CNTL 0x000d /* PLL */ +#define XDLL_CNTL 0x000c /* PLL */ +#define XPLL_CNTL 0x000b /* PLL */ + + + + /* Registers for 3D/TCL */ +#define PP_BORDER_COLOR_0 0x1d40 +#define PP_BORDER_COLOR_1 0x1d44 +#define PP_BORDER_COLOR_2 0x1d48 +#define PP_CNTL 0x1c38 +# define STIPPLE_ENABLE (1 << 0) +# define SCISSOR_ENABLE (1 << 1) +# define PATTERN_ENABLE (1 << 2) +# define SHADOW_ENABLE (1 << 3) +# define TEX_ENABLE_MASK (0xf << 4) +# define TEX_0_ENABLE (1 << 4) +# define TEX_1_ENABLE (1 << 5) +# define TEX_2_ENABLE (1 << 6) +# define TEX_3_ENABLE (1 << 7) +# define TEX_BLEND_ENABLE_MASK (0xf << 12) +# define TEX_BLEND_0_ENABLE (1 << 12) +# define TEX_BLEND_1_ENABLE (1 << 13) +# define TEX_BLEND_2_ENABLE (1 << 14) +# define TEX_BLEND_3_ENABLE (1 << 15) +# define PLANAR_YUV_ENABLE (1 << 20) +# define SPECULAR_ENABLE (1 << 21) +# define FOG_ENABLE (1 << 22) +# define ALPHA_TEST_ENABLE (1 << 23) +# define ANTI_ALIAS_NONE (0 << 24) +# define ANTI_ALIAS_LINE (1 << 24) +# define ANTI_ALIAS_POLY (2 << 24) +# define ANTI_ALIAS_LINE_POLY (3 << 24) +# define BUMP_MAP_ENABLE (1 << 26) +# define BUMPED_MAP_T0 (0 << 27) +# define BUMPED_MAP_T1 (1 << 27) +# define BUMPED_MAP_T2 (2 << 27) +# define TEX_3D_ENABLE_0 (1 << 29) +# define TEX_3D_ENABLE_1 (1 << 30) +# define MC_ENABLE (1 << 31) +#define PP_FOG_COLOR 0x1c18 +# define FOG_COLOR_MASK 0x00ffffff +# define FOG_VERTEX (0 << 24) +# define FOG_TABLE (1 << 24) +# define FOG_USE_DEPTH (0 << 25) +# define FOG_USE_DIFFUSE_ALPHA (2 << 25) +# define FOG_USE_SPEC_ALPHA (3 << 25) +#define PP_LUM_MATRIX 0x1d00 +#define PP_MISC 0x1c14 +# define REF_ALPHA_MASK 0x000000ff +# define ALPHA_TEST_FAIL (0 << 8) +# define ALPHA_TEST_LESS (1 << 8) +# define ALPHA_TEST_LEQUAL (2 << 8) +# define ALPHA_TEST_EQUAL (3 << 8) +# define ALPHA_TEST_GEQUAL (4 << 8) +# define ALPHA_TEST_GREATER (5 << 8) +# define ALPHA_TEST_NEQUAL (6 << 8) +# define ALPHA_TEST_PASS (7 << 8) +# define ALPHA_TEST_OP_MASK (7 << 8) +# define CHROMA_FUNC_FAIL (0 << 16) +# define CHROMA_FUNC_PASS (1 << 16) +# define CHROMA_FUNC_NEQUAL (2 << 16) +# define CHROMA_FUNC_EQUAL (3 << 16) +# define CHROMA_KEY_NEAREST (0 << 18) +# define CHROMA_KEY_ZERO (1 << 18) +# define SHADOW_ID_AUTO_INC (1 << 20) +# define SHADOW_FUNC_EQUAL (0 << 21) +# define SHADOW_FUNC_NEQUAL (1 << 21) +# define SHADOW_PASS_1 (0 << 22) +# define SHADOW_PASS_2 (1 << 22) +# define RIGHT_HAND_CUBE_D3D (0 << 24) +# define RIGHT_HAND_CUBE_OGL (1 << 24) +#define PP_ROT_MATRIX_0 0x1d58 +#define PP_ROT_MATRIX_1 0x1d5c +#define PP_TXFILTER_0 0x1c54 +#define PP_TXFILTER_1 0x1c6c +#define PP_TXFILTER_2 0x1c84 +# define MAG_FILTER_NEAREST (0 << 0) +# define MAG_FILTER_LINEAR (1 << 0) +# define MAG_FILTER_MASK (1 << 0) +# define MIN_FILTER_NEAREST (0 << 1) +# define MIN_FILTER_LINEAR (1 << 1) +# define MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) +# define MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) +# define MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) +# define MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) +# define MIN_FILTER_ANISO_NEAREST (8 << 1) +# define MIN_FILTER_ANISO_LINEAR (9 << 1) +# define MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) +# define MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) +# define MIN_FILTER_MASK (15 << 1) +# define MAX_ANISO_1_TO_1 (0 << 5) +# define MAX_ANISO_2_TO_1 (1 << 5) +# define MAX_ANISO_4_TO_1 (2 << 5) +# define MAX_ANISO_8_TO_1 (3 << 5) +# define MAX_ANISO_16_TO_1 (4 << 5) +# define MAX_ANISO_MASK (7 << 5) +# define LOD_BIAS_MASK (0xff << 8) +# define LOD_BIAS_SHIFT 8 +# define MAX_MIP_LEVEL_MASK (0x0f << 16) +# define MAX_MIP_LEVEL_SHIFT 16 +# define YUV_TO_RGB (1 << 20) +# define YUV_TEMPERATURE_COOL (0 << 21) +# define YUV_TEMPERATURE_HOT (1 << 21) +# define YUV_TEMPERATURE_MASK (1 << 21) +# define WRAPEN_S (1 << 22) +# define CLAMP_S_WRAP (0 << 23) +# define CLAMP_S_MIRROR (1 << 23) +# define CLAMP_S_CLAMP_LAST (2 << 23) +# define CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) +# define CLAMP_S_CLAMP_BORDER (4 << 23) +# define CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) +# define CLAMP_S_CLAMP_GL (6 << 23) +# define CLAMP_S_MIRROR_CLAMP_GL (7 << 23) +# define CLAMP_S_MASK (7 << 23) +# define WRAPEN_T (1 << 26) +# define CLAMP_T_WRAP (0 << 27) +# define CLAMP_T_MIRROR (1 << 27) +# define CLAMP_T_CLAMP_LAST (2 << 27) +# define CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) +# define CLAMP_T_CLAMP_BORDER (4 << 27) +# define CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) +# define CLAMP_T_CLAMP_GL (6 << 27) +# define CLAMP_T_MIRROR_CLAMP_GL (7 << 27) +# define CLAMP_T_MASK (7 << 27) +# define BORDER_MODE_OGL (0 << 31) +# define BORDER_MODE_D3D (1 << 31) +#define PP_TXFORMAT_0 0x1c58 +#define PP_TXFORMAT_1 0x1c70 +#define PP_TXFORMAT_2 0x1c88 +# define TXFORMAT_I8 (0 << 0) +# define TXFORMAT_AI88 (1 << 0) +# define TXFORMAT_RGB332 (2 << 0) +# define TXFORMAT_ARGB1555 (3 << 0) +# define TXFORMAT_RGB565 (4 << 0) +# define TXFORMAT_ARGB4444 (5 << 0) +# define TXFORMAT_ARGB8888 (6 << 0) +# define TXFORMAT_RGBA8888 (7 << 0) +# define TXFORMAT_Y8 (8 << 0) +# define TXFORMAT_VYUY422 (10 << 0) +# define TXFORMAT_YVYU422 (11 << 0) +# define TXFORMAT_DXT1 (12 << 0) +# define TXFORMAT_DXT23 (14 << 0) +# define TXFORMAT_DXT45 (15 << 0) +# define TXFORMAT_FORMAT_MASK (31 << 0) +# define TXFORMAT_FORMAT_SHIFT 0 +# define TXFORMAT_APPLE_YUV_MODE (1 << 5) +# define TXFORMAT_ALPHA_IN_MAP (1 << 6) +# define TXFORMAT_NON_POWER2 (1 << 7) +# define TXFORMAT_WIDTH_MASK (15 << 8) +# define TXFORMAT_WIDTH_SHIFT 8 +# define TXFORMAT_HEIGHT_MASK (15 << 12) +# define TXFORMAT_HEIGHT_SHIFT 12 +# define TXFORMAT_F5_WIDTH_MASK (15 << 16) +# define TXFORMAT_F5_WIDTH_SHIFT 16 +# define TXFORMAT_F5_HEIGHT_MASK (15 << 20) +# define TXFORMAT_F5_HEIGHT_SHIFT 20 +# define TXFORMAT_ST_ROUTE_STQ0 (0 << 24) +# define TXFORMAT_ST_ROUTE_MASK (3 << 24) +# define TXFORMAT_ST_ROUTE_STQ1 (1 << 24) +# define TXFORMAT_ST_ROUTE_STQ2 (2 << 24) +# define TXFORMAT_ENDIAN_NO_SWAP (0 << 26) +# define TXFORMAT_ENDIAN_16BPP_SWAP (1 << 26) +# define TXFORMAT_ENDIAN_32BPP_SWAP (2 << 26) +# define TXFORMAT_ENDIAN_HALFDW_SWAP (3 << 26) +# define TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) +# define TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) +# define TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) +# define TXFORMAT_PERSPECTIVE_ENABLE (1 << 31) +#define PP_CUBIC_FACES_0 0x1d24 +#define PP_CUBIC_FACES_1 0x1d28 +#define PP_CUBIC_FACES_2 0x1d2c +# define FACE_WIDTH_1_SHIFT 0 +# define FACE_HEIGHT_1_SHIFT 4 +# define FACE_WIDTH_1_MASK (0xf << 0) +# define FACE_HEIGHT_1_MASK (0xf << 4) +# define FACE_WIDTH_2_SHIFT 8 +# define FACE_HEIGHT_2_SHIFT 12 +# define FACE_WIDTH_2_MASK (0xf << 8) +# define FACE_HEIGHT_2_MASK (0xf << 12) +# define FACE_WIDTH_3_SHIFT 16 +# define FACE_HEIGHT_3_SHIFT 20 +# define FACE_WIDTH_3_MASK (0xf << 16) +# define FACE_HEIGHT_3_MASK (0xf << 20) +# define FACE_WIDTH_4_SHIFT 24 +# define FACE_HEIGHT_4_SHIFT 28 +# define FACE_WIDTH_4_MASK (0xf << 24) +# define FACE_HEIGHT_4_MASK (0xf << 28) + +#define PP_TXOFFSET_0 0x1c5c +#define PP_TXOFFSET_1 0x1c74 +#define PP_TXOFFSET_2 0x1c8c +# define TXO_ENDIAN_NO_SWAP (0 << 0) +# define TXO_ENDIAN_BYTE_SWAP (1 << 0) +# define TXO_ENDIAN_WORD_SWAP (2 << 0) +# define TXO_ENDIAN_HALFDW_SWAP (3 << 0) +# define TXO_MACRO_LINEAR (0 << 2) +# define TXO_MACRO_TILE (1 << 2) +# define TXO_MICRO_LINEAR (0 << 3) +# define TXO_MICRO_TILE_X2 (1 << 3) +# define TXO_MICRO_TILE_OPT (2 << 3) +# define TXO_OFFSET_MASK 0xffffffe0 +# define TXO_OFFSET_SHIFT 5 + +#define PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */ +#define PP_CUBIC_OFFSET_T0_1 0x1dd4 +#define PP_CUBIC_OFFSET_T0_2 0x1dd8 +#define PP_CUBIC_OFFSET_T0_3 0x1ddc +#define PP_CUBIC_OFFSET_T0_4 0x1de0 +#define PP_CUBIC_OFFSET_T1_0 0x1e00 +#define PP_CUBIC_OFFSET_T1_1 0x1e04 +#define PP_CUBIC_OFFSET_T1_2 0x1e08 +#define PP_CUBIC_OFFSET_T1_3 0x1e0c +#define PP_CUBIC_OFFSET_T1_4 0x1e10 +#define PP_CUBIC_OFFSET_T2_0 0x1e14 +#define PP_CUBIC_OFFSET_T2_1 0x1e18 +#define PP_CUBIC_OFFSET_T2_2 0x1e1c +#define PP_CUBIC_OFFSET_T2_3 0x1e20 +#define PP_CUBIC_OFFSET_T2_4 0x1e24 + +#define PP_TEX_SIZE_0 0x1d04 /* NPOT */ +#define PP_TEX_SIZE_1 0x1d0c +#define PP_TEX_SIZE_2 0x1d14 +# define TEX_USIZE_MASK (0x7ff << 0) +# define TEX_USIZE_SHIFT 0 +# define TEX_VSIZE_MASK (0x7ff << 16) +# define TEX_VSIZE_SHIFT 16 +# define SIGNED_RGB_MASK (1 << 30) +# define SIGNED_RGB_SHIFT 30 +# define SIGNED_ALPHA_MASK (1 << 31) +# define SIGNED_ALPHA_SHIFT 31 +#define PP_TEX_PITCH_0 0x1d08 /* NPOT */ +#define PP_TEX_PITCH_1 0x1d10 /* NPOT */ +#define PP_TEX_PITCH_2 0x1d18 /* NPOT */ +/* note: bits 13-5: 32 byte aligned stride of texture map */ + +#define PP_TXCBLEND_0 0x1c60 +#define PP_TXCBLEND_1 0x1c78 +#define PP_TXCBLEND_2 0x1c90 +# define COLOR_ARG_A_SHIFT 0 +# define COLOR_ARG_A_MASK (0x1f << 0) +# define COLOR_ARG_A_ZERO (0 << 0) +# define COLOR_ARG_A_CURRENT_COLOR (2 << 0) +# define COLOR_ARG_A_CURRENT_ALPHA (3 << 0) +# define COLOR_ARG_A_DIFFUSE_COLOR (4 << 0) +# define COLOR_ARG_A_DIFFUSE_ALPHA (5 << 0) +# define COLOR_ARG_A_SPECULAR_COLOR (6 << 0) +# define COLOR_ARG_A_SPECULAR_ALPHA (7 << 0) +# define COLOR_ARG_A_TFACTOR_COLOR (8 << 0) +# define COLOR_ARG_A_TFACTOR_ALPHA (9 << 0) +# define COLOR_ARG_A_T0_COLOR (10 << 0) +# define COLOR_ARG_A_T0_ALPHA (11 << 0) +# define COLOR_ARG_A_T1_COLOR (12 << 0) +# define COLOR_ARG_A_T1_ALPHA (13 << 0) +# define COLOR_ARG_A_T2_COLOR (14 << 0) +# define COLOR_ARG_A_T2_ALPHA (15 << 0) +# define COLOR_ARG_A_T3_COLOR (16 << 0) +# define COLOR_ARG_A_T3_ALPHA (17 << 0) +# define COLOR_ARG_B_SHIFT 5 +# define COLOR_ARG_B_MASK (0x1f << 5) +# define COLOR_ARG_B_ZERO (0 << 5) +# define COLOR_ARG_B_CURRENT_COLOR (2 << 5) +# define COLOR_ARG_B_CURRENT_ALPHA (3 << 5) +# define COLOR_ARG_B_DIFFUSE_COLOR (4 << 5) +# define COLOR_ARG_B_DIFFUSE_ALPHA (5 << 5) +# define COLOR_ARG_B_SPECULAR_COLOR (6 << 5) +# define COLOR_ARG_B_SPECULAR_ALPHA (7 << 5) +# define COLOR_ARG_B_TFACTOR_COLOR (8 << 5) +# define COLOR_ARG_B_TFACTOR_ALPHA (9 << 5) +# define COLOR_ARG_B_T0_COLOR (10 << 5) +# define COLOR_ARG_B_T0_ALPHA (11 << 5) +# define COLOR_ARG_B_T1_COLOR (12 << 5) +# define COLOR_ARG_B_T1_ALPHA (13 << 5) +# define COLOR_ARG_B_T2_COLOR (14 << 5) +# define COLOR_ARG_B_T2_ALPHA (15 << 5) +# define COLOR_ARG_B_T3_COLOR (16 << 5) +# define COLOR_ARG_B_T3_ALPHA (17 << 5) +# define COLOR_ARG_C_SHIFT 10 +# define COLOR_ARG_C_MASK (0x1f << 10) +# define COLOR_ARG_C_ZERO (0 << 10) +# define COLOR_ARG_C_CURRENT_COLOR (2 << 10) +# define COLOR_ARG_C_CURRENT_ALPHA (3 << 10) +# define COLOR_ARG_C_DIFFUSE_COLOR (4 << 10) +# define COLOR_ARG_C_DIFFUSE_ALPHA (5 << 10) +# define COLOR_ARG_C_SPECULAR_COLOR (6 << 10) +# define COLOR_ARG_C_SPECULAR_ALPHA (7 << 10) +# define COLOR_ARG_C_TFACTOR_COLOR (8 << 10) +# define COLOR_ARG_C_TFACTOR_ALPHA (9 << 10) +# define COLOR_ARG_C_T0_COLOR (10 << 10) +# define COLOR_ARG_C_T0_ALPHA (11 << 10) +# define COLOR_ARG_C_T1_COLOR (12 << 10) +# define COLOR_ARG_C_T1_ALPHA (13 << 10) +# define COLOR_ARG_C_T2_COLOR (14 << 10) +# define COLOR_ARG_C_T2_ALPHA (15 << 10) +# define COLOR_ARG_C_T3_COLOR (16 << 10) +# define COLOR_ARG_C_T3_ALPHA (17 << 10) +# define COMP_ARG_A (1 << 15) +# define COMP_ARG_A_SHIFT 15 +# define COMP_ARG_B (1 << 16) +# define COMP_ARG_B_SHIFT 16 +# define COMP_ARG_C (1 << 17) +# define COMP_ARG_C_SHIFT 17 +# define BLEND_CTL_MASK (7 << 18) +# define BLEND_CTL_ADD (0 << 18) +# define BLEND_CTL_SUBTRACT (1 << 18) +# define BLEND_CTL_ADDSIGNED (2 << 18) +# define BLEND_CTL_BLEND (3 << 18) +# define BLEND_CTL_DOT3 (4 << 18) +# define SCALE_SHIFT 21 +# define SCALE_MASK (3 << 21) +# define SCALE_1X (0 << 21) +# define SCALE_2X (1 << 21) +# define SCALE_4X (2 << 21) +# define CLAMP_TX (1 << 23) +# define T0_EQ_TCUR (1 << 24) +# define T1_EQ_TCUR (1 << 25) +# define T2_EQ_TCUR (1 << 26) +# define T3_EQ_TCUR (1 << 27) +# define COLOR_ARG_MASK 0x1f +# define COMP_ARG_SHIFT 15 +#define PP_TXABLEND_0 0x1c64 +#define PP_TXABLEND_1 0x1c7c +#define PP_TXABLEND_2 0x1c94 +# define ALPHA_ARG_A_SHIFT 0 +# define ALPHA_ARG_A_MASK (0xf << 0) +# define ALPHA_ARG_A_ZERO (0 << 0) +# define ALPHA_ARG_A_CURRENT_ALPHA (1 << 0) +# define ALPHA_ARG_A_DIFFUSE_ALPHA (2 << 0) +# define ALPHA_ARG_A_SPECULAR_ALPHA (3 << 0) +# define ALPHA_ARG_A_TFACTOR_ALPHA (4 << 0) +# define ALPHA_ARG_A_T0_ALPHA (5 << 0) +# define ALPHA_ARG_A_T1_ALPHA (6 << 0) +# define ALPHA_ARG_A_T2_ALPHA (7 << 0) +# define ALPHA_ARG_A_T3_ALPHA (8 << 0) +# define ALPHA_ARG_B_SHIFT 4 +# define ALPHA_ARG_B_MASK (0xf << 4) +# define ALPHA_ARG_B_ZERO (0 << 4) +# define ALPHA_ARG_B_CURRENT_ALPHA (1 << 4) +# define ALPHA_ARG_B_DIFFUSE_ALPHA (2 << 4) +# define ALPHA_ARG_B_SPECULAR_ALPHA (3 << 4) +# define ALPHA_ARG_B_TFACTOR_ALPHA (4 << 4) +# define ALPHA_ARG_B_T0_ALPHA (5 << 4) +# define ALPHA_ARG_B_T1_ALPHA (6 << 4) +# define ALPHA_ARG_B_T2_ALPHA (7 << 4) +# define ALPHA_ARG_B_T3_ALPHA (8 << 4) +# define ALPHA_ARG_C_SHIFT 8 +# define ALPHA_ARG_C_MASK (0xf << 8) +# define ALPHA_ARG_C_ZERO (0 << 8) +# define ALPHA_ARG_C_CURRENT_ALPHA (1 << 8) +# define ALPHA_ARG_C_DIFFUSE_ALPHA (2 << 8) +# define ALPHA_ARG_C_SPECULAR_ALPHA (3 << 8) +# define ALPHA_ARG_C_TFACTOR_ALPHA (4 << 8) +# define ALPHA_ARG_C_T0_ALPHA (5 << 8) +# define ALPHA_ARG_C_T1_ALPHA (6 << 8) +# define ALPHA_ARG_C_T2_ALPHA (7 << 8) +# define ALPHA_ARG_C_T3_ALPHA (8 << 8) +# define DOT_ALPHA_DONT_REPLICATE (1 << 9) +# define ALPHA_ARG_MASK 0xf + +#define PP_TFACTOR_0 0x1c68 +#define PP_TFACTOR_1 0x1c80 +#define PP_TFACTOR_2 0x1c98 + +#define RB3D_BLENDCNTL 0x1c20 +# define COMB_FCN_MASK (3 << 12) +# define COMB_FCN_ADD_CLAMP (0 << 12) +# define COMB_FCN_ADD_NOCLAMP (1 << 12) +# define COMB_FCN_SUB_CLAMP (2 << 12) +# define COMB_FCN_SUB_NOCLAMP (3 << 12) +# define SRC_BLEND_GL_ZERO (32 << 16) +# define SRC_BLEND_GL_ONE (33 << 16) +# define SRC_BLEND_GL_SRC_COLOR (34 << 16) +# define SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) +# define SRC_BLEND_GL_DST_COLOR (36 << 16) +# define SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) +# define SRC_BLEND_GL_SRC_ALPHA (38 << 16) +# define SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) +# define SRC_BLEND_GL_DST_ALPHA (40 << 16) +# define SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) +# define SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) +# define SRC_BLEND_MASK (63 << 16) +# define DST_BLEND_GL_ZERO (32 << 24) +# define DST_BLEND_GL_ONE (33 << 24) +# define DST_BLEND_GL_SRC_COLOR (34 << 24) +# define DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) +# define DST_BLEND_GL_DST_COLOR (36 << 24) +# define DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) +# define DST_BLEND_GL_SRC_ALPHA (38 << 24) +# define DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) +# define DST_BLEND_GL_DST_ALPHA (40 << 24) +# define DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) +# define DST_BLEND_MASK (63 << 24) +#define RB3D_CNTL 0x1c3c +# define ALPHA_BLEND_ENABLE (1 << 0) +# define PLANE_MASK_ENABLE (1 << 1) +# define DITHER_ENABLE (1 << 2) +# define ROUND_ENABLE (1 << 3) +# define SCALE_DITHER_ENABLE (1 << 4) +# define DITHER_INIT (1 << 5) +# define ROP_ENABLE (1 << 6) +# define STENCIL_ENABLE (1 << 7) +# define Z_ENABLE (1 << 8) +# define DEPTH_XZ_OFFEST_ENABLE (1 << 9) +# define COLOR_FORMAT_ARGB1555 (3 << 10) +# define COLOR_FORMAT_RGB565 (4 << 10) +# define COLOR_FORMAT_ARGB8888 (6 << 10) +# define COLOR_FORMAT_RGB332 (7 << 10) +# define COLOR_FORMAT_Y8 (8 << 10) +# define COLOR_FORMAT_RGB8 (9 << 10) +# define COLOR_FORMAT_YUV422_VYUY (11 << 10) +# define COLOR_FORMAT_YUV422_YVYU (12 << 10) +# define COLOR_FORMAT_AVYU (14 << 10) +# define COLOR_FORMAT_ARGB4444 (15 << 10) +# define CLRCMP_FLIP_ENABLE (1 << 14) +# define SEPARATE_ALPHA_ENABLE (1 << 16) +#define RB3D_COLOROFFSET 0x1c40 +# define COLOROFFSET_MASK 0xfffffff0 +#define RB3D_COLORPITCH 0x1c48 +# define COLORPITCH_MASK 0x000001ff8 +# define COLOR_TILE_ENABLE (1 << 16) +# define COLOR_MICROTILE_ENABLE (1 << 17) +# define COLOR_ENDIAN_NO_SWAP (0 << 18) +# define COLOR_ENDIAN_WORD_SWAP (1 << 18) +# define COLOR_ENDIAN_DWORD_SWAP (2 << 18) +#define RB3D_DEPTHOFFSET 0x1c24 +#define RB3D_DEPTHPITCH 0x1c28 +# define DEPTHPITCH_MASK 0x00001ff8 +# define DEPTH_ENDIAN_NO_SWAP (0 << 18) +# define DEPTH_ENDIAN_WORD_SWAP (1 << 18) +# define DEPTH_ENDIAN_DWORD_SWAP (2 << 18) +#define RB3D_PLANEMASK 0x1d84 +#define RB3D_ROPCNTL 0x1d80 +# define ROP_MASK (15 << 8) +# define ROP_CLEAR (0 << 8) +# define ROP_NOR (1 << 8) +# define ROP_AND_INVERTED (2 << 8) +# define ROP_COPY_INVERTED (3 << 8) +# define ROP_AND_REVERSE (4 << 8) +# define ROP_INVERT (5 << 8) +# define ROP_XOR (6 << 8) +# define ROP_NAND (7 << 8) +# define ROP_AND (8 << 8) +# define ROP_EQUIV (9 << 8) +# define ROP_NOOP (10 << 8) +# define ROP_OR_INVERTED (11 << 8) +# define ROP_COPY (12 << 8) +# define ROP_OR_REVERSE (13 << 8) +# define ROP_OR (14 << 8) +# define ROP_SET (15 << 8) +#define RB3D_STENCILREFMASK 0x1d7c +# define STENCIL_REF_SHIFT 0 +# define STENCIL_REF_MASK (0xff << 0) +# define STENCIL_MASK_SHIFT 16 +# define STENCIL_VALUE_MASK (0xff << 16) +# define STENCIL_WRITEMASK_SHIFT 24 +# define STENCIL_WRITE_MASK (0xff << 24) +#define RB3D_ZSTENCILCNTL 0x1c2c +# define DEPTH_FORMAT_MASK (0xf << 0) +# define DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define DEPTH_FORMAT_24BIT_INT_Z (2 << 0) +# define DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) +# define DEPTH_FORMAT_32BIT_INT_Z (4 << 0) +# define DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) +# define DEPTH_FORMAT_16BIT_FLOAT_W (7 << 0) +# define DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) +# define DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) +# define Z_TEST_NEVER (0 << 4) +# define Z_TEST_LESS (1 << 4) +# define Z_TEST_LEQUAL (2 << 4) +# define Z_TEST_EQUAL (3 << 4) +# define Z_TEST_GEQUAL (4 << 4) +# define Z_TEST_GREATER (5 << 4) +# define Z_TEST_NEQUAL (6 << 4) +# define Z_TEST_ALWAYS (7 << 4) +# define Z_TEST_MASK (7 << 4) +# define STENCIL_TEST_NEVER (0 << 12) +# define STENCIL_TEST_LESS (1 << 12) +# define STENCIL_TEST_LEQUAL (2 << 12) +# define STENCIL_TEST_EQUAL (3 << 12) +# define STENCIL_TEST_GEQUAL (4 << 12) +# define STENCIL_TEST_GREATER (5 << 12) +# define STENCIL_TEST_NEQUAL (6 << 12) +# define STENCIL_TEST_ALWAYS (7 << 12) +# define STENCIL_TEST_MASK (0x7 << 12) +# define STENCIL_FAIL_KEEP (0 << 16) +# define STENCIL_FAIL_ZERO (1 << 16) +# define STENCIL_FAIL_REPLACE (2 << 16) +# define STENCIL_FAIL_INC (3 << 16) +# define STENCIL_FAIL_DEC (4 << 16) +# define STENCIL_FAIL_INVERT (5 << 16) +# define STENCIL_FAIL_MASK (0x7 << 16) +# define STENCIL_ZPASS_KEEP (0 << 20) +# define STENCIL_ZPASS_ZERO (1 << 20) +# define STENCIL_ZPASS_REPLACE (2 << 20) +# define STENCIL_ZPASS_INC (3 << 20) +# define STENCIL_ZPASS_DEC (4 << 20) +# define STENCIL_ZPASS_INVERT (5 << 20) +# define STENCIL_ZPASS_MASK (0x7 << 20) +# define STENCIL_ZFAIL_KEEP (0 << 24) +# define STENCIL_ZFAIL_ZERO (1 << 24) +# define STENCIL_ZFAIL_REPLACE (2 << 24) +# define STENCIL_ZFAIL_INC (3 << 24) +# define STENCIL_ZFAIL_DEC (4 << 24) +# define STENCIL_ZFAIL_INVERT (5 << 24) +# define STENCIL_ZFAIL_MASK (0x7 << 24) +# define Z_COMPRESSION_ENABLE (1 << 28) +# define FORCE_Z_DIRTY (1 << 29) +# define Z_WRITE_ENABLE (1 << 30) +#define RE_LINE_PATTERN 0x1cd0 +# define LINE_PATTERN_MASK 0x0000ffff +# define LINE_REPEAT_COUNT_SHIFT 16 +# define LINE_PATTERN_START_SHIFT 24 +# define LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) +# define LINE_PATTERN_BIG_BIT_ORDER (1 << 28) +# define LINE_PATTERN_AUTO_RESET (1 << 29) +#define RE_LINE_STATE 0x1cd4 +# define LINE_CURRENT_PTR_SHIFT 0 +# define LINE_CURRENT_COUNT_SHIFT 8 +#define RE_MISC 0x26c4 +# define STIPPLE_COORD_MASK 0x1f +# define STIPPLE_X_OFFSET_SHIFT 0 +# define STIPPLE_X_OFFSET_MASK (0x1f << 0) +# define STIPPLE_Y_OFFSET_SHIFT 8 +# define STIPPLE_Y_OFFSET_MASK (0x1f << 8) +# define STIPPLE_LITTLE_BIT_ORDER (0 << 16) +# define STIPPLE_BIG_BIT_ORDER (1 << 16) +#define RE_SOLID_COLOR 0x1c1c +#define RE_POINTSIZE 0x2648 +# define RE_POINTSIZE_SHIFT 0 +# define RE_MAXPOINTSIZE_SHIFT 16 +#define RE_TOP_LEFT 0x26c0 +# define RE_LEFT_SHIFT 0 +# define RE_TOP_SHIFT 16 +#define RE_BOTTOM_RIGHT 0x1c44 +# define RE_RIGHT_SHIFT 0 +# define RE_BOTTOM_SHIFT 16 + +#define SE_CNTL 0x1c4c +# define FFACE_CULL_CW (0 << 0) +# define FFACE_CULL_CCW (1 << 0) +# define FFACE_CULL_DIR_MASK (1 << 0) +# define BFACE_CULL (0 << 1) +# define BFACE_SOLID (3 << 1) +# define FFACE_CULL (0 << 3) +# define FFACE_SOLID (3 << 3) +# define FFACE_CULL_MASK (3 << 3) +# define BADVTX_CULL_DISABLE (1 << 5) +# define FLAT_SHADE_VTX_0 (0 << 6) +# define FLAT_SHADE_VTX_1 (1 << 6) +# define FLAT_SHADE_VTX_2 (2 << 6) +# define FLAT_SHADE_VTX_LAST (3 << 6) +# define DIFFUSE_SHADE_SOLID (0 << 8) +# define DIFFUSE_SHADE_FLAT (1 << 8) +# define DIFFUSE_SHADE_GOURAUD (2 << 8) +# define DIFFUSE_SHADE_MASK (3 << 8) +# define ALPHA_SHADE_SOLID (0 << 10) +# define ALPHA_SHADE_FLAT (1 << 10) +# define ALPHA_SHADE_GOURAUD (2 << 10) +# define ALPHA_SHADE_MASK (3 << 10) +# define SPECULAR_SHADE_SOLID (0 << 12) +# define SPECULAR_SHADE_FLAT (1 << 12) +# define SPECULAR_SHADE_GOURAUD (2 << 12) +# define SPECULAR_SHADE_MASK (3 << 12) +# define FOG_SHADE_SOLID (0 << 14) +# define FOG_SHADE_FLAT (1 << 14) +# define FOG_SHADE_GOURAUD (2 << 14) +# define FOG_SHADE_MASK (3 << 14) +# define ZBIAS_ENABLE_POINT (1 << 16) +# define ZBIAS_ENABLE_LINE (1 << 17) +# define ZBIAS_ENABLE_TRI (1 << 18) +# define WIDELINE_ENABLE (1 << 20) +# define VPORT_XY_XFORM_ENABLE (1 << 24) +# define VPORT_Z_XFORM_ENABLE (1 << 25) +# define VTX_PIX_CENTER_D3D (0 << 27) +# define VTX_PIX_CENTER_OGL (1 << 27) +# define ROUND_MODE_TRUNC (0 << 28) +# define ROUND_MODE_ROUND (1 << 28) +# define ROUND_MODE_ROUND_EVEN (2 << 28) +# define ROUND_MODE_ROUND_ODD (3 << 28) +# define ROUND_PREC_16TH_PIX (0 << 30) +# define ROUND_PREC_8TH_PIX (1 << 30) +# define ROUND_PREC_4TH_PIX (2 << 30) +# define ROUND_PREC_HALF_PIX (3 << 30) +#define R200_RE_CNTL 0x1c50 +# define R200_STIPPLE_ENABLE 0x1 +# define R200_SCISSOR_ENABLE 0x2 +# define R200_PATTERN_ENABLE 0x4 +# define R200_PERSPECTIVE_ENABLE 0x8 +# define R200_POINT_SMOOTH 0x20 +# define R200_VTX_STQ0_D3D 0x00010000 +# define R200_VTX_STQ1_D3D 0x00040000 +# define R200_VTX_STQ2_D3D 0x00100000 +# define R200_VTX_STQ3_D3D 0x00400000 +# define R200_VTX_STQ4_D3D 0x01000000 +# define R200_VTX_STQ5_D3D 0x04000000 +#define SE_CNTL_STATUS 0x2140 +# define VC_NO_SWAP (0 << 0) +# define VC_16BIT_SWAP (1 << 0) +# define VC_32BIT_SWAP (2 << 0) +# define VC_HALF_DWORD_SWAP (3 << 0) +# define TCL_BYPASS (1 << 8) +#define SE_COORD_FMT 0x1c50 +# define VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0) +# define VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1) +# define VTX_ST0_NONPARAMETRIC (1 << 8) +# define VTX_ST1_NONPARAMETRIC (1 << 9) +# define VTX_ST2_NONPARAMETRIC (1 << 10) +# define VTX_ST3_NONPARAMETRIC (1 << 11) +# define VTX_W0_NORMALIZE (1 << 12) +# define VTX_W0_IS_NOT_1_OVER_W0 (1 << 16) +# define VTX_ST0_PRE_MULT_1_OVER_W0 (1 << 17) +# define VTX_ST1_PRE_MULT_1_OVER_W0 (1 << 19) +# define VTX_ST2_PRE_MULT_1_OVER_W0 (1 << 21) +# define VTX_ST3_PRE_MULT_1_OVER_W0 (1 << 23) +# define TEX1_W_ROUTING_USE_W0 (0 << 26) +# define TEX1_W_ROUTING_USE_Q1 (1 << 26) +#define SE_LINE_WIDTH 0x1db8 +#define SE_TCL_LIGHT_MODEL_CTL 0x226c +# define LIGHTING_ENABLE (1 << 0) +# define LIGHT_IN_MODELSPACE (1 << 1) +# define LOCAL_VIEWER (1 << 2) +# define NORMALIZE_NORMALS (1 << 3) +# define RESCALE_NORMALS (1 << 4) +# define SPECULAR_LIGHTS (1 << 5) +# define DIFFUSE_SPECULAR_COMBINE (1 << 6) +# define LIGHT_ALPHA (1 << 7) +# define LOCAL_LIGHT_VEC_GL (1 << 8) +# define LIGHT_NO_NORMAL_AMBIENT_ONLY (1 << 9) +# define LM_SOURCE_STATE_PREMULT 0 +# define LM_SOURCE_STATE_MULT 1 +# define LM_SOURCE_VERTEX_DIFFUSE 2 +# define LM_SOURCE_VERTEX_SPECULAR 3 +# define EMISSIVE_SOURCE_SHIFT 16 +# define AMBIENT_SOURCE_SHIFT 18 +# define DIFFUSE_SOURCE_SHIFT 20 +# define SPECULAR_SOURCE_SHIFT 22 +#define SE_TCL_MATERIAL_AMBIENT_RED 0x2220 +#define SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224 +#define SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228 +#define SE_TCL_MATERIAL_AMBIENT_ALPHA 0x222c +#define SE_TCL_MATERIAL_DIFFUSE_RED 0x2230 +#define SE_TCL_MATERIAL_DIFFUSE_GREEN 0x2234 +#define SE_TCL_MATERIAL_DIFFUSE_BLUE 0x2238 +#define SE_TCL_MATERIAL_DIFFUSE_ALPHA 0x223c +#define SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define SE_TCL_MATERIAL_EMMISSIVE_GREEN 0x2214 +#define SE_TCL_MATERIAL_EMMISSIVE_BLUE 0x2218 +#define SE_TCL_MATERIAL_EMMISSIVE_ALPHA 0x221c +#define SE_TCL_MATERIAL_SPECULAR_RED 0x2240 +#define SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244 +#define SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248 +#define SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c +#define SE_TCL_MATRIX_SELECT_0 0x225c +# define MODELVIEW_0_SHIFT 0 +# define MODELVIEW_1_SHIFT 4 +# define MODELVIEW_2_SHIFT 8 +# define MODELVIEW_3_SHIFT 12 +# define IT_MODELVIEW_0_SHIFT 16 +# define IT_MODELVIEW_1_SHIFT 20 +# define IT_MODELVIEW_2_SHIFT 24 +# define IT_MODELVIEW_3_SHIFT 28 +#define SE_TCL_MATRIX_SELECT_1 0x2260 +# define MODELPROJECT_0_SHIFT 0 +# define MODELPROJECT_1_SHIFT 4 +# define MODELPROJECT_2_SHIFT 8 +# define MODELPROJECT_3_SHIFT 12 +# define TEXMAT_0_SHIFT 16 +# define TEXMAT_1_SHIFT 20 +# define TEXMAT_2_SHIFT 24 +# define TEXMAT_3_SHIFT 28 + + +#define SE_TCL_OUTPUT_VTX_FMT 0x2254 +# define TCL_VTX_W0 (1 << 0) +# define TCL_VTX_FP_DIFFUSE (1 << 1) +# define TCL_VTX_FP_ALPHA (1 << 2) +# define TCL_VTX_PK_DIFFUSE (1 << 3) +# define TCL_VTX_FP_SPEC (1 << 4) +# define TCL_VTX_FP_FOG (1 << 5) +# define TCL_VTX_PK_SPEC (1 << 6) +# define TCL_VTX_ST0 (1 << 7) +# define TCL_VTX_ST1 (1 << 8) +# define TCL_VTX_Q1 (1 << 9) +# define TCL_VTX_ST2 (1 << 10) +# define TCL_VTX_Q2 (1 << 11) +# define TCL_VTX_ST3 (1 << 12) +# define TCL_VTX_Q3 (1 << 13) +# define TCL_VTX_Q0 (1 << 14) +# define TCL_VTX_WEIGHT_COUNT_SHIFT 15 +# define TCL_VTX_NORM0 (1 << 18) +# define TCL_VTX_XY1 (1 << 27) +# define TCL_VTX_Z1 (1 << 28) +# define TCL_VTX_W1 (1 << 29) +# define TCL_VTX_NORM1 (1 << 30) +# define TCL_VTX_Z0 (1 << 31) + +#define SE_TCL_OUTPUT_VTX_SEL 0x2258 +# define TCL_COMPUTE_XYZW (1 << 0) +# define TCL_COMPUTE_DIFFUSE (1 << 1) +# define TCL_COMPUTE_SPECULAR (1 << 2) +# define TCL_FORCE_NAN_IF_COLOR_NAN (1 << 3) +# define TCL_FORCE_INORDER_PROC (1 << 4) +# define TCL_TEX_INPUT_TEX_0 0 +# define TCL_TEX_INPUT_TEX_1 1 +# define TCL_TEX_INPUT_TEX_2 2 +# define TCL_TEX_INPUT_TEX_3 3 +# define TCL_TEX_COMPUTED_TEX_0 8 +# define TCL_TEX_COMPUTED_TEX_1 9 +# define TCL_TEX_COMPUTED_TEX_2 10 +# define TCL_TEX_COMPUTED_TEX_3 11 +# define TCL_TEX_0_OUTPUT_SHIFT 16 +# define TCL_TEX_1_OUTPUT_SHIFT 20 +# define TCL_TEX_2_OUTPUT_SHIFT 24 +# define TCL_TEX_3_OUTPUT_SHIFT 28 + +#define SE_TCL_PER_LIGHT_CTL_0 0x2270 +# define LIGHT_0_ENABLE (1 << 0) +# define LIGHT_0_ENABLE_AMBIENT (1 << 1) +# define LIGHT_0_ENABLE_SPECULAR (1 << 2) +# define LIGHT_0_IS_LOCAL (1 << 3) +# define LIGHT_0_IS_SPOT (1 << 4) +# define LIGHT_0_DUAL_CONE (1 << 5) +# define LIGHT_0_ENABLE_RANGE_ATTEN (1 << 6) +# define LIGHT_0_CONSTANT_RANGE_ATTEN (1 << 7) +# define LIGHT_0_SHIFT 0 +# define LIGHT_1_ENABLE (1 << 16) +# define LIGHT_1_ENABLE_AMBIENT (1 << 17) +# define LIGHT_1_ENABLE_SPECULAR (1 << 18) +# define LIGHT_1_IS_LOCAL (1 << 19) +# define LIGHT_1_IS_SPOT (1 << 20) +# define LIGHT_1_DUAL_CONE (1 << 21) +# define LIGHT_1_ENABLE_RANGE_ATTEN (1 << 22) +# define LIGHT_1_CONSTANT_RANGE_ATTEN (1 << 23) +# define LIGHT_1_SHIFT 16 +#define SE_TCL_PER_LIGHT_CTL_1 0x2274 +# define LIGHT_2_SHIFT 0 +# define LIGHT_3_SHIFT 16 +#define SE_TCL_PER_LIGHT_CTL_2 0x2278 +# define LIGHT_4_SHIFT 0 +# define LIGHT_5_SHIFT 16 +#define SE_TCL_PER_LIGHT_CTL_3 0x227c +# define LIGHT_6_SHIFT 0 +# define LIGHT_7_SHIFT 16 + +#define SE_TCL_SHININESS 0x2250 + +#define SE_TCL_TEXTURE_PROC_CTL 0x2268 +# define TEXGEN_TEXMAT_0_ENABLE (1 << 0) +# define TEXGEN_TEXMAT_1_ENABLE (1 << 1) +# define TEXGEN_TEXMAT_2_ENABLE (1 << 2) +# define TEXGEN_TEXMAT_3_ENABLE (1 << 3) +# define TEXMAT_0_ENABLE (1 << 4) +# define TEXMAT_1_ENABLE (1 << 5) +# define TEXMAT_2_ENABLE (1 << 6) +# define TEXMAT_3_ENABLE (1 << 7) +# define TEXGEN_INPUT_MASK 0xf +# define TEXGEN_INPUT_TEXCOORD_0 0 +# define TEXGEN_INPUT_TEXCOORD_1 1 +# define TEXGEN_INPUT_TEXCOORD_2 2 +# define TEXGEN_INPUT_TEXCOORD_3 3 +# define TEXGEN_INPUT_OBJ 4 +# define TEXGEN_INPUT_EYE 5 +# define TEXGEN_INPUT_EYE_NORMAL 6 +# define TEXGEN_INPUT_EYE_REFLECT 7 +# define TEXGEN_INPUT_EYE_NORMALIZED 8 +# define TEXGEN_0_INPUT_SHIFT 16 +# define TEXGEN_1_INPUT_SHIFT 20 +# define TEXGEN_2_INPUT_SHIFT 24 +# define TEXGEN_3_INPUT_SHIFT 28 + +#define SE_TCL_UCP_VERT_BLEND_CTL 0x2264 +# define UCP_IN_CLIP_SPACE (1 << 0) +# define UCP_IN_MODEL_SPACE (1 << 1) +# define UCP_ENABLE_0 (1 << 2) +# define UCP_ENABLE_1 (1 << 3) +# define UCP_ENABLE_2 (1 << 4) +# define UCP_ENABLE_3 (1 << 5) +# define UCP_ENABLE_4 (1 << 6) +# define UCP_ENABLE_5 (1 << 7) +# define TCL_FOG_MASK (3 << 8) +# define TCL_FOG_DISABLE (0 << 8) +# define TCL_FOG_EXP (1 << 8) +# define TCL_FOG_EXP2 (2 << 8) +# define TCL_FOG_LINEAR (3 << 8) +# define RNG_BASED_FOG (1 << 10) +# define LIGHT_TWOSIDE (1 << 11) +# define BLEND_OP_COUNT_MASK (7 << 12) +# define BLEND_OP_COUNT_SHIFT 12 +# define POSITION_BLEND_OP_ENABLE (1 << 16) +# define NORMAL_BLEND_OP_ENABLE (1 << 17) +# define VERTEX_BLEND_SRC_0_PRIMARY (1 << 18) +# define VERTEX_BLEND_SRC_0_SECONDARY (1 << 18) +# define VERTEX_BLEND_SRC_1_PRIMARY (1 << 19) +# define VERTEX_BLEND_SRC_1_SECONDARY (1 << 19) +# define VERTEX_BLEND_SRC_2_PRIMARY (1 << 20) +# define VERTEX_BLEND_SRC_2_SECONDARY (1 << 20) +# define VERTEX_BLEND_SRC_3_PRIMARY (1 << 21) +# define VERTEX_BLEND_SRC_3_SECONDARY (1 << 21) +# define VERTEX_BLEND_WGT_MINUS_ONE (1 << 22) +# define CULL_FRONT_IS_CW (0 << 28) +# define CULL_FRONT_IS_CCW (1 << 28) +# define CULL_FRONT (1 << 29) +# define CULL_BACK (1 << 30) +# define FORCE_W_TO_ONE (1 << 31) + +#define SE_VPORT_XSCALE 0x1d98 +#define SE_VPORT_XOFFSET 0x1d9c +#define SE_VPORT_YSCALE 0x1da0 +#define SE_VPORT_YOFFSET 0x1da4 +#define SE_VPORT_ZSCALE 0x1da8 +#define SE_VPORT_ZOFFSET 0x1dac +#define SE_ZBIAS_FACTOR 0x1db0 +#define SE_ZBIAS_CONSTANT 0x1db4 + +#define SE_VTX_FMT 0x2080 +# define SE_VTX_FMT_XY 0x00000000 +# define SE_VTX_FMT_W0 0x00000001 +# define SE_VTX_FMT_FPCOLOR 0x00000002 +# define SE_VTX_FMT_FPALPHA 0x00000004 +# define SE_VTX_FMT_PKCOLOR 0x00000008 +# define SE_VTX_FMT_FPSPEC 0x00000010 +# define SE_VTX_FMT_FPFOG 0x00000020 +# define SE_VTX_FMT_PKSPEC 0x00000040 +# define SE_VTX_FMT_ST0 0x00000080 +# define SE_VTX_FMT_ST1 0x00000100 +# define SE_VTX_FMT_Q1 0x00000200 +# define SE_VTX_FMT_ST2 0x00000400 +# define SE_VTX_FMT_Q2 0x00000800 +# define SE_VTX_FMT_ST3 0x00001000 +# define SE_VTX_FMT_Q3 0x00002000 +# define SE_VTX_FMT_Q0 0x00004000 +# define SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 +# define SE_VTX_FMT_N0 0x00040000 +# define SE_VTX_FMT_XY1 0x08000000 +# define SE_VTX_FMT_Z1 0x10000000 +# define SE_VTX_FMT_W1 0x20000000 +# define SE_VTX_FMT_N1 0x40000000 +# define SE_VTX_FMT_Z 0x80000000 + +#define SE_VF_CNTL 0x2084 +# define VF_PRIM_TYPE_POINT_LIST 1 +# define VF_PRIM_TYPE_LINE_LIST 2 +# define VF_PRIM_TYPE_LINE_STRIP 3 +# define VF_PRIM_TYPE_TRIANGLE_LIST 4 +# define VF_PRIM_TYPE_TRIANGLE_FAN 5 +# define VF_PRIM_TYPE_TRIANGLE_STRIP 6 +# define VF_PRIM_TYPE_TRIANGLE_FLAG 7 +# define VF_PRIM_TYPE_RECTANGLE_LIST 8 +# define VF_PRIM_TYPE_POINT_LIST_3 9 +# define VF_PRIM_TYPE_LINE_LIST_3 10 +# define VF_PRIM_TYPE_SPIRIT_LIST 11 +# define VF_PRIM_TYPE_LINE_LOOP 12 +# define VF_PRIM_TYPE_QUAD_LIST 13 +# define VF_PRIM_TYPE_QUAD_STRIP 14 +# define VF_PRIM_TYPE_POLYGON 15 +# define VF_PRIM_WALK_STATE (0<<4) +# define VF_PRIM_WALK_INDEX (1<<4) +# define VF_PRIM_WALK_LIST (2<<4) +# define VF_PRIM_WALK_DATA (3<<4) +# define VF_COLOR_ORDER_RGBA (1<<6) +# define VF_RADEON_MODE (1<<8) +# define VF_TCL_OUTPUT_CTL_ENA (1<<9) +# define VF_PROG_STREAM_ENA (1<<10) +# define VF_INDEX_SIZE_SHIFT 11 +# define VF_NUM_VERTICES_SHIFT 16 + +#define SE_PORT_DATA0 0x2000 + +#define R200_SE_VAP_CNTL 0x2080 +# define R200_VAP_TCL_ENABLE 0x00000001 +# define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 +# define R200_VAP_FORCE_W_TO_ONE 0x00010000 +# define R200_VAP_D3D_TEX_DEFAULT 0x00020000 +# define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 +# define R200_VAP_VF_MAX_VTX_NUM (9 << 18) +# define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 +#define R200_VF_MAX_VTX_INDX 0x210c +#define R200_VF_MIN_VTX_INDX 0x2110 +#define R200_SE_VTE_CNTL 0x20b0 +# define R200_VPORT_X_SCALE_ENA 0x00000001 +# define R200_VPORT_X_OFFSET_ENA 0x00000002 +# define R200_VPORT_Y_SCALE_ENA 0x00000004 +# define R200_VPORT_Y_OFFSET_ENA 0x00000008 +# define R200_VPORT_Z_SCALE_ENA 0x00000010 +# define R200_VPORT_Z_OFFSET_ENA 0x00000020 +# define R200_VTX_XY_FMT 0x00000100 +# define R200_VTX_Z_FMT 0x00000200 +# define R200_VTX_W0_FMT 0x00000400 +# define R200_VTX_W0_NORMALIZE 0x00000800 +# define R200_VTX_ST_DENORMALIZED 0x00001000 +#define R200_SE_VAP_CNTL_STATUS 0x2140 +# define R200_VC_NO_SWAP (0 << 0) +# define R200_VC_16BIT_SWAP (1 << 0) +# define R200_VC_32BIT_SWAP (2 << 0) +# define R200_TCL_BYPASS (1 << 8) +#define R200_PP_TXFILTER_0 0x2c00 +#define R200_PP_TXFILTER_1 0x2c20 +# define R200_MAG_FILTER_NEAREST (0 << 0) +# define R200_MAG_FILTER_LINEAR (1 << 0) +# define R200_MAG_FILTER_MASK (1 << 0) +# define R200_MIN_FILTER_NEAREST (0 << 1) +# define R200_MIN_FILTER_LINEAR (1 << 1) +# define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) +# define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) +# define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) +# define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) +# define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) +# define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) +# define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) +# define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) +# define R200_MIN_FILTER_MASK (15 << 1) +# define R200_MAX_ANISO_1_TO_1 (0 << 5) +# define R200_MAX_ANISO_2_TO_1 (1 << 5) +# define R200_MAX_ANISO_4_TO_1 (2 << 5) +# define R200_MAX_ANISO_8_TO_1 (3 << 5) +# define R200_MAX_ANISO_16_TO_1 (4 << 5) +# define R200_MAX_ANISO_MASK (7 << 5) +# define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) +# define R200_MAX_MIP_LEVEL_SHIFT 16 +# define R200_YUV_TO_RGB (1 << 20) +# define R200_YUV_TEMPERATURE_COOL (0 << 21) +# define R200_YUV_TEMPERATURE_HOT (1 << 21) +# define R200_YUV_TEMPERATURE_MASK (1 << 21) +# define R200_WRAPEN_S (1 << 22) +# define R200_CLAMP_S_WRAP (0 << 23) +# define R200_CLAMP_S_MIRROR (1 << 23) +# define R200_CLAMP_S_CLAMP_LAST (2 << 23) +# define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) +# define R200_CLAMP_S_CLAMP_BORDER (4 << 23) +# define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) +# define R200_CLAMP_S_CLAMP_GL (6 << 23) +# define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) +# define R200_CLAMP_S_MASK (7 << 23) +# define R200_WRAPEN_T (1 << 26) +# define R200_CLAMP_T_WRAP (0 << 27) +# define R200_CLAMP_T_MIRROR (1 << 27) +# define R200_CLAMP_T_CLAMP_LAST (2 << 27) +# define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) +# define R200_CLAMP_T_CLAMP_BORDER (4 << 27) +# define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) +# define R200_CLAMP_T_CLAMP_GL (6 << 27) +# define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) +# define R200_CLAMP_T_MASK (7 << 27) +# define R200_KILL_LT_ZERO (1 << 30) +# define R200_BORDER_MODE_OGL (0 << 31) +# define R200_BORDER_MODE_D3D (1 << 31) +#define R200_PP_TXFORMAT_0 0x2c04 +#define R200_PP_TXFORMAT_1 0x2c24 +# define R200_TXFORMAT_I8 (0 << 0) +# define R200_TXFORMAT_AI88 (1 << 0) +# define R200_TXFORMAT_RGB332 (2 << 0) +# define R200_TXFORMAT_ARGB1555 (3 << 0) +# define R200_TXFORMAT_RGB565 (4 << 0) +# define R200_TXFORMAT_ARGB4444 (5 << 0) +# define R200_TXFORMAT_ARGB8888 (6 << 0) +# define R200_TXFORMAT_RGBA8888 (7 << 0) +# define R200_TXFORMAT_Y8 (8 << 0) +# define R200_TXFORMAT_AVYU (9 << 0) +# define R200_TXFORMAT_VYUY422 (10 << 0) +# define R200_TXFORMAT_YVYU422 (11 << 0) +# define R200_TXFORMAT_DXT1 (12 << 0) +# define R200_TXFORMAT_DXT23 (14 << 0) +# define R200_TXFORMAT_DXT45 (15 << 0) +# define R200_TXFORMAT_FORMAT_MASK (31 << 0) +# define R200_TXFORMAT_FORMAT_SHIFT 0 +# define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) +# define R200_TXFORMAT_NON_POWER2 (1 << 7) +# define R200_TXFORMAT_WIDTH_MASK (15 << 8) +# define R200_TXFORMAT_WIDTH_SHIFT 8 +# define R200_TXFORMAT_HEIGHT_MASK (15 << 12) +# define R200_TXFORMAT_HEIGHT_SHIFT 12 +# define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */ +# define R200_TXFORMAT_F5_WIDTH_SHIFT 16 +# define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) +# define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 +# define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) +# define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) +# define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) +# define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) +# define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) +# define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) +# define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) +# define R200_TXFORMAT_ST_ROUTE_SHIFT 24 +# define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) +# define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) +# define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) +#define R200_PP_TXFORMAT_X_0 0x2c08 +#define R200_PP_TXFORMAT_X_1 0x2c28 +#define R200_DEPTH_LOG2_MASK (0xf << 0) +#define R200_DEPTH_LOG2_SHIFT 0 +#define R200_VOLUME_FILTER_SHIFT 4 +#define R200_VOLUME_FILTER_MASK (1 << 4) +#define R200_VOLUME_FILTER_NEAREST (0 << 4) +#define R200_VOLUME_FILTER_LINEAR (1 << 4) +#define R200_WRAPEN_Q (1 << 8) +#define R200_CLAMP_Q_WRAP (0 << 9) +#define R200_CLAMP_Q_MIRROR (1 << 9) +#define R200_CLAMP_Q_CLAMP_LAST (2 << 9) +#define R200_CLAMP_Q_MIRROR_CLAMP_LAST (3 << 9) +#define R200_CLAMP_Q_CLAMP_BORDER (4 << 9) +#define R200_CLAMP_Q_MIRROR_CLAMP_BORDER (5 << 9) +#define R200_CLAMP_Q_CLAMP_GL (6 << 9) +#define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9) +#define R200_CLAMP_Q_MASK (7 << 9) +#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) +#define R200_MIN_MIP_LEVEL_SHIFT 12 +#define R200_TEXCOORD_NONPROJ (0 << 16) +#define R200_TEXCOORD_CUBIC_ENV (1 << 16) +#define R200_TEXCOORD_VOLUME (2 << 16) +#define R200_TEXCOORD_PROJ (3 << 16) +#define R200_TEXCOORD_DEPTH (4 << 16) +#define R200_TEXCOORD_1D_PROJ (5 << 16) +#define R200_TEXCOORD_1D (6 << 16) +#define R200_TEXCOORD_ZERO (7 << 16) +#define R200_TEXCOORD_MASK (7 << 16) +#define R200_LOD_BIAS_MASK (0xfff80000) +#define R200_LOD_BIAS_SHIFT 19 +#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ +#define R200_PP_TXSIZE_1 0x2c2c +#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ +#define R200_PP_TXPITCH_1 0x2c30 +#define R200_PP_BORDER_COLOR_0 0x2c14 +#define R200_PP_BORDER_COLOR_1 0x2c34 +#define R200_PP_TXOFFSET_0 0x2d00 +#define R200_PP_TXOFFSET_1 0x2d18 +# define R200_TXO_ENDIAN_NO_SWAP (0 << 0) +# define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) +# define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) +# define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) +# define R200_TXO_OFFSET_MASK 0xffffffe0 +# define R200_TXO_OFFSET_SHIFT 5 + + +#define R200_PP_TFACTOR_0 0x2ee0 +#define R200_PP_TFACTOR_1 0x2ee4 +#define R200_PP_TFACTOR_2 0x2ee8 +#define R200_PP_TFACTOR_3 0x2eec +#define R200_PP_TFACTOR_4 0x2ef0 +#define R200_PP_TFACTOR_5 0x2ef4 + +#define R200_PP_TXCBLEND_0 0x2f00 +#define R200_PP_TXCBLEND_1 0x2f10 +# define R200_TXC_ARG_A_ZERO (0) +# define R200_TXC_ARG_A_CURRENT_COLOR (2) +# define R200_TXC_ARG_A_CURRENT_ALPHA (3) +# define R200_TXC_ARG_A_DIFFUSE_COLOR (4) +# define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) +# define R200_TXC_ARG_A_SPECULAR_COLOR (6) +# define R200_TXC_ARG_A_SPECULAR_ALPHA (7) +# define R200_TXC_ARG_A_TFACTOR_COLOR (8) +# define R200_TXC_ARG_A_TFACTOR_ALPHA (9) +# define R200_TXC_ARG_A_R0_COLOR (10) +# define R200_TXC_ARG_A_R0_ALPHA (11) +# define R200_TXC_ARG_A_R1_COLOR (12) +# define R200_TXC_ARG_A_R1_ALPHA (13) +# define R200_TXC_ARG_A_R2_COLOR (14) +# define R200_TXC_ARG_A_R2_ALPHA (15) +# define R200_TXC_ARG_A_R3_COLOR (16) +# define R200_TXC_ARG_A_R3_ALPHA (17) +# define R200_TXC_ARG_A_R4_COLOR (18) +# define R200_TXC_ARG_A_R4_ALPHA (19) +# define R200_TXC_ARG_A_R5_COLOR (20) +# define R200_TXC_ARG_A_R5_ALPHA (21) +# define R200_TXC_ARG_A_TFACTOR1_COLOR (26) +# define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) +# define R200_TXC_ARG_A_MASK (31 << 0) +# define R200_TXC_ARG_A_SHIFT 0 +# define R200_TXC_ARG_B_ZERO (0 << 5) +# define R200_TXC_ARG_B_CURRENT_COLOR (2 << 5) +# define R200_TXC_ARG_B_CURRENT_ALPHA (3 << 5) +# define R200_TXC_ARG_B_DIFFUSE_COLOR (4 << 5) +# define R200_TXC_ARG_B_DIFFUSE_ALPHA (5 << 5) +# define R200_TXC_ARG_B_SPECULAR_COLOR (6 << 5) +# define R200_TXC_ARG_B_SPECULAR_ALPHA (7 << 5) +# define R200_TXC_ARG_B_TFACTOR_COLOR (8 << 5) +# define R200_TXC_ARG_B_TFACTOR_ALPHA (9 << 5) +# define R200_TXC_ARG_B_R0_COLOR (10 << 5) +# define R200_TXC_ARG_B_R0_ALPHA (11 << 5) +# define R200_TXC_ARG_B_R1_COLOR (12 << 5) +# define R200_TXC_ARG_B_R1_ALPHA (13 << 5) +# define R200_TXC_ARG_B_R2_COLOR (14 << 5) +# define R200_TXC_ARG_B_R2_ALPHA (15 << 5) +# define R200_TXC_ARG_B_R3_COLOR (16 << 5) +# define R200_TXC_ARG_B_R3_ALPHA (17 << 5) +# define R200_TXC_ARG_B_R4_COLOR (18 << 5) +# define R200_TXC_ARG_B_R4_ALPHA (19 << 5) +# define R200_TXC_ARG_B_R5_COLOR (20 << 5) +# define R200_TXC_ARG_B_R5_ALPHA (21 << 5) +# define R200_TXC_ARG_B_TFACTOR1_COLOR (26 << 5) +# define R200_TXC_ARG_B_TFACTOR1_ALPHA (27 << 5) +# define R200_TXC_ARG_B_MASK (31 << 5) +# define R200_TXC_ARG_B_SHIFT 5 +# define R200_TXC_ARG_C_ZERO (0 << 10) +# define R200_TXC_ARG_C_CURRENT_COLOR (2 << 10) +# define R200_TXC_ARG_C_CURRENT_ALPHA (3 << 10) +# define R200_TXC_ARG_C_DIFFUSE_COLOR (4 << 10) +# define R200_TXC_ARG_C_DIFFUSE_ALPHA (5 << 10) +# define R200_TXC_ARG_C_SPECULAR_COLOR (6 << 10) +# define R200_TXC_ARG_C_SPECULAR_ALPHA (7 << 10) +# define R200_TXC_ARG_C_TFACTOR_COLOR (8 << 10) +# define R200_TXC_ARG_C_TFACTOR_ALPHA (9 << 10) +# define R200_TXC_ARG_C_R0_COLOR (10 << 10) +# define R200_TXC_ARG_C_R0_ALPHA (11 << 10) +# define R200_TXC_ARG_C_R1_COLOR (12 << 10) +# define R200_TXC_ARG_C_R1_ALPHA (13 << 10) +# define R200_TXC_ARG_C_R2_COLOR (14 << 10) +# define R200_TXC_ARG_C_R2_ALPHA (15 << 10) +# define R200_TXC_ARG_C_R3_COLOR (16 << 10) +# define R200_TXC_ARG_C_R3_ALPHA (17 << 10) +# define R200_TXC_ARG_C_R4_COLOR (18 << 10) +# define R200_TXC_ARG_C_R4_ALPHA (19 << 10) +# define R200_TXC_ARG_C_R5_COLOR (20 << 10) +# define R200_TXC_ARG_C_R5_ALPHA (21 << 10) +# define R200_TXC_ARG_C_TFACTOR1_COLOR (26 << 10) +# define R200_TXC_ARG_C_TFACTOR1_ALPHA (27 << 10) +# define R200_TXC_ARG_C_MASK (31 << 10) +# define R200_TXC_ARG_C_SHIFT 10 +# define R200_TXC_COMP_ARG_A (1 << 16) +# define R200_TXC_COMP_ARG_A_SHIFT (16) +# define R200_TXC_BIAS_ARG_A (1 << 17) +# define R200_TXC_SCALE_ARG_A (1 << 18) +# define R200_TXC_NEG_ARG_A (1 << 19) +# define R200_TXC_COMP_ARG_B (1 << 20) +# define R200_TXC_COMP_ARG_B_SHIFT (20) +# define R200_TXC_BIAS_ARG_B (1 << 21) +# define R200_TXC_SCALE_ARG_B (1 << 22) +# define R200_TXC_NEG_ARG_B (1 << 23) +# define R200_TXC_COMP_ARG_C (1 << 24) +# define R200_TXC_COMP_ARG_C_SHIFT (24) +# define R200_TXC_BIAS_ARG_C (1 << 25) +# define R200_TXC_SCALE_ARG_C (1 << 26) +# define R200_TXC_NEG_ARG_C (1 << 27) +# define R200_TXC_OP_MADD (0 << 28) +# define R200_TXC_OP_CND0 (2 << 28) +# define R200_TXC_OP_LERP (3 << 28) +# define R200_TXC_OP_DOT3 (4 << 28) +# define R200_TXC_OP_DOT4 (5 << 28) +# define R200_TXC_OP_CONDITIONAL (6 << 28) +# define R200_TXC_OP_DOT2_ADD (7 << 28) +# define R200_TXC_OP_MASK (7 << 28) +#define R200_PP_TXCBLEND2_0 0x2f04 +#define R200_PP_TXCBLEND2_1 0x2f14 +# define R200_TXC_TFACTOR_SEL_SHIFT 0 +# define R200_TXC_TFACTOR_SEL_MASK 0x7 +# define R200_TXC_TFACTOR1_SEL_SHIFT 4 +# define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) +# define R200_TXC_SCALE_SHIFT 8 +# define R200_TXC_SCALE_MASK (7 << 8) +# define R200_TXC_SCALE_1X (0 << 8) +# define R200_TXC_SCALE_2X (1 << 8) +# define R200_TXC_SCALE_4X (2 << 8) +# define R200_TXC_SCALE_8X (3 << 8) +# define R200_TXC_SCALE_INV2 (5 << 8) +# define R200_TXC_SCALE_INV4 (6 << 8) +# define R200_TXC_SCALE_INV8 (7 << 8) +# define R200_TXC_CLAMP_SHIFT 12 +# define R200_TXC_CLAMP_MASK (3 << 12) +# define R200_TXC_CLAMP_WRAP (0 << 12) +# define R200_TXC_CLAMP_0_1 (1 << 12) +# define R200_TXC_CLAMP_8_8 (2 << 12) +# define R200_TXC_OUTPUT_REG_MASK (7 << 16) +# define R200_TXC_OUTPUT_REG_NONE (0 << 16) +# define R200_TXC_OUTPUT_REG_R0 (1 << 16) +# define R200_TXC_OUTPUT_REG_R1 (2 << 16) +# define R200_TXC_OUTPUT_REG_R2 (3 << 16) +# define R200_TXC_OUTPUT_REG_R3 (4 << 16) +# define R200_TXC_OUTPUT_REG_R4 (5 << 16) +# define R200_TXC_OUTPUT_REG_R5 (6 << 16) +# define R200_TXC_OUTPUT_MASK_MASK (7 << 20) +# define R200_TXC_OUTPUT_MASK_RGB (0 << 20) +# define R200_TXC_OUTPUT_MASK_RG (1 << 20) +# define R200_TXC_OUTPUT_MASK_RB (2 << 20) +# define R200_TXC_OUTPUT_MASK_R (3 << 20) +# define R200_TXC_OUTPUT_MASK_GB (4 << 20) +# define R200_TXC_OUTPUT_MASK_G (5 << 20) +# define R200_TXC_OUTPUT_MASK_B (6 << 20) +# define R200_TXC_OUTPUT_MASK_NONE (7 << 20) +# define R200_TXC_REPL_NORMAL 0 +# define R200_TXC_REPL_RED 1 +# define R200_TXC_REPL_GREEN 2 +# define R200_TXC_REPL_BLUE 3 +# define R200_TXC_REPL_ARG_A_SHIFT 26 +# define R200_TXC_REPL_ARG_A_MASK (3 << 26) +# define R200_TXC_REPL_ARG_B_SHIFT 28 +# define R200_TXC_REPL_ARG_B_MASK (3 << 28) +# define R200_TXC_REPL_ARG_C_SHIFT 30 +# define R200_TXC_REPL_ARG_C_MASK (3 << 30) +#define R200_PP_TXABLEND_0 0x2f08 +#define R200_PP_TXABLEND_1 0x2f18 +# define R200_TXA_ARG_A_ZERO (0) +# define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ +# define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ +# define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) +# define R200_TXA_ARG_A_DIFFUSE_BLUE (5) +# define R200_TXA_ARG_A_SPECULAR_ALPHA (6) +# define R200_TXA_ARG_A_SPECULAR_BLUE (7) +# define R200_TXA_ARG_A_TFACTOR_ALPHA (8) +# define R200_TXA_ARG_A_TFACTOR_BLUE (9) +# define R200_TXA_ARG_A_R0_ALPHA (10) +# define R200_TXA_ARG_A_R0_BLUE (11) +# define R200_TXA_ARG_A_R1_ALPHA (12) +# define R200_TXA_ARG_A_R1_BLUE (13) +# define R200_TXA_ARG_A_R2_ALPHA (14) +# define R200_TXA_ARG_A_R2_BLUE (15) +# define R200_TXA_ARG_A_R3_ALPHA (16) +# define R200_TXA_ARG_A_R3_BLUE (17) +# define R200_TXA_ARG_A_R4_ALPHA (18) +# define R200_TXA_ARG_A_R4_BLUE (19) +# define R200_TXA_ARG_A_R5_ALPHA (20) +# define R200_TXA_ARG_A_R5_BLUE (21) +# define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) +# define R200_TXA_ARG_A_TFACTOR1_BLUE (27) +# define R200_TXA_ARG_A_MASK (31 << 0) +# define R200_TXA_ARG_A_SHIFT 0 +# define R200_TXA_ARG_B_ZERO (0 << 5) +# define R200_TXA_ARG_B_CURRENT_ALPHA (2 << 5) /* guess */ +# define R200_TXA_ARG_B_CURRENT_BLUE (3 << 5) /* guess */ +# define R200_TXA_ARG_B_DIFFUSE_ALPHA (4 << 5) +# define R200_TXA_ARG_B_DIFFUSE_BLUE (5 << 5) +# define R200_TXA_ARG_B_SPECULAR_ALPHA (6 << 5) +# define R200_TXA_ARG_B_SPECULAR_BLUE (7 << 5) +# define R200_TXA_ARG_B_TFACTOR_ALPHA (8 << 5) +# define R200_TXA_ARG_B_TFACTOR_BLUE (9 << 5) +# define R200_TXA_ARG_B_R0_ALPHA (10 << 5) +# define R200_TXA_ARG_B_R0_BLUE (11 << 5) +# define R200_TXA_ARG_B_R1_ALPHA (12 << 5) +# define R200_TXA_ARG_B_R1_BLUE (13 << 5) +# define R200_TXA_ARG_B_R2_ALPHA (14 << 5) +# define R200_TXA_ARG_B_R2_BLUE (15 << 5) +# define R200_TXA_ARG_B_R3_ALPHA (16 << 5) +# define R200_TXA_ARG_B_R3_BLUE (17 << 5) +# define R200_TXA_ARG_B_R4_ALPHA (18 << 5) +# define R200_TXA_ARG_B_R4_BLUE (19 << 5) +# define R200_TXA_ARG_B_R5_ALPHA (20 << 5) +# define R200_TXA_ARG_B_R5_BLUE (21 << 5) +# define R200_TXA_ARG_B_TFACTOR1_ALPHA (26 << 5) +# define R200_TXA_ARG_B_TFACTOR1_BLUE (27 << 5) +# define R200_TXA_ARG_B_MASK (31 << 5) +# define R200_TXA_ARG_B_SHIFT 5 +# define R200_TXA_ARG_C_ZERO (0 << 10) +# define R200_TXA_ARG_C_CURRENT_ALPHA (2 << 10) /* guess */ +# define R200_TXA_ARG_C_CURRENT_BLUE (3 << 10) /* guess */ +# define R200_TXA_ARG_C_DIFFUSE_ALPHA (4 << 10) +# define R200_TXA_ARG_C_DIFFUSE_BLUE (5 << 10) +# define R200_TXA_ARG_C_SPECULAR_ALPHA (6 << 10) +# define R200_TXA_ARG_C_SPECULAR_BLUE (7 << 10) +# define R200_TXA_ARG_C_TFACTOR_ALPHA (8 << 10) +# define R200_TXA_ARG_C_TFACTOR_BLUE (9 << 10) +# define R200_TXA_ARG_C_R0_ALPHA (10 << 10) +# define R200_TXA_ARG_C_R0_BLUE (11 << 10) +# define R200_TXA_ARG_C_R1_ALPHA (12 << 10) +# define R200_TXA_ARG_C_R1_BLUE (13 << 10) +# define R200_TXA_ARG_C_R2_ALPHA (14 << 10) +# define R200_TXA_ARG_C_R2_BLUE (15 << 10) +# define R200_TXA_ARG_C_R3_ALPHA (16 << 10) +# define R200_TXA_ARG_C_R3_BLUE (17 << 10) +# define R200_TXA_ARG_C_R4_ALPHA (18 << 10) +# define R200_TXA_ARG_C_R4_BLUE (19 << 10) +# define R200_TXA_ARG_C_R5_ALPHA (20 << 10) +# define R200_TXA_ARG_C_R5_BLUE (21 << 10) +# define R200_TXA_ARG_C_TFACTOR1_ALPHA (26 << 10) +# define R200_TXA_ARG_C_TFACTOR1_BLUE (27 << 10) +# define R200_TXA_ARG_C_MASK (31 << 10) +# define R200_TXA_ARG_C_SHIFT 10 +# define R200_TXA_COMP_ARG_A (1 << 16) +# define R200_TXA_COMP_ARG_A_SHIFT (16) +# define R200_TXA_BIAS_ARG_A (1 << 17) +# define R200_TXA_SCALE_ARG_A (1 << 18) +# define R200_TXA_NEG_ARG_A (1 << 19) +# define R200_TXA_COMP_ARG_B (1 << 20) +# define R200_TXA_COMP_ARG_B_SHIFT (20) +# define R200_TXA_BIAS_ARG_B (1 << 21) +# define R200_TXA_SCALE_ARG_B (1 << 22) +# define R200_TXA_NEG_ARG_B (1 << 23) +# define R200_TXA_COMP_ARG_C (1 << 24) +# define R200_TXA_COMP_ARG_C_SHIFT (24) +# define R200_TXA_BIAS_ARG_C (1 << 25) +# define R200_TXA_SCALE_ARG_C (1 << 26) +# define R200_TXA_NEG_ARG_C (1 << 27) +# define R200_TXA_OP_MADD (0 << 28) +# define R200_TXA_OP_CND0 (2 << 28) +# define R200_TXA_OP_LERP (3 << 28) +# define R200_TXA_OP_CONDITIONAL (6 << 28) +# define R200_TXA_OP_MASK (7 << 28) +#define R200_PP_TXABLEND2_0 0x2f0c +#define R200_PP_TXABLEND2_1 0x2f1c +# define R200_TXA_TFACTOR_SEL_SHIFT 0 +# define R200_TXA_TFACTOR_SEL_MASK 0x7 +# define R200_TXA_TFACTOR1_SEL_SHIFT 4 +# define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) +# define R200_TXA_SCALE_SHIFT 8 +# define R200_TXA_SCALE_MASK (7 << 8) +# define R200_TXA_SCALE_1X (0 << 8) +# define R200_TXA_SCALE_2X (1 << 8) +# define R200_TXA_SCALE_4X (2 << 8) +# define R200_TXA_SCALE_8X (3 << 8) +# define R200_TXA_SCALE_INV2 (5 << 8) +# define R200_TXA_SCALE_INV4 (6 << 8) +# define R200_TXA_SCALE_INV8 (7 << 8) +# define R200_TXA_CLAMP_SHIFT 12 +# define R200_TXA_CLAMP_MASK (3 << 12) +# define R200_TXA_CLAMP_WRAP (0 << 12) +# define R200_TXA_CLAMP_0_1 (1 << 12) +# define R200_TXA_CLAMP_8_8 (2 << 12) +# define R200_TXA_OUTPUT_REG_MASK (7 << 16) +# define R200_TXA_OUTPUT_REG_NONE (0 << 16) +# define R200_TXA_OUTPUT_REG_R0 (1 << 16) +# define R200_TXA_OUTPUT_REG_R1 (2 << 16) +# define R200_TXA_OUTPUT_REG_R2 (3 << 16) +# define R200_TXA_OUTPUT_REG_R3 (4 << 16) +# define R200_TXA_OUTPUT_REG_R4 (5 << 16) +# define R200_TXA_OUTPUT_REG_R5 (6 << 16) +# define R200_TXA_DOT_ALPHA (1 << 20) +# define R200_TXA_REPL_NORMAL 0 +# define R200_TXA_REPL_RED 1 +# define R200_TXA_REPL_GREEN 2 +# define R200_TXA_REPL_ARG_A_SHIFT 26 +# define R200_TXA_REPL_ARG_A_MASK (3 << 26) +# define R200_TXA_REPL_ARG_B_SHIFT 28 +# define R200_TXA_REPL_ARG_B_MASK (3 << 28) +# define R200_TXA_REPL_ARG_C_SHIFT 30 +# define R200_TXA_REPL_ARG_C_MASK (3 << 30) +#define R200_RB3D_BLENDCOLOR 0x3218 /* ARGB 8888 */ +#define R200_RB3D_ABLENDCNTL 0x321C /* see BLENDCNTL */ +#define R200_RB3D_CBLENDCNTL 0x3220 /* see BLENDCNTL */ + +#define R200_SE_VTX_FMT_0 0x2088 +# define R200_VTX_XY 0 /* always have xy */ +# define R200_VTX_Z0 (1<<0) +# define R200_VTX_W0 (1<<1) +# define R200_VTX_WEIGHT_COUNT_SHIFT (2) +# define R200_VTX_PV_MATRIX_SEL (1<<5) +# define R200_VTX_N0 (1<<6) +# define R200_VTX_POINT_SIZE (1<<7) +# define R200_VTX_DISCRETE_FOG (1<<8) +# define R200_VTX_SHININESS_0 (1<<9) +# define R200_VTX_SHININESS_1 (1<<10) +# define R200_VTX_COLOR_NOT_PRESENT 0 +# define R200_VTX_PK_RGBA 1 +# define R200_VTX_FP_RGB 2 +# define R200_VTX_FP_RGBA 3 +# define R200_VTX_COLOR_MASK 3 +# define R200_VTX_COLOR_0_SHIFT 11 +# define R200_VTX_COLOR_1_SHIFT 13 +# define R200_VTX_COLOR_2_SHIFT 15 +# define R200_VTX_COLOR_3_SHIFT 17 +# define R200_VTX_COLOR_4_SHIFT 19 +# define R200_VTX_COLOR_5_SHIFT 21 +# define R200_VTX_COLOR_6_SHIFT 23 +# define R200_VTX_COLOR_7_SHIFT 25 +# define R200_VTX_XY1 (1<<28) +# define R200_VTX_Z1 (1<<29) +# define R200_VTX_W1 (1<<30) +# define R200_VTX_N1 (1<<31) +#define R200_SE_VTX_FMT_1 0x208c +# define R200_VTX_TEX0_COMP_CNT_SHIFT 0 +# define R200_VTX_TEX1_COMP_CNT_SHIFT 3 +# define R200_VTX_TEX2_COMP_CNT_SHIFT 6 +# define R200_VTX_TEX3_COMP_CNT_SHIFT 9 +# define R200_VTX_TEX4_COMP_CNT_SHIFT 12 +# define R200_VTX_TEX5_COMP_CNT_SHIFT 15 + +#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 +#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 +#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 +# define R200_OUTPUT_XYZW (1<<0) +# define R200_OUTPUT_COLOR_0 (1<<8) +# define R200_OUTPUT_COLOR_1 (1<<9) +# define R200_OUTPUT_TEX_0 (1<<16) +# define R200_OUTPUT_TEX_1 (1<<17) +# define R200_OUTPUT_TEX_2 (1<<18) +# define R200_OUTPUT_TEX_3 (1<<19) +# define R200_OUTPUT_TEX_4 (1<<20) +# define R200_OUTPUT_TEX_5 (1<<21) +# define R200_OUTPUT_TEX_MASK (0x3f<<16) +# define R200_OUTPUT_DISCRETE_FOG (1<<24) +# define R200_OUTPUT_PT_SIZE (1<<25) +# define R200_FORCE_INORDER_PROC (1<<31) +#define R200_PP_CNTL_X 0x2cc4 +#define R200_PP_TXMULTI_CTL_0 0x2c1c +#define R200_SE_VTX_STATE_CNTL 0x2180 +# define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16) + + + /* R300 3D registers */ +#define R300_MC_INIT_MISC_LAT_TIMER 0x180 +# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0 +# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4 +# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8 +# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12 +# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16 +# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20 +# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24 +# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28 + + +#define R300_MC_INIT_GFX_LAT_TIMER 0x154 +# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0 +# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4 +# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8 +# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12 +# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16 +# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20 +# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24 +# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28 + +/* +This file contains registers and constants for the R300. They have been +found mostly by examining command buffers captured using glxtest, as well +as by extrapolating some known registers and constants from the R200. + +I am fairly certain that they are correct unless stated otherwise in comments. +*/ + +#define R300_SE_VPORT_XSCALE 0x1D98 +#define R300_SE_VPORT_XOFFSET 0x1D9C +#define R300_SE_VPORT_YSCALE 0x1DA0 +#define R300_SE_VPORT_YOFFSET 0x1DA4 +#define R300_SE_VPORT_ZSCALE 0x1DA8 +#define R300_SE_VPORT_ZOFFSET 0x1DAC + +/* BEGIN: Wild guesses */ +#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 +# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1) +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */ +# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */ + +#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 +/* END */ + +#define R300_SE_VTE_CNTL 0x20b0 +# define R300_VPORT_X_SCALE_ENA 0x00000001 +# define R300_VPORT_X_OFFSET_ENA 0x00000002 +# define R300_VPORT_Y_SCALE_ENA 0x00000004 +# define R300_VPORT_Y_OFFSET_ENA 0x00000008 +# define R300_VPORT_Z_SCALE_ENA 0x00000010 +# define R300_VPORT_Z_OFFSET_ENA 0x00000020 +# define R300_VTX_XY_FMT 0x00000100 +# define R300_VTX_Z_FMT 0x00000200 +# define R300_VTX_W0_FMT 0x00000400 +# define R300_VTX_W0_NORMALIZE 0x00000800 +# define R300_VTX_ST_DENORMALIZED 0x00001000 + +/* BEGIN: Vertex data assembly - lots of uncertainties */ +/* gap */ +/* Where do we get our vertex data? +// +// Vertex data either comes either from immediate mode registers or from +// vertex arrays. +// There appears to be no mixed mode (though we can force the pitch of +// vertex arrays to 0, effectively reusing the same element over and over +// again). +// +// Immediate mode is controlled by the INPUT_CNTL registers. I am not sure +// if these registers influence vertex array processing. +// +// Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3. +// +// In both cases, vertex attributes are then passed through INPUT_ROUTE. + +// Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data +// into the vertex processor's input registers. +// The first word routes the first input, the second word the second, etc. +// The corresponding input is routed into the register with the given index. +// The list is ended by a word with INPUT_ROUTE_END set. +// +// Always set COMPONENTS_4 in immediate mode. */ + +#define R300_VAP_INPUT_ROUTE_0_0 0x2150 +# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0) +# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0) +# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0) +# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0) +# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */ +# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8 +# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */ +# define R300_VAP_INPUT_ROUTE_END (1 << 13) +# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */ +# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */ +#define R300_VAP_INPUT_ROUTE_0_1 0x2154 +#define R300_VAP_INPUT_ROUTE_0_2 0x2158 +#define R300_VAP_INPUT_ROUTE_0_3 0x215C +#define R300_VAP_INPUT_ROUTE_0_4 0x2160 +#define R300_VAP_INPUT_ROUTE_0_5 0x2164 +#define R300_VAP_INPUT_ROUTE_0_6 0x2168 +#define R300_VAP_INPUT_ROUTE_0_7 0x216C + +/* gap */ +/* Notes: +// - always set up to produce at least two attributes: +// if vertex program uses only position, fglrx will set normal, too +// - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal */ +#define R300_VAP_INPUT_CNTL_0 0x2180 +# define R300_INPUT_CNTL_0_COLOR 0x00000001 +#define R300_VAP_INPUT_CNTL_1 0x2184 +# define R300_INPUT_CNTL_POS 0x00000001 +# define R300_INPUT_CNTL_NORMAL 0x00000002 +# define R300_INPUT_CNTL_COLOR 0x00000004 +# define R300_INPUT_CNTL_TC0 0x00000400 +# define R300_INPUT_CNTL_TC1 0x00000800 +# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */ +# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */ +# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */ +# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */ +# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */ +# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */ + +/* gap */ +/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0 +// are set to a swizzling bit pattern, other words are 0. +// +// In immediate mode, the pattern is always set to xyzw. In vertex array +// mode, the swizzling pattern is e.g. used to set zw components in texture +// coordinates with only tweo components. */ +#define R300_VAP_INPUT_ROUTE_1_0 0x21E0 +# define R300_INPUT_ROUTE_SELECT_X 0 +# define R300_INPUT_ROUTE_SELECT_Y 1 +# define R300_INPUT_ROUTE_SELECT_Z 2 +# define R300_INPUT_ROUTE_SELECT_W 3 +# define R300_INPUT_ROUTE_SELECT_ZERO 4 +# define R300_INPUT_ROUTE_SELECT_ONE 5 +# define R300_INPUT_ROUTE_SELECT_MASK 7 +# define R300_INPUT_ROUTE_X_SHIFT 0 +# define R300_INPUT_ROUTE_Y_SHIFT 3 +# define R300_INPUT_ROUTE_Z_SHIFT 6 +# define R300_INPUT_ROUTE_W_SHIFT 9 +# define R300_INPUT_ROUTE_ENABLE (15 << 12) +#define R300_VAP_INPUT_ROUTE_1_1 0x21E4 +#define R300_VAP_INPUT_ROUTE_1_2 0x21E8 +#define R300_VAP_INPUT_ROUTE_1_3 0x21EC +#define R300_VAP_INPUT_ROUTE_1_4 0x21F0 +#define R300_VAP_INPUT_ROUTE_1_5 0x21F4 +#define R300_VAP_INPUT_ROUTE_1_6 0x21F8 +#define R300_VAP_INPUT_ROUTE_1_7 0x21FC + +/* END */ + +/* gap */ +/* BEGIN: Upload vertex program and data +// The programmable vertex shader unit has a memory bank of unknown size +// that can be written to in 16 byte units by writing the address into +// UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs). +// +// Pointers into the memory bank are always in multiples of 16 bytes. +// +// The memory bank is divided into areas with fixed meaning. +// +// Starting at address UPLOAD_PROGRAM: Vertex program instructions. +// Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB), +// whereas the difference between known addresses suggests size 512. +// +// Starting at address UPLOAD_PARAMETERS: Vertex program parameters. +// Native reported limits and the VPI layout suggest size 256, whereas +// difference between known addresses suggests size 512. +// +// At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the +// floating point pointsize. The exact purpose of this state is uncertain, +// as there is also the R300_RE_POINTSIZE register. +// +// Multiple vertex programs and parameter sets can be loaded at once, +// which could explain the size discrepancy. */ +#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 +# define R300_PVS_UPLOAD_PROGRAM 0x00000000 +# define R300_PVS_UPLOAD_PARAMETERS 0x00000200 +# define R300_PVS_UPLOAD_POINTSIZE 0x00000406 +/* gap */ +#define R300_VAP_PVS_UPLOAD_DATA 0x2208 +/* END */ + +/* gap */ +/* I do not know the purpose of this register. However, I do know that +// it is set to 221C_CLEAR for clear operations and to 221C_NORMAL +// for normal rendering. */ +#define R300_VAP_UNKNOWN_221C 0x221C +# define R300_221C_NORMAL 0x00000000 +# define R300_221C_CLEAR 0x0001C000 + +/* gap */ +/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between +// rendering commands and overwriting vertex program parameters. +// Therefore, I suspect writing zero to 0x2284 synchronizes the engine and +// avoids bugs caused by still running shaders reading bad data from memory. */ +#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */ + +/* Absolutely no clue what this register is about. */ +#define R300_VAP_UNKNOWN_2288 0x2288 +# define R300_2288_R300 0x00750000 /* -- nh */ +# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ + +/* gap */ +/* Addresses are relative to the vertex program instruction area of the +// memory bank. PROGRAM_END points to the last instruction of the active +// program +// +// The meaning of the two UNKNOWN fields is obviously not known. However, +// experiments so far have shown that both *must* point to an instruction +// inside the vertex program, otherwise the GPU locks up. +// fglrx usually sets CNTL_3_UNKNOWN to the end of the program and +// CNTL_1_UNKNOWN points to instruction where last write to position takes place. +// Most likely this is used to ignore rest of the program in cases where group of verts arent visible. +// For some reason this "section" is sometimes accepted other instruction that have +// no relationship with position calculations. +*/ +#define R300_VAP_PVS_CNTL_1 0x22D0 +# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 +# define R300_PVS_CNTL_1_POS_END_SHIFT 10 +# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20 +/* Addresses are relative the the vertex program parameters area. */ +#define R300_VAP_PVS_CNTL_2 0x22D4 +# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0 +# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16 +#define R300_VAP_PVS_CNTL_3 0x22D8 +# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10 +# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0 + +/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for +// immediate vertices */ +#define R300_VAP_VTX_COLOR_R 0x2464 +#define R300_VAP_VTX_COLOR_G 0x2468 +#define R300_VAP_VTX_COLOR_B 0x246C +#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */ +#define R300_VAP_VTX_POS_0_Y_1 0x2494 +#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */ +#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */ +#define R300_VAP_VTX_POS_0_Y_2 0x24A4 +#define R300_VAP_VTX_POS_0_Z_2 0x24A8 +#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */ + +/* gap */ + +/* These are values from r300_reg/r300_reg.h - they are known to be correct + and are here so we can use one register file instead of several + - Vladimir */ +#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000 +# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5) +# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16) + +#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004 + /* each of the following is 3 bits wide, specifies number + of components */ +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 + +/* UNK30 seems to enables point to quad transformation on textures + (or something closely related to that). + This bit is rather fatal at the time being due to lackings at pixel shader side */ +#define R300_GB_ENABLE 0x4008 +# define R300_GB_POINT_STUFF_ENABLE (1<<0) +# define R300_GB_LINE_STUFF_ENABLE (1<<1) +# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2) +# define R300_GB_STENCIL_AUTO_ENABLE (1<<4) +# define R300_GB_UNK30 (1<<30) + /* each of the following is 2 bits wide */ +#define R300_GB_TEX_REPLICATE 0 +#define R300_GB_TEX_ST 1 +#define R300_GB_TEX_STR 2 +# define R300_GB_TEX0_SOURCE_SHIFT 16 +# define R300_GB_TEX1_SOURCE_SHIFT 18 +# define R300_GB_TEX2_SOURCE_SHIFT 20 +# define R300_GB_TEX3_SOURCE_SHIFT 22 +# define R300_GB_TEX4_SOURCE_SHIFT 24 +# define R300_GB_TEX5_SOURCE_SHIFT 26 +# define R300_GB_TEX6_SOURCE_SHIFT 28 +# define R300_GB_TEX7_SOURCE_SHIFT 30 + +/* MSPOS - positions for multisample antialiasing (?) */ +#define R300_GB_MSPOS0 0x4010 + /* shifts - each of the fields is 4 bits */ +# define R300_GB_MSPOS0__MS_X0_SHIFT 0 +# define R300_GB_MSPOS0__MS_Y0_SHIFT 4 +# define R300_GB_MSPOS0__MS_X1_SHIFT 8 +# define R300_GB_MSPOS0__MS_Y1_SHIFT 12 +# define R300_GB_MSPOS0__MS_X2_SHIFT 16 +# define R300_GB_MSPOS0__MS_Y2_SHIFT 20 +# define R300_GB_MSPOS0__MSBD0_Y 24 +# define R300_GB_MSPOS0__MSBD0_X 28 + +#define R300_GB_MSPOS1 0x4014 +# define R300_GB_MSPOS1__MS_X3_SHIFT 0 +# define R300_GB_MSPOS1__MS_Y3_SHIFT 4 +# define R300_GB_MSPOS1__MS_X4_SHIFT 8 +# define R300_GB_MSPOS1__MS_Y4_SHIFT 12 +# define R300_GB_MSPOS1__MS_X5_SHIFT 16 +# define R300_GB_MSPOS1__MS_Y5_SHIFT 20 +# define R300_GB_MSPOS1__MSBD1 24 + + +#define R300_GB_TILE_CONFIG 0x4018 +# define R300_GB_TILE_ENABLE (1<<0) +# define R300_GB_TILE_PIPE_COUNT_RV300 0 +# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1) +# define R300_GB_TILE_PIPE_COUNT_R420 (7<<1) +# define R300_GB_TILE_SIZE_8 0 +# define R300_GB_TILE_SIZE_16 (1<<4) +# define R300_GB_TILE_SIZE_32 (2<<4) +# define R300_GB_SUPER_SIZE_1 (0<<6) +# define R300_GB_SUPER_SIZE_2 (1<<6) +# define R300_GB_SUPER_SIZE_4 (2<<6) +# define R300_GB_SUPER_SIZE_8 (3<<6) +# define R300_GB_SUPER_SIZE_16 (4<<6) +# define R300_GB_SUPER_SIZE_32 (5<<6) +# define R300_GB_SUPER_SIZE_64 (6<<6) +# define R300_GB_SUPER_SIZE_128 (7<<6) +# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */ +# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */ +# define R300_GB_SUPER_TILE_A 0 +# define R300_GB_SUPER_TILE_B (1<<15) +# define R300_GB_SUBPIXEL_1_12 0 +# define R300_GB_SUBPIXEL_1_16 (1<<16) + +#define R300_GB_FIFO_SIZE 0x4024 + /* each of the following is 2 bits wide */ +#define R300_GB_FIFO_SIZE_32 0 +#define R300_GB_FIFO_SIZE_64 1 +#define R300_GB_FIFO_SIZE_128 2 +#define R300_GB_FIFO_SIZE_256 3 +# define R300_SC_IFIFO_SIZE_SHIFT 0 +# define R300_SC_TZFIFO_SIZE_SHIFT 2 +# define R300_SC_BFIFO_SIZE_SHIFT 4 + +# define R300_US_OFIFO_SIZE_SHIFT 12 +# define R300_US_WFIFO_SIZE_SHIFT 14 + /* the following use the same constants as above, but meaning is + is times 2 (i.e. instead of 32 words it means 64 */ +# define R300_RS_TFIFO_SIZE_SHIFT 6 +# define R300_RS_CFIFO_SIZE_SHIFT 8 +# define R300_US_RAM_SIZE_SHIFT 10 + /* watermarks, 3 bits wide */ +# define R300_RS_HIGHWATER_COL_SHIFT 16 +# define R300_RS_HIGHWATER_TEX_SHIFT 19 +# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ +# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 + +#define R300_GB_SELECT 0x401C +# define R300_GB_FOG_SELECT_C0A 0 +# define R300_GB_FOG_SELECT_C1A 1 +# define R300_GB_FOG_SELECT_C2A 2 +# define R300_GB_FOG_SELECT_C3A 3 +# define R300_GB_FOG_SELECT_1_1_W 4 +# define R300_GB_FOG_SELECT_Z 5 +# define R300_GB_DEPTH_SELECT_Z 0 +# define R300_GB_DEPTH_SELECT_1_1_W (1<<3) +# define R300_GB_W_SELECT_1_W 0 +# define R300_GB_W_SELECT_1 (1<<4) + +#define R300_GB_AA_CONFIG 0x4020 +# define R300_AA_ENABLE 0x01 +# define R300_AA_SUBSAMPLES_2 0 +# define R300_AA_SUBSAMPLES_3 (1<<1) +# define R300_AA_SUBSAMPLES_4 (2<<1) +# define R300_AA_SUBSAMPLES_6 (3<<1) + +/* END */ + +/* gap */ +/* Zero to flush caches. */ +#define R300_TX_CNTL 0x4100 + +/* The upper enable bits are guessed, based on fglrx reported limits. */ +#define R300_TX_ENABLE 0x4104 +# define R300_TX_ENABLE_0 (1 << 0) +# define R300_TX_ENABLE_1 (1 << 1) +# define R300_TX_ENABLE_2 (1 << 2) +# define R300_TX_ENABLE_3 (1 << 3) +# define R300_TX_ENABLE_4 (1 << 4) +# define R300_TX_ENABLE_5 (1 << 5) +# define R300_TX_ENABLE_6 (1 << 6) +# define R300_TX_ENABLE_7 (1 << 7) +# define R300_TX_ENABLE_8 (1 << 8) +# define R300_TX_ENABLE_9 (1 << 9) +# define R300_TX_ENABLE_10 (1 << 10) +# define R300_TX_ENABLE_11 (1 << 11) +# define R300_TX_ENABLE_12 (1 << 12) +# define R300_TX_ENABLE_13 (1 << 13) +# define R300_TX_ENABLE_14 (1 << 14) +# define R300_TX_ENABLE_15 (1 << 15) + +/* The pointsize is given in multiples of 6. The pointsize can be +// enormous: Clear() renders a single point that fills the entire +// framebuffer. */ +#define R300_RE_POINTSIZE 0x421C +# define R300_POINTSIZE_Y_SHIFT 0 +# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */ +# define R300_POINTSIZE_X_SHIFT 16 +# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */ +# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6) + +/* The line width is given in multiples of 6. + In default mode lines are classified as vertical lines. + HO: horizontal + VE: vertical or horizontal + HO & VE: no classification +*/ +#define R300_RE_LINE_CNT 0x4234 +# define R300_LINESIZE_SHIFT 0 +# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */ +# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6) +# define R300_LINE_CNT_HO (1 << 16) +# define R300_LINE_CNT_VE (1 << 17) + +/* Some sort of scale or clamp value for texcoordless textures. */ +#define R300_RE_UNK4238 0x4238 + +#define R300_RE_SHADE_MODEL 0x4278 +# define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa +# define R300_RE_SHADE_MODEL_FLAT 0x39595 + +/* Dangerous */ +#define R300_RE_POLYGON_MODE 0x4288 +# define R300_PM_ENABLED (1 << 0) +# define R300_PM_FRONT_POINT (0 << 0) +# define R300_PM_BACK_POINT (0 << 0) +# define R300_PM_FRONT_LINE (1 << 4) +# define R300_PM_FRONT_FILL (1 << 5) +# define R300_PM_BACK_LINE (1 << 7) +# define R300_PM_BACK_FILL (1 << 8) + +/* Not sure why there are duplicate of factor and constant values. + My best guess so far is that there are seperate zbiases for test and write. + Ordering might be wrong. + Some of the tests indicate that fgl has a fallback implementation of zbias + via pixel shaders. */ +#define R300_RE_ZBIAS_T_FACTOR 0x42A4 +#define R300_RE_ZBIAS_T_CONSTANT 0x42A8 +#define R300_RE_ZBIAS_W_FACTOR 0x42AC +#define R300_RE_ZBIAS_W_CONSTANT 0x42B0 + +/* This register needs to be set to (1<<1) for RV350 to correctly + perform depth test (see --vb-triangles in r300_demo) + Don't know about other chips. - Vladimir + This is set to 3 when GL_POLYGON_OFFSET_FILL is on. + My guess is that there are two bits for each zbias primitive (FILL, LINE, POINT). + One to enable depth test and one for depth write. + Yet this doesnt explain why depth writes work ... + */ +#define R300_RE_OCCLUSION_CNTL 0x42B4 +# define R300_OCCLUSION_ON (1<<1) + +#define R300_RE_CULL_CNTL 0x42B8 +# define R300_CULL_FRONT (1 << 0) +# define R300_CULL_BACK (1 << 1) +# define R300_FRONT_FACE_CCW (0 << 2) +# define R300_FRONT_FACE_CW (1 << 2) + + +/* BEGIN: Rasterization / Interpolators - many guesses +// 0_UNKNOWN_18 has always been set except for clear operations. +// TC_CNT is the number of incoming texture coordinate sets (i.e. it depends +// on the vertex program, *not* the fragment program) */ +#define R300_RS_CNTL_0 0x4300 +# define R300_RS_CNTL_TC_CNT_SHIFT 2 +# define R300_RS_CNTL_TC_CNT_MASK (7 << 2) +# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */ +# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18) +/* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */ +#define R300_RS_CNTL_1 0x4304 + +/* gap */ +/* Only used for texture coordinates. +// Use the source field to route texture coordinate input from the vertex program +// to the desired interpolator. Note that the source field is relative to the +// outputs the vertex program *actually* writes. If a vertex program only writes +// texcoord[1], this will be source index 0. +// Set INTERP_USED on all interpolators that produce data used by the +// fragment program. INTERP_USED looks like a swizzling mask, but +// I haven't seen it used that way. +// +// Note: The _UNKNOWN constants are always set in their respective register. +// I don't know if this is necessary. */ +#define R300_RS_INTERP_0 0x4310 +#define R300_RS_INTERP_1 0x4314 +# define R300_RS_INTERP_1_UNKNOWN 0x40 +#define R300_RS_INTERP_2 0x4318 +# define R300_RS_INTERP_2_UNKNOWN 0x80 +#define R300_RS_INTERP_3 0x431C +# define R300_RS_INTERP_3_UNKNOWN 0xC0 +#define R300_RS_INTERP_4 0x4320 +#define R300_RS_INTERP_5 0x4324 +#define R300_RS_INTERP_6 0x4328 +#define R300_RS_INTERP_7 0x432C +# define R300_RS_INTERP_SRC_SHIFT 2 +# define R300_RS_INTERP_SRC_MASK (7 << 2) +# define R300_RS_INTERP_USED 0x00D10000 + +/* These DWORDs control how vertex data is routed into fragment program +// registers, after interpolators. */ +#define R300_RS_ROUTE_0 0x4330 +#define R300_RS_ROUTE_1 0x4334 +#define R300_RS_ROUTE_2 0x4338 +#define R300_RS_ROUTE_3 0x433C /* GUESS */ +#define R300_RS_ROUTE_4 0x4340 /* GUESS */ +#define R300_RS_ROUTE_5 0x4344 /* GUESS */ +#define R300_RS_ROUTE_6 0x4348 /* GUESS */ +#define R300_RS_ROUTE_7 0x434C /* GUESS */ +# define R300_RS_ROUTE_SOURCE_INTERP_0 0 +# define R300_RS_ROUTE_SOURCE_INTERP_1 1 +# define R300_RS_ROUTE_SOURCE_INTERP_2 2 +# define R300_RS_ROUTE_SOURCE_INTERP_3 3 +# define R300_RS_ROUTE_SOURCE_INTERP_4 4 +# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ +# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ +# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ +# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ +# define R300_RS_ROUTE_DEST_SHIFT 6 +# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ + +/* Special handling for color: When the fragment program uses color, +// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the +// color register index. */ +# define R300_RS_ROUTE_0_COLOR (1 << 14) +# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17 +# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ +/* As above, but for secondary color */ +# define R300_RS_ROUTE_1_COLOR1 (1 << 14) +# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 +# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17) +# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11) +/* END */ + +/* BEGIN: Scissors and cliprects +// There are four clipping rectangles. Their corner coordinates are inclusive. +// Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending +// on whether the pixel is inside cliprects 0-3, respectively. For example, +// if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned +// the number 3 (binary 0011). +// Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set, +// the pixel is rasterized. +// +// In addition to this, there is a scissors rectangle. Only pixels inside the +// scissors rectangle are drawn. (coordinates are inclusive) +// +// For some reason, the top-left corner of the framebuffer is at (1440, 1440) +// for the purpose of clipping and scissors. */ +#define R300_RE_CLIPRECT_TL_0 0x43B0 +#define R300_RE_CLIPRECT_BR_0 0x43B4 +#define R300_RE_CLIPRECT_TL_1 0x43B8 +#define R300_RE_CLIPRECT_BR_1 0x43BC +#define R300_RE_CLIPRECT_TL_2 0x43C0 +#define R300_RE_CLIPRECT_BR_2 0x43C4 +#define R300_RE_CLIPRECT_TL_3 0x43C8 +#define R300_RE_CLIPRECT_BR_3 0x43CC +# define R300_CLIPRECT_OFFSET 1440 +# define R300_CLIPRECT_MASK 0x1FFF +# define R300_CLIPRECT_X_SHIFT 0 +# define R300_CLIPRECT_X_MASK (0x1FFF << 0) +# define R300_CLIPRECT_Y_SHIFT 13 +# define R300_CLIPRECT_Y_MASK (0x1FFF << 13) +#define R300_RE_CLIPRECT_CNTL 0x43D0 +# define R300_CLIP_OUT (1 << 0) +# define R300_CLIP_0 (1 << 1) +# define R300_CLIP_1 (1 << 2) +# define R300_CLIP_10 (1 << 3) +# define R300_CLIP_2 (1 << 4) +# define R300_CLIP_20 (1 << 5) +# define R300_CLIP_21 (1 << 6) +# define R300_CLIP_210 (1 << 7) +# define R300_CLIP_3 (1 << 8) +# define R300_CLIP_30 (1 << 9) +# define R300_CLIP_31 (1 << 10) +# define R300_CLIP_310 (1 << 11) +# define R300_CLIP_32 (1 << 12) +# define R300_CLIP_320 (1 << 13) +# define R300_CLIP_321 (1 << 14) +# define R300_CLIP_3210 (1 << 15) + +/* gap */ +#define R300_RE_SCISSORS_TL 0x43E0 +#define R300_RE_SCISSORS_BR 0x43E4 +# define R300_SCISSORS_OFFSET 1440 +# define R300_SCISSORS_X_SHIFT 0 +# define R300_SCISSORS_X_MASK (0x1FFF << 0) +# define R300_SCISSORS_Y_SHIFT 13 +# define R300_SCISSORS_Y_MASK (0x1FFF << 13) +/* END */ + +/* BEGIN: Texture specification +// The texture specification dwords are grouped by meaning and not by texture unit. +// This means that e.g. the offset for texture image unit N is found in register +// TX_OFFSET_0 + (4*N) */ +#define R300_TX_FILTER_0 0x4400 +#define R300_TX_FILTER_1 0x4404 +# define R300_TX_REPEAT 0 +# define R300_TX_MIRRORED 1 +# define R300_TX_CLAMP 4 +# define R300_TX_CLAMP_TO_EDGE 2 +# define R300_TX_CLAMP_TO_BORDER 6 +# define R300_TX_WRAP_S_SHIFT 0 +# define R300_TX_WRAP_S_MASK (7 << 0) +# define R300_TX_WRAP_T_SHIFT 3 +# define R300_TX_WRAP_T_MASK (7 << 3) +# define R300_TX_WRAP_Q_SHIFT 6 +# define R300_TX_WRAP_Q_MASK (7 << 6) +# define R300_TX_MAG_FILTER_NEAREST (1 << 9) +# define R300_TX_MAG_FILTER_LINEAR (2 << 9) +# define R300_TX_MAG_FILTER_MASK (3 << 9) +# define R300_TX_MIN_FILTER_NEAREST (1 << 11) +# define R300_TX_MIN_FILTER_LINEAR (2 << 11) +# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11) +# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11) +# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) +# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) +/* NOTE: NEAREST doesnt seem to exist. + Im not seting MAG_FILTER_MASK and (3 << 11) on for all + anisotropy modes because that would void selected mag filter */ +# define R300_TX_MIN_FILTER_ANISO_NEAREST ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_ANISO_LINEAR ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST ((1 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR ((2 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) ) +# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21) +# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21) +# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21) +# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21) +# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) +# define R300_TX_MAX_ANISO_MASK (14 << 21) + +#define R300_TX_FILTER1_0 0x4440 +#define R300_TX_FILTER1_1 0x4444 +# define R300_CHROMA_KEY_MODE_DISABLE 0 +# define R300_CHROMA_KEY_FORCE 1 +# define R300_CHROMA_KEY_BLEND 2 +# define R300_MC_ROUND_NORMAL (0<<2) +# define R300_MC_ROUND_MPEG4 (1<<2) +# define R300_LOD_BIAS_MASK 0x1fff +# define R300_EDGE_ANISO_EDGE_DIAG (0<<13) +# define R300_EDGE_ANISO_EDGE_ONLY (1<<13) +# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) +# define R300_MC_COORD_TRUNCATE_MPEG (1<<14) +# define R300_TX_TRI_PERF_0_8 (0<<15) +# define R300_TX_TRI_PERF_1_8 (1<<15) +# define R300_TX_TRI_PERF_1_4 (2<<15) +# define R300_TX_TRI_PERF_3_8 (3<<15) +# define R300_ANISO_THRESHOLD_MASK (7<<17) + +#define R300_TX_SIZE_0 0x4480 +#define R300_TX_SIZE_1 0x4484 +# define R300_TX_WIDTH_SHIFT 0 +# define R300_TX_WIDTH_MASK (2047 << 0) +# define R300_TX_HEIGHT_SHIFT 11 +# define R300_TX_HEIGHT_MASK (2047 << 11) +# define R300_TX_UNK23 (1 << 23) +# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ +# define R300_TX_SIZE_MASK (15 << 26) +# define R300_TX_SIZE_PROJECTED (1<<30) +# define R300_TX_SIZE_TXPITCH_EN (1<<31) + +#define R300_TX_FORMAT_0 0x44C0 +#define R300_TX_FORMAT_1 0x44C4 + /* The interpretation of the format word by Wladimir van der Laan */ + /* The X, Y, Z and W refer to the layout of the components. + They are given meanings as R, G, B and Alpha by the swizzle + specification */ +# define R300_TX_FORMAT_X8 0x0 +# define R300_TX_FORMAT_X16 0x1 +# define R300_TX_FORMAT_Y4X4 0x2 +# define R300_TX_FORMAT_Y8X8 0x3 +# define R300_TX_FORMAT_Y16X16 0x4 +# define R300_TX_FORMAT_Z3Y3X2 0x5 +# define R300_TX_FORMAT_Z5Y6X5 0x6 +# define R300_TX_FORMAT_Z6Y5X5 0x7 +# define R300_TX_FORMAT_Z11Y11X10 0x8 +# define R300_TX_FORMAT_Z10Y11X11 0x9 +# define R300_TX_FORMAT_W4Z4Y4X4 0xA +# define R300_TX_FORMAT_W1Z5Y5X5 0xB +# define R300_TX_FORMAT_W8Z8Y8X8 0xC +# define R300_TX_FORMAT_W2Z10Y10X10 0xD +# define R300_TX_FORMAT_W16Z16Y16X16 0xE +# define R300_TX_FORMAT_DXT1 0xF +# define R300_TX_FORMAT_DXT3 0x10 +# define R300_TX_FORMAT_DXT5 0x11 +# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ +# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ +# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ +# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ + /* 0x16 - some 16 bit green format.. ?? */ +# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ +# define R300_TX_FORMAT_CUBIC_MAP (1 << 26) + /* gap */ + /* Floating point formats */ + /* Note - hardware supports both 16 and 32 bit floating point */ +# define R300_TX_FORMAT_FL_I16 0x18 +# define R300_TX_FORMAT_FL_I16A16 0x19 +# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A +# define R300_TX_FORMAT_FL_I32 0x1B +# define R300_TX_FORMAT_FL_I32A32 0x1C +# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D + /* alpha modes, convenience mostly */ + /* if you have alpha, pick constant appropriate to the + number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ +# define R300_TX_FORMAT_ALPHA_1CH 0x000 +# define R300_TX_FORMAT_ALPHA_2CH 0x200 +# define R300_TX_FORMAT_ALPHA_4CH 0x600 +# define R300_TX_FORMAT_ALPHA_NONE 0xA00 + /* Swizzling */ + /* constants */ +# define R300_TX_FORMAT_X 0 +# define R300_TX_FORMAT_Y 1 +# define R300_TX_FORMAT_Z 2 +# define R300_TX_FORMAT_W 3 +# define R300_TX_FORMAT_ZERO 4 +# define R300_TX_FORMAT_ONE 5 +# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */ +# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */ +# define R300_TX_FORMAT_B_SHIFT 18 +# define R300_TX_FORMAT_G_SHIFT 15 +# define R300_TX_FORMAT_R_SHIFT 12 +# define R300_TX_FORMAT_A_SHIFT 9 + /* Convenience macro to take care of layout and swizzling */ +# define R300_EASY_TXFORMAT(B, G, R, A, FMT) (\ + ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT) \ + | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \ + | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \ + | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \ + | (R300_TX_FORMAT_##FMT) \ + ) + /* These can be ORed with result of R300_EASY_TX_FORMAT() */ + /* We don't really know what they do. Take values from a constant color ? */ +# define R300_TX_FORMAT_CONST_X (1<<5) +# define R300_TX_FORMAT_CONST_Y (2<<5) +# define R300_TX_FORMAT_CONST_Z (4<<5) +# define R300_TX_FORMAT_CONST_W (8<<5) +# define R300_TX_FORMAT_YUV_MODE 0x00800000 + /* Precalculated formats */ +# define R300_TXFORMAT_ARGB8888 R300_EASY_TXFORMAT(X, Y, Z, W, W8Z8Y8X8) +# define R300_TXFORMAT_XRGB8888 R300_EASY_TXFORMAT(X, Y, Z, ONE, W8Z8Y8X8) +# define R300_TXFORMAT_RGB565 R300_EASY_TXFORMAT(X, Y, Z, ONE, Z5Y6X5) +# define R300_TXFORMAT_ARGB4444 R300_EASY_TXFORMAT(X, Y, Z, W, W4Z4Y4X4) +# define R300_TXFORMAT_ARGB1555 R300_EASY_TXFORMAT(X, Y, Z, W, W1Z5Y5X5) +# define R300_TXFORMAT_RGB444 R300_EASY_TXFORMAT(X, Y, Z, ONE, W4Z4Y4X4) +# define R300_TXFORMAT_RGB555 R300_EASY_TXFORMAT(X, Y, Z, ONE, W1Z5Y5X5) +# define R300_TXFORMAT_RGB332 R300_EASY_TXFORMAT(X, Y, Z, ONE, Z3Y3X2) +# define R300_TXFORMAT_A8 R300_EASY_TXFORMAT(ONE, ONE, ONE, X, X8) +# define R300_TXFORMAT_I8 R300_EASY_TXFORMAT(X, X, X, X, X8) +# define R300_TXFORMAT_VYUY422 R300_EASY_TXFORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE +# define R300_TXFORMAT_YVYU422 R300_EASY_TXFORMAT(X, Y, Z, ONE, B8G8_B8G8)|R300_TX_FORMAT_YUV_MODE + + +#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */ +#define R300_TX_PITCH_1 0x4504 + +#define R300_TX_OFFSET_0 0x4540 +#define R300_TX_OFFSET_1 0x4544 +/* BEGIN: Guess from R200 */ +# define R300_TXO_ENDIAN_NO_SWAP (0 << 0) +# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) +# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) +# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) +# define R300_TXO_MACRO_TILE (1 << 2) +# define R300_TXO_MICRO_TILE (1 << 3) +# define R300_TXO_OFFSET_MASK 0xffffffe0 +/* END */ + +#define R300_TX_CHROMA_KEY_0 0x4580 /* pixel value */ + +#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } + +/* END */ + +/* BEGIN: Fragment program instruction set +// Fragment programs are written directly into register space. +// There are separate instruction streams for texture instructions and ALU +// instructions. +// In order to synchronize these streams, the program is divided into up +// to 4 nodes. Each node begins with a number of TEX operations, followed +// by a number of ALU operations. +// The first node can have zero TEX ops, all subsequent nodes must have at least +// one TEX ops. +// All nodes must have at least one ALU op. +// +// The index of the last node is stored in PFS_CNTL_0: A value of 0 means +// 1 node, a value of 3 means 4 nodes. +// The total amount of instructions is defined in PFS_CNTL_2. The offsets are +// offsets into the respective instruction streams, while *_END points to the +// last instruction relative to this offset. */ +#define R300_PFS_CNTL_0 0x4600 +# define R300_PFS_CNTL_LAST_NODES_SHIFT 0 +# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0) +# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3) +#define R300_PFS_CNTL_1 0x4604 +/* There is an unshifted value here which has so far always been equal to the +// index of the highest used temporary register. */ +#define R300_PFS_CNTL_2 0x4608 +# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0 +# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0) +# define R300_PFS_CNTL_ALU_END_SHIFT 6 +# define R300_PFS_CNTL_ALU_END_MASK (63 << 0) +# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12 +# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */ +# define R300_PFS_CNTL_TEX_END_SHIFT 18 +# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */ + +/* gap */ +/* Nodes are stored backwards. The last active node is always stored in +// PFS_NODE_3. +// Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The +// first node is stored in NODE_2, the second node is stored in NODE_3. +// +// Offsets are relative to the master offset from PFS_CNTL_2. +// LAST_NODE is set for the last node, and only for the last node. */ +#define R300_PFS_NODE_0 0x4610 +#define R300_PFS_NODE_1 0x4614 +#define R300_PFS_NODE_2 0x4618 +#define R300_PFS_NODE_3 0x461C +# define R300_PFS_NODE_ALU_OFFSET_SHIFT 0 +# define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0) +# define R300_PFS_NODE_ALU_END_SHIFT 6 +# define R300_PFS_NODE_ALU_END_MASK (63 << 6) +# define R300_PFS_NODE_TEX_OFFSET_SHIFT 12 +# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) +# define R300_PFS_NODE_TEX_END_SHIFT 17 +# define R300_PFS_NODE_TEX_END_MASK (31 << 17) +/*# define R300_PFS_NODE_LAST_NODE (1 << 22) */ +# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22) +# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23) + +/* TEX +// As far as I can tell, texture instructions cannot write into output +// registers directly. A subsequent ALU instruction is always necessary, +// even if it's just MAD o0, r0, 1, 0 */ +#define R300_PFS_TEXI_0 0x4620 +#define R300_PFS_TEXI_1 0x4624 +# define R300_FPITX_SRC_SHIFT 0 +# define R300_FPITX_SRC_MASK (31 << 0) +# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */ +# define R300_FPITX_DST_SHIFT 6 +# define R300_FPITX_DST_MASK (31 << 6) +# define R300_FPITX_IMAGE_SHIFT 11 +# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */ +/* Unsure if these are opcodes, or some kind of bitfield, but this is how + * they were set when I checked + */ +# define R300_FPITX_OPCODE_SHIFT 15 +# define R300_FPITX_OP_TEX (1 << 15) +# define R300_FPITX_OP_KIL (2 << 15) +# define R300_FPITX_OP_TXP (3 << 15) +# define R300_FPITX_OP_TXB (4 << 15) + +/* ALU +// The ALU instructions register blocks are enumerated according to the order +// in which fglrx. I assume there is space for 64 instructions, since +// each block has space for a maximum of 64 DWORDs, and this matches reported +// native limits. +// +// The basic functional block seems to be one MAD for each color and alpha, +// and an adder that adds all components after the MUL. +// - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands +// - DP4: Use OUTC_DP4, OUTA_DP4 +// - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands +// - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands +// - CMP: If ARG2 < 0, return ARG1, else return ARG0 +// - FLR: use FRC+MAD +// - XPD: use MAD+MAD +// - SGE, SLT: use MAD+CMP +// - RSQ: use ABS modifier for argument +// - Use OUTC_REPL_ALPHA to write results of an alpha-only operation (e.g. RCP) +// into color register +// - apparently, there's no quick DST operation +// - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2" +// - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0" +// - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1" +// +// Operand selection +// First stage selects three sources from the available registers and +// constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha). +// fglrx sorts the three source fields: Registers before constants, +// lower indices before higher indices; I do not know whether this is necessary. +// fglrx fills unused sources with "read constant 0" +// According to specs, you cannot select more than two different constants. +// +// Second stage selects the operands from the sources. This is defined in +// INSTR0 (color) and INSTR2 (alpha). You can also select the special constants +// zero and one. +// Swizzling and negation happens in this stage, as well. +// +// Important: Color and alpha seem to be mostly separate, i.e. their sources +// selection appears to be fully independent (the register storage is probably +// physically split into a color and an alpha section). +// However (because of the apparent physical split), there is some interaction +// WRT swizzling. If, for example, you want to load an R component into an +// Alpha operand, this R component is taken from a *color* source, not from +// an alpha source. The corresponding register doesn't even have to appear in +// the alpha sources list. (I hope this alll makes sense to you) +// +// Destination selection +// The destination register index is in FPI1 (color) and FPI3 (alpha) together +// with enable bits. +// There are separate enable bits for writing into temporary registers +// (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* /DSTA_OUTPUT). +// You can write to both at once, or not write at all (the same index +// must be used for both). +// +// Note: There is a special form for LRP +// - Argument order is the same as in ARB_fragment_program. +// - Operation is MAD +// - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP +// - Set FPI0/FPI2_SPECIAL_LRP +// Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD */ +#define R300_PFS_INSTR1_0 0x46C0 +# define R300_FPI1_SRC0C_SHIFT 0 +# define R300_FPI1_SRC0C_MASK (31 << 0) +# define R300_FPI1_SRC0C_CONST (1 << 5) +# define R300_FPI1_SRC1C_SHIFT 6 +# define R300_FPI1_SRC1C_MASK (31 << 6) +# define R300_FPI1_SRC1C_CONST (1 << 11) +# define R300_FPI1_SRC2C_SHIFT 12 +# define R300_FPI1_SRC2C_MASK (31 << 12) +# define R300_FPI1_SRC2C_CONST (1 << 17) +# define R300_FPI1_DSTC_SHIFT 18 +# define R300_FPI1_DSTC_MASK (31 << 18) +# define R300_FPI1_DSTC_REG_MASK_SHIFT 23 +# define R300_FPI1_DSTC_REG_X (1 << 23) +# define R300_FPI1_DSTC_REG_Y (1 << 24) +# define R300_FPI1_DSTC_REG_Z (1 << 25) +# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26 +# define R300_FPI1_DSTC_OUTPUT_X (1 << 26) +# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) +# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) + +#define R300_PFS_INSTR3_0 0x47C0 +# define R300_FPI3_SRC0A_SHIFT 0 +# define R300_FPI3_SRC0A_MASK (31 << 0) +# define R300_FPI3_SRC0A_CONST (1 << 5) +# define R300_FPI3_SRC1A_SHIFT 6 +# define R300_FPI3_SRC1A_MASK (31 << 6) +# define R300_FPI3_SRC1A_CONST (1 << 11) +# define R300_FPI3_SRC2A_SHIFT 12 +# define R300_FPI3_SRC2A_MASK (31 << 12) +# define R300_FPI3_SRC2A_CONST (1 << 17) +# define R300_FPI3_DSTA_SHIFT 18 +# define R300_FPI3_DSTA_MASK (31 << 18) +# define R300_FPI3_DSTA_REG (1 << 23) +# define R300_FPI3_DSTA_OUTPUT (1 << 24) +# define R300_FPI3_DSTA_DEPTH (1 << 27) + +#define R300_PFS_INSTR0_0 0x48C0 +# define R300_FPI0_ARGC_SRC0C_XYZ 0 +# define R300_FPI0_ARGC_SRC0C_XXX 1 +# define R300_FPI0_ARGC_SRC0C_YYY 2 +# define R300_FPI0_ARGC_SRC0C_ZZZ 3 +# define R300_FPI0_ARGC_SRC1C_XYZ 4 +# define R300_FPI0_ARGC_SRC1C_XXX 5 +# define R300_FPI0_ARGC_SRC1C_YYY 6 +# define R300_FPI0_ARGC_SRC1C_ZZZ 7 +# define R300_FPI0_ARGC_SRC2C_XYZ 8 +# define R300_FPI0_ARGC_SRC2C_XXX 9 +# define R300_FPI0_ARGC_SRC2C_YYY 10 +# define R300_FPI0_ARGC_SRC2C_ZZZ 11 +# define R300_FPI0_ARGC_SRC0A 12 +# define R300_FPI0_ARGC_SRC1A 13 +# define R300_FPI0_ARGC_SRC2A 14 +# define R300_FPI0_ARGC_SRC1C_LRP 15 +# define R300_FPI0_ARGC_ZERO 20 +# define R300_FPI0_ARGC_ONE 21 +# define R300_FPI0_ARGC_HALF 22 /* GUESS */ +# define R300_FPI0_ARGC_SRC0C_YZX 23 +# define R300_FPI0_ARGC_SRC1C_YZX 24 +# define R300_FPI0_ARGC_SRC2C_YZX 25 +# define R300_FPI0_ARGC_SRC0C_ZXY 26 +# define R300_FPI0_ARGC_SRC1C_ZXY 27 +# define R300_FPI0_ARGC_SRC2C_ZXY 28 +# define R300_FPI0_ARGC_SRC0CA_WZY 29 +# define R300_FPI0_ARGC_SRC1CA_WZY 30 +# define R300_FPI0_ARGC_SRC2CA_WZY 31 + +# define R300_FPI0_ARG0C_SHIFT 0 +# define R300_FPI0_ARG0C_MASK (31 << 0) +# define R300_FPI0_ARG0C_NEG (1 << 5) +# define R300_FPI0_ARG0C_ABS (1 << 6) +# define R300_FPI0_ARG1C_SHIFT 7 +# define R300_FPI0_ARG1C_MASK (31 << 7) +# define R300_FPI0_ARG1C_NEG (1 << 12) +# define R300_FPI0_ARG1C_ABS (1 << 13) +# define R300_FPI0_ARG2C_SHIFT 14 +# define R300_FPI0_ARG2C_MASK (31 << 14) +# define R300_FPI0_ARG2C_NEG (1 << 19) +# define R300_FPI0_ARG2C_ABS (1 << 20) +# define R300_FPI0_SPECIAL_LRP (1 << 21) +# define R300_FPI0_OUTC_MAD (0 << 23) +# define R300_FPI0_OUTC_DP3 (1 << 23) +# define R300_FPI0_OUTC_DP4 (2 << 23) +# define R300_FPI0_OUTC_MIN (4 << 23) +# define R300_FPI0_OUTC_MAX (5 << 23) +# define R300_FPI0_OUTC_CMP (8 << 23) +# define R300_FPI0_OUTC_FRC (9 << 23) +# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) +# define R300_FPI0_OUTC_SAT (1 << 30) +# define R300_FPI0_INSERT_NOP (1 << 31) + +#define R300_PFS_INSTR2_0 0x49C0 +# define R300_FPI2_ARGA_SRC0C_X 0 +# define R300_FPI2_ARGA_SRC0C_Y 1 +# define R300_FPI2_ARGA_SRC0C_Z 2 +# define R300_FPI2_ARGA_SRC1C_X 3 +# define R300_FPI2_ARGA_SRC1C_Y 4 +# define R300_FPI2_ARGA_SRC1C_Z 5 +# define R300_FPI2_ARGA_SRC2C_X 6 +# define R300_FPI2_ARGA_SRC2C_Y 7 +# define R300_FPI2_ARGA_SRC2C_Z 8 +# define R300_FPI2_ARGA_SRC0A 9 +# define R300_FPI2_ARGA_SRC1A 10 +# define R300_FPI2_ARGA_SRC2A 11 +# define R300_FPI2_ARGA_SRC1A_LRP 15 +# define R300_FPI2_ARGA_ZERO 16 +# define R300_FPI2_ARGA_ONE 17 +# define R300_FPI2_ARGA_HALF 18 /* GUESS */ + +# define R300_FPI2_ARG0A_SHIFT 0 +# define R300_FPI2_ARG0A_MASK (31 << 0) +# define R300_FPI2_ARG0A_NEG (1 << 5) +# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */ +# define R300_FPI2_ARG1A_SHIFT 7 +# define R300_FPI2_ARG1A_MASK (31 << 7) +# define R300_FPI2_ARG1A_NEG (1 << 12) +# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */ +# define R300_FPI2_ARG2A_SHIFT 14 +# define R300_FPI2_ARG2A_MASK (31 << 14) +# define R300_FPI2_ARG2A_NEG (1 << 19) +# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */ +# define R300_FPI2_SPECIAL_LRP (1 << 21) +# define R300_FPI2_OUTA_MAD (0 << 23) +# define R300_FPI2_OUTA_DP4 (1 << 23) +# define R300_FPI2_OUTA_MIN (2 << 23) +# define R300_FPI2_OUTA_MAX (3 << 23) +# define R300_FPI2_OUTA_CMP (6 << 23) +# define R300_FPI2_OUTA_FRC (7 << 23) +# define R300_FPI2_OUTA_EX2 (8 << 23) +# define R300_FPI2_OUTA_LG2 (9 << 23) +# define R300_FPI2_OUTA_RCP (10 << 23) +# define R300_FPI2_OUTA_RSQ (11 << 23) +# define R300_FPI2_OUTA_SAT (1 << 30) +# define R300_FPI2_UNKNOWN_31 (1 << 31) +/* END */ + +/* gap */ +#define R300_PP_ALPHA_TEST 0x4BD4 +# define R300_REF_ALPHA_MASK 0x000000ff +# define R300_ALPHA_TEST_FAIL (0 << 8) +# define R300_ALPHA_TEST_LESS (1 << 8) +# define R300_ALPHA_TEST_LEQUAL (3 << 8) +# define R300_ALPHA_TEST_EQUAL (2 << 8) +# define R300_ALPHA_TEST_GEQUAL (6 << 8) +# define R300_ALPHA_TEST_GREATER (4 << 8) +# define R300_ALPHA_TEST_NEQUAL (5 << 8) +# define R300_ALPHA_TEST_PASS (7 << 8) +# define R300_ALPHA_TEST_OP_MASK (7 << 8) +# define R300_ALPHA_TEST_ENABLE (1 << 11) + +/* gap */ +/* Fragment program parameters in 7.16 floating point */ +#define R300_PFS_PARAM_0_X 0x4C00 +#define R300_PFS_PARAM_0_Y 0x4C04 +#define R300_PFS_PARAM_0_Z 0x4C08 +#define R300_PFS_PARAM_0_W 0x4C0C +/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */ +#define R300_PFS_PARAM_31_X 0x4DF0 +#define R300_PFS_PARAM_31_Y 0x4DF4 +#define R300_PFS_PARAM_31_Z 0x4DF8 +#define R300_PFS_PARAM_31_W 0x4DFC + +/* Notes: +// - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in the application +// - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND are set to the same +// function (both registers are always set up completely in any case) +// - Most blend flags are simply copied from R200 and not tested yet */ +#define R300_RB3D_CBLEND 0x4E04 +#define R300_RB3D_ABLEND 0x4E08 + /* the following only appear in CBLEND */ +# define R300_BLEND_ENABLE (1 << 0) +# define R300_BLEND_UNKNOWN (3 << 1) +# define R300_BLEND_NO_SEPARATE (1 << 3) + /* the following are shared between CBLEND and ABLEND */ +# define R300_FCN_MASK (3 << 12) +# define R300_COMB_FCN_ADD_CLAMP (0 << 12) +# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12) +# define R300_COMB_FCN_SUB_CLAMP (2 << 12) +# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12) +# define R300_SRC_BLEND_GL_ZERO (32 << 16) +# define R300_SRC_BLEND_GL_ONE (33 << 16) +# define R300_SRC_BLEND_GL_SRC_COLOR (34 << 16) +# define R300_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) +# define R300_SRC_BLEND_GL_DST_COLOR (36 << 16) +# define R300_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) +# define R300_SRC_BLEND_GL_SRC_ALPHA (38 << 16) +# define R300_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) +# define R300_SRC_BLEND_GL_DST_ALPHA (40 << 16) +# define R300_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) +# define R300_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) +# define R300_SRC_BLEND_GL_CONST_COLOR (43 << 16) +# define R300_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 16) +# define R300_SRC_BLEND_GL_CONST_ALPHA (45 << 16) +# define R300_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 16) +# define R300_SRC_BLEND_MASK (63 << 16) +# define R300_DST_BLEND_GL_ZERO (32 << 24) +# define R300_DST_BLEND_GL_ONE (33 << 24) +# define R300_DST_BLEND_GL_SRC_COLOR (34 << 24) +# define R300_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) +# define R300_DST_BLEND_GL_DST_COLOR (36 << 24) +# define R300_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) +# define R300_DST_BLEND_GL_SRC_ALPHA (38 << 24) +# define R300_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) +# define R300_DST_BLEND_GL_DST_ALPHA (40 << 24) +# define R300_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) +# define R300_DST_BLEND_GL_CONST_COLOR (43 << 24) +# define R300_DST_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 24) +# define R300_DST_BLEND_GL_CONST_ALPHA (45 << 24) +# define R300_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 24) +# define R300_DST_BLEND_MASK (63 << 24) +#define R300_RB3D_COLORMASK 0x4E0C +# define R300_COLORMASK0_B (1<<0) +# define R300_COLORMASK0_G (1<<1) +# define R300_COLORMASK0_R (1<<2) +# define R300_COLORMASK0_A (1<<3) + +#define R300_RB3D_BLENDCOLOR 0x4E10 /* ARGB */ + +/* gap */ +#define R300_RB3D_COLOROFFSET0 0x4E28 +# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ +#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ +#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ +#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */ +/* gap */ +/* Bit 16: Larger tiles +// Bit 17: 4x2 tiles +// Bit 18: Extremely weird tile like, but some pixels duplicated? */ +#define R300_RB3D_COLORPITCH0 0x4E38 +# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ +# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ +# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ +# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ +# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ +# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ +# define R300_COLOR_FORMAT_RGB565 (2 << 22) +# define R300_COLOR_FORMAT_ARGB8888 (3 << 22) +# define R300_COLOR_FORMAT_RGB8 (4 << 22) +# define R300_COLOR_FORMAT_MASK (7 << 22) +#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */ +#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ +#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ + +#define R300_RB3D_DSTCACHE_MODE 0x4E48 +/* gap */ +/* Guess by Vladimir. +// Set to 0A before 3D operations, set to 02 afterwards. */ +#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C +# define R300_RB3D_DSTCACHE_02 0x00000002 +# define R300_RB3D_DSTCACHE_0A 0x0000000A + +/* gap */ +/* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */ +/* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */ +#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00 +# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */ +# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */ +# define R300_RB3D_Z_TEST 0x00000012 +# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 +# define R300_RB3D_Z_WRITE_ONLY 0x00000006 +# define R300_RB3D_STENCIL_ENABLE 0x00000001 + +#define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04 + /* functions */ +# define R300_ZS_NEVER 0 +# define R300_ZS_LESS 1 +# define R300_ZS_LEQUAL 2 +# define R300_ZS_EQUAL 3 +# define R300_ZS_GEQUAL 4 +# define R300_ZS_GREATER 5 +# define R300_ZS_NOTEQUAL 6 +# define R300_ZS_ALWAYS 7 +# define R300_ZS_MASK 7 + /* operations */ +# define R300_ZS_KEEP 0 +# define R300_ZS_ZERO 1 +# define R300_ZS_REPLACE 2 +# define R300_ZS_INCR 3 +# define R300_ZS_DECR 4 +# define R300_ZS_INVERT 5 +# define R300_ZS_INCR_WRAP 6 +# define R300_ZS_DECR_WRAP 7 + + /* front and back refer to operations done for front + and back faces, i.e. separate stencil function support */ +# define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT 0 +# define R300_RB3D_ZS1_FRONT_FUNC_SHIFT 3 +# define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT 6 +# define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT 9 +# define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT 12 +# define R300_RB3D_ZS1_BACK_FUNC_SHIFT 15 +# define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT 18 +# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21 +# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24 + + + +#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08 +# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0 +# define R300_RB3D_ZS2_STENCIL_MASK 0xFF +# define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8 +# define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16 + +/* gap */ + +#define R300_RB3D_ZSTENCIL_FORMAT 0x4F10 +# define R300_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define R300_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) + /* 16 bit format or some aditional bit ? */ +# define R300_DEPTH_FORMAT_UNK32 (32 << 0) + +/* gap */ +#define R300_RB3D_DEPTHOFFSET 0x4F20 +#define R300_RB3D_DEPTHPITCH 0x4F24 +# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ +# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */ +# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */ +# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ +# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ +# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ + +/* BEGIN: Vertex program instruction set +// Every instruction is four dwords long: +// DWORD 0: output and opcode +// DWORD 1: first argument +// DWORD 2: second argument +// DWORD 3: third argument +// +// Notes: +// - ABS r, a is implemented as MAX r, a, -a +// - MOV is implemented as ADD to zero +// - XPD is implemented as MUL + MAD +// - FLR is implemented as FRC + ADD +// - apparently, fglrx tries to schedule instructions so that there is at least +// one instruction between the write to a temporary and the first read +// from said temporary; however, violations of this scheduling are allowed +// - register indices seem to be unrelated with OpenGL aliasing to conventional state +// - only one attribute and one parameter can be loaded at a time; however, the +// same attribute/parameter can be used for more than one argument +// - the second software argument for POW is the third hardware argument (no idea why) +// - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2 +// +// There is some magic surrounding LIT: +// The single argument is replicated across all three inputs, but swizzled: +// First argument: xyzy +// Second argument: xyzx +// Third argument: xyzw +// Whenever the result is used later in the fragment program, fglrx forces x and w +// to be 1.0 in the input selection; I don't know whether this is strictly necessary */ +#define R300_VPI_OUT_OP_DOT (1 << 0) +#define R300_VPI_OUT_OP_MUL (2 << 0) +#define R300_VPI_OUT_OP_ADD (3 << 0) +#define R300_VPI_OUT_OP_MAD (4 << 0) +#define R300_VPI_OUT_OP_DST (5 << 0) +#define R300_VPI_OUT_OP_FRC (6 << 0) +#define R300_VPI_OUT_OP_MAX (7 << 0) +#define R300_VPI_OUT_OP_MIN (8 << 0) +#define R300_VPI_OUT_OP_SGE (9 << 0) +#define R300_VPI_OUT_OP_SLT (10 << 0) +#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */ +#define R300_VPI_OUT_OP_EXP (65 << 0) +#define R300_VPI_OUT_OP_LOG (66 << 0) +#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */ +#define R300_VPI_OUT_OP_LIT (68 << 0) +#define R300_VPI_OUT_OP_POW (69 << 0) +#define R300_VPI_OUT_OP_RCP (70 << 0) +#define R300_VPI_OUT_OP_RSQ (72 << 0) +#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */ +#define R300_VPI_OUT_OP_EX2 (75 << 0) +#define R300_VPI_OUT_OP_LG2 (76 << 0) +#define R300_VPI_OUT_OP_MAD_2 (128 << 0) +#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */ + +#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8) +#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8) +#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8) + +#define R300_VPI_OUT_REG_INDEX_SHIFT 13 +#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */ + +#define R300_VPI_OUT_WRITE_X (1 << 20) +#define R300_VPI_OUT_WRITE_Y (1 << 21) +#define R300_VPI_OUT_WRITE_Z (1 << 22) +#define R300_VPI_OUT_WRITE_W (1 << 23) + +#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0) +#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0) +#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0) +#define R300_VPI_IN_REG_CLASS_NONE (9 << 0) +#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */ + +#define R300_VPI_IN_REG_INDEX_SHIFT 5 +#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */ + +/* The R300 can select components from the input register arbitrarily. +// Use the following constants, shifted by the component shift you +// want to select */ +#define R300_VPI_IN_SELECT_X 0 +#define R300_VPI_IN_SELECT_Y 1 +#define R300_VPI_IN_SELECT_Z 2 +#define R300_VPI_IN_SELECT_W 3 +#define R300_VPI_IN_SELECT_ZERO 4 +#define R300_VPI_IN_SELECT_ONE 5 +#define R300_VPI_IN_SELECT_MASK 7 + +#define R300_VPI_IN_X_SHIFT 13 +#define R300_VPI_IN_Y_SHIFT 16 +#define R300_VPI_IN_Z_SHIFT 19 +#define R300_VPI_IN_W_SHIFT 22 + +#define R300_VPI_IN_NEG_X (1 << 25) +#define R300_VPI_IN_NEG_Y (1 << 26) +#define R300_VPI_IN_NEG_Z (1 << 27) +#define R300_VPI_IN_NEG_W (1 << 28) +/* END */ + +//BEGIN: Packet 3 commands + +// A primitive emission dword. +#define R300_PRIM_TYPE_NONE (0 << 0) +#define R300_PRIM_TYPE_POINT (1 << 0) +#define R300_PRIM_TYPE_LINE (2 << 0) +#define R300_PRIM_TYPE_LINE_STRIP (3 << 0) +#define R300_PRIM_TYPE_TRI_LIST (4 << 0) +#define R300_PRIM_TYPE_TRI_FAN (5 << 0) +#define R300_PRIM_TYPE_TRI_STRIP (6 << 0) +#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0) +#define R300_PRIM_TYPE_RECT_LIST (8 << 0) +#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) +#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) +#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200) +#define R300_PRIM_TYPE_LINE_LOOP (12 << 0) +#define R300_PRIM_TYPE_QUADS (13 << 0) +#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0) +#define R300_PRIM_TYPE_POLYGON (15 << 0) +#define R300_PRIM_TYPE_MASK 0xF +#define R300_PRIM_WALK_IND (1 << 4) +#define R300_PRIM_WALK_LIST (2 << 4) +#define R300_PRIM_WALK_RING (3 << 4) +#define R300_PRIM_WALK_MASK (3 << 4) +#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200) +#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS +#define R300_PRIM_NUM_VERTICES_SHIFT 16 + + /* Registers for CP and Microcode Engine */ +#define CP_ME_RAM_ADDR 0x07d4 +#define CP_ME_RAM_RADDR 0x07d8 +#define CP_ME_RAM_DATAH 0x07dc +#define CP_ME_RAM_DATAL 0x07e0 + +#define CP_RB_BASE 0x0700 +#define CP_RB_CNTL 0x0704 +#define CP_RB_RPTR_ADDR 0x070c +#define CP_RB_RPTR 0x0710 +#define CP_RB_WPTR 0x0714 + +#define CP_IB_BASE 0x0738 +#define CP_IB_BUFSZ 0x073c + +#define CP_CSQ_CNTL 0x0740 +# define CSQ_CNT_PRIMARY_MASK (0xff << 0) +# define CSQ_PRIDIS_INDDIS (0 << 28) +# define CSQ_PRIPIO_INDDIS (1 << 28) +# define CSQ_PRIBM_INDDIS (2 << 28) +# define CSQ_PRIPIO_INDBM (3 << 28) +# define CSQ_PRIBM_INDBM (4 << 28) +# define CSQ_PRIPIO_INDPIO (15 << 28) +#define CP_CSQ_STAT 0x07f8 +# define CSQ_RPTR_PRIMARY_MASK (0xff << 0) +# define CSQ_WPTR_PRIMARY_MASK (0xff << 8) +# define CSQ_RPTR_INDIRECT_MASK (0xff << 16) +# define CSQ_WPTR_INDIRECT_MASK (0xff << 24) +#define CP_CSQ_ADDR 0x07f0 +#define CP_CSQ_DATA 0x07f4 +#define CP_CSQ_APER_PRIMARY 0x1000 +#define CP_CSQ_APER_INDIRECT 0x1300 + +#define CP_RB_WPTR_DELAY 0x0718 +# define PRE_WRITE_TIMER_SHIFT 0 +# define PRE_WRITE_LIMIT_SHIFT 23 + +#define AIC_CNTL 0x01d0 +# define PCIGART_TRANSLATE_EN (1 << 0) +#define AIC_LO_ADDR 0x01dc + + + + /* Constants */ +#define LAST_FRAME_REG GUI_SCRATCH_REG0 +#define LAST_CLEAR_REG GUI_SCRATCH_REG2 + + + + /* CP packet types */ +#define CP_PACKET0 0x00000000 +#define CP_PACKET1 0x40000000 +#define CP_PACKET2 0x80000000 +#define CP_PACKET3 0xC0000000 +# define CP_PACKET_MASK 0xC0000000 +# define CP_PACKET_COUNT_MASK 0x3fff0000 +# define CP_PACKET_MAX_DWORDS (1 << 12) +# define CP_PACKET0_REG_MASK 0x000007ff +# define CP_PACKET1_REG0_MASK 0x000007ff +# define CP_PACKET1_REG1_MASK 0x003ff800 + +#define CP_PACKET0_ONE_REG_WR 0x00008000 + +#define CP_PACKET3_NOP 0xC0001000 +#define CP_PACKET3_NEXT_CHAR 0xC0001900 +#define CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define CP_PACKET3_SET_SCISSORS 0xC0001E00 +#define CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define CP_PACKET3_LOAD_MICROCODE 0xC0002400 +#define CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 +#define CP_PACKET3_3D_DRAW_VBUF 0xC0002800 +#define CP_PACKET3_3D_DRAW_IMMD 0xC0002900 +#define CP_PACKET3_3D_DRAW_INDX 0xC0002A00 +#define CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define R200_CP_PACKET3_3D_DRAW_IMMD_2 0xc0003500 +#define CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 +#define CP_PACKET3_CNTL_PAINT 0xC0009100 +#define CP_PACKET3_CNTL_BITBLT 0xC0009200 +#define CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define CP_PACKET3_CNTL_POLYLINE 0xC0009500 +#define CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 + + +#define CP_VC_FRMT_XY 0x00000000 +#define CP_VC_FRMT_W0 0x00000001 +#define CP_VC_FRMT_FPCOLOR 0x00000002 +#define CP_VC_FRMT_FPALPHA 0x00000004 +#define CP_VC_FRMT_PKCOLOR 0x00000008 +#define CP_VC_FRMT_FPSPEC 0x00000010 +#define CP_VC_FRMT_FPFOG 0x00000020 +#define CP_VC_FRMT_PKSPEC 0x00000040 +#define CP_VC_FRMT_ST0 0x00000080 +#define CP_VC_FRMT_ST1 0x00000100 +#define CP_VC_FRMT_Q1 0x00000200 +#define CP_VC_FRMT_ST2 0x00000400 +#define CP_VC_FRMT_Q2 0x00000800 +#define CP_VC_FRMT_ST3 0x00001000 +#define CP_VC_FRMT_Q3 0x00002000 +#define CP_VC_FRMT_Q0 0x00004000 +#define CP_VC_FRMT_BLND_WEIGHT_CNT_MASK 0x00038000 +#define CP_VC_FRMT_N0 0x00040000 +#define CP_VC_FRMT_XY1 0x08000000 +#define CP_VC_FRMT_Z1 0x10000000 +#define CP_VC_FRMT_W1 0x20000000 +#define CP_VC_FRMT_N1 0x40000000 +#define CP_VC_FRMT_Z 0x80000000 + +#define CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 +#define CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2 0x00000007 +#define CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 +#define CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 +#define CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a +#define CP_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define CP_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 +#define CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 +#define CP_VC_CNTL_MAOS_ENABLE 0x00000080 +#define CP_VC_CNTL_VTX_FMT_NON_MODE 0x00000000 +#define CP_VC_CNTL_VTX_FMT_MODE 0x00000100 +#define CP_VC_CNTL_TCL_DISABLE 0x00000000 +#define CP_VC_CNTL_TCL_ENABLE 0x00000200 +#define CP_VC_CNTL_NUM_SHIFT 16 + +#define VS_MATRIX_0_ADDR 0 +#define VS_MATRIX_1_ADDR 4 +#define VS_MATRIX_2_ADDR 8 +#define VS_MATRIX_3_ADDR 12 +#define VS_MATRIX_4_ADDR 16 +#define VS_MATRIX_5_ADDR 20 +#define VS_MATRIX_6_ADDR 24 +#define VS_MATRIX_7_ADDR 28 +#define VS_MATRIX_8_ADDR 32 +#define VS_MATRIX_9_ADDR 36 +#define VS_MATRIX_10_ADDR 40 +#define VS_MATRIX_11_ADDR 44 +#define VS_MATRIX_12_ADDR 48 +#define VS_MATRIX_13_ADDR 52 +#define VS_MATRIX_14_ADDR 56 +#define VS_MATRIX_15_ADDR 60 +#define VS_LIGHT_AMBIENT_ADDR 64 +#define VS_LIGHT_DIFFUSE_ADDR 72 +#define VS_LIGHT_SPECULAR_ADDR 80 +#define VS_LIGHT_DIRPOS_ADDR 88 +#define VS_LIGHT_HWVSPOT_ADDR 96 +#define VS_LIGHT_ATTENUATION_ADDR 104 +#define VS_MATRIX_EYE2CLIP_ADDR 112 +#define VS_UCP_ADDR 116 +#define VS_GLOBAL_AMBIENT_ADDR 122 +#define VS_FOG_PARAM_ADDR 123 +#define VS_EYE_VECTOR_ADDR 124 + +#define SS_LIGHT_DCD_ADDR 0 +#define SS_LIGHT_SPOT_EXPONENT_ADDR 8 +#define SS_LIGHT_SPOT_CUTOFF_ADDR 16 +#define SS_LIGHT_SPECULAR_THRESH_ADDR 24 +#define SS_LIGHT_RANGE_CUTOFF_ADDR 32 +#define SS_VERT_GUARD_CLIP_ADJ_ADDR 48 +#define SS_VERT_GUARD_DISCARD_ADJ_ADDR 49 +#define SS_HORZ_GUARD_CLIP_ADJ_ADDR 50 +#define SS_HORZ_GUARD_DISCARD_ADJ_ADDR 51 +#define SS_SHININESS 60 + + +#endif /* __RADEON_REGS_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_state.h b/Source/DirectFB/gfxdrivers/radeon/radeon_state.h new file mode 100755 index 0000000..a91eca1 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_state.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani <klan@users.sf.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __RADEON_STATE_H__ +#define __RADEON_STATE_H__ + +#include <core/surface.h> + +/* R100 state funcs */ +void r100_restore ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev ); +void r100_set_destination ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_source ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_source_mask ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_clip ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_drawing_color ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_src_colorkey ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_render_options( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_drawingflags ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r100_set_blittingflags ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); + +/* R200 state funcs */ +void r200_restore ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev ); +void r200_set_destination ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_source ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_source_mask ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_clip ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_drawing_color ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_src_colorkey ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_render_options( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_drawingflags ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r200_set_blittingflags ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); + +/* R300 state funcs */ +void r300_restore ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev ); +void r300_set_destination ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_source ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_clip3d ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + const DFBRegion *clip ); +void r300_set_clip ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_drawing_color ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_src_colorkey ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_render_options( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_drawingflags ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); +void r300_set_blittingflags ( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ); + + +#define RADEON_IS_SET( flag ) \ + ((rdev->set & SMF_##flag) == SMF_##flag) + +#define RADEON_SET( flag ) \ + rdev->set |= SMF_##flag + +#define RADEON_UNSET( flag ) \ + rdev->set &= ~(SMF_##flag) + + +static inline u32 +radeon_buffer_offset( RadeonDeviceData *rdev, CoreSurfaceBufferLock *lock ) +{ + if (lock->phys - lock->offset == rdev->fb_phys) + return lock->offset + rdev->fb_offset; + + return lock->offset + rdev->agp_offset; +} + + +#endif /* __RADEON_STATE_H__ */ diff --git a/Source/DirectFB/gfxdrivers/radeon/vertex_shader.h b/Source/DirectFB/gfxdrivers/radeon/vertex_shader.h new file mode 100755 index 0000000..4fd0fd2 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/vertex_shader.h @@ -0,0 +1,83 @@ +#ifndef __VERTEX_SHADER_H__ +#define __VERTEX_SHADER_H__ + +#define VSF_FLAG_X 1 +#define VSF_FLAG_Y 2 +#define VSF_FLAG_Z 4 +#define VSF_FLAG_W 8 +#define VSF_FLAG_XYZ (VSF_FLAG_X | VSF_FLAG_Y | VSF_FLAG_Z) +#define VSF_FLAG_ALL 0xf +#define VSF_FLAG_NONE 0 + +#define VSF_OUT_CLASS_TMP 0 +#define VSF_OUT_CLASS_ADDR 1 +#define VSF_OUT_CLASS_RESULT 2 + + +/* first CARD32 of an instruction */ + +/* possible operations: + DOT, MUL, ADD, MAD, FRC, MAX, MIN, SGE, SLT, EXP, LOG, LIT, POW, RCP, RSQ, EX2, + LG2, MAD_2 */ + +#define MAKE_VSF_OP(op, out_reg_index, out_reg_fields, class) \ + ((op) \ + | ((out_reg_index) << R300_VPI_OUT_REG_INDEX_SHIFT) \ + | ((out_reg_fields) << 20) \ + | ( (class) << 8 ) ) + +#define EASY_VSF_OP(op, out_reg_index, out_reg_fields, class) \ + MAKE_VSF_OP(R300_VPI_OUT_OP_##op, out_reg_index, VSF_FLAG_##out_reg_fields, VSF_OUT_CLASS_##class) \ + +/* according to Nikolai, the subsequent 3 CARD32 are sources, use same define for each */ + +#define VSF_IN_CLASS_TMP 0 +#define VSF_IN_CLASS_ATTR 1 +#define VSF_IN_CLASS_PARAM 2 +#define VSF_IN_CLASS_NONE 9 + +#define VSF_IN_COMPONENT_X 0 +#define VSF_IN_COMPONENT_Y 1 +#define VSF_IN_COMPONENT_Z 2 +#define VSF_IN_COMPONENT_W 3 +#define VSF_IN_COMPONENT_ZERO 4 +#define VSF_IN_COMPONENT_ONE 5 + +#define MAKE_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \ + ( ((in_reg_index)<<R300_VPI_IN_REG_INDEX_SHIFT) \ + | ((comp_x)<<R300_VPI_IN_X_SHIFT) \ + | ((comp_y)<<R300_VPI_IN_Y_SHIFT) \ + | ((comp_z)<<R300_VPI_IN_Z_SHIFT) \ + | ((comp_w)<<R300_VPI_IN_W_SHIFT) \ + | ((negate)<<25) | ((class))) + +#define EASY_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \ + MAKE_VSF_SOURCE(in_reg_index, \ + VSF_IN_COMPONENT_##comp_x, \ + VSF_IN_COMPONENT_##comp_y, \ + VSF_IN_COMPONENT_##comp_z, \ + VSF_IN_COMPONENT_##comp_w, \ + VSF_IN_CLASS_##class, VSF_FLAG_##negate) + +/* special sources: */ + +/* (1.0,1.0,1.0,1.0) vector (ATTR, plain ) */ +#define VSF_ATTR_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, ATTR, NONE) +#define VSF_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, NONE, NONE) + +/* contents of unmodified register */ +#define VSF_REG(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, ATTR, NONE) + +/* contents of unmodified parameter */ +#define VSF_PARAM(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, PARAM, NONE) + +/* contents of unmodified temporary register */ +#define VSF_TMP(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, TMP, NONE) + +/* components of ATTR register */ +#define VSF_ATTR_X(reg) EASY_VSF_SOURCE(reg, X, X, X, X, ATTR, NONE) +#define VSF_ATTR_Y(reg) EASY_VSF_SOURCE(reg, Y, Y, Y, Y, ATTR, NONE) +#define VSF_ATTR_Z(reg) EASY_VSF_SOURCE(reg, Z, Z, Z, Z, ATTR, NONE) +#define VSF_ATTR_W(reg) EASY_VSF_SOURCE(reg, W, W, W, W, ATTR, NONE) + +#endif |