glide3x/0040700000175300010010000000000007725035157011521 5ustar johndoeNoneglide3x/AUTHORS0100700000175300010010000000015007725034542012562 0ustar johndoeNone-*-text-*- This code is the result of many engineers at 3Dfx. Names are in the source code in places. glide3x/build.3dfx.in0100700000175300010010000000460307725034542014013 0ustar johndoeNone#!/bin/bash function timereport() { STARTTIME=$1 ENDTIME=$2 SECONDSPERMIN=60 SECONDSPERHOUR=`expr 60 \* 60` SECONDSPERDAY=`expr 60 \* 60 \* 24` SECONDSPERYEAR=`expr 60 \* 60 \* 24 \* 365` ELAPSEDTIME=`expr $ENDTIME - $STARTTIME` YEARS=`expr $ELAPSEDTIME / $SECONDSPERYEAR` ELAPSEDTIME=`expr $ELAPSEDTIME % $SECONDSPERYEAR` DAYS=`expr $ELAPSEDTIME / $SECONDSPERDAY` ELAPSEDTIME=`expr $ELAPSEDTIME % $SECONDSPERDAY` HOURS=`expr $ELAPSEDTIME / $SECONDSPERHOUR` ELAPSEDTIME=`expr $ELAPSEDTIME % $SECONDSPERHOUR` MINUTES=`expr $ELAPSEDTIME / $SECONDSPERMIN` ELAPSEDTIME=`expr $ELAPSEDTIME % $SECONDSPERMIN` echo "Time Elapsed: $YEARS Years, $DAYS Days, $HOURS Hours, $MINUTES Minutes, $ELAPSEDTIME Seconds" } function diskreport() { SIGN="" DISKUSAGE=`expr $2 - $1` if [ $DISKUSAGE -lt 0 ] then DISKUSAGE=`expr $DISKUSAGE '*' -1` SIGN='-' fi DISKUSAGE_INT=`expr $DISKUSAGE / 1024` DISKUSAGE_FRAC=`expr $DISKUSAGE % 1024` echo "Disk usage: $SIGN$DISKUSAGE_INT.$DISKUSAGE_FRAC Mb" } function instrument_command() { STARTDISK=`df -k . | grep --invert-match '^Filesystem' | awk '{print $3;}'` df -k . STARTTIME=`date +%s` (exec "$@") ENDTIME=`date +%s` ENDDISK=`df -k . | grep --invert-match '^Filesystem' | awk '{print $3;}'` df -k . timereport $STARTTIME $ENDTIME diskreport $STARTDISK $ENDDISK } function xterm_title () { local working_directory if [ -z "$PWD" ] then working_directory=`/bin/pwd` else working_directory="$PWD" fi if [ "$1" == --title ] then shift title="$1" shift else title="$* @ `hostname`.`dnsdomainname`:$working_directory" fi echo ']0;'"$title"'' if [ ! -z "$1" ] then "$@" fi } DONE=NO USING_XTERM=`expr "$TERM" : "xterm.*"` while [ "$DONE" = NO ] ; do case "$1" in --no-x) USING_XTERM=0 shift ;; *) DONE=YES ;; esac done if [ $USING_XTERM -gt 0 ] then xterm_title --title "build.3dfx $@ (RUNNING) @ `hostname --fqdn`:$PWD" fi instrument_command make -f makefile.autoconf "$@" 2>&1 retstat="$?" if test "$retstat" = 0 ; then RETVAL="DONE" else RETVAL="FAILED" fi if [ $USING_XTERM -gt 0 ] then xterm_title --title "build.3dfx $@ ($RETVAL) @ `hostname --fqdn`:$PWD" fi exit $retstat glide3x/ChangeLog0100700000175300010010000000230407725034542013267 0ustar johndoeNone2000-08-02 Bill White * Added the swlibs/texus2 directory, in support of compressed textures. 2000-08-01 Bill White * swlibs/include/makefile.autoconf.am: Added CLEANFILES definition. * makefile.autoconf.am: Added CLEANFILES definition. * h5/glide3/src/makefile.autoconf.am: Changed include_headers to include_HEADERS. Added CLEANFILES definition. * h3/makefile.autoconf.am: Added. * cvg/glide3/src/makefile.autoconf.am: Added include_HEADERS. * cvg/makefile.autoconf.am: Added incsrc to get sst1vid.h. * configure.in: Changed the includedir to glide3 not glide3x. Added makefiles in h3/incsrc and cvg/incsrc * chores.3dfx: Changed --build-directory switch to work with --build-dir. * INSTALL: Changed some wording and fixed some errors. Also, removed the automake-generic boilerplate. * README: Removed some of the old installation instructions, which are no longer needed. 2000-07-26 Bill White * Added automake/autoconf project build management files. glide3x/chores.3dfx0100700000175300010010000001661107725034542013574 0ustar johndoeNone#!/bin/sh -f do_nothing() { return 0; } device () { df -k $1 | grep -v '^Filesystem' | awk '{print $1;}' } inumber () { ls -id "$1" | awk '{print $1;}' } # # This function returns: # 0 if the files are identical, # 100 if either of the parameters are the empty string. # 101 if either of the parameters does not name a directory # 102 if both parameters name different directories. # files_are_equal() { local inode1 inode2 dev1 dev2 if [ -z "$1" ] || [ -z "$2" ] ; then return 100; fi # # For the purposes of this script, if either directory # does not exist, then they are not equal. # if [ ! -d "$1" ] || [ ! -d "$2" ] ; then return 101 fi inode1=`inumber $1` inode2=`inumber $2` dev1=`device $1` dev2=`device $2` [ "$dev1" = "$dev2" ] && [ "$inode1" = "$inode2" ] && return 0 return 102 } rm="/bin/rm -rf" DONE=NO DO_CONFIGURE=NO DO_BUILD=NO DO_CLEAN=NO DO_GENERATE=NO BUILD_DIRECTORY=build MAKE_HISTORY_FILE=make.hst CONFIGURE_OPTIONS= BUILD_IS_DOT=NO while [ ! -z "$1" ] && [ "$DONE" != YES ] ; do case "$1" in --help) echo 'usage: chores.3dfx [options]' echo ' Handle some 3dfx specific configuration chores' echo 'Options:' echo ' --help This note.' echo ' --clean Delete some files in the source' echo ' directory. Since we do not generally' echo ' run make in the source directory,' echo ' the "make clean" rules are not so' echo ' useful there. The files deleted' echo ' are:' echo ' configure,' echo ' makefile.autoconf.{in},' echo ' aclocal.m4' echo ' *~, #*#, xx, yy, zz' echo ' Note that you need to put local macros' echo ' in acinclude.m4, not aclocal.m4. The' echo ' former is included in the latter.' echo ' --debug-build Add configuration option for a' echo ' debug build.' echo ' --texus2 Add configuration option to use' echo ' the texus2 library. (Do not use this' echo ' unless you know what you are doing.)' echo ' --architecture=arch Configure for the given architecture.' echo ' Equivalent to giving' echo ' --enable-build-architecture=arch' echo ' to "configure".' echo ' --generate: Generate configure script and' echo ' makefile.autoconf.in files.' echo ' This is essentially just:' echo ' aclocal; automake; autoconf' echo ' --build-dir=dir' echo ' Set the build directory to dir.' echo ' --configure="configure options"' echo ' Configure in the build directory' echo ' with the given options.' echo ' NOTE: this will delete and recreate' echo ' your build directory if it' echo ' exists.' echo ' --build[=dirname] Build in the given build directory.' echo ' o The default directory name is' echo ' named "build".' echo ' o The directory does not need to' echo ' be a subdirectory of the source' echo ' directory.' echo ' This option is equivalent to specifying' echo ' --build-directory=dirname --build' echo '' echo 'Note that the operations are done in logical order, not' echo 'in the order that the operations are specified on the' echo 'command line.' echo '' exit 100 ;; --debug-build) CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --enable-fx-debug" shift ;; --texus2) CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --enable-fx-texlib=texus2" shift ;; --generate) DO_GENERATE=YES shift ;; --arch*=*) CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --enable-build-architecture=`echo $1 | sed s/--arch[^=]*=//`" shift ;; --configure) DO_CONFIGURE=YES shift ;; --configure=*) DO_CONFIGURE=YES CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS `echo $1 | sed s/--configure=//`" shift ;; --build-dir*=*) BUILD_DIRECTORY=`echo $1 | sed 's/--build-dir[^=]*=//'` shift ;; --build=*) DO_BUILD=YES BUILD_DIRECTORY=`echo $1 | sed s/--build=//` shift ;; --build) DO_BUILD=YES shift ;; --clean) DO_CLEAN=YES shift ;; --make-hst=*) MAKE_HISTORY_FILE=`echo "$1" | sed s/--make-hst=//'` shift ;; *) echo "chores.3dfx: Unknown command line parameter $1" exit 100 ;; esac done if [ "$DO_CLEAN" = YES ] ; then # # Remove detritus. # echo -n 'Removing detritus...' find . '(' -name config.cache -o -name config.status -o -name build.3dfx -o -name config.h -o -name stamp-h -name config.log -o -name aclocal.m4 -o -name configure -o -name '*~' -o -name '#*#' -o -name makefile.autoconf.in -o -name xx -o -name yy -o -name zz ')' -a -exec $rm {} \; echo 'Done' fi if [ "$DO_GENERATE" = YES ] ; then # # Regenerate everything. # echo -n 'Regenerating everything...' echo -n 'Aclocal...' if aclocal ; then do_nothing else echo 'Failed!!' exit 100 fi echo -n 'Automake...' if automake --add-missing --copy; then do_nothing else echo 'Failed!!' exit 100 fi echo -n 'Autoconf...' if autoconf ; then do_nothing else echo 'Failed!!' exit 100 fi echo 'Done.' fi # # See if the build directory is the current directory. # if files_are_equal "${PWD}" "${BUILD_DIRECTORY}" ; then BUILD_IS_DOT=YES fi if [ "$DO_CONFIGURE" = YES ] ; then if [ "$BUILD_IS_DOT" = NO ] ; then # # Get rid of the build directory. # echo -n 'Getting rid of the old build directory...' /bin/rm -rf $BUILD_DIRECTORY echo 'Done.' else echo 'Old build directory is current directory.' fi if [ ! -d "$BUILD_DIRECTORY" ] ; then # # Now, make a build directory, and configure in it. # echo -n "Making build directory $BUILD_DIRECTORY..." mkdir -p $BUILD_DIRECTORY echo 'Done' fi # # Configure. # echo -n "Configuring..." SRCDIR="${PWD}" (cd $BUILD_DIRECTORY; ${SRCDIR}/configure --quiet $CONFIGURE_OPTIONS) echo 'Done.' fi if [ "$DO_BUILD" = YES ] ; then # # Build in it. # cd $BUILD_DIRECTORY ./build.3dfx all | tee $MAKE_HISTORY_FILE fi glide3x/configure.in0100700000175300010010000003231407725034542014032 0ustar johndoeNonednl Process this file with autoconf to produce a configure script. # # THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY # PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT # TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX # INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE # DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). # THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER # EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A # FULL TEXT OF THE NON-WARRANTY PROVISIONS. # # USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO # RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN # TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, # AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR # SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF # THE UNITED STATES. # # COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED # # $Revision: 1.8.4.4 $ # $Date: 2003/08/22 05:29:58 $ # AC_INIT(h5/glide3/src/glfb.c) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(glide, 3.0) AM_CONFIG_HEADER(swlibs/include/config.h) AC_PREFIX_DEFAULT([/usr]) includedir='${prefix}/include/glide3' # # Variables local to the build. # FX_HW_PROJECTS=glide3 AC_SUBST(FX_HW_PROJECTS) # # --enable-fx-glide-hw chooses which ASIC to build for. # AC_ARG_ENABLE([fx-glide-hw], [dnl --enable-fx-glide-hw=ASIC Build for the given ASIC h5: VoodooV h3: Voodoo3 cvg: Voodoo2 [default=h5]], [case ${enableval} in h3|h5|cvg) FX_GLIDE_HW="${enableval}" ;; *) AC_MSG_ERROR([Illegal value ($enable_fx_glide_hw) for --enable-fx-glide-hw]) ;; esac],[FX_GLIDE_HW=h5]) AC_SUBST(FX_GLIDE_HW) # # --enable-fx-dri-build chooses to build with or without DRI. # AC_ARG_ENABLE([fx-dri-build], [dnl --enable-fx-build-dri Build for DRI. [default=yes]], [case ${enableval} in true|yes) DRI_BUILD=true ;; false|no) DRI_BUILD=false ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-fx-build-dri]) ;; esac],[DRI_BUILD=true]) AM_CONDITIONAL(DRI_BUILD,test x$DRI_BUILD = xtrue) AC_SUBST(DRI_BUILD) # # This is makefile.linux behavior. I don't know exactly # what this does. # AM_CONDITIONAL(HAL_HW, test "$FX_GLIDE_HW"=cvg && test ! -z "$HAL_HW") # # Define debugging # AC_ARG_ENABLE([fx-debug], [dnl --enable-fx-debug Enable a debugging glide build [default=no]], [case ${enableval} in true|yes) GLIDE_DEBUG=true ;; false|no) GLIDE_DEBUG=false ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-fx-debug]) ;; esac],[GLIDE_DEBUG=false]) AM_CONDITIONAL(GLIDE_DEBUG,test x$GLIDE_DEBUG = xtrue) AC_SUBST(GLIDE_DEBUG) # # Define --enable-amd3d # AC_ARG_ENABLE([amd3d], [dnl --enable-amd3d Enable AMD 3DNow instructions [default=no]], [case ${enableval} in true|yes) enable_amd3d=true ;; false|no) enable_amd3d=false ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-amd3d]) ;; esac],[enable_amd3d=false]) AM_CONDITIONAL(GL_AMD3D, test x$enable_amd3d = xtrue) # # Define --enable-sse # AC_ARG_ENABLE([sse], [dnl --enable-sse Enable SSE instructions [default=no]], [case ${enableval} in true|yes) enable_sse=true ;; false|no) enable_sse=false ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-sse]) ;; esac],[enable_sse=false]) AM_CONDITIONAL(GL_SSE, test x$enable_sse = xtrue) # # Define --enable-mmx # AC_ARG_ENABLE([mmx], [dnl --enable-mmx Enable MMX instructions [default=no]], [case ${enableval} in true|yes) enable_mmx=true ;; false|no) enable_mmx=false ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-mmx]) ;; esac],[enable_mmx=false]) AM_CONDITIONAL(GL_MMX, test x$enable_mmx = xtrue) # # Define --enable-sse2 # AC_ARG_ENABLE([sse2], [dnl --enable-sse2 Enable SSE2 instructions [default=no]], [case ${enableval} in true|yes) enable_sse2=true ;; false|no) enable_sse2=false ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-sse2]) ;; esac],[enable_sse2=false]) AM_CONDITIONAL(GL_SSE2, test x$enable_sse2 = xtrue) # # --enable-fx-texlib=texus2 enables new texus library. # AC_ARG_ENABLE([fx-texlib], [dnl --enable-fx-tex=dir Enable enhanced texture utilities library texus - original library texus2 - library for compressed textures [default=texus2]], [case ${enableval} in texus|texus2) TEXTURE_UTILITIES_DIR=${enableval} ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-fx-texus]) ;; esac],[TEXTURE_UTILITIES_DIR=texus2]) AC_SUBST(TEXTURE_UTILITIES_DIR) # # These are conditional variables whose value is set by # one of the other enable macros. # AM_CONDITIONAL(FX_GLIDE_H3, test x$FX_GLIDE_HW = xh3) AM_CONDITIONAL(FX_GLIDE_H5, test x$FX_GLIDE_HW = xh5) AM_CONDITIONAL(FX_GLIDE_CVG, test x$FX_GLIDE_HW = xcvg) # # Architecture # AC_ARG_ENABLE([build-architecture], [dnl --enable-build-architecture Enable AMD 3DNow instructions [default=current]], [case ${enableval} in i[3456]86|alpha) FX_GLIDE_BUILD_ARCHITECTURE=${enableval} ;; *) AC_MSG_ERROR([Illegal value (${enableval}) for --enable-build-architecture]) ;; esac],[FX_GLIDE_BUILD_ARCHITECTURE=`uname -m`]) AC_SUBST(FX_GLIDE_BUILD_ARCHITECTURE) # # Various tests needed at points in the build # First, we set defaults. # FX_GLIDE_PACKET_FIFO=true FX_GLIDE3=true FX_GLIDE_PACKET_FIFO=true FX_GLIDE_SW_SETUP=false FX_CHRIS_DENIS_ANTHONY_HACK=false FX_GLIDE_ALT_TAB=false FX_GLIDE_DIRECT_WRITE=false HAL_CSIM=false FX_GLIDE_NO_FIFO=false FX_GLIDE_DEBUG_FIFO=false FX_GLIDE_NO_PLUG=false FX_GLIDE_NO_SPLASH=false GLIDE_SANITY_ALL=false GLIDE_SANITY_SIZE=false FX_DLL_BUILD=false FX_GLIDE_HW_CULL=false FX_GLIDE_CTRISETUP=false # Next, we read some configuration options # statically. This is to avoid creating a bunch of # not-terribly-useful --enable options. # if test -f $srcdir/swlibs/include/make/3dfx.config.sh ; then . $srcdir/swlibs/include/make/3dfx.config.sh fi AM_CONDITIONAL(FX_GLIDE3, test x$FX_GLIDE3 = xtrue) AM_CONDITIONAL(FX_CHRIS_DENIS_ANTHONY_HACK,dnl test x$FX_CHRIS_DENIS_ANTHONY_HACK = xtrue) AM_CONDITIONAL(FX_GLIDE_ALT_TAB,dnl test x$FX_GLIDE_ALT_TAB = xtrue) AM_CONDITIONAL(FX_GLIDE_DIRECT_WRITE,dnl test x$FX_GLIDE_DIRECT_WRITE = xtrue) AM_CONDITIONAL(HAL_CSIM,dnl test x$HAL_CSIM = xtrue) AM_CONDITIONAL(FX_GLIDE_SW_SETUP,dnl test x$FX_GLIDE_SW_SETUP = xtrue) AM_CONDITIONAL(FX_GLIDE_NO_FIFO,dnl test x$FX_GLIDE_NO_FIFO = xtrue) AM_CONDITIONAL(FX_GLIDE_DEBUG_FIFO,dnl test x$FX_GLIDE_DEBUG_FIFO = xtrue) AM_CONDITIONAL(FX_GLIDE_NO_PLUG,dnl test x$FX_GLIDE_NO_PLUG = xtrue) AM_CONDITIONAL(FX_GLIDE_NO_SPLASH,dnl test x$FX_GLIDE_NO_SPLASH = xtrue) AM_CONDITIONAL(GLIDE_SANITY_ALL,dnl test x$GLIDE_SANITY_ALL = xtrue) AM_CONDITIONAL(GLIDE_SANITY_SIZE,dnl test x$GLIDE_SANITY_SIZE = xtrue) AM_CONDITIONAL(FX_DLL_BUILD,dnl test x$FX_DLL_BUILD = xtrue) AM_CONDITIONAL(FX_GLIDE_HW_CULL,dnl test x$FX_GLIDE_HW_CULL = xtrue) AM_CONDITIONAL(FX_GLIDE_CTRISETUP,dnl test x$FX_GLIDE_CTRISETUP = xtrue) AM_CONDITIONAL(FX_GLIDE_PACKET_FIFO,dnl test x$FX_GLIDE_PACKET_FIFO = xtrue) AM_CONDITIONAL(FX_GLIDE_VERTEX_TABLE,dnl test x$FX_GLIDE_VERTEX_TABLE = xtrue) AM_CONDITIONAL(FX_HOOPTI_TRI_SETUP_COMPARE,dnl test x$FX_HOOPTI_TRI_SETUP_COMPARE = xtrue) AM_CONDITIONAL(DRI_BUILD,dnl test x$DRI_BUILD = xtrue) dnl Checks for programs. AC_PROG_CC AC_PROG_CPP AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(CP, cp, false) AC_PROG_INSTALL AM_PROG_LIBTOOL AM_PROG_AS AC_CHECK_PROG([MAKE], [gmake], [gmake -f makefile.autoconf], [make -f makefile.autoconf]) AC_SUBST(MAKE) dnl Checks for libraries. dnl Checks for header files. AC_PATH_X AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h sys/time.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM dnl Checks for library functions. AC_PROG_GCC_TRADITIONAL AC_FUNC_MEMCMP AC_FUNC_MMAP AC_FUNC_VPRINTF AC_CHECK_FUNCS(ftime gethostname select strcspn strdup strstr strtoul) dnl dnl This is complicated perhaps. We create a makefile by concatenating dnl the two files: dnl o $makefile.in dnl o swlibs/include/make/makefile.autoconf.bottom dnl where $makefile is the makefile name. dnl AC_OUTPUT(build.3dfx makefile.autoconf:makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom cvg/makefile.autoconf:cvg/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom cvg/incsrc/makefile.autoconf:cvg/incsrc/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom cvg/init/makefile.autoconf:cvg/init/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom cvg/glide3/makefile.autoconf:cvg/glide3/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom cvg/glide3/src/makefile.autoconf:cvg/glide3/src/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h3/makefile.autoconf:h3/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h3/incsrc/makefile.autoconf:h3/incsrc/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h3/minihwc/makefile.autoconf:h3/minihwc/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h3/glide3/makefile.autoconf:h3/glide3/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h3/glide3/src/makefile.autoconf:h3/glide3/src/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h5/makefile.autoconf:h5/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h5/glide3/makefile.autoconf:h5/glide3/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h5/glide3/src/makefile.autoconf:h5/glide3/src/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h5/incsrc/makefile.autoconf:h5/incsrc/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom h5/minihwc/makefile.autoconf:h5/minihwc/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/makefile.autoconf:swlibs/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/fxmisc/makefile.autoconf:swlibs/fxmisc/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/newpci/makefile.autoconf:swlibs/newpci/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/newpci/pcilib/makefile.autoconf:swlibs/newpci/pcilib/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/texus/makefile.autoconf:swlibs/texus/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/texus/lib/makefile.autoconf:swlibs/texus/lib/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/texus2/makefile.autoconf:swlibs/texus2/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/texus2/lib/makefile.autoconf:swlibs/texus2/lib/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom swlibs/texus2/cmd/makefile.autoconf:swlibs/texus2/cmd/makefile.autoconf.in:swlibs/include/make/makefile.autoconf.bottom, [chmod +x build.3dfx] ) glide3x/COPYING0100700000175300010010000002764107725034542012563 0ustar johndoeNone3DFX GLIDE Source Code General Public License 1. PREAMBLE This license is for software that provides a 3D graphics application program interface (API).The license is intended to offer terms similar to some standard General Public Licenses designed to foster open standards and unrestricted accessibility to source code. Some of these licenses require that, as a condition of the license of the software, any derivative works (that is, new software which is a work containing the original program or a portion of it) must be available for general use, without restriction other than for a minor transfer fee, and that the source code for such derivative works must likewise be made available. The only restriction is that such derivative works must be subject to the same General Public License terms as the original work. This 3dfx GLIDE Source Code General Public License differs from the standard licenses of this type in that it does not require the entire derivative work to be made available under the terms of this license nor is the recipient required to make available the source code for the entire derivative work. Rather, the license is limited to only the identifiable portion of the derivative work that is derived from the licensed software. The precise terms and conditions for copying, distribution and modification follow. 2. DEFINITIONS 2.1 This License applies to any program (or other "work") which contains a notice placed by the copyright holder saying it may be distributed under the terms of this 3dfx GLIDE Source Code General Public License. 2.2 The term "Program" as used in this Agreement refers to 3DFX's GLIDE source code and object code and any Derivative Work. 2.3 "Derivative Work" means, for the purpose of the License, that portion of any work that contains the Program or the identifiable portion of a work that is derived from the Program, either verbatim or with modifications and/or translated into another language, and that performs 3D graphics API operations. It does not include any other portions of a work. 2.4 "Modifications of the Program" means any work, which includes a Derivative Work, and includes the whole of such work. 2.5 "License" means this 3dfx GLIDE Source Code General Public License. 2.6 The "Source Code" for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, any associated interface definition files, and the scripts used to control compilation and installation of the executable work. 2.7 "3dfx" means 3dfx Interactive, Inc. 3. LICENSED ACTIVITIES 3.1 COPYING - You may copy and distribute verbatim copies of the Program's Source Code as you receive it, in any medium, subject to the provision of section 3.3 and provided also that: (a) you conspicuously and appropriately publish on each copy an appropriate copyright notice (3dfx Interactive, Inc. 1999), a notice that recipients who wish to copy, distribute or modify the Program can only do so subject to this License, and a disclaimer of warranty as set forth in section 5; (b) keep intact all the notices that refer to this License and to the absence of any warranty; and (c) do not make any use of the GLIDE trademark without the prior written permission of 3dfx, and (d) give all recipients of the Program a copy of this License along with the Program or instructions on how to easily receive a copy of this License. 3.2 MODIFICATION OF THE PROGRAM/DERIVATIVE WORKS - You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications subject to the provisions of section 3.3 and provided that you also meet all of the following conditions: (a) you conspicuously and appropriately publish on each copy of a Derivative Work an appropriate copyright notice, a notice that recipients who wish to copy, distribute or modify the Derivative Work can only do so subject to this License, and a disclaimer of warranty as set forth in section 5; (b) keep intact all the notices that refer to this License and to the absence of any warranty; and (c) give all recipients of the Derivative Work a copy of this License along with the Derivative Work or instructions on how to easily receive a copy of this License. (d) You must cause the modified files of the Derivative Work to carry prominent notices stating that you changed the files and the date of any change. (e) You must cause any Derivative Work that you distribute or publish to be licensed at no charge to all third parties under the terms of this License. (f) You do not make any use of the GLIDE trademark without the prior written permission of 3dfx. (g) If the Derivative Work normally reads commands interactively when run, you must cause it, when started running for such interactive use, to print or display an announcement as follows: "COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED THIS SOFTWARE IS FREE AND PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. THERE IS NO RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE, INC. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE DISTRIBUTION AND NON-WARRANTY PROVISIONS (REQUEST COPY FROM INFO@3DFX.COM)." (h) The requirements of this section 3.2 do not apply to the modified work as a whole but only to the Derivative Work. It is not the intent of this License to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of Derivative Works. 3.3 DISTRIBUTION (a) All copies of the Program or Derivative Works which are distributed must include in the file headers the following language verbatim: "THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC (info@3dfx.com). THIS PROGRAM. IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE NON-WARRANTY PROVISIONS. USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED" (b) You may distribute the Program or a Derivative Work in object code or executable form under the terms of Sections 3.1 and 3.2 provided that you also do one of the following: (1) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 3.1 and 3.2; or, (2) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 3.1 and 3.2 on a medium customarily used for software interchange; or, (3) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection 3.3(b)(2) above.) (c) The source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable code. (d) If distribution of executable code or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. (e) Each time you redistribute the Program or any Derivative Work, the recipient automatically receives a license from 3dfx and successor licensors to copy, distribute or modify the Program and Derivative Works subject to the terms and conditions of the License. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. (f) You may not make any use of the GLIDE trademark without the prior written permission of 3dfx. (g) You may not copy, modify, sublicense, or distribute the Program or any Derivative Works except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program or any Derivative Works is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 4. MISCELLANEOUS 4.1 Acceptance of this License is voluntary. By using, modifying or distributing the Program or any Derivative Work, you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. Nothing else grants you permission to modify or distribute the Program or Derivative Works and doing so without acceptance of this License is in violation of the U.S. and international copyright laws. 4.2 If the distribution and/or use of the Program or Derivative Works is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 4.3 This License is to be construed according to the laws of the State of California and you consent to personal jurisdiction in the State of California in the event it is necessary to enforce the provisions of this License. 5. NO WARRANTIES 5.1 TO THE EXTENT PERMITTED BY APPLICABLE LAW, THERE IS NO WARRANTY FOR THE PROGRAM. OR DERIVATIVE WORKS THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM AND ANY DERIVATIVE WORKS"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM AND ANY DERIVATIVE WORK IS WITH YOU. SHOULD THE PROGRAM OR ANY DERIVATIVE WORK PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 5.2 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL 3DFX INTERACTIVE, INC., OR ANY OTHER COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM OR DERIVATIVE WORKS AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM OR DERIVATIVE WORKS (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM OR DERIVATIVE WORKS TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. glide3x/glide_license.txt0100700000175300010010000002764107725034542015057 0ustar johndoeNone3DFX GLIDE Source Code General Public License 1. PREAMBLE This license is for software that provides a 3D graphics application program interface (API).The license is intended to offer terms similar to some standard General Public Licenses designed to foster open standards and unrestricted accessibility to source code. Some of these licenses require that, as a condition of the license of the software, any derivative works (that is, new software which is a work containing the original program or a portion of it) must be available for general use, without restriction other than for a minor transfer fee, and that the source code for such derivative works must likewise be made available. The only restriction is that such derivative works must be subject to the same General Public License terms as the original work. This 3dfx GLIDE Source Code General Public License differs from the standard licenses of this type in that it does not require the entire derivative work to be made available under the terms of this license nor is the recipient required to make available the source code for the entire derivative work. Rather, the license is limited to only the identifiable portion of the derivative work that is derived from the licensed software. The precise terms and conditions for copying, distribution and modification follow. 2. DEFINITIONS 2.1 This License applies to any program (or other "work") which contains a notice placed by the copyright holder saying it may be distributed under the terms of this 3dfx GLIDE Source Code General Public License. 2.2 The term "Program" as used in this Agreement refers to 3DFX's GLIDE source code and object code and any Derivative Work. 2.3 "Derivative Work" means, for the purpose of the License, that portion of any work that contains the Program or the identifiable portion of a work that is derived from the Program, either verbatim or with modifications and/or translated into another language, and that performs 3D graphics API operations. It does not include any other portions of a work. 2.4 "Modifications of the Program" means any work, which includes a Derivative Work, and includes the whole of such work. 2.5 "License" means this 3dfx GLIDE Source Code General Public License. 2.6 The "Source Code" for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, any associated interface definition files, and the scripts used to control compilation and installation of the executable work. 2.7 "3dfx" means 3dfx Interactive, Inc. 3. LICENSED ACTIVITIES 3.1 COPYING - You may copy and distribute verbatim copies of the Program's Source Code as you receive it, in any medium, subject to the provision of section 3.3 and provided also that: (a) you conspicuously and appropriately publish on each copy an appropriate copyright notice (3dfx Interactive, Inc. 1999), a notice that recipients who wish to copy, distribute or modify the Program can only do so subject to this License, and a disclaimer of warranty as set forth in section 5; (b) keep intact all the notices that refer to this License and to the absence of any warranty; and (c) do not make any use of the GLIDE trademark without the prior written permission of 3dfx, and (d) give all recipients of the Program a copy of this License along with the Program or instructions on how to easily receive a copy of this License. 3.2 MODIFICATION OF THE PROGRAM/DERIVATIVE WORKS - You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications subject to the provisions of section 3.3 and provided that you also meet all of the following conditions: (a) you conspicuously and appropriately publish on each copy of a Derivative Work an appropriate copyright notice, a notice that recipients who wish to copy, distribute or modify the Derivative Work can only do so subject to this License, and a disclaimer of warranty as set forth in section 5; (b) keep intact all the notices that refer to this License and to the absence of any warranty; and (c) give all recipients of the Derivative Work a copy of this License along with the Derivative Work or instructions on how to easily receive a copy of this License. (d) You must cause the modified files of the Derivative Work to carry prominent notices stating that you changed the files and the date of any change. (e) You must cause any Derivative Work that you distribute or publish to be licensed at no charge to all third parties under the terms of this License. (f) You do not make any use of the GLIDE trademark without the prior written permission of 3dfx. (g) If the Derivative Work normally reads commands interactively when run, you must cause it, when started running for such interactive use, to print or display an announcement as follows: "COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED THIS SOFTWARE IS FREE AND PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. THERE IS NO RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE, INC. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE DISTRIBUTION AND NON-WARRANTY PROVISIONS (REQUEST COPY FROM INFO@3DFX.COM)." (h) The requirements of this section 3.2 do not apply to the modified work as a whole but only to the Derivative Work. It is not the intent of this License to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of Derivative Works. 3.3 DISTRIBUTION (a) All copies of the Program or Derivative Works which are distributed must include in the file headers the following language verbatim: "THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC (info@3dfx.com). THIS PROGRAM. IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE NON-WARRANTY PROVISIONS. USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED" (b) You may distribute the Program or a Derivative Work in object code or executable form under the terms of Sections 3.1 and 3.2 provided that you also do one of the following: (1) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 3.1 and 3.2; or, (2) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 3.1 and 3.2 on a medium customarily used for software interchange; or, (3) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection 3.3(b)(2) above.) (c) The source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable code. (d) If distribution of executable code or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. (e) Each time you redistribute the Program or any Derivative Work, the recipient automatically receives a license from 3dfx and successor licensors to copy, distribute or modify the Program and Derivative Works subject to the terms and conditions of the License. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. (f) You may not make any use of the GLIDE trademark without the prior written permission of 3dfx. (g) You may not copy, modify, sublicense, or distribute the Program or any Derivative Works except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program or any Derivative Works is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 4. MISCELLANEOUS 4.1 Acceptance of this License is voluntary. By using, modifying or distributing the Program or any Derivative Work, you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. Nothing else grants you permission to modify or distribute the Program or Derivative Works and doing so without acceptance of this License is in violation of the U.S. and international copyright laws. 4.2 If the distribution and/or use of the Program or Derivative Works is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 4.3 This License is to be construed according to the laws of the State of California and you consent to personal jurisdiction in the State of California in the event it is necessary to enforce the provisions of this License. 5. NO WARRANTIES 5.1 TO THE EXTENT PERMITTED BY APPLICABLE LAW, THERE IS NO WARRANTY FOR THE PROGRAM. OR DERIVATIVE WORKS THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM AND ANY DERIVATIVE WORKS"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM AND ANY DERIVATIVE WORK IS WITH YOU. SHOULD THE PROGRAM OR ANY DERIVATIVE WORK PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 5.2 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL 3DFX INTERACTIVE, INC., OR ANY OTHER COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM OR DERIVATIVE WORKS AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM OR DERIVATIVE WORKS (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM OR DERIVATIVE WORKS TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. glide3x/h5/0040700000175300010010000000000007725035157012035 5ustar johndoeNoneglide3x/h5/bin/0040700000175300010010000000000007725034434012602 5ustar johndoeNoneglide3x/h5/cinit/0040700000175300010010000000000007725034434013140 5ustar johndoeNoneglide3x/h5/cinit/h3cinit.c0100700000175300010010000012453107725034640014652 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** File name: h3cinit.c ** ** Description: HW-specific initialization routines for Banshee/Avenger. ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ ** ** $History: h3cinit.c $ ** ** ***************** Version 1 ***************** ** User: Sapphire Date: 3/16/99 Time: 7:28p ** Created in $/Releases/Voodoo3/V3_OEM_100/3dfx/devel/H3/cinit ** ** ***************** Version 60 ***************** ** User: Stb_srogers Date: 2/16/99 Time: 4:17p ** Updated in $/devel/h3/win95/dx/minivdd ** ** ***************** Version 59 ***************** ** User: Cwilcox Date: 2/10/99 Time: 6:23p ** Updated in $/devel/h3/Win95/dx/minivdd ** Fixed video initialization to handle tiled mode for low resolutions. ** ** ***************** Version 58 ***************** ** User: Cwilcox Date: 2/10/99 Time: 3:44p ** Updated in $/devel/h3/Win95/dx/minivdd ** Linear versus tiled promotion removal. ** ** ***************** Version 57 ***************** ** User: Andrew Date: 2/07/99 Time: 4:44p ** Updated in $/devel/h3/Win95/dx/minivdd ** Added a check for 2048 and then I make it 2046 so that the mode will ** come up. ** ** ***************** Version 56 ***************** ** User: Jeske Date: 1/15/99 Time: 11:41a ** Updated in $/devel/h3/cinit ** allow setting of only one clock for h3 ** ** ***************** Version 55 ***************** ** User: Michael Date: 1/05/99 Time: 8:44a ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 54 ***************** ** User: Jeske Date: 12/22/98 Time: 3:25p ** Updated in $/devel/h3/cinit ** added h3InitGetMemSize(), it calculates the memory size and does NOT ** write any registers... ** ** ***************** Version 53 ***************** ** User: Lab Date: 11/13/98 Time: 6:58p ** Updated in $/devel/h4/cinit ** Changed draminit1 for Avenger ** ** ***************** Version 52 ***************** ** User: Pault Date: 11/12/98 Time: 3:46p ** Updated in $/devel/h4/cinit ** Removed Banshee A series silicon support. No more ifdef H3_B0. ** ** ***************** Version 50 ***************** ** User: Pault Date: 11/05/98 Time: 2:04p ** Updated in $/devel/h4/cinit ** Added h4InitPlls function. ** ** ***************** Version 49 ***************** ** User: Jeske Date: 8/18/98 Time: 5:33p ** Updated in $/devel/h3/cinit ** don't change dramInit1 for diags either... this probably should be the ** case for everyone ** ** ***************** Version 48 ***************** ** User: Psmith Date: 7/29/98 Time: 8:22a ** Updated in $/devel/h3/cinit ** prevent memory type from being undefined, default to SGRAM ** ** ***************** Version 47 ***************** ** User: Psmith Date: 7/29/98 Time: 7:42a ** Updated in $/devel/h3/cinit ** added h3InitResetAll() routine to perform a full reset of the chip ** ** ***************** Version 46 ***************** ** User: Andrew Date: 7/27/98 Time: 1:29p ** Updated in $/devel/h3/Win95/dx/minivdd ** Added Scan Line Double Modes ** ** ***************** Version 45 ***************** ** User: Psmith Date: 7/23/98 Time: 5:14p ** Updated in $/devel/h3/cinit ** added initialization of dramInit1_strap for A-series silicon ** ** ***************** Version 44 ***************** ** User: Psmith Date: 7/23/98 Time: 6:14a ** Updated in $/devel/h3/cinit ** updated SDRAM init code to only disable 2d block writes ** ** ***************** Version 43 ***************** ** User: Psmith Date: 7/22/98 Time: 9:11a ** Updated in $/devel/h3/cinit ** added sdram support ** ** ***************** Version 42 ***************** ** User: Mikec Date: 7/20/98 Time: 11:14a ** Updated in $/devel/h3/cinit ** Made H3_A2 default instead of H3_B0. Also added #if H3VDD around ** vidOverlayDudxOffsetSrcWidth. ** ** ***************** Version 41 ***************** ** User: Psmith Date: 7/17/98 Time: 12:32p ** Updated in $/devel/h3/cinit ** updated dramInit1 timing parameters for Gateway ** made sgram vendor lookup case insensitive ** ** ***************** Version 40 ***************** ** User: Ken Date: 7/11/98 Time: 5:51p ** Updated in $/devel/h3/win95/dx/minivdd ** more b0 fixups for gateway ** ** ***************** Version 39 ***************** ** User: Ken Date: 7/10/98 Time: 9:00p ** Updated in $/devel/h3/win95/dx/minivdd ** memory / clock timing default changes. default grxclock and memclock ** timings are now settable at compile time. temporarily, set HR=B0 to ** compile for A2/A3 for minivdd only. dramInit0 is now not touched in ** the win95 init sequence, unless there's an override in the registry ** ** ***************** Version 38 ***************** ** User: Psmith Date: 7/10/98 Time: 5:18p ** Updated in $/devel/h3/cinit ** *** changed default compilation mode to H3_B0 *** ** new sgram config for b0 ** allow env variables to override sgram config values ** ** ***************** Version 37 ***************** ** User: Ken Date: 7/02/98 Time: 6:23p ** Updated in $/devel/h3/win95/dx/minivdd ** added magic parameter values to h3InitSGRAM so that windows boot can ** skip the writing of the SGRAM registers ** ** ***************** Version 36 ***************** ** User: Ken Date: 7/01/98 Time: 6:36p ** Updated in $/devel/h3/win95/dx/minivdd ** added 16bpp low res modes using video overlay stretching ** ** ***************** Version 35 ***************** ** User: Jeske Date: 6/03/98 Time: 1:51p ** Updated in $/devel/h3/cinit ** put h3InitSetVideoMode() back to taking refresh in Hz, documented the ** argument requirements. ** ** ***************** Version 34 ***************** ** User: Ken Date: 6/02/98 Time: 12:27p ** Updated in $/devel/h3/win95/dx/minivdd ** fixed off by one error in LUT initialization ** ** ***************** Version 33 ***************** ** User: Jeske Date: 6/01/98 Time: 5:48p ** Updated in $/devel/h3/cinit ** 1) convert the ordinal refresh mode to a numerical refresh in HZ, 2) ** support failing the video mode set so we can shutdown gracefully.. ** ** ***************** Version 32 ***************** ** User: Psmith Date: 5/09/98 Time: 11:20a ** Updated in $/devel/h3/cinit ** fixed #if's to compile correctly for H3_A2 ** ** ***************** Version 31 ***************** ** User: Psmith Date: 5/08/98 Time: 2:50p ** Updated in $/devel/h3/cinit ** added routine to set BlockWrite threshhold ** ** ***************** Version 30 ***************** ** User: Andrew Date: 5/07/98 Time: 2:42p ** Updated in $/devel/h3/Win95/dx/minivdd ** Added a hack to get 1800x1440 to work in Win '9X. Unknown why display ** pitch needs to be crunched. ** ** ***************** Version 29 ***************** ** User: Peter Date: 4/17/98 Time: 1:24p ** Updated in $/devel/h3/cinit ** 8.3 fun ** ** ***************** Version 28 ***************** ** User: Ken Date: 4/16/98 Time: 5:32p ** Updated in $/devel/h3/win95/dx/minivdd ** properly set the vidProcCfg 1x/2x bit ** ** ***************** Version 27 ***************** ** User: Dow Date: 4/16/98 Time: 12:00p ** Updated in $/devel/h3/cinit ** fixed warnings in h3cinit made warnings=errors for Glide ** ** ***************** Version 26 ***************** ** User: Ken Date: 4/15/98 Time: 6:41p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** ** ***************** Version 25 ***************** ** User: Psmith Date: 4/09/98 Time: 8:00p ** Updated in $/devel/h3/cinit ** added support for multiple SGRAM vendors ** added support for programming PLLs a wider range of clock frequencies ** ** ***************** Version 24 ***************** ** User: Psmith Date: 3/30/98 Time: 5:37p ** Updated in $/devel/h3/cinit ** fix for VGA blank with screen off ** ** ***************** Version 23 ***************** ** User: Ken Date: 3/20/98 Time: 11:30a ** Updated in $/devel/h3/win95/dx/minivdd ** removed non-vdd friendly stuff (ifdefed out proces monitor function, ** until its fixed up) ** ** ***************** Version 22 ***************** ** User: Psmith Date: 3/19/98 Time: 8:47p ** Updated in $/devel/h3/cinit ** added code to read/display silicon performance values ** ** ***************** Version 21 ***************** ** User: Ken Date: 3/17/98 Time: 3:55p ** Updated in $/devel/h3/win95/dx/minivdd ** added -DH3_A1 when compiling on A1. changed h3cinit.c so that until ** the non-MS folks add an H3_A0 flag, when not compiling the H3 VDD, the ** absence of H3_A1 automatically defines H3_A0 ** ** ***************** Version 20 ***************** ** User: Ken Date: 3/17/98 Time: 12:07p ** Updated in $/devel/h3/win95/dx/minivdd ** fixed incorrect #ifdef'ing for H3_A0 ** ** ***************** Version 19 ***************** ** User: Ken Date: 3/17/98 Time: 11:21a ** Updated in $/devel/h3/win95/dx/minivdd ** placed A0 workarounds in #ifdef H3_A0. updated makefiles to use ** environment variable HR for hardware rev. if hardware rev is not ** HR=A1, then we build an A0 revision. use #ifdef H3_A0 for A0 ** workarounds ** ** ***************** Version 18 ***************** ** User: Ken Date: 2/15/98 Time: 11:47a ** Updated in $/devel/h3/win95/dx/minivdd ** added parameter to setvideomode to conditionally initialize clut ** ** ***************** Version 17 ***************** ** User: Psmith Date: 2/13/98 Time: 7:38p ** Updated in $/devel/h3/cinit ** added 16Mbit SGRAM support ** ** ***************** Version 16 ***************** ** User: Ken Date: 2/13/98 Time: 4:55p ** Updated in $/devel/h3/win95/dx/minivdd ** added init of tmuGbeInit to turn off texture caching ** ** ***************** Version 15 ***************** ** User: Miriam Date: 2/13/98 Time: 1:17p ** Updated in $/devel/h3/Win95/dx/minivdd ** Can't use texture cache yet. ** ** ***************** Version 14 ***************** ** User: Ken Date: 2/11/98 Time: 8:13p ** Updated in $/devel/h3/win95/dx/minivdd ** updated to latest h3init.pm, fixes 1280 modes ** ** ***************** Version 13 ***************** ** User: Psmith Date: 2/10/98 Time: 7:34p ** Updated in $/devel/h3/cinit ** got rid of monitor click !!! ** ** ***************** Version 12 ***************** ** User: Bangell Date: 2/10/98 Time: 3:50p ** Updated in $/devel/h3/cinit ** allow MEM and GRX clocks to be set to different frequencies ** ** ***************** Version 11 ***************** ** User: Ken Date: 2/09/98 Time: 8:31a ** Updated in $/devel/h3/win95/dx/minivdd ** updated to andy's latest perl code, now has full mode table ** ** ***************** Version 10 ***************** ** User: Ken Date: 2/04/98 Time: 1:29p ** Updated in $/devel/h3/win95/dx/minivdd ** turn off VGA screen refresh in h3initSetVideoMode ** ** ***************** Version 9 ***************** ** User: Ken Date: 1/25/98 Time: 3:08p ** Updated in $/Users/ken/banshee-bringup/directdiags/xor ** added desktop/overlay surface functions ** ** ***************** Version 8 ***************** ** User: Ken Date: 1/25/98 Time: 1:13p ** Updated in $/Users/ken/banshee-bringup/directdiags/xor ** changed h3InitVideo to h3InitVideoProc, now takes a single ** parameter which is simply passed into the vidProcCfg register ** ** ***************** Version 7 ***************** ** User: Ken Date: 1/25/98 Time: 12:27p ** Updated in $/users/ken/banshee-bringup/directdiags/xor ** rollback, new version ** ** ***************** Version 5 ***************** ** User: Ken Date: 1/24/98 Time: 4:41p ** Updated in $/devel/h3/cinit ** works now ** ** ***************** Version 4 ***************** ** User: Dow Date: 1/24/98 Time: 9:11a ** Updated in $/devel/h3/cinit ** WIP ** ** ***************** Version 3 ***************** ** User: Dow Date: 1/23/98 Time: 3:28p ** Updated in $/devel/h3/cinit ** Keywords ** */ #include #include /* 8.3 fun */ #ifdef __DOS32__ #include "h3cini~1.h" #else #include "h3cinitdd.h" #endif // Fixing support for H4 pll tables. #ifdef H4 #include "h4oempll.h" #include "h4pll.h" #else #include "plltable.h" #endif #include "memtable.h" #ifndef H3VDD #include "stdlib.h" #endif // #ifndef H3VDD // LISTEN UP // // The macros used in this file need a varible called regBase. // Because the init registers are aliased both in the io and memory // map, it's up to the caller and the implementor of h3cinitdd.h to // agree on whether you're using the i/o or the memory mapping // /*---------------------------------------------------------------------- Function name: h3InitGetMemSize Description: Return the size of memory in MBs. Information: Return: FxU32 The size of memory in MBs. ----------------------------------------------------------------------*/ FxU32 h3InitGetMemSize (FxU32 regBase, FxBool isNapalm) { FxU32 partSize, // size of SGRAM chips in Mbits nChips, // # of chips of SDRAM/SGRAM dramInit0_strap; /* Determine memory size from strapping pins (dramInit0). */ dramInit0_strap = IGET32(dramInit0); #ifdef FX_GLIDE_NAPALM if (isNapalm) { // Napalm memory sizing nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8; switch (dramInit0_strap & SST_H5_SGRAM_TYPE) { case SST_SGRAM_TYPE_8MBIT: partSize = 8; break; case SST_SGRAM_TYPE_16MBIT: partSize = 16; break; case SST_SGRAM_TYPE_32MBIT: partSize = 32; break; case SST_SGRAM_TYPE_64MBIT: partSize = 64; break; case SST_SGRAM_TYPE_128MBIT: partSize = 128; break; default: return 0; // invalid sgram type! } } else #endif /* FX_GLIDE_NAPALM */ { // Banshee and Avenger memory sizing // determine memory type: SDRAM or SGRAM FxU32 dramInit1_strap = IGET32(dramInit1); if (dramInit1_strap & SST_MCTL_TYPE_SDRAM) { nChips = 8; partSize = 16; } else { nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8; switch (dramInit0_strap & SST_SGRAM_TYPE) { case SST_SGRAM_TYPE_8MBIT: partSize = 8; break; case SST_SGRAM_TYPE_16MBIT: partSize = 16; break; default: return 0; // invalid sgram type! } } } /* Compute memory size in megabytes. */ return (nChips * partSize) / 8; } /*---------------------------------------------------------------------- Function name: h3InitSgram Description: Initialize the dram registers. Information: Return: FxU32 The size of memory in MBs. ----------------------------------------------------------------------*/ FxU32 // return # of MB of memory h3InitSgram(FxU32 regBase, // init io-register base FxU32 sgramMode, FxU32 sgramMask, FxU32 sgramColor, char *vendorName // NULL or name of sgram vendor ) { FxU32 memType, // SGRAM or SDRAM partSize, // size of SGRAM chips in Mbits memSize, // total size of memory in MBytes nChips, // # chips of SDRAM/SGRAM dramInit0_strap, dramInit1_strap, dramInit0, dramInit1, miscInit1; FxU32 vendorID; // determine memory type: SDRAM or SGRAM memType = MEM_TYPE_SGRAM; dramInit1_strap = IGET32(dramInit1); dramInit1_strap &= SST_MCTL_TYPE_SDRAM; if ( dramInit1_strap & SST_MCTL_TYPE_SDRAM ) memType = MEM_TYPE_SDRAM; // set memory interface delay values and enable refresh // these apply to all RAM vendors dramInit1 = 0x0; dramInit1 |= SST_DRAM_REFRESH_EN; dramInit1 |= (0x18 << SST_DRAM_REFRESH_VALUE_SHIFT) & SST_DRAM_REFRESH_VALUE; dramInit1 |= SST_SGRAM_USE_INV_SAMPLE; dramInit1 |= SST_SGRAM_DEL_CLK_INVERT; dramInit1 |= (8<='a'&&(c)<='z') ? ((c)-'a'+'A') : (c) ) /* only works for alphabetic characters */ int i; char *v, *t; int found; // search table for a vendor/size match for (i=0; i= MEM_TABLE_SIZE ) GDBG_ERROR("h3InitSgram","vendor %s not found, defaulting to %s\n", vendorName, memTable[vendorID].vendor); } GDBG_INFO(80, "h3InitSgram: %d x %d Mbit %s %s parts = %d MBytes\n", nChips, partSize, memTable[vendorID].vendor, memType == MEM_TYPE_SDRAM ? "SDRAM" : "SGRAM", memSize); dramInit0 = memTable[vendorID].dramInit0; // write vendor specific SGRAM timings, preserving the SGRAM chipset/size // information #if !defined(H3VDD) && !defined(DIAG_BUILD) if ( GETENV("SSTH3_DRAMINIT0") ) dramInit0 = strtoul(GETENV("SSTH3_DRAMINIT0"),NULL,0); #endif // #ifndef H3VDD dramInit0 &= ~(SST_SGRAM_TYPE | SST_SGRAM_NUM_CHIPSETS); dramInit0 |= dramInit0_strap; #if !defined(H3VDD) && !defined(DIAG_BUILD) // don't write dramInit0 in the windows driver by default -- we're using // the BIOS's value instead. It can be overridden in the registry // if the user wants to change it or experiment // GDBG_INFO(80, "h3InitSgram: dramInit0 = 0x%x\n",dramInit0); ISET32(dramInit0, dramInit0); #endif // #ifndef H3VDD // Only set the SGRAM registers if the "magic code" isn't sent in. // The windows driver will send in the magic code for the main device // initialization on pre-B0 silicon, because writing to the SGRAM // registers on a soft reboot in certain conditions in pre-B silicon // causes the chip to go nuts, so in those cases we just have to live // with the BIOS defaults for the SGRAM registers. // if (!((sgramMode == 0xDEADBEEF) && (sgramMask == 0xF00DCAFE))) { #ifndef H3VDD sgramMode = memTable[vendorID].sgramMode; if ( GETENV("SSTH3_SGRAMMODE") ) sgramMode = strtoul(GETENV("SSTH3_SGRAMMODE"),NULL,0); #else sgramMode = memTable[vendorID].sgramMode; #endif // #ifndef H3VDD GDBG_INFO(80, "h3InitSgram: sgramMode = 0x%x\n", sgramMode); ISET32(dramData, sgramMode); ISET32(dramCommand, 0x10d); if ( memType == MEM_TYPE_SGRAM ) { // only for SGRAM ISET32(dramData, sgramMask); ISET32(dramCommand, 0x10e); ISET32(dramData, sgramColor); ISET32(dramCommand, 0x10f); } } // // disable block writes for SDRAM // if ( memType == MEM_TYPE_SDRAM ) { miscInit1 = IGET32(miscInit1); miscInit1 |= SST_DISABLE_2D_BLOCK_WRITE; ISET32(miscInit1, miscInit1); } // return # of MBytes of board memory return memSize; } // h3initSgram /*---------------------------------------------------------------------- Function name: h4InitPlls Description: Initialize the Avenger Plls. Information: Return: VOID ----------------------------------------------------------------------*/ #ifdef H4 void h4InitPlls(FxU32 regBase, // init register base FxU32 deviceID, // H4 or H4_OEM FxU32 grxSpeedInMHz) // desired clock frequency (MHz) { FxU32 maxGrxSpeedInMHz; if (deviceID == SST_DEVICE_ID_H4_OEM) { maxGrxSpeedInMHz = MAX_H4_OEM_PLL_FREQ; } else { maxGrxSpeedInMHz = MAX_H4_PLL_FREQ; } // set the graphics clock // if ( grxSpeedInMHz < MIN_PLL_FREQ || grxSpeedInMHz > maxGrxSpeedInMHz ) { MESSAGE("YO! GRX clock speed of %d MHz is out of range MIN_PLL_FREQ to maxGrxSpeedInMHz\n", grxSpeedInMHz); } else { GDBG_INFO(80, "Setting Graphics Clock (%d MHz)\n",grxSpeedInMHz); if (deviceID == SST_DEVICE_ID_H4_OEM) { ISET32(pllCtrl1, h4oempllTable[grxSpeedInMHz]); } else { ISET32(pllCtrl1, h4pllTable[grxSpeedInMHz]); } } } // h4InitPlls #else /*---------------------------------------------------------------------- Function name: h3InitPlls Description: Initialize the Banshee Plls. If you pass in a zero for one of the clock paramater, then that clock is ignored. Thus, you can set only the memory clock by calling h3InitPlls(regbase,0,memClock); Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitPlls(FxU32 regBase, // init iegister base FxU32 grxSpeedInMHz, // desired clock frequency (MHz) FxU32 memSpeedInMHz) // desired clock frequency (MHz) { // set the graphics clock // if ( grxSpeedInMHz < MIN_PLL_FREQ || grxSpeedInMHz > MAX_PLL_FREQ ) { if (grxSpeedInMHz != 0) { MESSAGE("YO! Figure out how to set GRX clock to %d MHz\n", grxSpeedInMHz); } } else { GDBG_INFO(80, "Setting Graphics Clock (%d MHz)\n",grxSpeedInMHz); ISET32(pllCtrl1, pllTable[grxSpeedInMHz]); } // set the memory clock // if ( memSpeedInMHz < MIN_PLL_FREQ || memSpeedInMHz > MAX_PLL_FREQ ) { if (memSpeedInMHz != 0) { MESSAGE("YO! Figure out how to set MEM clock to %d MHz\n", memSpeedInMHz); } } else { GDBG_INFO(80, "Setting Memory Clock (%d MHz)\n",memSpeedInMHz); ISET32(pllCtrl2, pllTable[memSpeedInMHz]); } } // h3InitPlls #endif /*---------------------------------------------------------------------- Function name: h3InitVga Description: Initialize the VGA. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVga( FxU32 regBase, // init iegister base FxU32 legacyDecode) // 1=enable VGA decode, 0=disable { FxU32 vgaInit0 = 0, miscInit1; vgaInit0 |= SST_VGA0_EXTENSIONS; vgaInit0 |= SST_WAKEUP_3C3 << SST_VGA0_WAKEUP_SELECT_SHIFT; if (legacyDecode) vgaInit0 |= SST_VGA0_ENABLE_DECODE << SST_VGA0_LEGACY_DECODE_SHIFT; else vgaInit0 |= SST_VGA0_DISABLE_DECODE << SST_VGA0_LEGACY_DECODE_SHIFT; vgaInit0 |= SST_ENABLE_ALT_READBACK << SST_VGA0_CONFIG_READBACK_SHIFT; CHECKFORROOM; ISET32(vgaInit0, vgaInit0); GDBG_INFO(80, "disable VESA mode and VGA VIDEO lock bits\n"); CHECKFORROOM; ISET32(vgaInit1, 0); CHECKFORROOM; ISET8PHYS(0xc3, 0x1); GDBG_INFO(80, "Cleared CLUT Invert Address\n"); miscInit1 = IGET32(miscInit1); miscInit1 |= BIT(0); CHECKFORROOM; ISET32(miscInit1, miscInit1); } // h3InitVga /*---------------------------------------------------------------------- Function name: h3InitVideoProc Description: Initialize the Video portion of the HW. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVideoProc(FxU32 regBase, FxU32 vidProcCfg) // control bits for video processor { ISET32(vidProcCfg, vidProcCfg); } // h3InitVideo FxU16 mode_table[][24] = { #include "modetabl.h" {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; FxU8 vgaattr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00}; /*---------------------------------------------------------------------- Function name: h3InitFindVideoMode Description: Find the video mode in the mode table based on the xRes, yRes, and refresh rate. Information: Return: (FxU16 *) Ptr to the entry in the mode table, NULL if failure. ----------------------------------------------------------------------*/ FxU16 *h3InitFindVideoMode (FxU32 xRes, FxU32 yRes, FxU32 refresh) { int i = 0; int best = -1; FxU32 error = -1; while (mode_table[i][0] != 0) { if ((mode_table[i][0] == xRes) && (mode_table[i][1] == yRes)) { FxU32 d = abs(mode_table[i][2] - refresh); if (error > d) { error = d; best = i; } } i++; } return (best == -1) ? NULL : (&mode_table[best][3]); } /*---------------------------------------------------------------------- Function name: h3InitSetVideoMode Description: Set the video mode. Information: Return: FxBool FXTRUE if success or, FXFALSE if failure. ----------------------------------------------------------------------*/ FxBool h3InitSetVideoMode( FxU32 regBase, // regBase of this card FxU32 xRes, // xResolution in pixels FxU32 yRes, // yResolution in pixels FxU32 refresh, // refresh rate in Hz #if defined(H3VDD) FxU32 loadClut, // really a bool, should we load the lookup table FxU32 scanlinedouble) // set scanline double bit and double y? #else FxU32 loadClut) // really a bool, should we load the lookup table #endif { FxU16 i, j; FxU8 garbage; FxU16 *rs = h3InitFindVideoMode(xRes, yRes, refresh); FxU32 vidProcCfg; #ifndef H3VDD FxU32 scanlinedouble; #endif if (rs == NULL) { GDBG_ERROR("h3InitSetVideoMode", "mode %d x %d @ %dHz is not supported\n", xRes, yRes, refresh); return FXFALSE; } GDBG_INFO(1, "h3InitSetVideoMode(%d, %d, %d)\n", xRes, yRes, refresh); #ifndef H3VDD scanlinedouble = (yRes != /* vDispEnd */ ( (((rs[15]<<8)&0x400) | ((rs[7]<<3)&0x200) | ((rs[7]<<7)&0x100) | rs[11]) + 1 ) ); #endif // // MISC REGISTERS // This register gets programmed first since the Mono/ Color // selection needs to be made. // // Sync polarities // Also force the programmable clock to be used with bits 3&2 // ISET8PHYS(0xc2, rs[16] | BIT(0)); // // CRTC REGISTERS // First Unlock CRTC, then program them // // Mystical VGA Magic ISET16PHYS(0x0d4, 0x11); ISET16PHYS(0x0d4, (rs[0] << 8) | 0x00); ISET16PHYS(0x0d4, (rs[1] << 8) | 0x01); ISET16PHYS(0x0d4, (rs[2] << 8) | 0x02); ISET16PHYS(0x0d4, (rs[3] << 8) | 0x03); ISET16PHYS(0x0d4, (rs[4] << 8) | 0x04); #ifdef H3_A0 // // The problem with 800x600 is due to a // synthesis bug (which A1 does not have) // if (rs[14] & 0x80) { ISET16PHYS(0xd4, ((rs[5] & 0xe0) << 8) | 0x05); } else { ISET16PHYS(0x0d4, (rs[5] << 8) | 0x05); } #else // #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[5] << 8) | 0x05); #endif // #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[6] << 8) | 0x06); ISET16PHYS(0x0d4, (rs[7] << 8) | 0x07); ISET16PHYS(0x0d4, (rs[8] << 8) | 0x09); ISET16PHYS(0x0d4, (rs[9] << 8) | 0x10); ISET16PHYS(0x0d4, (rs[10] << 8) | 0x11); ISET16PHYS(0x0d4, (rs[11] << 8) | 0x12); ISET16PHYS(0x0d4, (rs[12] << 8) | 0x15); ISET16PHYS(0x0d4, (rs[13] << 8) | 0x16); #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[14] << 8) | 0x101a); ISET16PHYS(0x0d4, (rs[15] << 8) | 0x101b); #else // #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[14] << 8) | 0x1a); ISET16PHYS(0x0d4, (rs[15] << 8) | 0x1b); #endif // #ifdef H3_A0 // // Enable Sync Outputs // ISET16PHYS(0x0d4, (0x80 << 8) | 0x17); // // VIDCLK (32 bit access only!) // Set the Video Clock to the correct frequency // ISET32(pllCtrl0, (rs[19] << 8) | rs[18]); // // dacMode (32 bit access only!) // (sets up 1x mode or 2x mode) // ISET32(dacMode, rs[20]); // // the 1x / 2x bit must also be set in vidProcConfig to properly // enable 1x / 2x mode // vidProcCfg = IGET32(vidProcCfg); vidProcCfg &= ~(SST_VIDEO_2X_MODE_EN | SST_HALF_MODE); if (rs[20]) vidProcCfg |= SST_VIDEO_2X_MODE_EN; if (scanlinedouble) vidProcCfg |= SST_HALF_MODE; ISET32(vidProcCfg, vidProcCfg); // // SEQ REGISTERS // set run mode in the sequencer (not reset) // // make sure bit 5 == 0 (i.e., screen on) // ISET16PHYS(0x0c4, ((rs[17] & ((FxU16) ~BIT(5))) << 8) | 0x1 ); ISET16PHYS(0x0c4, ( 0x3 << 8) | 0x0 ); // // turn off VGA's screen refresh, as this function only sets extended // video modes, and the VGA screen refresh eats up performance // (10% difference in screen to screen blits!). This code is not in // the perl, but should stay here unless specifically decided otherwise // ISET32(vgaInit0, IGET32(vgaInit0)|BIT(12) ); // // Make sure attribute index register is initialized // garbage = IGET8PHYS(0x0da); // return value not used for (i = 0; i <= 19; i++) { ISET8PHYS(0xc0, i); ISET8PHYS(0xc0, vgaattr[i]); } ISET8PHYS(0xc0, 0x34); ISET8PHYS(0xda, 0); // // Initialize VIDEO res & proc mode info... // if (scanlinedouble) ISET32( vidScreenSize, (yRes << 13) | (xRes & 0xfff)); else { if (2048 == xRes) ISET32( vidScreenSize, (yRes << 12) | ((xRes - 2) & 0xfff)); else ISET32( vidScreenSize, (yRes << 12) | (xRes & 0xfff)); } ISET32(vidOverlayStartCoords, 0); // I think "xFixRes" is obsolete since we're not supporting 1800 // modes (only 1792 or 1808), so I won't use it here. -KMW // ISET32(vidOverlayEndScreenCoord, (((yRes - 1) << 12) | ((xRes - 1) & 0xfff))); // // Load CLUTs with an inverted ramp (undo inversion with new hardware!) // // Put in another routines. // if (loadClut) { for( i=0; i <= 0x1ff; i++) { ISET32( dacAddr, i); // assumes CLUT Invert Address, // miscInit1[0], is set IGET32(dacAddr); j = i & 0xff; #ifdef H3_A0 ISET32(dacData, ~((j<<16) | (j<<8) | j)); #else // #ifdef H3_A0 ISET32(dacData, (j<<16) | (j<<8) | j); #endif // #ifdef H3_A0 IGET32(dacData); } } return FXTRUE; /* success! */ } // h3InitSetVideoMode /*---------------------------------------------------------------------- Function name: h3InitVideoDesktopSurface Description: Set the width/height/start address/stride (position, stretch, filter, etc. for overlay) parameters of these surfaces. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVideoDesktopSurface( FxU32 regBase, FxU32 enable, // 1=enable desktop surface (DS), 1=disable FxU32 tiled, // 0=DS linear, 1=tiled FxU32 pixFmt, // pixel format of DS FxU32 clutBypass, // bypass clut for DS? FxU32 clutSelect, // 0=lower 256 CLUT entries, 1=upper 256 FxU32 startAddress, // board address of beginning of DS FxU32 stride) // distance between scanlines of the DS, in // units of bytes for linear DS's and tiles for // tiled DS's { FxU32 doStride; FxU32 vidProcCfg = IGET32(vidProcCfg); vidProcCfg &= ~ (SST_DESKTOP_EN | SST_DESKTOP_TILED_EN | SST_DESKTOP_PIXEL_FORMAT | SST_DESKTOP_CLUT_BYPASS | SST_DESKTOP_CLUT_SELECT ); if (enable) vidProcCfg |= SST_DESKTOP_EN; if (tiled) vidProcCfg |= SST_DESKTOP_TILED_EN; vidProcCfg |= pixFmt; if (clutBypass) vidProcCfg |= SST_DESKTOP_CLUT_BYPASS; if (clutSelect) vidProcCfg |= SST_DESKTOP_CLUT_SELECT; ISET32(vidProcCfg, vidProcCfg); ISET32(vidDesktopStartAddr, (startAddress & SST_VIDEO_START_ADDR) << SST_VIDEO_START_ADDR_SHIFT); // change only the desktop portion of the vidDesktopOverlayStride register // doStride = IGET32(vidDesktopOverlayStride); doStride &= ~(SST_DESKTOP_LINEAR_STRIDE | SST_DESKTOP_TILE_STRIDE); stride <<= SST_DESKTOP_STRIDE_SHIFT; if (tiled) stride &= SST_DESKTOP_TILE_STRIDE; else stride &= SST_DESKTOP_LINEAR_STRIDE; doStride |= stride; ISET32(vidDesktopOverlayStride, doStride); } /*---------------------------------------------------------------------- Function name: h3InitVideoOverlaySurface Description: Initialize the video overlay surface. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVideoOverlaySurface( FxU32 regBase, FxU32 enable, // 1=enable Overlay surface (OS), 1=disable FxU32 stereo, // 1=enable OS stereo, 0=disable FxU32 horizScaling, // 1=enable horizontal scaling, 0=disable FxU32 dudx, // horizontal scale factor (ignored if not // scaling) FxU32 verticalScaling, // 1=enable vertical scaling, 0=disable FxU32 dvdy, // vertical scale factor (ignored if not // scaling) FxU32 filterMode, // duh FxU32 tiled, // 0=OS linear, 1=tiled FxU32 pixFmt, // pixel format of OS FxU32 clutBypass, // bypass clut for OS? FxU32 clutSelect, // 0=lower 256 CLUT entries, 1=upper 256 FxU32 startAddress, // board address of beginning of OS FxU32 stride) // distance between scanlines of the OS, in // units of bytes for linear OS's and tiles for // tiled OS's { FxU32 doStride; FxU32 vidProcCfg = IGET32(vidProcCfg); vidProcCfg &= ~(SST_OVERLAY_TILED_EN | SST_OVERLAY_STEREO_EN | SST_OVERLAY_HORIZ_SCALE_EN | SST_OVERLAY_VERT_SCALE_EN | SST_OVERLAY_TILED_EN | SST_OVERLAY_PIXEL_FORMAT | SST_OVERLAY_CLUT_BYPASS | SST_OVERLAY_CLUT_SELECT); if (enable) vidProcCfg |= SST_OVERLAY_EN; if (stereo) vidProcCfg |= SST_OVERLAY_STEREO_EN; if (horizScaling) vidProcCfg |= SST_OVERLAY_HORIZ_SCALE_EN; if (verticalScaling) vidProcCfg |= SST_OVERLAY_VERT_SCALE_EN; if (tiled) vidProcCfg |= SST_OVERLAY_TILED_EN; vidProcCfg |= pixFmt; if (clutBypass) vidProcCfg |= SST_OVERLAY_CLUT_BYPASS; if (clutSelect) vidProcCfg |= SST_OVERLAY_CLUT_SELECT; if (horizScaling) { vidProcCfg |= SST_OVERLAY_HORIZ_SCALE_EN; ISET32(vidOverlayDudx, dudx); } #ifdef H3VDD if (tiled) { ISET32(vidOverlayDudxOffsetSrcWidth, (0 | ((stride << 7) << SST_OVERLAY_FETCH_SIZE_SHIFT))); } else { ISET32(vidOverlayDudxOffsetSrcWidth, (0 | (stride << SST_OVERLAY_FETCH_SIZE_SHIFT))); } #endif if (verticalScaling) { vidProcCfg |= SST_OVERLAY_VERT_SCALE_EN; ISET32(vidOverlayDvdy, dvdy); ISET32(vidOverlayDvdyOffset, 0); } ISET32(vidProcCfg, vidProcCfg); // change only the overlay portion of the vidDesktopOverlayStride register // doStride = IGET32(vidDesktopOverlayStride); doStride &= ~(SST_OVERLAY_LINEAR_STRIDE | SST_OVERLAY_TILE_STRIDE); stride <<= SST_OVERLAY_STRIDE_SHIFT; if (tiled) stride &= SST_OVERLAY_TILE_STRIDE; else stride &= SST_OVERLAY_LINEAR_STRIDE; doStride |= stride; ISET32(vidDesktopOverlayStride, doStride); // must set the overlay start address! } /*---------------------------------------------------------------------- Function name: h3InitMeasureSiProcess Description: Read and display to the debug output device the performance monitor values. Information: Return: VOID ----------------------------------------------------------------------*/ #ifndef H3VDD // // read and display performance monitor values // void h3InitMeasureSiProcess(FxU32 regBase) // init register base { FxU32 siProcess, nandOsc, norOsc; FxU32 pciCntrLoad = 0xfff; if(GETENV("SSTH3_SIPROCESS_CNTR")) { pciCntrLoad = strtoul(GETENV("SSTH3_SIPROCESS_CNTR"),NULL,0); GDBG_INFO(1,"h3InitMeasureSiProcess(): Using PCI Counter preload value of 0x%x...\n", pciCntrLoad); } //////////////////////////////// // Test NAND oscillator tree... //////////////////////////////// ISET32(sipMonitor, (pciCntrLoad<>SST_BLOCK_WRITE_THRESH_SHIFT); } /*---------------------------------------------------------------------- Function name: h3InitResetAll Description: Perform a full HW reset. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitResetAll( FxU32 regBase) // init register base address { FxU32 miscInit0 = IGET32(miscInit0); FxU32 miscInit1 = IGET32(miscInit1); GDBG_INFO(80, "h3InitResetAll: initiating reset\n"); ISET32(miscInit1, miscInit1 | SST_CMDSTREAM_RESET); ISET32(miscInit0, miscInit0 | (SST_GRX_RESET | SST_FBI_FIFO_RESET | SST_VIDEO_RESET | SST_2D_RESET | SST_MEMORY_TIMING_RESET | SST_VGA_TIMING_RESET) ); ISET32(miscInit0, miscInit0 & ~(SST_GRX_RESET | SST_FBI_FIFO_RESET | SST_VIDEO_RESET | SST_2D_RESET | SST_MEMORY_TIMING_RESET | SST_VGA_TIMING_RESET) ); ISET32(miscInit1, miscInit1 & ~SST_CMDSTREAM_RESET); GDBG_INFO(80, "h3InitResetAll: reset completed\n"); } glide3x/h5/cinit/h3cinit.h0100700000175300010010000001220607725034640014652 0ustar johndoeNone/* -*-c++-*- */ /* $Header: /cvsroot/glide/glide3x/h5/cinit/Attic/h3cinit.h,v 1.1.2.1 2003/08/21 08:32:12 dborca Exp $ */ /* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ */ #ifndef __H3CINIT_H__ #define __H3CINIT_H__ #include <3dfx.h> #define H3_GRXCLK_SPEED 100 #define H4_GRXCLK_SPEED 143 #define H4_OEM_GRXCLK_SPEED 141 #define H4_BRINGUP_GRXCLK_SPEED 100 #ifdef H4 #define DEFAULT_GRXCLK_SPEED H4_BRINGUP_GRXCLK_SPEED #else #define DEFAULT_GRXCLK_SPEED H3_GRXCLK_SPEED #endif FxU32 // return # of MB of memory h3InitGetMemSize(FxU32 regBase, // init register base FxBool isNapalm);// Napalm FxU32 // return # of MB of memory h3InitSgram(FxU32 regBase, // init iegister base FxU32 sgramMode, FxU32 sgramMask, FxU32 sgramColor, char *vendorName); // NULL or name of SGRAM vendor void h3InitPlls(FxU32 regBase, // init iegister base FxU32 grxSpeedInMHz, // desired GRX clock frequency (MHz) FxU32 memSpeedInMHz); // desired MEM clock frequency (MHz) void h4InitPlls(FxU32 regBase, // init register base FxU32 deviceID, // H4 or H4_OEM FxU32 grxSpeedInMHz); // desired clock frequency (MHz) void h3InitVga( FxU32 regBase, // memory base address FxU32 legacyDecode); // 1=enable VGA decode, 0=disable void h3InitVideoProc( FxU32 regBase, // memory base address FxU32 vidProcCfg); // vidProcCfg register control bits FxBool h3InitSetVideoMode( FxU32 regBase, // memory base address FxU32 xRes, // x resolution FxU32 yRes, // y resolution FxU32 refresh, // refresh freq #if defined(H3VDD) && defined(H3_B0) FxU32 loadClut, // really a bool, should we load the lookup table FxU32 scanlinedouble); // set scanline double bit and double y? #else FxU32 loadClut) ; // initialize clut entries? #endif void h3InitVideoDesktopSurface( FxU32 regBase, FxU32 enable, // 1=enable desktop surface (DS), 1=disable FxU32 tiled, // 0=DS linear, 1=tiled FxU32 pixFmt, // pixel format of DS FxU32 clutBypass, // bypass clut for DS? FxU32 clutSelect, // 0=lower 256 CLUT entries, 1=upper 256 FxU32 startAddress, // board address of beginning of DS FxU32 stride); // distance between scanlines of the DS, in // units of bytes for linear DS's and tiles for // tiled DS's void h3InitVideoOverlaySurface( FxU32 regBase, FxU32 enable, // 1=enable Overlay surface (OS), 1=disable FxU32 stereo, // 1=enable OS stereo, 0=disable FxU32 horizScaling, // 1=enable horizontal scaling, 0=disable FxU32 dudx, // horizontal scale factor (ignored if not // scaling) FxU32 verticalScaling, // 1=enable vertical scaling, 0=disable FxU32 dvdy, // vertical scale factor (ignored if not // scaling) FxU32 filterMode, // duh FxU32 tiled, // 0=OS linear, 1=tiled FxU32 pixFmt, // pixel format of OS FxU32 clutBypass, // bypass clut for OS? FxU32 clutSelect, // 0=lower 256 CLUT entries, 1=upper 256 FxU32 startAddress, // board address of beginning of OS FxU32 stride); // distance between scanlines of the OS, in // units of bytes for linear OS's and tiles for // tiled OS's #ifndef H3VDD void h3InitMeasureSiProcess( FxU32 regBase); // init register base #endif // #ifndef H3VDD void h3InitBlockWrite( FxU32 regBase, FxU32 enable, // 1=enable block writes, 0=disable FxU32 threshhold); // block write threshhold void h3InitResetAll( FxU32 regBase); // init register base #endif /* __H3CINIT_H__ */ glide3x/h5/cinit/h3cinitdd.h0100700000175300010010000000456607725034640015174 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ */ #include #include /* [dBorca] */ #ifdef __DJGPP__ #include #endif #if defined(__WATCOMC__) #define _inp inp #define _outp outp #define _inpw inpw #define _outpw outpw #define _inpd inpd #define _outpd outpd #endif #define SSTIOADDR(regName) ((FxU16)offsetof(SstIORegs, regName)) #define ISET32(addr, value) _outpd((FxU16) ((FxU16) regBase + (FxU16) (SSTIOADDR(addr))), value) #define IGET32(addr) _inpd((FxU16) ((FxU16) regBase + (FxU16) (SSTIOADDR(addr)))) #define ISET8PHYS(a,b) {\ FxU16 port = (FxU16) (regBase) + (FxU16) (a);\ GDBG_INFO(120, "OUT8: Port 0x%x Value 0x%x\n", port, b);\ _outp(port, (FxU8) (b));} #define ISET16PHYS(a,b) {\ FxU16 port = (FxU16)(regBase) + (FxU16)(a);\ GDBG_INFO(120, "OUT16: Port 0x%x Value 0x%x\n", port, b);\ _outpw(port, (FxU16) (b));} #define IGET8PHYS(a) _inp((FxU16) ((FxU16) (regBase) + (FxU16) (a))) #define IGET16PHYS(a) _inpw((FxU16) ((FxU16) (regBase) + (FxU16)(a))) #define CHECKFORROOM while (! (_inp((FxU16) regBase) & (FxU16)(0x3f))) #define MESSAGE GDBG_PRINTF #ifdef OLD #define ISET32(a,b)\ GDBG_INFO(120, "SET32: Register 0x%x Value 0x%x\n", (FxU32) (&((SstIORegs *)regBase)->a) - (FxU32) regBase, b); \ ((FxU32) (((SstIORegs *) regBase)->a)) = (FxU32) b #define IGET32(a) ((FxU32) (((SstIORegs *) regBase)->a)) #endif /* #ifdef OLD */ glide3x/h5/cinit/h4oempll.h0100700000175300010010000002352207725034640015040 0ustar johndoeNone/* -*-c++-*- */ /* $Header: /cvsroot/glide/glide3x/h5/cinit/Attic/h4oempll.h,v 1.1.2.1 2003/08/21 08:32:12 dborca Exp $ */ /* ** Copyright (c) 1995-1999, 3Dfx Interactive, Inc. ** All Rights Reserved. ** ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; ** the contents of this file may not be disclosed to third parties, copied or ** duplicated in any form, in whole or in part, without the prior written ** permission of 3Dfx Interactive, Inc. ** ** RESTRICTED RIGHTS LEGEND: ** Use, duplication or disclosure by the Government is subject to restrictions ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - ** rights reserved under the Copyright Laws of the United States. ** ** File name: h4oempll.h ** ** Description: Avenger OEM PLL table and values. ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ ** ** $History: h4oempll.h $ ** ** ***************** Version 2 ***************** ** User: Michael Date: 1/08/99 Time: 1:50p ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 1 ***************** ** User: Andrew Date: 12/20/98 Time: 11:10a ** Created in $/devel/h3/Win95/dx/minivdd ** H4 OEM Pll Table ** ** ***************** Version 5 ***************** ** User: Pault Date: 11/05/98 Time: 2:07p ** Updated in $/devel/h4/cinit ** The table now goes up to 220 MHz for Avenger. Also, all of the entries ** up through 141 MHz have the M factor set at 24 so the entries can be ** used with Avenger OEM. ** ** ***************** Version 3 ***************** ** User: Artg Date: 8/27/98 Time: 11:08a ** Updated in $/devel/h3/Win95/dx/minivdd ** added guard ifdef for redundant plltable define. ** ** ***************** Version 2 ***************** ** User: Ken Date: 4/15/98 Time: 6:42p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** */ // // generated by gen_plltable.pl at Thu Nov 5 12:38:23 1998 // #define MIN_PLL_FREQ 30 #define MAX_PLL_FREQ 120 #define MAX_H4_OEM_PLL_FREQ 141 #define MAX_H4_PLL_FREQ 220 FxU32 _h4oempllTable[] = { // pllCtrl n m k actual(MHz) // ------- --- --- --- ----------- 0x00003460, // 52 24 0 29.737758 0x00003660, // 54 24 0 30.839157 0x00003860, // 56 24 0 31.940555 0x00003A60, // 58 24 0 33.041954 0x00003C60, // 60 24 0 34.143352 0x00003E60, // 62 24 0 35.244751 0x00003F60, // 63 24 0 35.795450 0x00004160, // 65 24 0 36.896848 0x00004360, // 67 24 0 37.998247 0x00004560, // 69 24 0 39.099645 0x00004760, // 71 24 0 40.201044 0x00004860, // 72 24 0 40.751743 0x00004A60, // 74 24 0 41.853142 0x00004C60, // 76 24 0 42.954540 0x00004E60, // 78 24 0 44.055938 0x00005060, // 80 24 0 45.157337 0x00005260, // 82 24 0 46.258735 0x00005360, // 83 24 0 46.809435 0x00005560, // 85 24 0 47.910833 0x00005760, // 87 24 0 49.012232 0x00005960, // 89 24 0 50.113630 0x00005B60, // 91 24 0 51.215028 0x00005C60, // 92 24 0 51.765728 0x00005E60, // 94 24 0 52.867126 0x00006060, // 96 24 0 53.968525 0x00006260, // 98 24 0 55.069923 0x00006460, // 100 24 0 56.171322 0x00006660, // 102 24 0 57.272720 0x00006760, // 103 24 0 57.823419 0x00006960, // 105 24 0 58.924818 0x00006B60, // 107 24 0 60.026216 0x00006D60, // 109 24 0 61.127615 0x00006F60, // 111 24 0 62.229013 0x00007060, // 112 24 0 62.779712 0x00007260, // 114 24 0 63.881111 0x00007460, // 116 24 0 64.982509 0x00007660, // 118 24 0 66.083908 0x00007860, // 120 24 0 67.185306 0x00007960, // 121 24 0 67.736005 0x00007B60, // 123 24 0 68.837404 0x00007D60, // 125 24 0 69.938802 0x00007F60, // 127 24 0 71.040201 0x00008160, // 129 24 0 72.141599 0x00008360, // 131 24 0 73.242998 0x00008460, // 132 24 0 73.793697 0x00008660, // 134 24 0 74.895095 0x00008860, // 136 24 0 75.996494 0x00008A60, // 138 24 0 77.097892 0x00008C60, // 140 24 0 78.199291 0x00008D60, // 141 24 0 78.749990 0x00008F60, // 143 24 0 79.851388 0x00009160, // 145 24 0 80.952787 0x00009360, // 147 24 0 82.054185 0x00009560, // 149 24 0 83.155584 0x00009760, // 151 24 0 84.256982 0x00009860, // 152 24 0 84.807682 0x00009A60, // 154 24 0 85.909080 0x00009C60, // 156 24 0 87.010478 0x00009E60, // 158 24 0 88.111877 0x0000A060, // 160 24 0 89.213275 0x0000A160, // 161 24 0 89.763975 0x0000A360, // 163 24 0 90.865373 0x0000A560, // 165 24 0 91.966772 0x0000A760, // 167 24 0 93.068170 0x0000A960, // 169 24 0 94.169568 0x0000AB60, // 171 24 0 95.270967 0x0000AC60, // 172 24 0 95.821666 0x0000AE60, // 174 24 0 96.923065 0x0000B060, // 176 24 0 98.024463 0x0000B260, // 178 24 0 99.125862 0x0000B460, // 180 24 0 100.227260 0x0000B560, // 181 24 0 100.777959 0x0000B760, // 183 24 0 101.879358 0x0000B960, // 185 24 0 102.980756 0x0000BB60, // 187 24 0 104.082155 0x0000BD60, // 189 24 0 105.183553 0x0000BE60, // 190 24 0 105.734252 0x0000C060, // 192 24 0 106.835651 0x0000C260, // 194 24 0 107.937049 0x0000C460, // 196 24 0 109.038448 0x0000C660, // 198 24 0 110.139846 0x0000C860, // 200 24 0 111.241245 0x0000C960, // 201 24 0 111.791944 0x0000CB60, // 203 24 0 112.893342 0x0000CD60, // 205 24 0 113.994741 0x0000CF60, // 207 24 0 115.096139 0x0000D160, // 209 24 0 116.197538 0x0000D260, // 210 24 0 116.748237 0x0000D460, // 212 24 0 117.849635 0x0000D660, // 214 24 0 118.951034 0x0000D860, // 216 24 0 120.052432 0x0000DA60, // 218 24 0 121.153831 0x0000DC60, // 220 24 0 122.255229 0x0000DD60, // 221 24 0 122.805928 0x0000DF60, // 223 24 0 123.907327 0x0000E160, // 225 24 0 125.008725 0x0000E360, // 227 24 0 126.110124 0x0000E560, // 229 24 0 127.211522 0x0000E660, // 230 24 0 127.762222 0x0000E860, // 232 24 0 128.863620 0x0000EA60, // 234 24 0 129.965018 0x0000EC60, // 236 24 0 131.066417 0x0000EE60, // 238 24 0 132.167815 0x0000F060, // 240 24 0 133.269214 0x0000F160, // 241 24 0 133.819913 0x0000F360, // 243 24 0 134.921312 0x0000F560, // 245 24 0 136.022710 0x0000F760, // 247 24 0 137.124108 0x0000F960, // 249 24 0 138.225507 0x0000FA60, // 250 24 0 138.776206 0x0000FC60, // 252 24 0 139.877605 0x0000FE60, // 254 24 0 140.979003 0x00007528, // 117 10 0 141.988618 0x00001200, // 18 0 0 143.181800 0x0000B340, // 179 16 0 143.977254 0x00004F18, // 79 6 0 144.971573 0x0000310C, // 49 3 0 146.045436 0x00009834, // 152 13 0 146.999981 0x00001D04, // 29 1 0 147.954527 0x0000E350, // 227 20 0 149.039237 0x0000DA4C, // 218 19 0 149.999981 0x00007224, // 114 9 0 150.991716 0x0000882C, // 136 11 0 151.992988 0x0000C944, // 201 17 0 152.978449 0x00002908, // 41 2 0 153.920435 0x0000F754, // 247 21 0 155.009862 0x0000CD44, // 205 17 0 155.992803 0x0000FA54, // 250 21 0 156.877450 0x0000FC54, // 252 21 0 158.122510 0x0000D144, // 209 17 0 159.007157 0x0000BC3C, // 188 15 0 160.026718 0x00002B08, // 43 2 0 161.079525 0x0000D544, // 213 17 0 162.021511 0x0000922C, // 146 11 0 163.006972 0x00007C24, // 124 9 0 164.008244 0x0000F04C, // 240 19 0 164.999979 0x0000FD50, // 253 20 0 165.960723 0x00002104, // 33 1 0 167.045433 0x0000AE34, // 174 13 0 167.999979 0x0000390C, // 57 3 0 168.954524 0x00005D18, // 93 6 0 170.028388 0x0000D540, // 213 16 0 171.022706 0x00001600, // 22 0 0 171.818160 0x00008F28, // 143 10 0 173.011342 0x00009C2C, // 156 11 0 174.020957 0x00006C1C, // 108 7 0 174.999978 0x0000CF3C, // 207 15 0 176.029389 0x00008624, // 134 9 0 177.024771 0x00005514, // 85 5 0 177.954523 0x00001700, // 23 0 0 178.977250 0x00005614, // 86 5 0 179.999977 0x0000AF30, // 175 12 0 181.022704 0x00005714, // 87 5 0 182.045431 0x0000711C, // 113 7 0 182.954522 0x0000A52C, // 165 11 0 183.933543 0x0000A62C, // 166 11 0 185.034942 0x00001800, // 24 0 0 186.136340 0x0000DC3C, // 220 15 0 186.978586 0x0000C334, // 195 13 0 188.045431 0x0000400C, // 64 3 0 188.999976 0x00009024, // 144 9 0 190.041298 0x00002604, // 38 1 0 190.909067 0x0000E23C, // 226 15 0 192.032061 0x0000FE44, // 254 17 0 192.918636 0x00009324, // 147 9 0 193.946256 0x0000AF2C, // 175 11 0 194.947528 0x0000D938, // 217 14 0 195.980089 0x0000E83C, // 232 15 0 197.085536 0x00005110, // 81 4 0 198.068157 0x00008920, // 137 8 0 199.022702 0x0000F940, // 249 16 0 199.659066 0x0000FB40, // 251 16 0 201.249974 0x00007D1C, // 125 7 0 202.045429 0x0000EF3C, // 239 15 0 202.981258 0x00003708, // 55 2 0 204.034065 0x0000E338, // 227 14 0 204.928951 0x0000B92C, // 185 11 0 205.961512 0x00009D24, // 157 9 0 206.962784 0x0000F53C, // 245 15 0 208.034733 0x0000470C, // 71 3 0 209.045428 0x00002A04, // 42 1 0 209.999973 0x0000DB34, // 219 13 0 210.954519 0x0000EB38, // 235 14 0 212.088041 0x00007518, // 117 6 0 212.982927 0x0000FC3C, // 252 15 0 213.930454 0x00001C00, // 28 0 0 214.772700 0x0000B328, // 179 10 0 215.965882 0x0000C32C, // 195 11 0 216.975497 0x0000871C, // 135 7 0 217.954518 0x00009720, // 151 8 0 219.068154 0x0000A724, // 167 9 0 219.979311 }; FxU32 *h4oempllTable = (FxU32*) (_h4oempllTable - MIN_PLL_FREQ); glide3x/h5/cinit/h4pll.h0100700000175300010010000002511307725034640014335 0ustar johndoeNone/* -*-c++-*- */ /* $Header: /cvsroot/glide/glide3x/h5/cinit/Attic/h4pll.h,v 1.1.2.1 2003/08/21 08:32:12 dborca Exp $ */ /* ** Copyright (c) 1995-1999, 3Dfx Interactive, Inc. ** All Rights Reserved. ** ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; ** the contents of this file may not be disclosed to third parties, copied or ** duplicated in any form, in whole or in part, without the prior written ** permission of 3Dfx Interactive, Inc. ** ** RESTRICTED RIGHTS LEGEND: ** Use, duplication or disclosure by the Government is subject to restrictions ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - ** rights reserved under the Copyright Laws of the United States. ** ** File name: h4pll.h ** ** Description: Avenger PLL table and values. ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ ** ** $History: h4pll.h $ ** ** ***************** Version 2 ***************** ** User: Michael Date: 1/08/99 Time: 1:51p ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 1 ***************** ** User: Andrew Date: 11/18/98 Time: 12:27p ** Created in $/devel/h3/Win95/dx/minivdd ** Pll Table for Avenger ** ** ***************** Version 8 ***************** ** User: Pault Date: 11/16/98 Time: 3:30p ** Updated in $/devel/h4/cinit ** This version of the table has m=k=1 and is based on the same ** calculations we have been using in the lab. This will not work for ** AvengerOEM. ** ** ***************** Version 7 ***************** ** User: Pault Date: 11/15/98 Time: 4:17p ** Updated in $/devel/h4/cinit ** Added missing pllTable definition at the bottom of the file. ** ** ***************** Version 6 ***************** ** User: Pault Date: 11/15/98 Time: 2:00p ** Updated in $/devel/h4/cinit ** Temporary table to work with Avenger. This table has k=1. But m values ** are not wedged to 24 below 141 MHz, so this table with not work with ** AvengerOEM. ** ** ***************** Version 5 ***************** ** User: Pault Date: 11/05/98 Time: 2:07p ** Updated in $/devel/h4/cinit ** The table now goes up to 220 MHz for Avenger. Also, all of the entries ** up through 141 MHz have the M factor set at 24 so the entries can be ** used with Avenger OEM. ** ** ***************** Version 3 ***************** ** User: Artg Date: 8/27/98 Time: 11:08a ** Updated in $/devel/h3/Win95/dx/minivdd ** added guard ifdef for redundant plltable define. ** ** ***************** Version 2 ***************** ** User: Ken Date: 4/15/98 Time: 6:42p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** */ // // generated by gen_plltable_at.pl at Sun Nov 15 14:16:18 1998 // #define MIN_PLL_FREQ 30 #define MAX_PLL_FREQ 120 #define MAX_H4_OEM_PLL_FREQ 141 #define MAX_H4_PLL_FREQ 220 FxU32 _h4pllTable[] = { // pllCtrl n m k actual(MHz) // ------- --- --- --- ----------- 0x00000B05, // 11 1 1 31.022723 0x00000B05, // 11 1 1 31.022723 0x00000B05, // 11 1 1 31.022723 0x00000C05, // 12 1 1 33.409087 0x00000C05, // 12 1 1 33.409087 0x00000D05, // 13 1 1 35.795450 0x00000D05, // 13 1 1 35.795450 0x00000E05, // 14 1 1 38.181813 0x00000E05, // 14 1 1 38.181813 0x00000E05, // 14 1 1 38.181813 0x00000F05, // 15 1 1 40.568177 0x00000F05, // 15 1 1 40.568177 0x00001005, // 16 1 1 42.954540 0x00001005, // 16 1 1 42.954540 0x00001005, // 16 1 1 42.954540 0x00001105, // 17 1 1 45.340903 0x00001105, // 17 1 1 45.340903 0x00001205, // 18 1 1 47.727267 0x00001205, // 18 1 1 47.727267 0x00001305, // 19 1 1 50.113630 0x00001305, // 19 1 1 50.113630 0x00001305, // 19 1 1 50.113630 0x00001405, // 20 1 1 52.499993 0x00001405, // 20 1 1 52.499993 0x00001505, // 21 1 1 54.886357 0x00001505, // 21 1 1 54.886357 0x00001505, // 21 1 1 54.886357 0x00001605, // 22 1 1 57.272720 0x00001605, // 22 1 1 57.272720 0x00001705, // 23 1 1 59.659083 0x00001705, // 23 1 1 59.659083 0x00001805, // 24 1 1 62.045447 0x00001805, // 24 1 1 62.045447 0x00001805, // 24 1 1 62.045447 0x00001905, // 25 1 1 64.431810 0x00001905, // 25 1 1 64.431810 0x00001A05, // 26 1 1 66.818173 0x00001A05, // 26 1 1 66.818173 0x00001A05, // 26 1 1 66.818173 0x00001B05, // 27 1 1 69.204537 0x00001B05, // 27 1 1 69.204537 0x00001C05, // 28 1 1 71.590900 0x00001C05, // 28 1 1 71.590900 0x00001D05, // 29 1 1 73.977263 0x00001D05, // 29 1 1 73.977263 0x00001D05, // 29 1 1 73.977263 0x00001E05, // 30 1 1 76.363627 0x00001E05, // 30 1 1 76.363627 0x00001F05, // 31 1 1 78.749990 0x00001F05, // 31 1 1 78.749990 0x00002005, // 32 1 1 81.136353 0x00002005, // 32 1 1 81.136353 0x00002005, // 32 1 1 81.136353 0x00002105, // 33 1 1 83.522717 0x00002105, // 33 1 1 83.522717 0x00002205, // 34 1 1 85.909080 0x00002205, // 34 1 1 85.909080 0x00002205, // 34 1 1 85.909080 0x00002305, // 35 1 1 88.295443 0x00002305, // 35 1 1 88.295443 0x00002405, // 36 1 1 90.681807 0x00002405, // 36 1 1 90.681807 0x00002505, // 37 1 1 93.068170 0x00002505, // 37 1 1 93.068170 0x00002505, // 37 1 1 93.068170 0x00002605, // 38 1 1 95.454533 0x00002605, // 38 1 1 95.454533 0x00002705, // 39 1 1 97.840897 0x00002705, // 39 1 1 97.840897 0x00002705, // 39 1 1 97.840897 0x00002805, // 40 1 1 100.227260 0x00002805, // 40 1 1 100.227260 0x00002905, // 41 1 1 102.613623 0x00002905, // 41 1 1 102.613623 0x00002A05, // 42 1 1 104.999987 0x00002A05, // 42 1 1 104.999987 0x00002A05, // 42 1 1 104.999987 0x00002B05, // 43 1 1 107.386350 0x00002B05, // 43 1 1 107.386350 0x00002C05, // 44 1 1 109.772713 0x00002C05, // 44 1 1 109.772713 0x00002D05, // 45 1 1 112.159077 0x00002D05, // 45 1 1 112.159077 0x00002D05, // 45 1 1 112.159077 0x00002E05, // 46 1 1 114.545440 0x00002E05, // 46 1 1 114.545440 0x00002F05, // 47 1 1 116.931803 0x00002F05, // 47 1 1 116.931803 0x00002F05, // 47 1 1 116.931803 0x00003005, // 48 1 1 119.318167 0x00003005, // 48 1 1 119.318167 0x00003105, // 49 1 1 121.704530 0x00003105, // 49 1 1 121.704530 0x00003205, // 50 1 1 124.090893 0x00003205, // 50 1 1 124.090893 0x00003205, // 50 1 1 124.090893 0x00003305, // 51 1 1 126.477257 0x00003305, // 51 1 1 126.477257 0x00003405, // 52 1 1 128.863620 0x00003405, // 52 1 1 128.863620 0x00003405, // 52 1 1 128.863620 0x00003505, // 53 1 1 131.249983 0x00003505, // 53 1 1 131.249983 0x00003605, // 54 1 1 133.636347 0x00003605, // 54 1 1 133.636347 0x00003705, // 55 1 1 136.022710 0x00003705, // 55 1 1 136.022710 0x00003705, // 55 1 1 136.022710 0x00003805, // 56 1 1 138.409073 0x00003805, // 56 1 1 138.409073 0x00003905, // 57 1 1 140.795437 0x00003905, // 57 1 1 140.795437 0x00003A05, // 58 1 1 143.181800 0x00003A05, // 58 1 1 143.181800 0x00003A05, // 58 1 1 143.181800 0x00003B05, // 59 1 1 145.568163 0x00003B05, // 59 1 1 145.568163 0x00003C05, // 60 1 1 147.954527 0x00003C05, // 60 1 1 147.954527 0x00003C05, // 60 1 1 147.954527 0x00003D05, // 61 1 1 150.340890 0x00003D05, // 61 1 1 150.340890 0x00003E05, // 62 1 1 152.727253 0x00003E05, // 62 1 1 152.727253 0x00003F05, // 63 1 1 155.113617 0x00003F05, // 63 1 1 155.113617 0x00003F05, // 63 1 1 155.113617 0x00004005, // 64 1 1 157.499980 0x00004005, // 64 1 1 157.499980 0x00004105, // 65 1 1 159.886343 0x00004105, // 65 1 1 159.886343 0x00004105, // 65 1 1 159.886343 0x00004205, // 66 1 1 162.272707 0x00004205, // 66 1 1 162.272707 0x00004305, // 67 1 1 164.659070 0x00004305, // 67 1 1 164.659070 0x0000e721, // 68 1 1 166.81 0x0000e721, // 68 1 1 166.81 0x0000e721, // 68 1 1 166.81 0x00004505, // 69 1 1 169.431797 0x00004505, // 69 1 1 169.431797 0x00004605, // 70 1 1 171.818160 0x00004605, // 70 1 1 171.818160 0x00004605, // 70 1 1 171.818160 0x00004705, // 71 1 1 174.204523 0x00004705, // 71 1 1 174.204523 0x00004805, // 72 1 1 176.590887 0x00004805, // 72 1 1 176.590887 0x00004905, // 73 1 1 178.977250 0x00004905, // 73 1 1 178.977250 0x00004905, // 73 1 1 178.977250 0x00004A05, // 74 1 1 181.363613 0x00004A05, // 74 1 1 181.363613 0x00004B05, // 75 1 1 183.749977 0x00004B05, // 75 1 1 183.749977 0x00004C05, // 76 1 1 186.136340 0x00004C05, // 76 1 1 186.136340 0x00004C05, // 76 1 1 186.136340 0x00004D05, // 77 1 1 188.522703 0x00004D05, // 77 1 1 188.522703 0x00004E05, // 78 1 1 190.909067 0x00004E05, // 78 1 1 190.909067 0x00004E05, // 78 1 1 190.909067 0x00004F05, // 79 1 1 193.295430 0x00004F05, // 79 1 1 193.295430 0x00005005, // 80 1 1 195.681793 0x00005005, // 80 1 1 195.681793 0x00005105, // 81 1 1 198.068157 0x00005105, // 81 1 1 198.068157 0x00005105, // 81 1 1 198.068157 0x00005205, // 82 1 1 200.454520 0x00005205, // 82 1 1 200.454520 0x00005305, // 83 1 1 202.840883 0x00005305, // 83 1 1 202.840883 0x00005305, // 83 1 1 202.840883 0x00005405, // 84 1 1 205.227247 0x00005405, // 84 1 1 205.227247 0x00005505, // 85 1 1 207.613610 0x00005505, // 85 1 1 207.613610 0x00005605, // 86 1 1 209.999973 0x00005605, // 86 1 1 209.999973 0x00005605, // 86 1 1 209.999973 0x00005705, // 87 1 1 212.386337 0x00005705, // 87 1 1 212.386337 0x00005805, // 88 1 1 214.772700 0x00005805, // 88 1 1 214.772700 0x00005905, // 89 1 1 217.159063 0x00005905, // 89 1 1 217.159063 0x00005905, // 89 1 1 217.159063 0x00005A05, // 90 1 1 219.545427 0x00005A05, // 90 1 1 219.545427 }; FxU32 *h4pllTable = (FxU32*) (_h4pllTable - MIN_PLL_FREQ); glide3x/h5/cinit/memtable.h0100700000175300010010000001031007725034640015071 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** File name: memtable.h ** ** Description: Table to initialize dramInit0 and sgramMode. ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ ** ** $History: memtable.h $ ** ** ***************** Version 1 ***************** ** User: Sapphire Date: 3/16/99 Time: 7:28p ** Created in $/Releases/Voodoo3/V3_OEM_100/3dfx/devel/H3/cinit ** ** ***************** Version 6 ***************** ** User: Michael Date: 1/11/99 Time: 3:53p ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 5 ***************** ** User: Psmith Date: 8/09/98 Time: 7:53a ** Updated in $/devel/h3/cinit ** added Generic SGRAM/SDRAM memory timings that have lower performance ** but will work for all currently-supported chips. ** default memory vendor type changed to Generic from Samsung. ** ** ***************** Version 4 ***************** ** User: Psmith Date: 7/31/98 Time: 1:35a ** Updated in $/devel/h3/cinit ** changed block write to 2 cycles for Etron 16Mbit partsd ** ** ***************** Version 3 ***************** ** User: Psmith Date: 7/22/98 Time: 9:11a ** Updated in $/devel/h3/cinit ** added sdram support ** ** ***************** Version 2 ***************** ** User: Ken Date: 4/15/98 Time: 6:41p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** */ // // generated by gen_memtable.pl at Sun Aug 9 07:21:36 1998 // #define MEM_TYPE_SGRAM 0 #define MEM_TYPE_SDRAM 1 struct memTable_st { char vendor[8]; FxU32 type; FxU32 size; FxU32 dramInit0; FxU32 sgramMode; } memTable[] = { // vendor type size dramInit0 sgramMode // ---------- ---- ---- --------- --------- { "ETRON", MEM_TYPE_SGRAM, 16, 0x001698e9, 0x00000037} , { "ETRON", MEM_TYPE_SGRAM, 8, 0x0016a169, 0x00000037} , { "GENERIC", MEM_TYPE_SDRAM, 16, 0x00169d25, 0x00000037} , { "GENERIC", MEM_TYPE_SGRAM, 16, 0x00179d29, 0x00000037} , { "GENERIC", MEM_TYPE_SGRAM, 8, 0x001fa569, 0x00000037} , { "GLINK", MEM_TYPE_SGRAM, 8, 0x001ea169, 0x00000037} , { "MOSYS", MEM_TYPE_SGRAM, 16, 0x00015495, 0x00000027} , { "MOSYS", MEM_TYPE_SGRAM, 8, 0x00155495, 0x00000027} , { "SAMSUNG", MEM_TYPE_SDRAM, 16, 0x00169d25, 0x00000037} , { "SAMSUNG", MEM_TYPE_SGRAM, 16, 0x00169d25, 0x00000037} , { "SAMSUNG", MEM_TYPE_SGRAM, 8, 0x00169d25, 0x00000037} , { "SIEMENS", MEM_TYPE_SGRAM, 8, 0x0016a169, 0x00000037} , { "TOSHIBA", MEM_TYPE_SGRAM, 8, 0x0016a565, 0x00000037} , }; #define MEM_TABLE_SIZE (sizeof(memTable)/sizeof(struct memTable_st)) #define MEM_ETRON_SGRAM_16 0 #define MEM_ETRON_SGRAM_8 1 #define MEM_GENERIC_SDRAM_16 2 #define MEM_GENERIC_SGRAM_16 3 #define MEM_GENERIC_SGRAM_8 4 #define MEM_GLINK_SGRAM_8 5 #define MEM_MOSYS_SGRAM_16 6 #define MEM_MOSYS_SGRAM_8 7 #define MEM_SAMSUNG_SDRAM_16 8 #define MEM_SAMSUNG_SGRAM_16 9 #define MEM_SAMSUNG_SGRAM_8 10 #define MEM_SIEMENS_SGRAM_8 11 #define MEM_TOSHIBA_SGRAM_8 12 #define MEM_DEFAULT_SGRAM_8 MEM_GENERIC_SGRAM_8 #define MEM_DEFAULT_SGRAM_16 MEM_GENERIC_SGRAM_16 #define MEM_DEFAULT_SDRAM_16 MEM_GENERIC_SDRAM_16 glide3x/h5/cinit/modetabl.h0100700000175300010010000006560207725034640015110 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** File name: modetabl.h ** ** Description: Mode table that contains modes and related register values. ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ ** ** $History: modetabl.h $ ** ** ***************** Version 1 ***************** ** User: Sapphire Date: 3/16/99 Time: 7:28p ** Created in $/Releases/Voodoo3/V3_OEM_100/3dfx/devel/H3/cinit ** ** ***************** Version 25 ***************** ** User: Stb_srogers Date: 3/02/99 Time: 4:04p ** Updated in $/devel/h3/Win95/dx/minivdd ** Adding the 960x720 & 1280x960 modes ** ** ***************** Version 24 ***************** ** User: Stb_srogers Date: 2/16/99 Time: 5:04p ** Updated in $/devel/h3/win95/dx/minivdd ** ** ***************** Version 22 ***************** ** User: Stb_srogers Date: 2/11/99 Time: 6:59p ** Updated in $/devel/h3/win95/dx/minivdd ** ** ***************** Version 21 ***************** ** User: Stb_srogers Date: 2/09/99 Time: 11:30a ** Updated in $/devel/h3/win95/dx/minivdd ** ** ***************** Version 20 ***************** ** User: Andrew Date: 2/07/99 Time: 4:45p ** Updated in $/devel/h3/Win95/dx/minivdd ** Change the clocks as per Malcolm Gray suggestion and added new modes ** 1600x1024, 1920x1200, and 2048x1536. ** ** ***************** Version 19 ***************** ** User: Stb_srogers Date: 1/29/99 Time: 8:08a ** Updated in $/devel/h3/win95/dx/minivdd ** ** ***************** Version 18 ***************** ** User: Andrew Date: 1/12/99 Time: 12:40p ** Updated in $/devel/h3/Win95/dx/minivdd ** Removed my changes since complaint mode is 75 Hz ** ** ***************** Version 16 ***************** ** User: Michael Date: 1/11/99 Time: 3:54p ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 15 ***************** ** User: Michael Date: 12/31/98 Time: 9:55a ** Updated in $/devel/h3/Win95/dx/minivdd ** STB's customized refresh rates. Customizations are surrounded by ** "#ifdef INCSTBCUST". ** ** ***************** Version 14 ***************** ** User: Andrew Date: 8/31/98 Time: 11:26p ** Updated in $/devel/h3/Win95/dx/minivdd ** John's fixes for 800x600 ** ** ***************** Version 13 ***************** ** User: Andrew Date: 8/20/98 Time: 10:11p ** Updated in $/devel/h3/Win95/dx/minivdd ** Updated 320x240@60,72 400x300 @ 72 & 85, 1792x1392 changed from 72 to ** 75. ** ** ***************** Version 12 ***************** ** User: Andrew Date: 7/27/98 Time: 11:12a ** Updated in $/devel/h3/Win95/dx/minivdd ** Added updates for 400x300 modes since SCANLINEDBL was not set in xls ** file ** ** ***************** Version 11 ***************** ** User: Andrew Date: 7/21/98 Time: 2:42p ** Updated in $/devel/h3/Win95/dx/minivdd ** Modified to support the new final mode list -- add new refreshs ** 320x200, 320x240, 400x300, 512x384, and 1152x864. ** ** ***************** Version 10 ***************** ** User: Andrew Date: 7/04/98 Time: 10:37a ** Updated in $/devel/h3/Win95/dx/minivdd ** Got modetabl.h the right way.....Differences hsync skew on 1920x1440 ** and clocks on low-rez modes ** ** ***************** Version 9 ***************** ** User: Andrew Date: 6/29/98 Time: 10:58a ** Updated in $/devel/h3/Win95/dx/minivdd ** Changed Dot Clock on 1792x1344 and Refresh Rate from 70 to 72. Changed ** CR04 on 1792x1344 @ 60 Hz ** ** ***************** Version 8 ***************** ** User: Andrew Date: 6/24/98 Time: 9:32a ** Updated in $/devel/h3/Win95/dx/minivdd ** New mode additions for 1792x1344 and 1856x1392 plus 1152x864 @ 100 ** ** ***************** Version 7 ***************** ** User: Andrew Date: 5/19/98 Time: 6:12p ** Updated in $/devel/h3/Win95/dx/minivdd ** changed 1800 to 1808 and changed timing to 1808 ** ** ***************** Version 6 ***************** ** User: Andrew Date: 5/07/98 Time: 11:24a ** Updated in $/devel/h3/Win95/dx/minivdd ** Added modes 1792x1440 and 1920x1440. 1800x1440 was updated but still ** does not work ** ** ***************** Version 5 ***************** ** User: Andrew Date: 4/22/98 Time: 2:58p ** Updated in $/devel/h3/Win95/dx/minivdd ** Changed clock at 1280x960 @ 75 hz and 1600x1200 @ 85 Hz and added ** broken 1800x1440 ** ** ***************** Version 4 ***************** ** User: Ken Date: 4/15/98 Time: 6:42p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** */ // Begin STB Changes // STB-SR 12/23/98 changing modetable // STB-SR 12/30/98 All but 720x350 and 720x400 work // STB-SR 01/07/99 720x350 and 720x400 work. I had assumed that SR1 (Sequencer // Register 1), was always 0x21. Bit 0 defines wether or not the character // width is 8 or 9. 1->8 pixel wide char, 0->9 pixel char. The actual change // was made in minivdd\modetabl.h // STB-SR 02/11/99 Adding STB & 3Dfx unified modes for Voodoo3 #ifdef H4 // If you need to make changes to the modetable, you must also edit // dd16\h3.c and dd16\setmode.c // r[0] r[1] r[2] r[3] r[4] r[5] r[6] r[7] r[8] r[9] r[10] r[11] r[12] r[13] r[14] r[15] r[16] r[17] r[18] r[19] r[20] // x y rr, 0h 1h 2h 3h 4h 5h 6h 7h 9h 10h 11h 12h 15h 16h 1ah 1bh 3c2 SR1 pllctrl0 dacmode // x y rr, Htotl HDEnE HBlSt HBlEn HSySt HSyEn Vtotl Ovflw MxSLn VSySt VSyEn VDEnE VBlSt VBlEn HExtn VExtn MiscO SR1 pllctrl0 dacmode // New Standardized modetable for both 3Dfx and STB { 640, 480, 60, 0x5f, 0x4f, 0x4f, 0x83, 0x51, 0x9d, 0x0b, 0x3e, 0x40, 0xe9, 0x2b, 0xdf, 0xdf, 0x0c, 0x00, 0x00, 0xcf, 0x21, 0x37, 0xd1, 0x00}, { 640, 480, 72, 0x63, 0x4f, 0x4f, 0x87, 0x52, 0x97, 0x06, 0x3e, 0x40, 0xe8, 0x2b, 0xdf, 0xdf, 0x07, 0x00, 0x00, 0xcf, 0x21, 0x0f, 0x56, 0x00}, { 640, 480, 75, 0x64, 0x4f, 0x4f, 0x88, 0x51, 0x99, 0xf2, 0x1f, 0x40, 0xe0, 0x23, 0xdf, 0xdf, 0xf3, 0x00, 0x00, 0xcf, 0x21, 0x0f, 0x56, 0x00}, { 640, 480, 85, 0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9d, 0xfb, 0x1f, 0x40, 0xe0, 0x23, 0xdf, 0xdf, 0xfc, 0x00, 0x00, 0xcf, 0x21, 0x1f, 0xb3, 0x00}, { 800, 600, 56, 0x7b, 0x63, 0x63, 0x9f, 0x66, 0x8f, 0x6f, 0xf0, 0x60, 0x58, 0x2a, 0x57, 0x57, 0x70, 0x80, 0x00, 0x0f, 0x21, 0x1f, 0xb3, 0x00}, { 800, 600, 60, 0x7f, 0x63, 0x63, 0x83, 0x68, 0x18, 0x72, 0xf0, 0x60, 0x58, 0x2c, 0x57, 0x57, 0x73, 0xa0, 0x00, 0x0f, 0x21, 0x27, 0xf4, 0x00}, { 800, 600, 72, 0x7d, 0x63, 0x63, 0x81, 0x6a, 0x19, 0x98, 0xf0, 0x60, 0x7c, 0x22, 0x57, 0x57, 0x99, 0xa0, 0x00, 0x0f, 0x21, 0x1f, 0xf9, 0x00}, { 800, 600, 75, 0x7f, 0x63, 0x63, 0x83, 0x65, 0x0f, 0x6f, 0xf0, 0x60, 0x58, 0x2b, 0x57, 0x57, 0x70, 0xa0, 0x00, 0x0f, 0x21, 0x07, 0x51, 0x00}, { 800, 600, 85, 0x7e, 0x63, 0x63, 0x82, 0x67, 0x0f, 0x75, 0xf0, 0x60, 0x58, 0x2b, 0x57, 0x57, 0x76, 0xa0, 0x00, 0x0f, 0x21, 0x17, 0xda, 0x00}, { 1024, 768, 60, 0xa3, 0x7f, 0x7f, 0x87, 0x82, 0x93, 0x24, 0xf5, 0x60, 0x02, 0x28, 0xff, 0xff, 0x25, 0x20, 0x00, 0xcf, 0x21, 0x07, 0x6b, 0x00}, { 1024, 768, 70, 0xa1, 0x7f, 0x7f, 0x85, 0x82, 0x93, 0x24, 0xf5, 0x60, 0x02, 0x28, 0xff, 0xff, 0x25, 0x20, 0x00, 0xcf, 0x21, 0x2a, 0xf9, 0x00}, { 1024, 768, 75, 0x9f, 0x7f, 0x7f, 0x83, 0x81, 0x8d, 0x1e, 0xf5, 0x60, 0x00, 0x23, 0xff, 0xff, 0x1f, 0x20, 0x00, 0x0f, 0x21, 0x06, 0x40, 0x00}, { 1024, 768, 85, 0xa7, 0x7f, 0x7f, 0x8b, 0x85, 0x91, 0x26, 0xf5, 0x60, 0x00, 0x23, 0xff, 0xff, 0x27, 0x20, 0x00, 0x0f, 0x21, 0x0e, 0x82, 0x00}, { 1152, 864, 60, 0xb3, 0x8f, 0x8f, 0x97, 0x93, 0x9f, 0x87, 0xff, 0x60, 0x60, 0x23, 0x5f, 0x5f, 0x88, 0x00, 0x00, 0x0f, 0x21, 0x26, 0xf4, 0x00}, { 1152, 864, 70, 0xb4, 0x8f, 0x8f, 0x98, 0x93, 0x9f, 0x8e, 0xff, 0x60, 0x60, 0x23, 0x5f, 0x5f, 0x8f, 0x00, 0x00, 0x0f, 0x21, 0x0e, 0x82, 0x00}, { 1152, 864, 75, 0xc3, 0x8f, 0x8f, 0x87, 0x97, 0x07, 0x82, 0xff, 0x60, 0x60, 0x23, 0x5f, 0x5f, 0x83, 0xa0, 0x00, 0x0f, 0x21, 0x12, 0xb3, 0x00}, { 1152, 864, 85, 0xbf, 0x8f, 0x8f, 0x83, 0x97, 0x07, 0x8d, 0xff, 0x60, 0x60, 0x23, 0x5f, 0x5f, 0x8e, 0xa0, 0x00, 0x0f, 0x21, 0x06, 0x64, 0x00}, { 1280, 960, 60, 0xdc, 0x9f, 0x9f, 0x80, 0xab, 0x99, 0xe6, 0xff, 0x60, 0xc0, 0x23, 0xbf, 0xbf, 0xe7, 0xa0, 0x00, 0x0f, 0x21, 0x12, 0xb3, 0x00}, { 1280, 960, 85, 0xd3, 0x9f, 0x9f, 0x97, 0xa7, 0x1b, 0xf1, 0xff, 0x60, 0xc0, 0x23, 0xbf, 0xbf, 0xf2, 0xa0, 0x00, 0x0f, 0x21, 0x0a, 0xa4, 0x00}, { 1280, 1024, 60, 0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x13, 0x28, 0x5a, 0x60, 0x00, 0x23, 0xff, 0xff, 0x29, 0xa0, 0x41, 0x0f, 0x21, 0x12, 0xb3, 0x00}, { 1280, 1024, 75, 0xce, 0x9f, 0x9f, 0x92, 0xa1, 0x13, 0x28, 0x5a, 0x60, 0x00, 0x23, 0xff, 0xff, 0x29, 0xa0, 0x41, 0x0f, 0x21, 0x0a, 0x95, 0x00}, { 1280, 1024, 85, 0xd3, 0x9f, 0x9f, 0x97, 0xa7, 0x1b, 0x2e, 0x5a, 0x60, 0x00, 0x23, 0xff, 0xff, 0x2f, 0xa0, 0x41, 0x0f, 0x21, 0x05, 0x40, 0x00}, { 1600, 1024, 60, 0x00, 0xc7, 0xc7, 0x84, 0xcb, 0x1f, 0x2c, 0x5a, 0x60, 0x02, 0x25, 0xff, 0xff, 0x2d, 0x21, 0x41, 0xcf, 0x21, 0x0e, 0xb9, 0x00}, { 1600, 1024, 76, 0x00, 0xc7, 0xc7, 0x84, 0xcb, 0x1f, 0x2c, 0x5a, 0x60, 0x02, 0x25, 0xff, 0xff, 0x2d, 0x21, 0x41, 0xcf, 0x21, 0x15, 0xa4, 0x00}, { 1600, 1024, 85, 0x00, 0xc7, 0xc7, 0x84, 0xcb, 0x1f, 0x2c, 0x5a, 0x60, 0x02, 0x25, 0xff, 0xff, 0x2d, 0x21, 0x41, 0xcf, 0x21, 0x09, 0x68, 0x00}, { 1600, 1200, 60, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x19, 0xad, 0x00}, { 1600, 1200, 65, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x21, 0xeb, 0x00}, { 1600, 1200, 70, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x09, 0x64, 0x00}, { 1600, 1200, 75, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x05, 0x50, 0x00}, { 1600, 1200, 80, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x11, 0xad, 0x00}, { 1600, 1200, 85, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x05, 0x5b, 0x00}, { 1600, 1200, 100, 0x00, 0xc7, 0xc7, 0x84, 0xcf, 0x07, 0xe0, 0x10, 0x40, 0xb0, 0x23, 0xaf, 0xaf, 0xe1, 0xa1, 0x55, 0x0f, 0x21, 0x15, 0xfd, 0x00}, { 1792, 1344, 60, 0x94, 0x6f, 0x6f, 0x98, 0x77, 0x04, 0x70, 0x1f, 0x40, 0x40, 0x23, 0x3f, 0x3f, 0x71, 0x20, 0x55, 0x4f, 0x21, 0x0d, 0x8d, 0x01}, { 1792, 1344, 75, 0x95, 0x6f, 0x6f, 0x99, 0x75, 0x03, 0x87, 0x1f, 0x40, 0x40, 0x23, 0x3f, 0x3f, 0x88, 0x20, 0x55, 0x4f, 0x21, 0x15, 0xfd, 0x01}, { 1856, 1392, 60, 0x99, 0x73, 0x73, 0x9d, 0x79, 0x07, 0x9d, 0x1f, 0x40, 0x70, 0x23, 0x6f, 0x6f, 0x9e, 0x20, 0x55, 0x4f, 0x21, 0x09, 0x78, 0x01}, { 1856, 1392, 75, 0x9b, 0x73, 0x73, 0x9f, 0x7b, 0x09, 0xda, 0x1f, 0x40, 0x70, 0x23, 0x6f, 0x6f, 0xdb, 0x20, 0x55, 0x4f, 0x21, 0x09, 0x9f, 0x01}, { 1920, 1080, 60, 0x8f, 0x77, 0x77, 0x93, 0x79, 0x02, 0x63, 0x10, 0x40, 0x3a, 0x2d, 0x37, 0x37, 0x64, 0x20, 0x55, 0xcf, 0x21, 0x05, 0x41, 0x01}, { 1920, 1080, 72, 0x9b, 0x77, 0x77, 0x9f, 0x7a, 0x08, 0x92, 0x10, 0x40, 0x3a, 0x2d, 0x37, 0x37, 0x93, 0x20, 0x55, 0xcf, 0x21, 0x11, 0xb3, 0x01}, { 1920, 1200, 60, 0x9d, 0x77, 0x77, 0x81, 0x7b, 0x8b, 0xe0, 0x10, 0x40, 0xb2, 0x25, 0xaf, 0xaf, 0xe1, 0x20, 0x55, 0xcf, 0x21, 0x1d, 0xf2, 0x01}, { 1920, 1200, 76, 0x9d, 0x77, 0x77, 0x81, 0x7b, 0x8b, 0xe0, 0x10, 0x40, 0xb2, 0x25, 0xaf, 0xaf, 0xe1, 0x20, 0x55, 0xcf, 0x21, 0x15, 0xee, 0x01}, { 1920, 1440, 60, 0x9e, 0x77, 0x77, 0x82, 0x7f, 0x8c, 0xda, 0x1f, 0x40, 0xa0, 0x23, 0x9f, 0x9f, 0xdb, 0x20, 0x55, 0x4f, 0x21, 0x05, 0x60, 0x01}, { 1920, 1440, 75, 0xa0, 0x77, 0x77, 0x84, 0x80, 0x8e, 0xda, 0x1f, 0x40, 0xa0, 0x23, 0x9f, 0x9f, 0xdb, 0x20, 0x55, 0x4f, 0x21, 0x09, 0xa4, 0x01}, { 2048, 1536, 60, 0x98, 0x7f, 0x7f, 0x9c, 0x82, 0x10, 0x3b, 0xba, 0x40, 0x00, 0x23, 0xff, 0xff, 0x3c, 0x20, 0x55, 0x0f, 0x21, 0x09, 0x84, 0x01}, { 2048, 1536, 75, 0xa1, 0x7f, 0x7f, 0x85, 0x83, 0x91, 0x44, 0xba, 0x40, 0x00, 0x23, 0xff, 0xff, 0x45, 0x20, 0x55, 0x0f, 0x21, 0x05, 0x84, 0x01}, { 320, 200, 70, 0x2d, 0x27, 0x27, 0x91, 0x28, 0x8e, 0xbf, 0x1f, 0xc0, 0x9c, 0x2e, 0x8f, 0x8f, 0xc0, 0x80, 0x00, 0x4f, 0x21, 0x73, 0xd1, 0x00}, { 320, 200, 85, 0x2f, 0x27, 0x27, 0x93, 0x29, 0x8d, 0xbb, 0x1f, 0xc0, 0x90, 0x23, 0x8f, 0x8f, 0xbc, 0x80, 0x00, 0x4f, 0x21, 0x0f, 0x2a, 0x00}, { 320, 240, 60, 0x2d, 0x27, 0x27, 0x91, 0x28, 0x8e, 0x0b, 0x3e, 0xc0, 0xe9, 0x2b, 0xdf, 0xdf, 0x0c, 0x80, 0x00, 0xcf, 0x21, 0x73, 0xd1, 0x00}, { 320, 240, 72, 0x2f, 0x27, 0x27, 0x93, 0x29, 0x8b, 0x06, 0x3e, 0xc0, 0xe8, 0x2b, 0xdf, 0xdf, 0x07, 0x80, 0x00, 0xcf, 0x21, 0x0f, 0x2a, 0x00}, { 320, 240, 75, 0x30, 0x27, 0x27, 0x94, 0x28, 0x8c, 0xf2, 0x1f, 0xc0, 0xe0, 0x23, 0xdf, 0xdf, 0xf3, 0x80, 0x00, 0xcf, 0x21, 0x63, 0xe5, 0x00}, { 320, 240, 85, 0x2f, 0x27, 0x27, 0x93, 0x2a, 0x8e, 0xfb, 0x1f, 0xc0, 0xe0, 0x23, 0xdf, 0xdf, 0xfc, 0x80, 0x00, 0xcf, 0x21, 0x43, 0xb3, 0x00}, { 400, 300, 60, 0x3d, 0x31, 0x31, 0x81, 0x34, 0x1c, 0x72, 0xf0, 0xe0, 0x58, 0x2c, 0x57, 0x57, 0x73, 0xa0, 0x00, 0x0f, 0x21, 0x3f, 0xbc, 0x00}, { 400, 300, 72, 0x3c, 0x31, 0x31, 0x80, 0x35, 0x1c, 0x98, 0xf0, 0xe0, 0x7c, 0x22, 0x57, 0x57, 0x99, 0xa0, 0x00, 0x0f, 0x21, 0x43, 0xf9, 0x00}, { 400, 300, 75, 0x3d, 0x31, 0x31, 0x81, 0x32, 0x17, 0x6f, 0xf0, 0xe0, 0x58, 0x2b, 0x57, 0x57, 0x70, 0xa0, 0x00, 0x0f, 0x21, 0x13, 0x51, 0x00}, { 400, 300, 85, 0x3d, 0x31, 0x31, 0x81, 0x33, 0x17, 0x75, 0xf0, 0xe0, 0x58, 0x2b, 0x57, 0x57, 0x76, 0xa0, 0x00, 0x0f, 0x21, 0x13, 0x5d, 0x00}, { 512, 384, 60, 0x4f, 0x3f, 0x3f, 0x93, 0x41, 0x09, 0x24, 0xf5, 0xe0, 0x02, 0x28, 0xff, 0xff, 0x25, 0x20, 0x00, 0xcf, 0x21, 0x2f, 0xea, 0x00}, { 512, 384, 70, 0x4e, 0x3f, 0x3f, 0x92, 0x41, 0x09, 0x24, 0xf5, 0xe0, 0x02, 0x28, 0xff, 0xff, 0x25, 0x20, 0x00, 0xcf, 0x21, 0x2b, 0xf9, 0x00}, { 512, 384, 75, 0x4d, 0x3f, 0x3f, 0x91, 0x40, 0x06, 0x1e, 0xf5, 0xe0, 0x00, 0x23, 0xff, 0xff, 0x1f, 0x20, 0x00, 0xcf, 0x21, 0x07, 0x40, 0x00}, { 512, 384, 85, 0x51, 0x3f, 0x3f, 0x95, 0x42, 0x08, 0x26, 0xf5, 0xe0, 0x00, 0x23, 0xff, 0xff, 0x27, 0x20, 0x00, 0xcf, 0x21, 0x0f, 0x82, 0x00}, { 640, 400, 70, 0x5f, 0x4f, 0x4f, 0x83, 0x51, 0x9d, 0xbf, 0x1f, 0x40, 0x9c, 0x2e, 0x8f, 0x8f, 0xc0, 0x00, 0x00, 0x4f, 0x21, 0x37, 0xd1, 0x00}, { 640, 400, 85, 0x63, 0x4f, 0x4f, 0x87, 0x53, 0x9b, 0xbb, 0x1f, 0x40, 0x90, 0x23, 0x8f, 0x8f, 0xbc, 0x00, 0x00, 0x4f, 0x21, 0x0f, 0x56, 0x00}, { 720, 480, 60, 0x6b, 0x59, 0x59, 0x8f, 0x5b, 0x8a, 0x0b, 0x3e, 0x40, 0xe9, 0x2b, 0xdf, 0xdf, 0x0c, 0x80, 0x00, 0xcf, 0x21, 0x0b, 0x3d, 0x00}, { 720, 480, 72, 0x6e, 0x59, 0x59, 0x92, 0x5b, 0x8c, 0x06, 0x3e, 0x40, 0xe8, 0x2b, 0xdf, 0xdf, 0x07, 0x80, 0x00, 0xcf, 0x21, 0x2f, 0xfb, 0x00}, { 720, 480, 85, 0x70, 0x59, 0x59, 0x94, 0x61, 0x89, 0xfb, 0x1f, 0x40, 0xe0, 0x23, 0xdf, 0xdf, 0xfc, 0x80, 0x00, 0xcf, 0x21, 0x1b, 0xb3, 0x00}, { 720, 576, 72, 0x70, 0x59, 0x59, 0x94, 0x5d, 0x89, 0x80, 0xf0, 0x60, 0x41, 0x25, 0x3f, 0x3f, 0x81, 0x80, 0x00, 0x0f, 0x21, 0x13, 0x8f, 0x00}, { 720, 576, 100, 0x70, 0x59, 0x59, 0x94, 0x5d, 0x89, 0x80, 0xf0, 0x60, 0x41, 0x25, 0x3f, 0x3f, 0x81, 0x80, 0x00, 0x0f, 0x21, 0x17, 0xe9, 0x00}, #else // #ifdef H4 // STB End Changes {320, 200, 70, 0x2f, 0x27, 0x27, 0x93, 0x2a, 0x8e, 0xbb, 0x1f, 0x40, 0x91, 0x24, 0x8f, 0x8f, 0xbc, 0x80, 0x00, 0x4f, 0x21, 0xee, 0xdb, 0x00}, {320, 200, 85, 0x2f, 0x27, 0x27, 0x93, 0x2a, 0x8e, 0xbb, 0x1f, 0x40, 0x91, 0x24, 0x8f, 0x8f, 0xbc, 0x80, 0x00, 0x4f, 0x21, 0x37, 0x82, 0x00}, {320, 240, 60, 0x2d, 0x27, 0x27, 0x8f, 0x29, 0x8e, 0x0b, 0x3e, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xfc, 0x80, 0x00, 0xcf, 0x21, 0xea, 0xd1, 0x00}, {320, 240, 72, 0x2f, 0x27, 0x27, 0x93, 0x2a, 0x8e, 0x06, 0x3e, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xfc, 0x80, 0x00, 0xcf, 0x21, 0x37, 0x82, 0x00}, {320, 240, 85, 0x2f, 0x27, 0x27, 0x93, 0x2a, 0x8e, 0xfb, 0x1f, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xfc, 0x80, 0x00, 0xcf, 0x21, 0x3f, 0xa9, 0x00}, {400, 300, 60, 0x3d, 0x31, 0x31, 0x81, 0x34, 0x1c, 0x72, 0xf0, 0x60, 0x59, 0x2d, 0x57, 0x57, 0x73, 0xa0, 0x00, 0x0f, 0x21, 0xf4, 0x56, 0x00}, {400, 300, 72, 0x3c, 0x31, 0x31, 0x80, 0x34, 0x1b, 0x98, 0xf0, 0x60, 0x7d, 0x23, 0x57, 0x57, 0x99, 0xa0, 0x00, 0x0f, 0x21, 0xf4, 0x6c, 0x00}, {400, 300, 85, 0x3d, 0x31, 0x31, 0x80, 0x33, 0x1b, 0x75, 0xf0, 0x60, 0x59, 0x2c, 0x57, 0x57, 0x76, 0xa0, 0x00, 0x0f, 0x21, 0xb8, 0x5d, 0x00}, {512, 384, 60, 0x4f, 0x3f, 0x3f, 0x93, 0x41, 0x0a, 0x24, 0xf5, 0x60, 0x04, 0x2a, 0xff, 0xff, 0x25, 0x20, 0x00, 0xcf, 0x21, 0x5e, 0xe1, 0x00}, {512, 384, 72, 0x4e, 0x3f, 0x3f, 0x92, 0x41, 0x0a, 0x24, 0xf5, 0x60, 0x03, 0x29, 0xff, 0xff, 0x25, 0x20, 0x00, 0xcf, 0x21, 0xbc, 0x82, 0x00}, {512, 384, 75, 0x4d, 0x3f, 0x3f, 0x91, 0x41, 0x07, 0x1e, 0xf5, 0x60, 0x01, 0x24, 0xff, 0xff, 0x1f, 0x20, 0x00, 0x0f, 0x21, 0x2a, 0x82, 0x00}, {512, 384, 85, 0x51, 0x3f, 0x3f, 0x95, 0x43, 0x09, 0x26, 0xf5, 0x60, 0x01, 0x24, 0xff, 0xff, 0x27, 0x20, 0x00, 0x0f, 0x21, 0x36, 0xc4, 0x00}, {640, 350, 85, 0x63, 0x4f, 0x4f, 0x87, 0x54, 0x9c, 0xbb, 0x1f, 0x40, 0x7e, 0x21, 0x5d, 0x5d, 0xbc, 0x20, 0x00, 0x8f, 0x21, 0x36, 0x82, 0x00}, {640, 400, 70, 0x63, 0x4f, 0x4f, 0x87, 0x54, 0x9c, 0xbb, 0x1f, 0x40, 0x91, 0x24, 0x8f, 0x8f, 0xbc, 0x20, 0x00, 0x4f, 0x21, 0xed, 0xdb, 0x00}, {640, 400, 85, 0x63, 0x4f, 0x4f, 0x87, 0x54, 0x9c, 0xbb, 0x1f, 0x40, 0x91, 0x24, 0x8f, 0x8f, 0xbc, 0x20, 0x00, 0x4f, 0x21, 0x36, 0x82, 0x00}, {640, 480, 60, 0x5f, 0x4f, 0x4f, 0x83, 0x52, 0x9e, 0x0b, 0x3e, 0x40, 0xea, 0x2c, 0xdf, 0xdf, 0x0c, 0x20, 0x00, 0xcf, 0x21, 0x7d, 0x72, 0x00}, {640, 480, 72, 0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9b, 0x06, 0x3e, 0x40, 0xe9, 0x2c, 0xdf, 0xdf, 0x07, 0x20, 0x00, 0xcf, 0x21, 0x36, 0x82, 0x00}, {640, 480, 75, 0x64, 0x4f, 0x4f, 0x88, 0x51, 0x99, 0xf2, 0x1f, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xf3, 0x20, 0x00, 0xcf, 0x21, 0x36, 0x82, 0x00}, {640, 480, 85, 0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9e, 0xfb, 0x1f, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xfc, 0x20, 0x00, 0xcf, 0x21, 0x3e, 0xa9, 0x00}, {640, 480, 100, 0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9e, 0xfb, 0x1f, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xfc, 0x20, 0x00, 0xcf, 0x21, 0x58, 0x45, 0x00}, {640, 480, 120, 0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9e, 0xfb, 0x1f, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0xfc, 0x20, 0x00, 0xcf, 0x21, 0x48, 0x45, 0x00}, {720, 400, 72, 0x70, 0x59, 0x59, 0x94, 0x5e, 0x87, 0xbc, 0x1f, 0x40, 0x91, 0x24, 0x8f, 0x8f, 0xbd, 0xa0, 0x00, 0x4f, 0x21, 0x20, 0x13, 0x00}, {720, 400, 85, 0x70, 0x59, 0x59, 0x94, 0x5e, 0x87, 0xbc, 0x1f, 0x40, 0x91, 0x24, 0x8f, 0x8f, 0xbd, 0xa0, 0x00, 0x4f, 0x21, 0xb8, 0x75, 0x00}, {720, 480, 60, 0x70, 0x59, 0x59, 0x94, 0x5e, 0x87, 0x15, 0x3e, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0x16, 0xa0, 0x00, 0x4f, 0x21, 0xc4, 0x69, 0x00}, {720, 480, 72, 0x70, 0x59, 0x59, 0x94, 0x5e, 0x87, 0x15, 0x3e, 0x40, 0xe1, 0x24, 0xdf, 0xdf, 0x16, 0xa0, 0x00, 0x4f, 0x21, 0xd8, 0x8b, 0x00}, {720, 576, 72, 0x70, 0x59, 0x59, 0x94, 0x5e, 0x87, 0x80, 0xf0, 0x60, 0x41, 0x24, 0x3f, 0x3f, 0x81, 0xa0, 0x00, 0x4f, 0x21, 0xb0, 0x89, 0x00}, {720, 576, 100, 0x70, 0x59, 0x59, 0x94, 0x5e, 0x87, 0x80, 0xf0, 0x60, 0x41, 0x24, 0x3f, 0x3f, 0x81, 0xa0, 0x00, 0x4f, 0x21, 0xec, 0xfe, 0x00}, {800, 600, 56, 0x7b, 0x63, 0x63, 0x9f, 0x69, 0x99, 0x6f, 0xf0, 0x60, 0x59, 0x2b, 0x57, 0x57, 0x70, 0xa0, 0x00, 0x0f, 0x21, 0x3e, 0xa9, 0x00}, {800, 600, 60, 0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x94, 0x6c, 0xf0, 0x60, 0x59, 0x2c, 0x57, 0x57, 0x6d, 0xa0, 0x00, 0x0f, 0x21, 0x06, 0x1e, 0x00}, {800, 600, 72, 0x7d, 0x63, 0x63, 0x81, 0x68, 0x17, 0x98, 0xf0, 0x60, 0x7d, 0x23, 0x57, 0x57, 0x99, 0x80, 0x00, 0x0f, 0x21, 0x06, 0x28, 0x00}, {800, 600, 75, 0x7f, 0x63, 0x63, 0x83, 0x65, 0x0f, 0x6f, 0xf0, 0x60, 0x59, 0x2c, 0x57, 0x57, 0x70, 0x80, 0x00, 0x0f, 0x21, 0x55, 0x9d, 0x00}, {800, 600, 85, 0x7e, 0x63, 0x63, 0x82, 0x67, 0x0f, 0x75, 0xf0, 0x60, 0x59, 0x2c, 0x57, 0x57, 0x76, 0x80, 0x00, 0x0f, 0x21, 0x31, 0x6c, 0x00}, {800, 600, 100, 0x7e, 0x63, 0x63, 0x82, 0x66, 0x0e, 0x75, 0xf0, 0x60, 0x59, // 0x2c, 0x57, 0x57, 0x76, 0x80, 0x00, 0x0f, 0x21, 0x8c, 0xa9, 0x00}, 0x2c, 0x57, 0x57, 0x76, 0x80, 0x00, 0x0f, 0x21, 0x0b, 0x92, 0x00}, {800, 600, 120, 0x7e, 0x63, 0x63, 0x82, 0x66, 0x0e, 0x75, 0xf0, 0x60, 0x59, 0x2c, 0x57, 0x57, 0x76, 0x80, 0x00, 0x0f, 0x21, 0x24, 0x3b, 0x00}, {1152, 864, 60, 0xb4, 0x8f, 0x8f, 0x98, 0x94, 0x80, 0x8e, 0xff, 0x60, 0x61, // 0x24, 0x5f, 0x5f, 0x8f, 0x80, 0x00, 0x0f, 0x21, 0x84, 0xc4, 0x00}, 0x24, 0x5f, 0x5f, 0x8f, 0x80, 0x00, 0x0f, 0x21, 0x0b, 0xb3, 0x00}, {1152, 864, 75, 0xc3, 0x8f, 0x8f, 0x87, 0x98, 0x08, 0x82, 0xff, 0x60, 0x61, // 0x24, 0x5f, 0x5f, 0x83, 0xa0, 0x00, 0x0f, 0x21, 0x50, 0xa4, 0x00}, 0x24, 0x5f, 0x5f, 0x83, 0xa0, 0x00, 0x0f, 0x21, 0x12, 0xb3, 0x00}, {1152, 864, 85, 0xc0, 0x8f, 0x8f, 0x84, 0x98, 0x08, 0x89, 0xff, 0x60, 0x61, // 0x24, 0x5f, 0x5f, 0x8a, 0xa0, 0x00, 0x0f, 0x21, 0x6c, 0xf4, 0x00}, 0x24, 0x5f, 0x5f, 0x8a, 0xa0, 0x00, 0x0f, 0x21, 0x16, 0xeb, 0x00}, {1152, 864, 100, 0x5f, 0x47, 0x47, 0x83, 0x4c, 0x93, 0x82, 0xff, 0x60, 0x61, // 0x24, 0x5f, 0x5f, 0x83, 0x20, 0x00, 0x0f, 0x21, 0x40, 0xb3, 0x01}, 0x24, 0x5f, 0x5f, 0x83, 0x20, 0x00, 0x0f, 0x21, 0x0a, 0x9f, 0x01}, {1024, 768, 60, 0xa3, 0x7f, 0x7f, 0x87, 0x83, 0x94, 0x24, 0xf5, 0x60, 0x04, // 0x2a, 0xff, 0xff, 0x25, 0x00, 0x00, 0xcf, 0x21, 0x5d, 0xe1, 0x00}, 0x2a, 0xff, 0xff, 0x25, 0x00, 0x00, 0xcf, 0x21, 0x07, 0x6b, 0x00}, {1024, 768, 70, 0xa1, 0x7f, 0x7f, 0x85, 0x83, 0x94, 0x24, 0xf5, 0x60, 0x03, // 0x29, 0xff, 0xff, 0x25, 0x00, 0x00, 0xcf, 0x21, 0x4d, 0xda, 0x00}, 0x29, 0xff, 0xff, 0x25, 0x00, 0x00, 0xcf, 0x21, 0x13, 0xf9, 0x00}, {1024, 768, 72, 0xa1, 0x7f, 0x7f, 0x85, 0x83, 0x94, 0x24, 0xf5, 0x60, 0x03, 0x29, 0xff, 0xff, 0x25, 0x00, 0x00, 0xcf, 0x21, 0x74, 0xa5, 0x00}, {1024, 768, 75, 0x9f, 0x7f, 0x7f, 0x83, 0x82, 0x8e, 0x1e, 0xf5, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x0f, 0x21, 0x29, 0x82, 0x00}, 0x24, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x0f, 0x21, 0x12, 0x82, 0x00}, {1024, 768, 85, 0xa7, 0x7f, 0x7f, 0x8b, 0x86, 0x92, 0x26, 0xf5, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x27, 0x00, 0x00, 0x0f, 0x21, 0x35, 0xc4, 0x00}, 0x24, 0xff, 0xff, 0x27, 0x00, 0x00, 0x0f, 0x21, 0x0e, 0x82, 0x00}, {1024, 768, 100, 0xa7, 0x7f, 0x7f, 0x8b, 0x86, 0x92, 0x26, 0xf5, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x27, 0x00, 0x00, 0x0f, 0x21, 0x3c, 0x82, 0x00}, 0x24, 0xff, 0xff, 0x27, 0x00, 0x00, 0x0f, 0x21, 0x06, 0x5b, 0x00}, {1024, 768, 120, 0xa7, 0x7f, 0x7f, 0x8b, 0x86, 0x92, 0x26, 0xf5, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x27, 0x00, 0x00, 0x0f, 0x21, 0x50, 0xcb, 0x00}, 0x24, 0xff, 0xff, 0x27, 0x00, 0x00, 0x0f, 0x21, 0x0a, 0x93, 0x00}, {1280, 960, 60, 0xdc, 0x9f, 0x9f, 0x80, 0xac, 0x9a, 0xe6, 0xff, 0x60, 0xc1, 0x24, 0xbf, 0xbf, 0xe7, 0xa0, 0x00, 0x0f, 0x21, 0x50, 0xa4, 0x00}, {1280, 960, 75, 0xcd, 0x9f, 0x9f, 0x91, 0xa4, 0x16, 0xe6, 0xff, 0x60, 0xc1, 0x24, 0xbf, 0xbf, 0xe7, 0xa0, 0x00, 0x0f, 0x21, 0x0c, 0x2a, 0x00}, {1280, 960, 85, 0x67, 0x4f, 0x4f, 0x8b, 0x54, 0x9e, 0xf1, 0xff, 0x60, 0xc1, 0x24, 0xbf, 0xbf, 0xf2, 0x20, 0x00, 0x0f, 0x21, 0x38, 0xa4, 0x01}, {1280, 1024, 60, 0xce, 0x9f, 0x9f, 0x92, 0xa6, 0x14, 0x28, 0x5a, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x29, 0xa0, 0x41, 0x0f, 0x21, 0x50, 0xa4, 0x00}, 0x24, 0xff, 0xff, 0x29, 0xa0, 0x41, 0x0f, 0x21, 0x12, 0xb3, 0x00}, {1280, 1024, 75, 0xce, 0x9f, 0x9f, 0x92, 0xa2, 0x14, 0x28, 0x5a, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x29, 0xa0, 0x41, 0x0f, 0x21, 0x30, 0x82, 0x00}, 0x24, 0xff, 0xff, 0x29, 0xa0, 0x41, 0x0f, 0x21, 0x15, 0x82, 0x00}, {1280, 1024, 85, 0x67, 0x4f, 0x4f, 0x8b, 0x54, 0x9e, 0x2e, 0x5a, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x2f, 0x20, 0x41, 0x0f, 0x21, 0x28, 0x82, 0x01}, 0x24, 0xff, 0xff, 0x2f, 0x20, 0x41, 0x0f, 0x21, 0x11, 0x82, 0x01}, {1280, 1024, 100, 0x67, 0x4f, 0x4f, 0x8b, 0x54, 0x9e, 0x2e, 0x5a, 0x60, 0x01, // 0x24, 0xff, 0xff, 0x2f, 0x20, 0x41, 0x0f, 0x21, 0x3c, 0xda, 0x01}, 0x24, 0xff, 0xff, 0x2f, 0x20, 0x41, 0x0f, 0x21, 0x0a, 0xcd, 0x01}, {1600, 1024, 76, 0x7e, 0x63, 0x63, 0x82, 0x66, 0x0f, 0x2c, 0x5a, 0x60, 0x03, 0x06, 0xff, 0xff, 0x2d, 0x80, 0x41, 0xcf, 0x21, 0x4c, 0xf8, 0x01,}, {1600, 1200, 60, 0x82, 0x63, 0x63, 0x86, 0x68, 0x14, 0xe0, 0x10, 0x40, 0xb1, // 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x44, 0xd5, 0x01}, 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x0a, 0xb3, 0x01}, {1600, 1200, 65, 0x82, 0x63, 0x63, 0x86, 0x68, 0x14, 0xe0, 0x10, 0x40, 0xb1, // 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x44, 0xe7, 0x01}, 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x11, 0x91, 0x01}, {1600, 1200, 70, 0x82, 0x63, 0x63, 0x86, 0x68, 0x14, 0xe0, 0x10, 0x40, 0xb1, // 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x34, 0xc4, 0x01}, 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x0d, 0x82, 0x01}, {1600, 1200, 75, 0x82, 0x63, 0x63, 0x86, 0x68, 0x14, 0xe0, 0x10, 0x40, 0xb1, // 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x30, 0xc4, 0x01}, 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x09, 0x6f, 0x01}, {1600, 1200, 80, 0x82, 0x63, 0x63, 0x86, 0x68, 0x14, 0xe0, 0x10, 0x40, 0xb1, // 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x24, 0xa4, 0x01}, 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x11, 0xb3, 0x01}, {1600, 1200, 85, 0x82, 0x63, 0x63, 0x86, 0x68, 0x14, 0xe0, 0x10, 0x40, 0xb1, // 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x0c, 0x4e, 0x01}, 0x24, 0xaf, 0xaf, 0xe1, 0x80, 0x55, 0x0f, 0x21, 0x09, 0x7e, 0x01}, {1792, 1344, 60, 0x8e, 0x6f, 0x6f, 0x92, 0x71, 0x1f, 0x74, 0x1f, 0x40, 0x43, // 0x29, 0x3f, 0x3f, 0x75, 0x80, 0x55, 0x0f, 0x21, 0x30, 0xbf, 0x01}, 0x29, 0x3f, 0x3f, 0x75, 0x80, 0x55, 0x0f, 0x21, 0x15, 0xbf, 0x01}, {1792, 1344, 75, 0x94, 0x6f, 0x6f, 0x98, 0x74, 0x01, 0x87, 0x1f, 0x40, 0x4a, // 0x4d, 0x3f, 0x3f, 0x88, 0x00, 0x55, 0x0f, 0x21, 0x0c, 0x59, 0x01}, 0x4d, 0x3f, 0x3f, 0x88, 0x00, 0x55, 0x0f, 0x21, 0x05, 0x6b, 0x01}, {1856, 1392, 60, 0x92, 0x73, 0x73, 0x96, 0x7c, 0x03, 0xa4, 0x1f, 0x40, 0x73, // 0x29, 0x6f, 0x6f, 0xa5, 0x00, 0x55, 0x0f, 0x21, 0x3c, 0xf7, 0x01}, 0x29, 0x6f, 0x6f, 0xa5, 0x00, 0x55, 0x0f, 0x21, 0x15, 0xcb, 0x01}, {1920, 1200, 76, 0x9d, 0x77, 0x77, 0x81, 0x7c, 0x8b, 0xe0, 0x10, 0x40, 0xb3, 0xb6, 0xaf, 0xaf, 0xe1, 0x00, 0x55, 0xcf, 0x21, 0x14, 0x76, 0x01,}, {1920, 1440, 60, 0x9d, 0x77, 0x77, 0x81, 0x7a, 0x87, 0xda, 0x1f, 0x40, 0xa1, // 0x24, 0x9f, 0x9f, 0xdb, 0x00, 0x55, 0x0f, 0x21, 0x30, 0xe3, 0x01}, 0x24, 0x9f, 0x9f, 0xdb, 0x00, 0x55, 0x0f, 0x21, 0x0d, 0xa1, 0x01}, {2048, 1536, 60, 0x98, 0x7f, 0x7f, 0x9c, 0x80, 0x0f, 0x3b, 0xba, 0x40, 0x01, 0x04, 0xff, 0xff, 0x3c, 0x00, 0x55, 0x0f, 0x21, 0x28, 0xc7, 0x01,}, {2048, 1536, 75, 0xa1, 0x7f, 0x7f, 0x85, 0x84, 0x90, 0x44, 0xba, 0x40, 0x01, 0x04, 0xff, 0xff, 0x45, 0x00, 0x55, 0x0f, 0x21, 0x1c, 0xc7, 0x01,}, // STB Begin Changes #endif // #ifdef H4 // STB End Changes glide3x/h5/cinit/plltable.h0100700000175300010010000001327207725034640015114 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** File name: plltable.h ** ** Description: The V3 PLL table. ** ** $Revision: 1.1.2.1 $ ** $Date: 2003/08/21 08:32:12 $ ** ** $History: plltable.h $ ** ** ***************** Version 1 ***************** ** User: Sapphire Date: 3/16/99 Time: 7:28p ** Created in $/Releases/Voodoo3/V3_OEM_100/3dfx/devel/H3/cinit ** ** ***************** Version 4 ***************** ** User: Michael Date: 1/12/99 Time: 9:23a ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 3 ***************** ** User: Artg Date: 8/27/98 Time: 11:08a ** Updated in $/devel/h3/Win95/dx/minivdd ** added guard ifdef for redundant plltable define. ** ** ***************** Version 2 ***************** ** User: Ken Date: 4/15/98 Time: 6:42p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** */ // // generated by gen_plltable.pl at Thu Apr 9 18:44:30 1998 // #define MIN_PLL_FREQ 30 #define MAX_PLL_FREQ 120 #if !defined(Host_H3) FxU32 _pllTable[] = { // pllCtrl n m k actual(MHz) // ------- --- --- --- ----------- 0x00006B2E, // 107 11 2 30.013108 0x00001806, // 24 1 2 31.022723 0x00007B32, // 123 12 2 31.960223 0x0000511E, // 81 7 2 33.011359 0x0000240A, // 36 2 2 34.005677 0x0000561E, // 86 7 2 34.999996 0x0000772A, // 119 10 2 36.093745 0x00001D06, // 29 1 2 36.988632 0x0000531A, // 83 6 2 38.032666 0x00006B22, // 107 8 2 39.017041 0x00007926, // 121 9 2 40.025821 0x00007C26, // 124 9 2 41.002061 0x00002D0A, // 45 2 2 42.059654 0x00002206, // 34 1 2 42.954540 0x00005416, // 84 5 2 43.977267 0x00005616, // 86 5 2 44.999994 0x00005816, // 88 5 2 46.022721 0x0000671A, // 103 6 2 46.981528 0x0000410E, // 65 3 2 47.965903 0x00002706, // 39 1 2 48.920448 0x00002806, // 40 1 2 50.113630 0x0000370A, // 55 2 2 51.008516 0x0000380A, // 56 2 2 51.903402 0x0000480E, // 72 3 2 52.977266 0x0000771A, // 119 6 2 54.140618 0x0000791A, // 121 6 2 55.035504 0x00007B1A, // 123 6 2 55.930391 0x00007D1A, // 125 6 2 56.825277 0x00004F0E, // 79 3 2 57.988629 0x0000400A, // 64 2 2 59.062492 0x00006B2D, // 107 11 1 60.026216 0x00007E35, // 126 13 1 61.090901 0x00001805, // 24 1 1 62.045447 0x00002A0D, // 42 3 1 62.999992 0x00007B31, // 123 12 1 63.920446 0x0000742D, // 116 11 1 64.982509 0x0000511D, // 81 7 1 66.022719 0x00006525, // 101 9 1 67.035115 0x00002409, // 36 2 1 68.011355 0x00006825, // 104 9 1 68.987595 0x0000561D, // 86 7 1 69.999991 0x00007529, // 117 10 1 70.994309 0x00007729, // 119 10 1 72.187491 0x0000310D, // 49 3 1 73.022718 0x00001D05, // 29 1 1 73.977263 0x00007125, // 113 9 1 74.845032 0x00005319, // 83 6 1 76.065331 0x00002909, // 41 2 1 76.960217 0x00006B21, // 107 8 1 78.034081 0x00001F05, // 31 1 1 78.749990 0x00007925, // 121 9 1 80.051643 0x00006F21, // 111 8 1 80.897717 0x00007C25, // 124 9 1 82.004122 0x0000380D, // 56 3 1 83.045444 0x00002D09, // 45 2 1 84.119308 0x00005D19, // 93 6 1 85.014194 0x00002205, // 34 1 1 85.909080 0x00005315, // 83 5 1 86.931807 0x00005415, // 84 5 1 87.954534 0x00005515, // 85 5 1 88.977261 0x00005615, // 86 5 1 89.999989 0x00005715, // 87 5 1 91.022716 0x00005815, // 88 5 1 92.045443 0x00002505, // 37 1 1 93.068170 0x00006719, // 103 6 1 93.963056 0x00005B15, // 91 5 1 95.113624 0x0000410D, // 65 3 1 95.931806 0x0000781D, // 120 7 1 97.045442 0x00002705, // 39 1 1 97.840897 0x00005111, // 81 4 1 99.034078 0x00002805, // 40 1 1 100.227260 0x00007D1D, // 125 7 1 101.022714 0x00003709, // 55 2 1 102.017033 0x00007119, // 113 6 1 102.911919 0x00003809, // 56 2 1 103.806805 0x00002A05, // 42 1 1 104.999987 0x0000480D, // 72 3 1 105.954532 0x00002B05, // 43 1 1 107.386350 0x00007719, // 119 6 1 108.281236 0x00003B09, // 59 2 1 109.176123 0x00007919, // 121 6 1 110.071009 0x00003C09, // 60 2 1 110.965895 0x00007B19, // 123 6 1 111.860781 0x00004D0D, // 77 3 1 113.113622 0x00007D19, // 125 6 1 113.650554 0x00002E05, // 46 1 1 114.545440 0x00004F0D, // 79 3 1 115.977258 0x00002F05, // 47 1 1 116.931803 0x00004009, // 64 2 1 118.124985 0x0000510D, // 81 3 1 118.840894 0x00006B2C, // 107 11 0 120.052432 }; FxU32 *pllTable = (FxU32*) (_pllTable - MIN_PLL_FREQ); #endif glide3x/h5/glide3/0040700000175300010010000000000007725034435013202 5ustar johndoeNoneglide3x/h5/glide3/makefile.autoconf.am0100700000175300010010000000212407725034660017112 0ustar johndoeNone## ## THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ## PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ## TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ## INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ## DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ## THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ## EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ## FULL TEXT OF THE NON-WARRANTY PROVISIONS. ## ## USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ## RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ## TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ## AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ## SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ## THE UNITED STATES. ## ## COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ## ## $Revision: 1.1 $ ## $Date: 2000/07/27 02:39:18 $ ## # # Note that we are not building tests. # SUBDIRS = src glide3x/h5/glide3/src/0040700000175300010010000000000007725034435013771 5ustar johndoeNoneglide3x/h5/glide3/src/banner.inc0100700000175300010010000010057607725034667015751 0ustar johndoeNonestatic unsigned long fxPlugWidth = 180; static unsigned long fxPlugHeight = 90; static unsigned long fxPlugStride = 360; static unsigned char tga_16rle[] = { 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x98, 0x00, 0x00, 0x06, 0x00, 0x00, 0x40, 0x10, 0xa0, 0x20, 0xe0, 0x30, 0x40, 0x41, 0x60, 0x51, 0xa0, 0x59, 0x81, 0xa0, 0x59, 0x05, 0x80, 0x59, 0x60, 0x49, 0x20, 0x41, 0xc0, 0x28, 0x60, 0x10, 0x20, 0x00, 0xff, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x0b, 0x20, 0x08, 0xa0, 0x20, 0x40, 0x49, 0xe0, 0x69, 0xa1, 0x92, 0x41, 0xb3, 0xc1, 0xd3, 0xe1, 0xdb, 0xe1, 0xdb, 0x01, 0xe4, 0x21, 0xe4, 0x21, 0xec, 0x81, 0x21, 0xec, 0x09, 0x21, 0xec, 0x01, 0xe4, 0x01, 0xe4, 0xe1, 0xdb, 0xc1, 0xd3, 0x41, 0xbb, 0x81, 0x8a, 0xc0, 0x61, 0xc0, 0x28, 0x00, 0x00, 0xff, 0x00, 0x00, 0x97, 0x00, 0x00, 0x1d, 0x00, 0x00, 0xa0, 0x20, 0x80, 0x51, 0x61, 0x8a, 0x61, 0xbb, 0xe1, 0xdb, 0x21, 0xec, 0x41, 0xf4, 0x41, 0xf4, 0x41, 0xec, 0x21, 0xec, 0x21, 0xec, 0x21, 0xec, 0x21, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x01, 0xe4, 0x21, 0xe4, 0x21, 0xec, 0x21, 0xec, 0xe1, 0xdb, 0x41, 0xb3, 0xe0, 0x69, 0xa0, 0x20, 0xff, 0x00, 0x00, 0x92, 0x00, 0x00, 0x13, 0x00, 0x00, 0xa0, 0x20, 0x00, 0x72, 0x41, 0xb3, 0x01, 0xe4, 0x61, 0xf4, 0x61, 0xfc, 0x21, 0xec, 0x01, 0xe4, 0xe1, 0xdb, 0xc1, 0xd3, 0x61, 0xc3, 0x41, 0xbb, 0x41, 0xbb, 0x41, 0xbb, 0x41, 0xbb, 0x81, 0xc3, 0xc1, 0xd3, 0xe1, 0xdb, 0x01, 0xe4, 0x81, 0x21, 0xec, 0x01, 0x01, 0xe4, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x06, 0x01, 0xe4, 0x01, 0xe4, 0x21, 0xec, 0x21, 0xec, 0xe1, 0xdb, 0x81, 0x8a, 0x80, 0x20, 0xff, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x0f, 0xa0, 0x20, 0x00, 0x72, 0x41, 0xbb, 0x21, 0xec, 0x41, 0xf4, 0x01, 0xe4, 0x41, 0xbb, 0x81, 0x8a, 0xe0, 0x69, 0x60, 0x49, 0xe0, 0x30, 0x80, 0x18, 0x40, 0x10, 0x20, 0x08, 0x20, 0x00, 0x00, 0x00, 0x81, 0x20, 0x00, 0x09, 0x20, 0x08, 0x40, 0x10, 0xc0, 0x28, 0x20, 0x41, 0xc0, 0x61, 0xa1, 0x92, 0xa1, 0xcb, 0x01, 0xe4, 0x21, 0xec, 0x01, 0xe4, 0x85, 0x01, 0xe4, 0x04, 0x01, 0xe4, 0x41, 0xec, 0xc1, 0xd3, 0xe0, 0x69, 0x20, 0x08, 0xff, 0x00, 0x00, 0x89, 0x00, 0x00, 0x09, 0x40, 0x10, 0x80, 0x59, 0x01, 0xab, 0x01, 0xe4, 0x21, 0xe4, 0x41, 0xbb, 0x20, 0x7a, 0x40, 0x49, 0x80, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x05, 0x40, 0x10, 0x20, 0x41, 0x61, 0x82, 0xc1, 0xd3, 0x21, 0xec, 0x01, 0xe4, 0x85, 0x01, 0xe4, 0x03, 0x01, 0xe4, 0x41, 0xec, 0x21, 0xb3, 0xc0, 0x28, 0xff, 0x00, 0x00, 0x86, 0x00, 0x00, 0x07, 0xc0, 0x28, 0x61, 0x8a, 0xa1, 0xcb, 0xe1, 0xdb, 0xe1, 0xa2, 0xa0, 0x59, 0xa0, 0x20, 0x00, 0x00, 0x97, 0x00, 0x00, 0x04, 0x80, 0x18, 0x00, 0x72, 0xa1, 0xd3, 0x21, 0xec, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x03, 0x01, 0xe4, 0x21, 0xec, 0xc1, 0xd3, 0x40, 0x49, 0xff, 0x00, 0x00, 0x83, 0x00, 0x00, 0x05, 0x40, 0x41, 0xe1, 0xa2, 0xc1, 0xd3, 0x01, 0xab, 0xa0, 0x59, 0x80, 0x18, 0x9d, 0x00, 0x00, 0x03, 0x80, 0x20, 0x81, 0x8a, 0x21, 0xec, 0x01, 0xe4, 0x85, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x01, 0xe4, 0x60, 0x51, 0xff, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40, 0x49, 0x01, 0xab, 0x81, 0xcb, 0x81, 0x8a, 0xe0, 0x30, 0xa2, 0x00, 0x00, 0x02, 0xa0, 0x59, 0xe1, 0xdb, 0x21, 0xec, 0x85, 0x01, 0xe4, 0x02, 0x21, 0xe4, 0xe1, 0xdb, 0x00, 0x39, 0xfc, 0x00, 0x00, 0x05, 0x00, 0x00, 0x60, 0x51, 0x01, 0xab, 0x21, 0xb3, 0xc0, 0x61, 0x40, 0x10, 0xa5, 0x00, 0x00, 0x02, 0x00, 0x39, 0xa1, 0xd3, 0x21, 0xec, 0x85, 0x01, 0xe4, 0x02, 0x21, 0xec, 0xa1, 0xcb, 0x80, 0x20, 0xf9, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40, 0x49, 0xe1, 0xa2, 0xe1, 0xa2, 0x40, 0x49, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x02, 0xe0, 0x30, 0xc1, 0xd3, 0x21, 0xec, 0x85, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x21, 0xb3, 0x20, 0x08, 0xf7, 0x00, 0x00, 0x03, 0x00, 0x39, 0xa1, 0x92, 0xa1, 0x9a, 0x00, 0x39, 0xac, 0x00, 0x00, 0x02, 0x00, 0x39, 0xe1, 0xdb, 0x01, 0xe4, 0x85, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x00, 0x72, 0xf5, 0x00, 0x00, 0x03, 0x80, 0x20, 0x61, 0x8a, 0xc1, 0x9a, 0x00, 0x39, 0xaf, 0x00, 0x00, 0x02, 0xa0, 0x61, 0x21, 0xec, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xc1, 0xd3, 0x80, 0x20, 0xf2, 0x00, 0x00, 0x04, 0x20, 0x08, 0xc0, 0x61, 0x81, 0x92, 0x40, 0x49, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x02, 0x00, 0x00, 0xe1, 0xa2, 0x21, 0xec, 0x85, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x40, 0x7a, 0xf1, 0x00, 0x00, 0x03, 0x20, 0x41, 0x61, 0x8a, 0xa0, 0x59, 0x20, 0x08, 0xb3, 0x00, 0x00, 0x02, 0xc0, 0x28, 0xe1, 0xdb, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xc1, 0xd3, 0x60, 0x18, 0xee, 0x00, 0x00, 0x03, 0x80, 0x20, 0x20, 0x7a, 0xe0, 0x69, 0x60, 0x18, 0xb6, 0x00, 0x00, 0x01, 0x81, 0x8a, 0x21, 0xec, 0x85, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xc0, 0x61, 0xec, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x51, 0x20, 0x7a, 0xe0, 0x30, 0xb8, 0x00, 0x00, 0x02, 0xc0, 0x28, 0xe1, 0xdb, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x21, 0xab, 0x00, 0x00, 0xea, 0x00, 0x00, 0x03, 0xa0, 0x20, 0xe0, 0x69, 0xa0, 0x59, 0x00, 0x00, 0xba, 0x00, 0x00, 0x01, 0xc1, 0x9a, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0xa0, 0x20, 0xe8, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40, 0x41, 0xe0, 0x69, 0xa0, 0x20, 0xbc, 0x00, 0x00, 0x02, 0x80, 0x51, 0x21, 0xec, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xec, 0x80, 0x51, 0xe7, 0x00, 0x00, 0x03, 0x60, 0x18, 0xa0, 0x61, 0x40, 0x49, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x02, 0x80, 0x18, 0xe1, 0xdb, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x41, 0x82, 0xe6, 0x00, 0x00, 0x02, 0x00, 0x39, 0xc0, 0x61, 0x80, 0x20, 0xbf, 0x00, 0x00, 0x02, 0x00, 0x00, 0x21, 0xb3, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x21, 0xb3, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x03, 0x20, 0x08, 0x60, 0x51, 0x60, 0x49, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x09, 0xa2, 0x10, 0x49, 0x4a, 0x4d, 0x6b, 0xef, 0x7b, 0x10, 0x84, 0x8e, 0x73, 0x0c, 0x63, 0x49, 0x4a, 0x45, 0x29, 0x20, 0x00, 0x8f, 0x00, 0x00, 0x01, 0x41, 0x82, 0x41, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xa1, 0xd3, 0x40, 0x10, 0xe2, 0x00, 0x00, 0x02, 0x60, 0x18, 0x80, 0x59, 0xc0, 0x28, 0x94, 0x00, 0x00, 0x00, 0x8a, 0x52, 0x87, 0x59, 0xce, 0x00, 0x8a, 0x52, 0x88, 0x00, 0x00, 0x02, 0x28, 0x42, 0x55, 0xad, 0x5d, 0xef, 0x86, 0xff, 0xff, 0x01, 0xdf, 0xff, 0x28, 0x42, 0x8f, 0x00, 0x00, 0x02, 0xa0, 0x59, 0x21, 0xec, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0xc0, 0x28, 0xe1, 0x00, 0x00, 0x02, 0xe0, 0x30, 0x60, 0x51, 0x60, 0x10, 0x95, 0x00, 0x00, 0x00, 0x6d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x6d, 0x6b, 0x87, 0x00, 0x00, 0x01, 0x30, 0x84, 0xff, 0xff, 0x89, 0xff, 0xff, 0x00, 0x49, 0x4a, 0x8f, 0x00, 0x00, 0x00, 0x20, 0x41, 0x81, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x01, 0xe4, 0x20, 0x41, 0xdf, 0x00, 0x00, 0x03, 0x00, 0x00, 0x20, 0x41, 0x20, 0x41, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x86, 0x00, 0x00, 0x00, 0xcf, 0x7b, 0x8b, 0xff, 0xff, 0x00, 0x49, 0x4a, 0x8f, 0x00, 0x00, 0x02, 0xc0, 0x28, 0xe1, 0xdb, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xe4, 0x80, 0x51, 0xde, 0x00, 0x00, 0x02, 0x40, 0x10, 0x40, 0x49, 0xa0, 0x28, 0x98, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x85, 0x00, 0x00, 0x01, 0x45, 0x29, 0xbe, 0xf7, 0x8b, 0xff, 0xff, 0x00, 0x49, 0x4a, 0x8f, 0x00, 0x00, 0x02, 0x80, 0x20, 0xe1, 0xdb, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xec, 0xa0, 0x59, 0xdd, 0x00, 0x00, 0x02, 0x60, 0x18, 0x40, 0x49, 0x60, 0x18, 0x99, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x85, 0x00, 0x00, 0x00, 0x51, 0x8c, 0x8c, 0xff, 0xff, 0x00, 0x49, 0x4a, 0x8f, 0x00, 0x00, 0x02, 0x60, 0x10, 0xc1, 0xd3, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xc0, 0x61, 0xdc, 0x00, 0x00, 0x02, 0xa0, 0x20, 0x20, 0x41, 0x20, 0x08, 0x9a, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0x00, 0x00, 0x38, 0xc6, 0x8c, 0xff, 0xff, 0x00, 0x49, 0x4a, 0x8f, 0x00, 0x00, 0x02, 0x40, 0x10, 0xc1, 0xd3, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xc0, 0x61, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x30, 0x00, 0x39, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0x61, 0x08, 0x5d, 0xef, 0x89, 0xff, 0xff, 0x03, 0x7d, 0xef, 0x9a, 0xd6, 0x59, 0xce, 0xc7, 0x39, 0x8f, 0x00, 0x00, 0x02, 0x40, 0x10, 0xc1, 0xd3, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xec, 0xa0, 0x59, 0xd9, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x39, 0xc0, 0x28, 0x9d, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xc3, 0x18, 0xbe, 0xf7, 0x87, 0xff, 0xff, 0x05, 0x3c, 0xe7, 0x2c, 0x63, 0xa2, 0x10, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x02, 0x60, 0x10, 0xc1, 0xd3, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xec, 0x80, 0x51, 0xd8, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x39, 0xa0, 0x20, 0x9e, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0x04, 0x21, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x01, 0xff, 0xff, 0x28, 0x42, 0x94, 0x00, 0x00, 0x02, 0x80, 0x20, 0xe1, 0xdb, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x01, 0xe4, 0x40, 0x41, 0xd7, 0x00, 0x00, 0x02, 0x20, 0x08, 0x00, 0x39, 0x80, 0x18, 0x9f, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x01, 0x79, 0xce, 0x00, 0x00, 0x94, 0x00, 0x00, 0x02, 0xc0, 0x28, 0xe1, 0xdb, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0xe0, 0x30, 0xd6, 0x00, 0x00, 0x02, 0x40, 0x08, 0x20, 0x39, 0x60, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xb6, 0xb5, 0x95, 0x00, 0x00, 0x02, 0x00, 0x39, 0x01, 0xe4, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xc1, 0xdb, 0x80, 0x18, 0xd5, 0x00, 0x00, 0x02, 0x20, 0x08, 0x00, 0x39, 0x40, 0x08, 0xa1, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x95, 0x00, 0x00, 0x02, 0x60, 0x51, 0x21, 0xe4, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x81, 0xc3, 0x20, 0x08, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x95, 0x00, 0x00, 0x01, 0xe0, 0x69, 0x41, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0xe1, 0xa2, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x95, 0x00, 0x00, 0x01, 0x81, 0x8a, 0x41, 0xec, 0x84, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x41, 0x82, 0xfb, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xb6, 0xb5, 0x94, 0x00, 0x00, 0x02, 0x00, 0x00, 0x21, 0xb3, 0x21, 0xec, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xec, 0xa0, 0x61, 0xdb, 0x00, 0x00, 0x07, 0x20, 0x00, 0x86, 0x31, 0xcb, 0x5a, 0x4d, 0x6b, 0x4d, 0x6b, 0xaa, 0x52, 0x86, 0x31, 0x61, 0x08, 0x8f, 0x00, 0x00, 0x05, 0x04, 0x21, 0x69, 0x4a, 0x2c, 0x63, 0x0c, 0x63, 0xe7, 0x39, 0x61, 0x08, 0x81, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x81, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x04, 0x21, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x84, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x85, 0x00, 0x00, 0x02, 0x60, 0x10, 0xc1, 0xd3, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x01, 0xe4, 0x00, 0x39, 0xd9, 0x00, 0x00, 0x03, 0x20, 0x00, 0x0c, 0x63, 0x59, 0xce, 0xdf, 0xff, 0x83, 0xff, 0xff, 0x03, 0xdf, 0xff, 0xfb, 0xde, 0x30, 0x84, 0x24, 0x21, 0x8b, 0x00, 0x00, 0x02, 0x24, 0x21, 0x14, 0xa5, 0x9e, 0xf7, 0x82, 0xff, 0xff, 0x04, 0xff, 0xff, 0xdb, 0xde, 0x6d, 0x6b, 0x00, 0x00, 0x2c, 0x63, 0x87, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0x0c, 0x63, 0x81, 0xf7, 0xbd, 0x02, 0xf7, 0xbd, 0x38, 0xc6, 0xff, 0xff, 0x86, 0xff, 0xff, 0x00, 0x7d, 0xef, 0x81, 0xf7, 0xbd, 0x81, 0xf7, 0xbd, 0x03, 0x14, 0xa5, 0x00, 0x00, 0xe7, 0x39, 0x18, 0xc6, 0x86, 0xf7, 0xbd, 0x00, 0xcf, 0x7b, 0x84, 0x00, 0x00, 0x02, 0x00, 0x39, 0x01, 0xe4, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xc1, 0xd3, 0x60, 0x10, 0xd8, 0x00, 0x00, 0x01, 0xc3, 0x18, 0xb6, 0xb5, 0x89, 0xff, 0xff, 0x01, 0x5d, 0xef, 0xeb, 0x5a, 0x89, 0x00, 0x00, 0x01, 0x86, 0x31, 0x1c, 0xe7, 0x87, 0xff, 0xff, 0x01, 0xb2, 0x94, 0x6d, 0x6b, 0x87, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0x30, 0x84, 0x90, 0xff, 0xff, 0x03, 0x1c, 0xe7, 0x20, 0x00, 0xa2, 0x10, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x01, 0x5d, 0xef, 0x61, 0x08, 0x83, 0x00, 0x00, 0x02, 0xc0, 0x61, 0x21, 0xec, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x21, 0xab, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x01, 0xe3, 0x18, 0x9a, 0xd6, 0x8c, 0xff, 0xff, 0x00, 0xcf, 0x7b, 0x87, 0x00, 0x00, 0x01, 0xc3, 0x18, 0xfb, 0xde, 0x89, 0xff, 0xff, 0x00, 0x3c, 0xe7, 0x87, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0x10, 0x84, 0x90, 0xff, 0xff, 0x03, 0xdb, 0xde, 0x41, 0x08, 0x00, 0x00, 0xd3, 0x9c, 0x87, 0xff, 0xff, 0x00, 0xeb, 0x5a, 0x83, 0x00, 0x00, 0x01, 0xa1, 0x92, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x21, 0x7a, 0xd7, 0x00, 0x00, 0x01, 0x20, 0x00, 0xf7, 0xbd, 0x8e, 0xff, 0xff, 0x00, 0xcb, 0x5a, 0x85, 0x00, 0x00, 0x01, 0x00, 0x00, 0x75, 0xad, 0x93, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0x10, 0x84, 0x90, 0xff, 0xff, 0x03, 0xdb, 0xde, 0x41, 0x08, 0x00, 0x00, 0x08, 0x42, 0x87, 0xff, 0xff, 0x00, 0xb6, 0xb5, 0x82, 0x00, 0x00, 0x02, 0x40, 0x10, 0xa1, 0xcb, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x01, 0xe4, 0x40, 0x49, 0xd7, 0x00, 0x00, 0x00, 0x8e, 0x73, 0x8f, 0xff, 0xff, 0x01, 0x3c, 0xe7, 0xa2, 0x10, 0x84, 0x00, 0x00, 0x00, 0x28, 0x42, 0x94, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0x10, 0x84, 0x90, 0xff, 0xff, 0x04, 0xdb, 0xde, 0x41, 0x08, 0x00, 0x00, 0x20, 0x00, 0x9a, 0xd6, 0x86, 0xff, 0xff, 0x01, 0xbe, 0xf7, 0x24, 0x21, 0x81, 0x00, 0x00, 0x02, 0x40, 0x49, 0x21, 0xe4, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xc1, 0xd3, 0x60, 0x18, 0xd6, 0x00, 0x00, 0x01, 0x61, 0x08, 0xfb, 0xde, 0x86, 0xff, 0xff, 0x01, 0xba, 0xd6, 0x7d, 0xef, 0x87, 0xff, 0xff, 0x00, 0x6d, 0x6b, 0x84, 0x00, 0x00, 0x00, 0x75, 0xad, 0x87, 0xff, 0xff, 0x03, 0x3c, 0xe7, 0x92, 0x94, 0x51, 0x8c, 0x59, 0xce, 0x88, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0x10, 0x84, 0x90, 0xff, 0xff, 0x01, 0xfb, 0xde, 0x41, 0x08, 0x81, 0x00, 0x00, 0x00, 0x8e, 0x73, 0x87, 0xff, 0xff, 0x00, 0x10, 0x84, 0x81, 0x00, 0x00, 0x01, 0x61, 0x82, 0x41, 0xec, 0x84, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xc1, 0xa2, 0xd7, 0x00, 0x00, 0x00, 0xaa, 0x52, 0x85, 0xff, 0xff, 0x04, 0x7d, 0xef, 0xaa, 0x52, 0x41, 0x08, 0x45, 0x29, 0xdb, 0xde, 0x86, 0xff, 0xff, 0x01, 0xf7, 0xbd, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0xe3, 0x18, 0x9e, 0xf7, 0x86, 0xff, 0xff, 0x01, 0x7d, 0xef, 0x86, 0x31, 0x81, 0x00, 0x00, 0x01, 0x41, 0x08, 0x55, 0xad, 0x87, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0xef, 0x7b, 0x82, 0xdf, 0xff, 0x00, 0xdf, 0xff, 0x87, 0xff, 0xff, 0x00, 0xff, 0xff, 0x83, 0xdf, 0xff, 0x01, 0xba, 0xd6, 0x41, 0x08, 0x81, 0x00, 0x00, 0x01, 0xe3, 0x18, 0x7d, 0xef, 0x86, 0xff, 0xff, 0x04, 0xfb, 0xde, 0x41, 0x08, 0x00, 0x00, 0x41, 0xbb, 0x21, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xc0, 0x61, 0xd7, 0x00, 0x00, 0x00, 0xb2, 0x94, 0x85, 0xff, 0xff, 0x00, 0x6d, 0x6b, 0x82, 0x00, 0x00, 0x00, 0x2c, 0x63, 0x86, 0xff, 0xff, 0x01, 0x9e, 0xf7, 0xa2, 0x10, 0x82, 0x00, 0x00, 0x00, 0xcb, 0x5a, 0x87, 0xff, 0xff, 0x00, 0xf3, 0x9c, 0x83, 0x00, 0x00, 0x00, 0x2c, 0x63, 0x87, 0xff, 0xff, 0x02, 0x4d, 0x6b, 0x00, 0x00, 0xa2, 0x10, 0x81, 0x65, 0x29, 0x02, 0x65, 0x29, 0x28, 0x42, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0x38, 0xc6, 0x83, 0x65, 0x29, 0x01, 0x24, 0x21, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x55, 0xad, 0x87, 0xff, 0xff, 0x01, 0x29, 0x42, 0x80, 0x28, 0x81, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0xa0, 0x28, 0xd7, 0x00, 0x00, 0x00, 0x18, 0xc6, 0x84, 0xff, 0xff, 0x01, 0x3c, 0xe7, 0x41, 0x08, 0x82, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x85, 0xff, 0xff, 0x01, 0xdf, 0xff, 0x86, 0x31, 0x82, 0x00, 0x00, 0x00, 0x92, 0x94, 0x87, 0xff, 0xff, 0x00, 0x0c, 0x63, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xc3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xb6, 0xb5, 0x88, 0x00, 0x00, 0x00, 0x8a, 0x52, 0x87, 0xff, 0xff, 0x02, 0x15, 0x9d, 0x20, 0x7a, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x01, 0xab, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0c, 0x63, 0x92, 0x94, 0x34, 0xa5, 0xf7, 0xbd, 0x9a, 0xd6, 0x7d, 0xef, 0x96, 0xb5, 0x83, 0x00, 0x00, 0x01, 0x41, 0x08, 0xfb, 0xde, 0x85, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe7, 0x39, 0x81, 0x00, 0x00, 0x01, 0x20, 0x00, 0x59, 0xce, 0x86, 0xff, 0xff, 0x01, 0xff, 0xff, 0xc7, 0x39, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x88, 0x00, 0x00, 0x01, 0x41, 0x08, 0xdb, 0xde, 0x86, 0xff, 0xff, 0x02, 0x9d, 0xf7, 0xe3, 0xd3, 0xe1, 0xe3, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x21, 0xec, 0xa0, 0x61, 0xdb, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0x82, 0x10, 0xa2, 0x10, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x20, 0x00, 0x9a, 0xd6, 0x85, 0xff, 0xff, 0x01, 0xff, 0xff, 0xc7, 0x39, 0x81, 0x00, 0x00, 0x01, 0xa2, 0x10, 0x9e, 0xf7, 0x86, 0xff, 0xff, 0x01, 0xbe, 0xf7, 0xe3, 0x18, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x89, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x86, 0xff, 0xff, 0x02, 0xb5, 0xf6, 0xe1, 0xe3, 0xe1, 0xe3, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0x80, 0x20, 0xe3, 0x00, 0x00, 0x01, 0x20, 0x00, 0x79, 0xce, 0x85, 0xff, 0xff, 0x01, 0xdf, 0xff, 0x65, 0x29, 0x81, 0x00, 0x00, 0x01, 0x86, 0x31, 0xdf, 0xff, 0x86, 0xff, 0xff, 0x01, 0x7d, 0xef, 0x61, 0x08, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x89, 0x00, 0x00, 0x01, 0xa6, 0x31, 0xdf, 0xff, 0x85, 0xff, 0xff, 0x01, 0x4b, 0xed, 0xc0, 0xdb, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0xc1, 0x9a, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x01, 0x20, 0x00, 0xfb, 0xde, 0x85, 0xff, 0xff, 0x01, 0x9e, 0xf7, 0xc3, 0x18, 0x81, 0x00, 0x00, 0x00, 0x69, 0x4a, 0x87, 0xff, 0xff, 0x01, 0x1c, 0xe7, 0x41, 0x08, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x89, 0x00, 0x00, 0x01, 0x00, 0x00, 0x18, 0xc6, 0x84, 0xff, 0xff, 0x02, 0x7b, 0xff, 0x23, 0xe4, 0xe1, 0xe3, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x01, 0xe4, 0x20, 0x41, 0xe4, 0x00, 0x00, 0x01, 0x86, 0x31, 0xdf, 0xff, 0x85, 0xff, 0xff, 0x01, 0x79, 0xce, 0x20, 0x00, 0x81, 0x00, 0x00, 0x00, 0x0c, 0x63, 0x87, 0xff, 0xff, 0x01, 0xdb, 0xde, 0x41, 0x08, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8a, 0x00, 0x00, 0x00, 0x6d, 0x6b, 0x84, 0xff, 0xff, 0x01, 0xcf, 0xed, 0xc0, 0xdb, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x41, 0xbb, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x01, 0x00, 0x00, 0x96, 0xb5, 0x86, 0xff, 0xff, 0x00, 0x30, 0x84, 0x82, 0x00, 0x00, 0x00, 0x8e, 0x73, 0x87, 0xff, 0xff, 0x01, 0x9a, 0xd6, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8a, 0x00, 0x00, 0x01, 0xc3, 0x18, 0x7d, 0xef, 0x82, 0xff, 0xff, 0x02, 0x9d, 0xff, 0x44, 0xe4, 0xe0, 0xdb, 0x84, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xe0, 0x69, 0xdf, 0x00, 0x00, 0x05, 0x00, 0x00, 0x41, 0x08, 0x61, 0x08, 0xc3, 0x18, 0x49, 0x4a, 0x96, 0xb5, 0x86, 0xff, 0xff, 0x01, 0xdf, 0xff, 0x65, 0x29, 0x82, 0x00, 0x00, 0x00, 0xef, 0x7b, 0x87, 0xff, 0xff, 0x01, 0x79, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8b, 0x00, 0x00, 0x00, 0x55, 0xad, 0x82, 0xff, 0xff, 0x01, 0x53, 0xf6, 0xc0, 0xdb, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xc1, 0xd3, 0x60, 0x18, 0xdf, 0x00, 0x00, 0x03, 0x04, 0x21, 0x9a, 0xd6, 0x1c, 0xe7, 0x9e, 0xf7, 0x88, 0xff, 0xff, 0x00, 0xcf, 0x7b, 0x83, 0x00, 0x00, 0x00, 0x30, 0x84, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8b, 0x00, 0x00, 0x00, 0x8a, 0x52, 0x81, 0xff, 0xff, 0x02, 0xde, 0xff, 0xa6, 0xe4, 0xe0, 0xdb, 0x84, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x81, 0x8a, 0xe0, 0x00, 0x00, 0x01, 0x24, 0x21, 0xff, 0xff, 0x87, 0xff, 0xff, 0x03, 0xff, 0xff, 0x3c, 0xe7, 0xae, 0x73, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x92, 0x94, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8b, 0x00, 0x00, 0x05, 0x20, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0x95, 0xf6, 0xc0, 0xdb, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0xc0, 0x28, 0xe0, 0x00, 0x00, 0x01, 0x24, 0x21, 0xbe, 0xf7, 0x87, 0xff, 0xff, 0x01, 0x9e, 0xf7, 0x8e, 0x73, 0x85, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8c, 0x00, 0x00, 0x03, 0xcf, 0x73, 0xff, 0xff, 0xc7, 0xe4, 0xc0, 0xdb, 0x84, 0x01, 0xe4, 0x01, 0x21, 0xec, 0xa1, 0x9a, 0xe1, 0x00, 0x00, 0x01, 0x24, 0x21, 0xbe, 0xf7, 0x87, 0xff, 0xff, 0x03, 0xff, 0xff, 0xdf, 0xff, 0x38, 0xc6, 0x86, 0x31, 0x83, 0x00, 0x00, 0x00, 0xf3, 0x9c, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8c, 0x00, 0x00, 0x03, 0x66, 0x29, 0x54, 0xee, 0xe0, 0xe3, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xe3, 0xe0, 0x38, 0xe1, 0x00, 0x00, 0x01, 0x24, 0x21, 0xbe, 0xf7, 0x8a, 0xff, 0xff, 0x01, 0x5d, 0xef, 0x86, 0x31, 0x82, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8c, 0x00, 0x00, 0x02, 0x20, 0x00, 0xc3, 0xc3, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x02, 0xe0, 0xe3, 0x09, 0xed, 0x28, 0x42, 0xe1, 0x00, 0x00, 0x01, 0x24, 0x21, 0xff, 0xff, 0x8b, 0xff, 0xff, 0x01, 0x79, 0xce, 0x41, 0x08, 0x81, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8c, 0x00, 0x00, 0x02, 0x40, 0x49, 0x01, 0xe4, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x03, 0xe1, 0xe3, 0xe1, 0xe3, 0x58, 0xff, 0x55, 0xa5, 0xe1, 0x00, 0x00, 0x05, 0x61, 0x08, 0xeb, 0x5a, 0x2c, 0x63, 0x8e, 0x73, 0xf3, 0x9c, 0x7d, 0xef, 0x88, 0xff, 0xff, 0x00, 0xaa, 0x52, 0x81, 0x00, 0x00, 0x00, 0x51, 0x8c, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8b, 0x00, 0x00, 0x02, 0x20, 0x08, 0x41, 0xbb, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x04, 0xc0, 0xdb, 0x09, 0xed, 0xff, 0xff, 0x7d, 0xef, 0xa2, 0x10, 0xe5, 0x00, 0x00, 0x01, 0x45, 0x29, 0x79, 0xce, 0x87, 0xff, 0xff, 0x00, 0x34, 0xa5, 0x81, 0x00, 0x00, 0x00, 0x10, 0x84, 0x87, 0xff, 0xff, 0x01, 0x79, 0xce, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8b, 0x00, 0x00, 0x01, 0xe0, 0x69, 0x41, 0xec, 0x84, 0x01, 0xe4, 0x02, 0xe1, 0xe3, 0xe1, 0xdb, 0xf8, 0xf6, 0x81, 0xff, 0xff, 0x00, 0x6d, 0x6b, 0xe6, 0x00, 0x00, 0x01, 0x08, 0x42, 0xff, 0xff, 0x86, 0xff, 0xff, 0x03, 0xfb, 0xde, 0x41, 0x08, 0x00, 0x00, 0xae, 0x73, 0x87, 0xff, 0xff, 0x01, 0x9a, 0xd6, 0x20, 0x00, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8a, 0x00, 0x00, 0x02, 0x60, 0x18, 0xa1, 0xcb, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0xc0, 0xdb, 0x6c, 0xed, 0x82, 0xff, 0xff, 0x00, 0xf7, 0xbd, 0xe6, 0x00, 0x00, 0x01, 0x20, 0x00, 0xba, 0xd6, 0x86, 0xff, 0xff, 0x03, 0xbe, 0xf7, 0x04, 0x21, 0x00, 0x00, 0x2c, 0x63, 0x87, 0xff, 0xff, 0x01, 0xdb, 0xde, 0x41, 0x08, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x8a, 0x00, 0x00, 0x01, 0x61, 0x82, 0x41, 0xec, 0x84, 0x01, 0xe4, 0x02, 0xe1, 0xdb, 0x02, 0xe4, 0x5a, 0xff, 0x82, 0xff, 0xff, 0x01, 0xdf, 0xff, 0x65, 0x29, 0xe6, 0x00, 0x00, 0x00, 0xd7, 0xbd, 0x86, 0xff, 0xff, 0x03, 0xdf, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x8a, 0x52, 0x87, 0xff, 0xff, 0x01, 0xfb, 0xde, 0x41, 0x08, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x89, 0x00, 0x00, 0x02, 0xe0, 0x30, 0x01, 0xdc, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0xc0, 0xdb, 0xcf, 0xed, 0x84, 0xff, 0xff, 0x00, 0x51, 0x8c, 0xde, 0x00, 0x00, 0x02, 0x00, 0x00, 0x41, 0x08, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x96, 0xb5, 0x86, 0xff, 0xff, 0x04, 0xff, 0xff, 0xe7, 0x39, 0x00, 0x00, 0xe7, 0x39, 0xff, 0xff, 0x86, 0xff, 0xff, 0x01, 0x7d, 0xef, 0x61, 0x08, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x88, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xab, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x02, 0xe0, 0xdb, 0x64, 0xe4, 0xbd, 0xff, 0x84, 0xff, 0xff, 0x01, 0xdb, 0xde, 0x41, 0x08, 0xd8, 0x00, 0x00, 0x07, 0x45, 0x29, 0xef, 0x7b, 0x71, 0x8c, 0xf3, 0x9c, 0x96, 0xb5, 0x18, 0xc6, 0xba, 0xd6, 0x30, 0x84, 0x84, 0x00, 0x00, 0x00, 0xb6, 0xb5, 0x86, 0xff, 0xff, 0x04, 0xff, 0xff, 0xc7, 0x39, 0x00, 0x00, 0x04, 0x21, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x01, 0xbe, 0xf7, 0xe3, 0x18, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x88, 0x00, 0x00, 0x02, 0xa0, 0x59, 0x21, 0xec, 0x01, 0xe4, 0x83, 0x01, 0xe4, 0x02, 0xe1, 0xe3, 0xe0, 0xe3, 0x73, 0xf6, 0x86, 0xff, 0xff, 0x00, 0x69, 0x4a, 0xd8, 0x00, 0x00, 0x00, 0x0c, 0x63, 0x85, 0xff, 0xff, 0x00, 0x34, 0xa5, 0x83, 0x00, 0x00, 0x01, 0x00, 0x00, 0x38, 0xc6, 0x86, 0xff, 0xff, 0x04, 0xbe, 0xf7, 0x04, 0x21, 0x00, 0x00, 0x41, 0x08, 0x1c, 0xe7, 0x86, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe7, 0x39, 0x83, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x87, 0x00, 0x00, 0x02, 0x60, 0x18, 0xa1, 0xcb, 0x21, 0xe4, 0x84, 0x01, 0xe4, 0x02, 0xe0, 0xe3, 0x46, 0xd4, 0xdf, 0xff, 0x86, 0xff, 0xff, 0x00, 0x96, 0xb5, 0xd8, 0x00, 0x00, 0x01, 0xc7, 0x39, 0xff, 0xff, 0x84, 0xff, 0xff, 0x00, 0x38, 0xc6, 0x83, 0x00, 0x00, 0x01, 0x61, 0x08, 0x5d, 0xef, 0x86, 0xff, 0xff, 0x01, 0xba, 0xd6, 0x20, 0x00, 0x81, 0x00, 0x00, 0x00, 0x75, 0xad, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x83, 0x00, 0x00, 0x00, 0x2c, 0x63, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x86, 0x00, 0x00, 0x02, 0x00, 0x00, 0xc1, 0x9a, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x03, 0x01, 0xe4, 0xa1, 0xd3, 0x22, 0x31, 0xbb, 0xd6, 0x86, 0xff, 0xff, 0x01, 0xdf, 0xff, 0x45, 0x29, 0xd7, 0x00, 0x00, 0x01, 0x82, 0x10, 0x5d, 0xef, 0x84, 0xff, 0xff, 0x01, 0xbe, 0xf7, 0x86, 0x31, 0x82, 0x00, 0x00, 0x00, 0xaa, 0x52, 0x87, 0xff, 0xff, 0x00, 0x92, 0x94, 0x82, 0x00, 0x00, 0x00, 0xae, 0x73, 0x87, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x83, 0x00, 0x00, 0x00, 0xef, 0x7b, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x86, 0x00, 0x00, 0x02, 0x80, 0x51, 0x21, 0xec, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x03, 0x21, 0xec, 0x00, 0x72, 0x00, 0x00, 0x51, 0x8c, 0x87, 0xff, 0xff, 0x00, 0xcf, 0x7b, 0xd8, 0x00, 0x00, 0x00, 0x96, 0xb5, 0x85, 0xff, 0xff, 0x04, 0x79, 0xce, 0xe7, 0x39, 0x61, 0x08, 0xc7, 0x39, 0xdb, 0xde, 0x87, 0xff, 0xff, 0x00, 0x08, 0x42, 0x82, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x87, 0xff, 0xff, 0x05, 0xff, 0xff, 0xb2, 0x94, 0x28, 0x42, 0x49, 0x4a, 0x71, 0x8c, 0x9e, 0xf7, 0x87, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x85, 0x00, 0x00, 0x02, 0x80, 0x20, 0xc1, 0xd3, 0x21, 0xe4, 0x84, 0x01, 0xe4, 0x05, 0x21, 0xec, 0x41, 0xb3, 0x20, 0x08, 0x00, 0x00, 0x65, 0x29, 0xdf, 0xff, 0x86, 0xff, 0xff, 0x01, 0xba, 0xd6, 0x20, 0x00, 0xd7, 0x00, 0x00, 0x00, 0xcb, 0x5a, 0x86, 0xff, 0xff, 0x02, 0xff, 0xff, 0x7d, 0xef, 0xdf, 0xff, 0x87, 0xff, 0xff, 0x01, 0x59, 0xce, 0x20, 0x00, 0x82, 0x00, 0x00, 0x01, 0x41, 0x08, 0xdb, 0xde, 0x94, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00, 0xc1, 0x9a, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0x01, 0xe4, 0x20, 0x39, 0x82, 0x00, 0x00, 0x00, 0x18, 0xc6, 0x87, 0xff, 0xff, 0x00, 0x08, 0x42, 0xd7, 0x00, 0x00, 0x01, 0x20, 0x00, 0x59, 0xce, 0x90, 0xff, 0xff, 0x00, 0x28, 0x42, 0x84, 0x00, 0x00, 0x00, 0xcf, 0x7b, 0x94, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x84, 0x00, 0x00, 0x02, 0xa0, 0x59, 0x21, 0xec, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x01, 0x41, 0xec, 0x40, 0x82, 0x83, 0x00, 0x00, 0x00, 0x6d, 0x6b, 0x87, 0xff, 0xff, 0x00, 0xb2, 0x94, 0x81, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x01, 0xe7, 0x39, 0xbe, 0xf7, 0x8e, 0xff, 0xff, 0x00, 0x71, 0x8c, 0x85, 0x00, 0x00, 0x01, 0xc3, 0x18, 0x3c, 0xe7, 0x8a, 0xff, 0xff, 0x01, 0xba, 0xd6, 0x9e, 0xf7, 0x86, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x83, 0x00, 0x00, 0x02, 0xc0, 0x28, 0xe1, 0xdb, 0x01, 0xe4, 0x84, 0x01, 0xe4, 0x02, 0x21, 0xec, 0x61, 0xbb, 0x40, 0x08, 0x83, 0x00, 0x00, 0x01, 0xa2, 0x10, 0x7d, 0xef, 0x86, 0xff, 0xff, 0x08, 0x7d, 0xef, 0xa2, 0x10, 0x00, 0x00, 0xc7, 0x39, 0x92, 0x94, 0x4d, 0x6b, 0x10, 0x84, 0xae, 0x73, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x01, 0x0c, 0x63, 0xdf, 0xff, 0x8c, 0xff, 0xff, 0x01, 0xf3, 0x9c, 0x20, 0x00, 0x86, 0x00, 0x00, 0x01, 0x8a, 0x52, 0xdf, 0xff, 0x88, 0xff, 0xff, 0x02, 0x9a, 0xd6, 0x65, 0x29, 0x5d, 0xef, 0x86, 0xff, 0xff, 0x00, 0x4d, 0x6b, 0x84, 0x00, 0x00, 0x01, 0xe3, 0x18, 0xbe, 0xf7, 0x86, 0xff, 0xff, 0x00, 0xd7, 0xbd, 0x82, 0x00, 0x00, 0x02, 0x40, 0x10, 0x21, 0xb3, 0x21, 0xec, 0x84, 0x01, 0xe4, 0x02, 0x01, 0xe4, 0xe1, 0xdb, 0x00, 0x39, 0x85, 0x00, 0x00, 0x00, 0x34, 0xa5, 0x87, 0xff, 0xff, 0x07, 0x0c, 0x63, 0x00, 0x00, 0xe3, 0x18, 0x71, 0x8c, 0x8e, 0x73, 0x7d, 0xef, 0x55, 0xad, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x01, 0xcb, 0x5a, 0x5d, 0xef, 0x89, 0xff, 0xff, 0x01, 0xdf, 0xff, 0xef, 0x7b, 0x89, 0x00, 0x00, 0x01, 0x6d, 0x6b, 0xff, 0xff, 0x86, 0xff, 0xff, 0x02, 0x79, 0xce, 0x04, 0x21, 0x20, 0x00, 0x87, 0xff, 0xff, 0x00, 0x8e, 0x73, 0x84, 0x00, 0x00, 0x00, 0x04, 0x21, 0x87, 0xff, 0xff, 0x00, 0x38, 0xc6, 0x81, 0x00, 0x00, 0x02, 0x20, 0x00, 0xc1, 0x9a, 0x81, 0xfc, 0x84, 0x41, 0xec, 0x02, 0x41, 0xf4, 0x61, 0xf4, 0xe0, 0x69, 0x86, 0x00, 0x00, 0x00, 0x69, 0x4a, 0x87, 0xff, 0xff, 0x07, 0x59, 0xce, 0x00, 0x00, 0xa2, 0x10, 0x51, 0x8c, 0xeb, 0x5a, 0x79, 0xce, 0x34, 0xa5, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x02, 0x24, 0x21, 0x92, 0x94, 0x5d, 0xef, 0x85, 0xff, 0xff, 0x02, 0x7d, 0xef, 0x14, 0xa5, 0xc7, 0x39, 0x8b, 0x00, 0x00, 0x0c, 0x49, 0x4a, 0xd7, 0xbd, 0xbe, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xdb, 0xde, 0xef, 0x7b, 0x82, 0x10, 0x00, 0x00, 0x41, 0x08, 0x30, 0x84, 0x92, 0x94, 0x84, 0x71, 0x8c, 0x01, 0x92, 0x94, 0xe7, 0x39, 0x84, 0x00, 0x00, 0x01, 0x82, 0x10, 0x51, 0x8c, 0x85, 0x71, 0x8c, 0x01, 0x92, 0x94, 0x2c, 0x63, 0x81, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x7a, 0x40, 0x82, 0x84, 0x40, 0x7a, 0x02, 0x40, 0x82, 0x00, 0x72, 0x20, 0x08, 0x86, 0x00, 0x00, 0x03, 0x20, 0x00, 0x10, 0x84, 0x71, 0x8c, 0xb2, 0x94, 0x84, 0xf3, 0x9c, 0x07, 0xb2, 0x94, 0x82, 0x10, 0x41, 0x08, 0x8a, 0x52, 0xa6, 0x31, 0x8a, 0x52, 0xeb, 0x5a, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x07, 0xc3, 0x18, 0x69, 0x4a, 0x6d, 0x6b, 0xef, 0x7b, 0xef, 0x7b, 0x4d, 0x6b, 0x49, 0x4a, 0xe3, 0x18, 0x8f, 0x00, 0x00, 0x04, 0x04, 0x21, 0xe7, 0x39, 0x08, 0x42, 0x65, 0x29, 0x41, 0x08, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xa3, 0x00, 0x00 }; glide3x/h5/glide3/src/cpuid.c0100700000175300010010000002212407725034667015251 0ustar johndoeNone/* * CPU detection code * * $Header: /cvsroot/glide/glide3x/h5/glide3/src/Attic/cpuid.c,v 1.1.2.9 2003/08/04 12:45:47 dborca Exp $ * $Log: cpuid.c,v $ * Revision 1.1.2.9 2003/08/04 12:45:47 dborca * Preparing for MinGW 2.0 * * Revision 1.1.2.8 2003/07/29 10:04:32 dborca * Shamelessness. * Safeguard in CPUID. * Changed contact address! * Koolsmoky's texture download fixes. * * Revision 1.1.2.7 2003/07/25 07:14:58 dborca * ... in the name of the Linux, DRI and the sacred Glide... * * Revision 1.1.2.6 2003/07/24 13:13:03 koolsmoky * use __try/__except mechanism for win32 to catch SSE sigillegal in win95 * * Revision 1.1.2.5 2003/07/01 11:16:42 dborca * fixed a bug in GNUC code when running Intel; also removed detritus * * Revision 1.1.2.3 2003/06/13 07:22:58 dborca * more fixes to NASM sources * */ #include #include #include #include "cpuid.h" typedef unsigned long word32; /* These are the bit flags that get set on calling cpuid * with register eax set to 1 */ #define _MMX_FEATURE_BIT 0x00800000 #define _SSE_FEATURE_BIT 0x02000000 #define _SSE2_FEATURE_BIT 0x04000000 /* This bit is set when cpuid is called with * register set to 80000001h (only applicable to AMD) */ #define _3DNOW_FEATURE_BIT 0x80000000 #define _3DNOWPLUS_FEATURE_BIT 0x40000000 #define _MMXPLUS_FEATURE_BIT 0x00400000 /* Testing code: * TEST_SSE = xorps xmm0, xmm0 * TEST_SSE2 = xorpd xmm0, xmm0 * TEST_3DNOW = femms * TEST_MMX = emms * TEST_3DNOWPLUS = femms | pswapd mm0, mm0 | femms * TEST_MMXPLUS = emms | pminsw mm0, mm0 | emms */ #ifdef __GNUC__ #define TEST_CPUID(f) __asm __volatile ("cpuid"::"a"(f):"%ebx", "%ecx", "%edx") #define TEST_SSE() __asm __volatile (".byte 0x0f, 0x57, 0xc0") #define TEST_SSE2() __asm __volatile (".byte 0x66, 0x0f, 0x57, 0xc0") #define TEST_3DNOW() __asm __volatile (".byte 0x0f, 0x0e") #define TEST_MMX() __asm __volatile (".byte 0x0f, 0x77") #define TEST_3DNOWPLUS() __asm __volatile (".byte 0x0f, 0x0e, 0x0f, 0x0f, 0xc0, 0xbb, 0x0f, 0x0e") #define TEST_MMXPLUS() __asm __volatile (".byte 0x0f, 0x77, 0x0f, 0xea, 0xc0, 0x0f, 0x77") #else #define TEST_CPUID(f) __asm { _asm mov eax, f _asm cpuid } #define TEST_SSE() __asm { _asm _emit 0x0f _asm _emit 0x57 _asm _emit 0xc0 } #define TEST_SSE2() __asm { _asm _emit 0x66 _asm _emit 0x0f _asm _emit 0x57 _asm _emit 0xc0 } #define TEST_3DNOW() __asm { _asm _emit 0x0f _asm _emit 0x0e } #define TEST_MMX() __asm { _asm _emit 0x0f _asm _emit 0x77 } #define TEST_3DNOWPLUS() __asm { _asm _emit 0x0f _asm _emit 0x0e _asm _emit 0x0f _asm _emit 0x0f _asm _emit 0xc0 _asm _emit 0xbb _asm _emit 0x0f _asm _emit 0x0e } #define TEST_MMXPLUS() __asm { _asm _emit 0x0f _asm _emit 0x77 _asm _emit 0x0f _asm _emit 0xea _asm _emit 0xc0 _asm _emit 0x0f _asm _emit 0x77 } #endif #ifndef __MSC__ static jmp_buf j; /* Desc: signal handler * * In : signal number * Out : - * * Note: returns by `longjmp'ing */ static void handler (int signal) { longjmp(j, signal + 1); /* so we can tell... also ensure we don't pass 0 */ } /* Desc: check if CPU has specific feature * * In : feature request * Out : 0 == fail, input == pass * * Note: this should be in the `has_feature' body. The reason it isn't: * under some systems (notably Linux), the `setjmp' may thrash EBX, * which is used for PositionIndependentCode/GlobalOffsetTable system. * Since EBX is non-volatile register, it should be restored upon return. */ static int check_feature (int feature) { if (setjmp(j)) { /* we got here only when `longjmp'ed by signal handlers */ return 0; } else { /* we have signals and jump buffer set */ switch (feature) { case _CPU_HAS_CPUID: TEST_CPUID(0); break; case _CPU_FEATURE_SSE: TEST_SSE(); break; case _CPU_FEATURE_SSE2: TEST_SSE2(); break; case _CPU_FEATURE_3DNOW: TEST_3DNOW(); break; case _CPU_FEATURE_MMX: TEST_MMX(); break; case _CPU_FEATURE_3DNOWPLUS: TEST_3DNOWPLUS(); break; case _CPU_FEATURE_MMXPLUS: TEST_MMXPLUS(); break; default: return 0; } return feature; } } #endif /* Desc: perform (possibly faulting) instructions in a safe manner * * In : feature request * Out : 0 == fail, input == pass * * Note: pure ANSI code; stupid Watcom cannot handle this. */ static int has_feature (int feature) { #ifndef __MSC__ int rv; /* register signal handlers */ void (*old_sigill)(int) = signal(SIGILL, handler); if (old_sigill == SIG_ERR) { return 0; } rv = check_feature(feature); /* restore the signal handlers */ signal(SIGILL, old_sigill); return rv; #else /* Use the non-standard __try/__except mechanism because win95 fails to catch * sigillegal for SSE using standard signal mechanism. * HACK ALERT! HACK ALERT! HACK ALERT! * This means the MinGW version cannot be safely run under Win95! */ #define _TRY() __try { #define _EXCEPTION() } __except(1) { return 0; } /* EXCEPTION_EXECUTE_HANDLER=1 */ switch (feature) { case _CPU_HAS_CPUID: _TRY() TEST_CPUID(0) _EXCEPTION() break; case _CPU_FEATURE_SSE: _TRY() TEST_SSE() _EXCEPTION() break; case _CPU_FEATURE_SSE2: _TRY() TEST_SSE2() _EXCEPTION() break; case _CPU_FEATURE_3DNOW: _TRY() TEST_3DNOW() _EXCEPTION() break; case _CPU_FEATURE_MMX: _TRY() TEST_MMX() _EXCEPTION() break; case _CPU_FEATURE_3DNOWPLUS: _TRY() TEST_3DNOWPLUS() _EXCEPTION() break; case _CPU_FEATURE_MMXPLUS: _TRY() TEST_MMXPLUS() _EXCEPTION() break; default: return 0; } return feature; #endif } /* Desc: get CPU info * * In : pointer to _p_info * Out : features * * Note: - */ int _cpuid (_p_info *pinfo) { word32 dwId = 0; word32 dwFeature = 0; word32 dwExt = 0; int feature = 0, os_support = 0; char Ident[13]; if (!has_feature(_CPU_HAS_CPUID)) { return 0; } #ifdef __GNUC__ __asm("\n\ pushl %%ebx \n\ /* get the vendor string */ \n\ xorl %%eax, %%eax \n\ cpuid \n\ movl %%ebx, %3 \n\ movl %%edx, %4 \n\ movl %%ecx, %5 \n\ /* get the Standard bits */ \n\ movl $1, %%eax \n\ cpuid \n\ movl %%eax, %1 \n\ movl %%edx, %2 \n\ /* get AMD-specials */ \n\ movl $0x80000000, %%eax \n\ cpuid \n\ cmpl $0x80000000, %%eax \n\ jc 0f \n\ movl $0x80000001, %%eax \n\ cpuid \n\ movl %%edx, %0 \n\ 0: \n\ popl %%ebx \n\ ":"=g"(dwExt), "=g"(dwId), "=g"(dwFeature), "=g"(((long *)Ident)[0]), "=g"(((long *)Ident)[1]), "=g"(((long *)Ident)[2]) ::"%eax", "%ebx", "%ecx", "%edx"); #else _asm { push ebx push ecx push edx /* get the vendor string */ xor eax,eax cpuid mov dword ptr [Ident],ebx mov dword ptr [Ident+4],edx mov dword ptr [Ident+8],ecx /* get the Standard bits */ mov eax,1 cpuid mov dwId,eax mov dwFeature,edx /* get AMD-specials */ mov eax,80000000h cpuid cmp eax,80000000h jc notamd mov eax,80000001h cpuid mov dwExt,edx notamd: pop ecx pop ebx pop edx } #endif if (dwFeature & _MMX_FEATURE_BIT) { feature |= _CPU_FEATURE_MMX; os_support |= has_feature(_CPU_FEATURE_MMX); } if (dwExt & _3DNOW_FEATURE_BIT) { feature |= _CPU_FEATURE_3DNOW; os_support |= has_feature(_CPU_FEATURE_3DNOW); } if (dwExt & _3DNOWPLUS_FEATURE_BIT) { feature |= _CPU_FEATURE_3DNOWPLUS; os_support |= has_feature(_CPU_FEATURE_3DNOWPLUS); } if (dwExt & _MMXPLUS_FEATURE_BIT) { feature |= _CPU_FEATURE_MMXPLUS; os_support |= has_feature(_CPU_FEATURE_MMXPLUS); } if (dwFeature & _SSE_FEATURE_BIT) { feature |= _CPU_FEATURE_SSE; os_support |= has_feature(_CPU_FEATURE_SSE); } if (dwFeature & _SSE2_FEATURE_BIT) { feature |= _CPU_FEATURE_SSE2; os_support |= has_feature(_CPU_FEATURE_SSE2); } if (pinfo) { memset(pinfo, 0, sizeof(_p_info)); pinfo->os_support = os_support; pinfo->feature = feature; pinfo->family = (dwId >> 8) & 0xF; /* retrieving family */ pinfo->model = (dwId >> 4) & 0xF; /* retrieving model */ pinfo->stepping = dwId & 0xF; /* retrieving stepping */ Ident[12] = 0; strcpy(pinfo->v_name, Ident); } return feature; } #if CPUTEST #include /* Desc: * * In : * Out : * * Note: */ int main (void) { _p_info p; _cpuid(&p); printf("vendor : %s\n", p.v_name); printf("family : %d\n", p.family); printf("model : %d\n", p.model); printf("stepping: %X\n", p.stepping); printf("feature : %08x\n", p.feature); printf("support : %08x\n", p.os_support); printf("--------\n"); printf("cpuid : %d\n", has_feature(_CPU_HAS_CPUID)); printf("MMX : %d\n", has_feature(_CPU_FEATURE_MMX)); printf("SSE : %d\n", has_feature(_CPU_FEATURE_SSE)); printf("SSE2 : %d\n", has_feature(_CPU_FEATURE_SSE2)); printf("3DNow! : %d\n", has_feature(_CPU_FEATURE_3DNOW)); printf("3DNow!+ : %d\n", has_feature(_CPU_FEATURE_3DNOWPLUS)); printf("MMX+ : %d\n", has_feature(_CPU_FEATURE_MMXPLUS)); return 0; } #endif glide3x/h5/glide3/src/diget.c0100700000175300010010000011030207725034667015235 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/diget.c,v 1.4.4.2 2003/06/05 08:23:50 koolsmoky Exp $ ** $Log: ** 22 3dfx 1.17.1.0.1.210/11/00 Brent Forced check in to enforce ** branching. ** 21 3dfx 1.17.1.0.1.109/15/00 troy thornton grqueryresolutions now ** checks the refreshrate of the monitor before returning a valid screen mode ** ** 20 3dfx 1.17.1.0.1.008/29/00 Jonny Cochrane Some 8x FSAA code ** 19 3dfx 1.17.1.0 06/07/00 Daoxiang Gong Fixes PRS 14363. Make sure ** grGet returns proper color bit depth info. ** 18 3dfx 1.17 04/17/00 Adam Briggs added ** grGetRegistryOrEnvironmentStringExt call so that OpenGL has an easy way to ** read environment settings from the registry. To save you the trouble of ** asking, the answer is no, I could not think of a longer name for the ** function. I did try, though. ** 17 3dfx 1.16 04/10/00 Larry warner Report max texture size ** 2048 for Napalm and 256 otherwise. ** 16 3dfx 1.15 04/06/00 Larry warner So much for the palindrome. ** 15 3dfx 1.14 03/31/00 Kenneth Dyke Get number of chips from ** bInfo so we report back the right kind of card. (Cosmetic). ** 14 3dfx 1.13 02/22/00 Kenneth Dyke Base min/max z and w buffer ** values on actual pixel depth, and not on the hardware we're on. ** 13 3dfx 1.12 02/10/00 Adam Briggs grGet(GR_NUM_FB) now ** returns the number of chips on a board. ** 12 3dfx 1.11 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 11 3dfx 1.10 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 10 3dfx 1.9 01/30/00 Adam Briggs get napalm status correctly ** 9 3dfx 1.8 01/18/00 Kenneth Dyke Fix query value for maximum ** texture size. ** 8 3dfx 1.7 01/04/00 Adam Briggs changed grGetGammaTable to ** be an extension called grGetGammaTableExt ** 7 3dfx 1.6 12/13/99 Adam Briggs Made ** grGetString(GR_HARDWARE) return Voodoo4 or VoodooV instead of Napalm ** 6 3dfx 1.5 12/10/99 Leo Galway Removed previous hi-res ** mode information for Glide3. These modes were only necessary for ** Cornerstone (or future hi-res) support in RT4.2 source branch and ** proceeded to break the V3 and V2 builds (from 3dfx view), hence they have ** been removed. ** 5 3dfx 1.4 12/08/99 Leo Galway Added mode information for ** 1600x1280, 1792x1440, 1920x1080, 1920x1200, 2046x1536 (as a result of ** glide being tested with Cornerstone modes). Although not all of these ** modes are currently capable under Glide, their inclusion prevents Glide ** apps from displaying in incorrect modes when these hi-res modes are ** selected. Search for SUSTAINED_ENGINEERING_CHANGE_BEGIN. ** 4 3dfx 1.3 10/26/99 Anthony tai workaround for calling ** grGetString before the gc exist ** 3 3dfx 1.2 09/28/99 Anthony tai workaround for dct bug ** 2 3dfx 1.1 09/22/99 Adam Briggs Added ** grConstantColorValueExt ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 93 9/09/99 4:19p Adamb ** Added TEXTUREBUFFER to GR_EXTENSION string ** ** 92 8/23/99 3:14p Kcd ** New MacOS 8 surface stuff. ** ** 91 8/19/99 5:57p Atai ** new string for napalm ext ** ** 90 7/23/99 2:00p Atai ** change tbuffer interface to grTBufferWriteMaskExt ** ** 89 7/22/99 1:18p Atai ** added grTBufferMaskExt ** ** 88 7/18/99 1:59p Atai ** added grAlphaBlendFunctionExt ** ** 87 7/14/99 5:07p Atai ** fixed stencil interface and some cc/ac stuff ** ** 86 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 85 7/08/99 8:48p Atai ** stencil interface update ** ** 84 7/06/99 5:23p Atai ** fake resolution ** ** 83 7/06/99 2:44p Atai ** added grColorMaskExt ** ** 82 7/01/99 6:42p Larryw ** Added TEXFMT extension. ** ** 81 6/24/99 7:11p Atai ** added STENCIL and COMBINE extension ** ** 80 6/22/99 2:56p Larryw ** Added grGetString placeholder for Napalm. ** Report "3dfx Interactive" instead of "3Dfx Interactive" as the vendor. ** ** 79 6/13/99 6:16p Atai ** use "PIXEXT" for winopen ext ** ** 78 6/04/99 11:00a Atai ** added stencil functions ** ** 77 6/03/99 4:47p Atai ** modify grGet(GR_WDEPTH_MIN_MAX) and grGet(GR_ZDEPTH_MIN_MAX) ** ** 76 6/01/99 2:34p Atai ** Added "NAPALM" Extension as a place holder. How do we want to call the ** new extension? ** ** 75 5/24/99 2:49p Jamesb ** Added ptrLostContext field to exported command transport struct. ** ** 74 5/19/99 3:55p Denis ** ** 73 5/19/99 3:48p Denis ** ** 72 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a "tbext" comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 71 4/16/99 2:45p Kcd ** Mac Surface extensions. ** ** 70 4/10/99 1:23p Atai ** fixed code to compile in packet fifo mode ** ** 69 4/07/99 7:18p Atai ** added uma extension ** ** 68 3/19/99 11:26a Peter ** expose direct fifo for gl ** ** 67 3/14/99 1:47p Peter ** temp implemntation of my surface extension extension, bottleneck ** through _grSstStatus ** ** 66 3/11/99 7:14p Dow ** Resolution help ** ** 65 3/11/99 6:38p Dow ** Resolution help ** ** 64 3/05/99 10:34a Atai ** fixed fbmem in grQueryResolutions ** ** 63 3/04/99 3:11p Atai ** fixed voodoo3 rev number. ** ** 62 2/26/99 2:54p Atai ** added fbi and tmu revision ** ** 61 2/18/99 3:07p Kcd ** I mean in this time, really. ** ** 60 2/18/99 3:01p Kcd ** Surface Extensions disabled for non-Win32 systems. ** ** 59 2/13/99 2:01p Dow ** Added code for new resolutions ** ** 58 2/10/99 2:12p Peter ** forgot about refresh_any ** ** 57 2/09/99 1:59p Peter ** fixed grGet(Num_boards) w/o any boards installed ** ** 56 2/08/99 10:59a Peter ** constrained query should not clamp on out of bounds values ** ** 55 2/02/99 4:38p Peter ** 16 byte texture alignmnet boundary ** ** 54 1/20/99 10:54a Dow ** Voodoo 3 id for apps ** ** 53 1/14/99 11:03a Dow ** Fixed gets for memory ** ** 52 1/04/99 12:01p Peter ** turned on surface extension for nt ** ** 51 12/14/98 6:19p Dow ** Fixed for current surface extension spec ** ** 50 12/03/98 9:11p Dow ** More Debug messages ** ** 49 12/03/98 9:37a Dow ** Added reserved enumerant for RAM type ** ** 48 12/02/98 9:35p Dow ** QueryResolutions ** ** 47 12/01/98 12:04p Atai ** fixed tri stats reset ** ** 46 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 45 11/21/98 8:22a Atai ** fixed GR_MEMORY_UMA return value and length ** ** 44 11/17/98 4:25p Atai ** fixed my previous check-in ** ** 43 11/15/98 3:43a Atai ** fixed GR_MEMORY_TMU ** ** 42 10/20/98 8:28p Peter ** shared files and fixed whackage ** ** 41 10/09/98 12:18p Dow ** Fixed extension string ** ** 40 10/09/98 10:20a Dow ** Fixed call to _grSstStatus ** ** 39 10/09/98 10:05a Dow ** Fixed grGet() stuff ** ** 38 10/09/98 9:40a Dow ** Fixed some grGet Stuff ** ** 37 9/30/98 10:31a Atai ** fixed GR_IS_BUSY ** ** 36 9/21/98 4:39p Atai ** fixed grGet ** ** 35 9/02/98 10:36a Atai ** fixed grQueryResolution ** ** 34 9/02/98 9:20a Peter ** update grGet(xxx_mem) values after open ** ** 33 8/30/98 3:55p Dow ** Turned of Surface Extension for WNT ** ** 32 8/29/98 2:28p Peter ** tls happiness w/ debug builds ** ** 31 8/28/98 4:01p Jdt ** Export grSurfacereleaseContextExt. ** ** 30 8/05/98 11:45p Atai ** 1. grBufferSwap argument FxU32 ** 2. grGet return FxU32 ** ** 29 8/03/98 6:35a Jdt ** multi-thread changes ** ** 28 8/02/98 5:01p Dow ** Glide Surface Extension ** ** 27 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 26 7/18/98 10:39a Dow ** Added Aux & Tex buffer ** ** 25 7/16/98 8:27a Jdt ** ** 24 7/16/98 8:14a Jdt ** fxcmd.h ** ** 23 7/13/98 10:19p Jdt ** Added SURFACE extension. ** ** Re-wrote grGetProcAddress to be table-driven. ** ** 22 7/01/98 12:39p Jdt ** Added vertex layout size query ** ** 21 6/25/98 2:17p Atai ** grGet (GR_NUM_BOARDS) can be called before grGlideInit ** ** 20 6/24/98 2:43p Jdt ** Added query for state size. ** ** 19 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 18 5/21/98 7:15p Atai ** fix q0 and q1 for clip coords ** ** 17 5/19/98 6:43p Atai ** swap history ** ** 16 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 15 5/11/98 4:14p Atai ** added frame buffer constrained query ** ** 14 5/08/98 1:40p Peter ** merged Anthony's palette of Taco changes ** ** 13 5/08/98 12:15p Peter ** expressions w/o sideffects are pretty lame ** ** 11 5/05/98 2:22p Peter ** banshee is really banshee ** ** 10 5/01/98 4:08p Peter ** fixed strings for banshee ** ** 9 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 8 4/30/98 10:34a Peter ** merged w/ cvg again ** ** 7 4/24/98 2:18p Atai ** fix GR_NON_POWER_OF_TWO_TEXTURES ** ** 6 4/16/98 6:15p Atai ** added grReset(GR_VERTEX_PARAMETER) ** ** 5 1/30/98 4:27p Atai ** gufog* prototype ** ** 4 1/28/98 6:36p Atai ** remove z,w, min_max definition ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 2 1/16/98 6:44p Atai * fixed for glide 3 build * * 1 1/16/98 4:29p Atai * create glide 3 src * * 9 1/10/98 4:01p Atai * inititialize vertex layout, viewport, added defines * * 6 1/07/98 6:04p Atai * GR_PENDING_BUFFERSWAPS * * 5 1/06/98 3:53p Atai * remove grHint, modify grLfbWriteRegion and grGet * * 3 12/18/97 10:52a Atai * fixed grGet(GR_VIDEO_POS) * * 2 12/17/97 4:05p Atai * added grChromaRange(), grGammaCorrecionRGB(), grRest(), and grGet() * functions * * 1 12/14/97 1:41p Pgj ** */ #if defined(GLIDE3) && defined(GLIDE3_ALPHA) #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #include "gsfc.h" #include "rcver.h" #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #if HAL_CSIM #include #else #include #endif #endif #include "fxinline.h" /*------------------------------------------------------------------- Function: grGet Date: 14-Dec-97 Implementor(s): pgj Description: Implements Glide 3.0 grGet() and grGetString() XXX This is a work in progress. There are ugly #ifdefs in some of the selectors, yet grGet seems like it should be di. After bringup is further along, consider pushing some of this into dd in order to eliminate platform #ifdefs. Arguments: pname - parameter to be returned, e.g. GR_BITS_RGBA params - address of returned parameters Return: FXTRUE if successful -------------------------------------------------------------------*/ GR_DIENTRY(grGet, FxU32, (FxU32 pname, FxU32 plength, FxI32 *params)) { #define FN_NAME "grGet" FxBool retVal = FXFALSE; if (params == NULL) return FXFALSE; switch(pname) { case GR_BITS_DEPTH: if (plength == 4) { GR_DCL_GC; retVal = plength; *params = gc->bInfo->h3pixelSize << 3 ; } break; case GR_BITS_RGBA: if (plength == 16) { GR_DCL_GC; retVal = plength; switch(gc->grPixelFormat) { case GR_PIXFMT_RGB_565: case GR_PIXFMT_AA_2_RGB_565: case GR_PIXFMT_AA_4_RGB_565: case GR_PIXFMT_AA_8_RGB_565: /* 8xaa */ *params = 5; *(params+1) = 6; *(params+2) = 5; *(params+3) = 0; break; case GR_PIXFMT_ARGB_1555: case GR_PIXFMT_AA_2_ARGB_1555: case GR_PIXFMT_AA_4_ARGB_1555: case GR_PIXFMT_AA_8_ARGB_1555: /* 8xaa */ *params = 5; *(params+1) = 5; *(params+2) = 5; *(params+3) = 1; break; case GR_PIXFMT_ARGB_8888: case GR_PIXFMT_AA_2_ARGB_8888: case GR_PIXFMT_AA_4_ARGB_8888: case GR_PIXFMT_AA_8_ARGB_8888: /* 8xaa */ *params = 8; *(params+1) = 8; *(params+2) = 8; *(params+3) = 8; break; default: break; } } break; case GR_FIFO_FULLNESS: if (plength == 8) { const FxU32 status = _grSstStatus(); *params = (status & SST_PCIFIFO_FREE); *(params + 1) = status; retVal = plength; } break; case GR_FOG_TABLE_ENTRIES: if (plength == 4) { *params = kInternalFogTableEntryCount; retVal = plength; } break; case GR_BITS_GAMMA: if (plength == 4) { *params = 8; retVal = plength; } break; case GR_GAMMA_TABLE_ENTRIES: if (plength == 4) { *params = VOODOO_GAMMA_TABLE_SIZE; retVal = plength; } break; case GR_GLIDE_STATE_SIZE: if ( plength == 4 ) { *params = sizeof( GrState ); retVal = plength; } break; case GR_GLIDE_VERTEXLAYOUT_SIZE: if ( plength == 4 ) { *params = sizeof( GrVertexLayout ); retVal = plength; } break; case GR_IS_BUSY: if (plength == 4) { *params = _grSstIsBusy() ; retVal = plength; } break; case GR_LFB_PIXEL_PIPE: if (plength == 4) { *params = (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_SST96); retVal = plength; } break; case GR_MAX_TEXTURE_SIZE: if (plength == 4) { GR_DCL_GC; if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { *params = 2048; } else { *params = 256; } retVal = plength; } break; case GR_MAX_TEXTURE_ASPECT_RATIO: if (plength == 4) { *params = 3; retVal = plength; } break; case GR_MEMORY_FB: if (plength == 4) { GR_DCL_GC; /* Default to the whole memory size until the application inits * buffers etc then subtract off start of the first color buffer. */ #ifdef GLIDE_INIT_HWC if (gc->open) *params = ((gc->bInfo->h3Mem << 20) - gc->fbOffset); else #endif *params = (gc->fbuf_size - 2) << 20; retVal = plength; } break; case GR_MEMORY_TMU: if (plength == 4) { GR_DCL_GC; if (gc->open) *params = (gc->tmu_state[0].total_mem); else *params = 2 << 20; retVal = plength; } break; case GR_MEMORY_UMA: if (plength == 4) { GR_DCL_GC; #ifdef GLIDE_INIT_HWC *params = gc->bInfo->h3Mem << 20; #endif retVal = plength; } break; case GR_NUM_BOARDS: if (plength == 4) { *params = (_grSstDetectResources() ? _GlideRoot.hwConfig.num_sst : 0); retVal = plength; } break; case GR_NON_POWER_OF_TWO_TEXTURES: if (plength == 4) { *params = FXFALSE; retVal = plength; } break; case GR_NUM_FB: if (plength == 4) { GR_DCL_GC; if ((gc) && (gc->chipCount)) *params = gc->chipCount ; else *params = 1 ; retVal = plength; } break; case GR_NUM_TMU: if (plength == 4) { *params = _GlideRoot.GCs[_GlideRoot.current_sst].num_tmu; retVal = plength; } break; case GR_PENDING_BUFFERSWAPS: if (plength == 4) { *params = _grBufferNumPending(); retVal = plength; } break; case GR_REVISION_FB: case GR_REVISION_TMU: if (plength == 4) { GR_DCL_GC; #ifdef GLIDE_INIT_HWC switch (gc->bInfo->pciInfo.deviceID) { case SST_DEVICE_ID_H3: *params = 0x1000; /* banshee */ break; case SST_DEVICE_ID_H4_OEM: case SST_DEVICE_ID_H4: *params = 0x11100; /* voodoo3 = banshee + voodoo2 */ break; default: *params = 0; } #endif retVal = plength; } break; case GR_STATS_LINES: if (plength == 4) { GR_DCL_GC; *params = gc->stats.linesDrawn; retVal = plength; } break; case GR_STATS_PIXELS_AFUNC_FAIL: { GR_DCL_GC; if ((((SstRegs *)gc->sstRegs)) && (plength == 4)) { *params = GR_GET(((SstRegs *)gc->sstRegs)->stats.fbiAfuncFail); retVal = plength; } break; } case GR_STATS_PIXELS_CHROMA_FAIL: { GR_DCL_GC; if ((((SstRegs *)gc->sstRegs)) && (plength == 4)) { *params = GR_GET(((SstRegs *)gc->sstRegs)->stats.fbiChromaFail); retVal = plength; } break; } case GR_STATS_PIXELS_DEPTHFUNC_FAIL: { GR_DCL_GC; if ((((SstRegs *)gc->sstRegs)) && (plength == 4)) { *params = GR_GET(((SstRegs *)gc->sstRegs)->stats.fbiZfuncFail); retVal = plength; } break; } case GR_STATS_PIXELS_IN: { GR_DCL_GC; if ((((SstRegs *)gc->sstRegs)) && (plength == 4)) { *params = GR_GET(((SstRegs *)gc->sstRegs)->stats.fbiPixelsIn); retVal = plength; } break; } case GR_STATS_PIXELS_OUT: { GR_DCL_GC; if ((((SstRegs *)gc->sstRegs)) && (plength == 4)) { *params = GR_GET(((SstRegs *)gc->sstRegs)->stats.fbiPixelsOut); retVal = plength; } break; } case GR_STATS_POINTS: if (plength == 4) { GR_DCL_GC; *params = gc->stats.pointsDrawn; retVal = plength; } break; case GR_STATS_TRIANGLES_IN: if (plength == 4) { GR_DCL_GC; *params = gc->stats.trisProcessed; retVal = plength; /* XXX TBD */ } break; case GR_STATS_TRIANGLES_OUT: if (plength == 4) { GR_DCL_GC; *params = GR_GET(((SstRegs *)gc->sstRegs)->fbiTrianglesOut) - gc->stats.othertrisDrawn; retVal = plength; } break; case GR_NUM_SWAP_HISTORY_BUFFER: if (plength == 4) { *params = 8; /* in Voodoo2 and Banshee, the swap history size is 8 */ retVal = plength; } break; case GR_SWAP_HISTORY: if (plength == 32) { GR_DCL_GC; FxU32 sh = GR_GET(((SstRegs *)gc->sstRegs)->fbiSwapHistory), i; for (i = 0; i < 8; i++) { *(params +i) = sh & 0xf; sh = sh >> 4; } retVal = plength; } break; case GR_SUPPORTS_PASSTHRU: if (plength == 4) { *params = FXFALSE; retVal = plength; } break; case GR_TEXTURE_ALIGN: if (plength == 4) { *params = SST_TEXTURE_ALIGN; retVal = plength; } break; case GR_VIDEO_POSITION: #if defined(GLIDE3) && defined(GLIDE3_ALPHA) if (plength == 8) { *params = *(params + 1) = 0; retVal = plength; } #endif break; case GR_VIEWPORT: if (plength == 16) { GR_DCL_GC; *params = (FxI32) (gc->state.Viewport.ox - gc->state.Viewport.hwidth); *(params+1) = (FxI32) (gc->state.Viewport.oy - gc->state.Viewport.hheight); *(params+2) = (FxI32) (gc->state.Viewport.hwidth * 2.f); *(params+3) = (FxI32) (gc->state.Viewport.hheight * 2.f); retVal = plength; } break; case GR_WDEPTH_MIN_MAX: if (plength == 8) { GR_DCL_GC; *params = SST1_WDEPTHVALUE_NEAREST; *(params+1) = (gc->grPixelSize <= 2) ? SST1_WDEPTHVALUE_FARTHEST : NAPALM_WDEPTHVALUE_FARTHEST; retVal = plength; } break; case GR_ZDEPTH_MIN_MAX: if (plength == 8) { GR_DCL_GC; *params = (gc->grPixelSize <= 2) ? SST1_ZDEPTHVALUE_NEAREST : NAPALM_ZDEPTHVALUE_NEAREST; *(params+1) = SST1_ZDEPTHVALUE_FARTHEST; retVal = plength; } break; case GR_SURFACE_SIZE: if (plength == 4) { #ifdef GLIDE_INIT_HWC *params = sizeof(hwcBufferDesc); retVal = plength; #endif } break; case GR_SURFACE_TEXTURE: if (plength == 4) { GR_DCL_GC; #ifdef GLIDE_INIT_HWC *params = (FxU32) &gc->tBuffer; retVal = plength; #endif } break; case GR_MEMTYPE: if (plength == 4) { GR_DCL_GC; #ifdef GLIDE_INIT_HWC *params = (FxU32)gc->bInfo->sdRAM; retVal = plength; #endif } break; default: retVal = FXFALSE; /* XXX TBD */ break; } /* end switch */ return retVal; #undef FN_NAME } /* end grGet() */ /*------------------------------------------------------------------- Function: grGetString Date: 14-Dec-97 Implementor(s): pgj Description: Implements Glide 3.0 grGetString() Arguments: pname - parameter to be returned, e.g. GR_VENDOR Return: pointer to the selected string if successful -------------------------------------------------------------------*/ #if GLIDE_POINTCAST_PALETTE #define POINTCAST_EXT_STR "POINTCAST " #else #define POINTCAST_EXT_STR "" #endif #ifdef QUERY_EXTENSION_SUPPORTED #define QUERY_EXT_STR "QUERY " #else #define QUERY_EXT_STR "" #endif #define BASE_EXT_STR "CHROMARANGE TEXCHROMA TEXMIRROR TEXUMA PALETTE6666 FOGCOORD SURFACE COMMAND_TRANSPORT TEXTUREBUFFER GETGAMMA GETREGISTRY ALPHAFOG " #define NAPALM_EXT_STR "PIXEXT COMBINE TEXFMT " GR_DIENTRY(grGetString, const char *, (FxU32 pname)) { #define FN_NAME "grGetString" const char *rv = "ERROR"; switch(pname) { case GR_EXTENSION: /* NOTE!: leave a leading and trailing spaces on the list so that apps can disambiguate substrings */ { GR_DCL_GC; if (!gc) /* workaround null gc bug */ return rv; if (!IS_NAPALM(gc->bInfo->pciInfo.deviceID)) rv = " " BASE_EXT_STR QUERY_EXT_STR POINTCAST_EXT_STR; else rv = " " BASE_EXT_STR NAPALM_EXT_STR QUERY_EXT_STR POINTCAST_EXT_STR; } break; case GR_HARDWARE: { GR_DCL_GC; #ifdef GLIDE_INIT_HWC if (!gc) /* workaround null gc bug */ return rv; switch (gc->bInfo->pciInfo.deviceID) { case SST_DEVICE_ID_H3: rv = "Voodoo Banshee (tm)"; break; case SST_DEVICE_ID_H4: case SST_DEVICE_ID_H4_OEM: rv = "Voodoo3 (tm)"; break; default: if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->bInfo->pciInfo.realNumChips == 4) { rv = "Voodoo5 6000 (tm)" ; } else if (gc->bInfo->pciInfo.realNumChips == 2) { rv = "Voodoo5 5500 (tm)" ; } else if (gc->bInfo->pciInfo.realNumChips >= 2) { rv = "Voodoo5 (tm)" ; } else { rv = "Voodoo4 (tm)" ; } } /* default: "ERROR" */ break; } #endif } break; case GR_RENDERER: rv = "Glide"; break; case GR_VENDOR: rv = "3dfx Interactive"; break; case GR_VERSION: rv = VERSIONSTR; break; } /* end switch */ return rv; #undef FN_NAME } /* grGetString */ /*------------------------------------------------------------------- Function: grGetRegistryOrEnvironmentStringExt Date: 4/17/2000 Implementor(s): atom Description: This is here so the spooky code for finding the correct registry tweak path in 9x/NT/2K does not have to be duplicated in 3dfxogl. Arguments: char* to the name of the setting to check for. Return: char* to the requested entry either from the registry or the environment settings. NULL on error. -------------------------------------------------------------------*/ GR_EXT_ENTRY(grGetRegistryOrEnvironmentString, char*, (char* theEntry)) { #define FN_NAME "grGetRegistryOrEnvironmentString" char* retval ; #if !defined(GLIDE_INIT_HAL) retval = hwcGetenv(theEntry) ; #else retval = getenv(theEntry) ; #endif return retval ; #undef FN_NAME } /* grGetRegistryOrEnvironmentString */ /*------------------------------------------------------------------- Function: grReset Date: 16-Dec-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grReset, FxBool, (FxU32 what)) { #define FN_NAME "grReset" FxBool retVal; GR_DCL_GC; switch(what) { case GR_STATS_POINTS: gc->stats.pointsDrawn = 0; retVal = FXTRUE; break; case GR_STATS_LINES: gc->stats.linesDrawn = 0; retVal = FXTRUE; break; case GR_STATS_PIXELS: #if defined(GLIDE3) && (GLIDE3_ALPHA) _grSstResetPerfStats(); #endif retVal = FXTRUE; break; case GR_STATS_TRIANGLES: #if defined(GLIDE3) && (GLIDE3_ALPHA) { GR_DCL_HW; _grResetTriStats(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0x02); GR_CHECK_SIZE(); } #endif retVal = FXTRUE; break; case GR_VERTEX_PARAMETER: #if defined(GLIDE3) && (GLIDE3_ALPHA) { gc->state.vData.vertexInfo.offset = 0; gc->state.vData.vertexInfo.mode = GR_MODE_DISABLE; gc->state.vData.zInfo.offset = 0; gc->state.vData.zInfo.mode = GR_MODE_DISABLE; gc->state.vData.wInfo.offset = 0; gc->state.vData.wInfo.mode = GR_MODE_DISABLE; gc->state.vData.aInfo.offset = 0; gc->state.vData.aInfo.mode = GR_MODE_DISABLE; gc->state.vData.rgbInfo.offset = 0; gc->state.vData.rgbInfo.mode = GR_MODE_DISABLE; gc->state.vData.pargbInfo.offset = 0; gc->state.vData.pargbInfo.mode = GR_MODE_DISABLE; gc->state.vData.st0Info.offset = 0; gc->state.vData.st0Info.mode = GR_MODE_DISABLE; gc->state.vData.st1Info.offset = 0; gc->state.vData.st1Info.mode = GR_MODE_DISABLE; gc->state.vData.qInfo.offset = 0; gc->state.vData.qInfo.mode = GR_MODE_DISABLE; gc->state.vData.q0Info.offset = 0; gc->state.vData.q0Info.mode = GR_MODE_DISABLE; gc->state.vData.q1Info.offset = 0; gc->state.vData.q1Info.mode = GR_MODE_DISABLE; gc->state.invalid &= ~vtxlayoutBIT; gc->state.vData.colorType = GR_FLOAT; } #endif retVal = FXTRUE; break; default: retVal = FXFALSE; } return retVal; #undef FN_NAME } /* end grReset() */ /*------------------------------------------------------------------- Function: grGetProcAddress Date: 05-Jan-97 Implementor(s): atai, jdt Description: Return a pointer to a glide extension function. Note: all functions are typed __stdcall. There is an inconsistency here in that the GetProcAddr() names for all glide functions are decorated for __stdcall, yet there are not. This function must work outside of grSstWinOpen/Close. Arguments: Return: -------------------------------------------------------------------*/ typedef struct { const char *name; GrProc proc; } GrExtensionTuple; static GrExtensionTuple _extensionTable[] = { { "grGetRegistryOrEnvironmentStringExt", (GrProc)grGetRegistryOrEnvironmentString }, { "grGetGammaTableExt", (GrProc)grGetGammaTable }, { "grChromaRangeModeExt", (GrProc)grChromaRangeMode }, { "grChromaRangeExt", (GrProc)grChromaRange }, { "grTexChromaModeExt", (GrProc)grTexChromaMode }, { "grTexChromaRangeExt",(GrProc)grTexChromaRange }, /* tbext */ { "grTextureBufferExt",(GrProc)grTextureBuffer }, { "grTextureAuxBufferExt",(GrProc)grTextureAuxBuffer }, { "grAuxBufferExt",(GrProc)grAuxBuffer }, #if (GLIDE_PLATFORM & (GLIDE_OS_WIN32|GLIDE_OS_MACOS)) { "grSurfaceCreateContextExt", (GrProc)grSurfaceCreateContext }, { "grSurfaceReleaseContextExt", (GrProc)grSurfaceReleaseContext }, { "grSurfaceSetRenderingSurfaceExt", (GrProc)grSurfaceSetRenderingSurface }, { "grSurfaceCalcTextureWHDExt", (GrProc)grSurfaceCalcTextureWHD }, { "grSurfaceSetAuxSurfaceExt", (GrProc)grSurfaceSetAuxSurface }, { "grSurfaceSetTextureSurfaceExt", (GrProc)grSurfaceSetTextureSurface }, { "grDeviceQueryExt", (GrProc)grDeviceQuery }, #endif /* (GLIDE_PLATFORM & GLIDE_OS_WIN32) */ #if defined( USE_PACKET_FIFO ) { "grCommandTransportInfoExt2", (GrProc)_grCommandTransportInfo }, { "grCommandTransportMakeRoomExt2", (GrProc)_grCommandTransportMakeRoom }, #endif #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) { "grSurfaceCreateExt", (GrProc)grSurfaceCreate }, { "grSurfaceReleaseExt", (GrProc)grSurfaceRelease }, { "grSurfaceGetDescExt", (GrProc)grSurfaceGetDesc }, #endif /* (GLIDE_PLATFORM & GLIDE_OS_MACOS) */ #ifdef FX_GLIDE_NAPALM { "grSstWinOpenExt", (GrProc)grSstWinOpenExt }, { "grStencilFuncExt", (GrProc)grStencilFunc }, { "grStencilMaskExt", (GrProc)grStencilMask }, { "grStencilOpExt", (GrProc)grStencilOp }, { "grLfbConstantStencilExt", (GrProc)grLfbConstantStencil }, { "grBufferClearExt", (GrProc)grBufferClearExt }, { "grColorCombineExt", (GrProc)grColorCombineExt }, { "grAlphaCombineExt", (GrProc)grAlphaCombineExt }, { "grTexColorCombineExt", (GrProc)grTexColorCombineExt }, { "grTexAlphaCombineExt", (GrProc)grTexAlphaCombineExt }, { "grConstantColorValueExt", (GrProc)grConstantColorValueExt }, { "grColorMaskExt", (GrProc)grColorMaskExt }, { "grAlphaBlendFunctionExt", (GrProc)grAlphaBlendFunctionExt }, { "grTBufferWriteMaskExt", (GrProc)grTBufferWriteMaskExt }, #endif /* FX_GLIDE_NAPALM */ /* QUERY */ #ifdef QUERY_EXTENSION_SUPPORTED { "grSstQueryBoards", (GrProc)grSstQueryBoards }, { "grSstQueryHardware", (GrProc)grSstQueryHardware }, #endif /* POINTCAST */ #if GLIDE_POINTCAST_PALETTE { "grTexDownloadTableExt", (GrProc)grTexDownloadTableExt }, { "grTexDownloadTablePartialExt", (GrProc)grTexDownloadTablePartialExt }, { "grTexNCCTableExt", (GrProc)grTexNCCTableExt }, #endif { 0, 0 } }; GR_DIENTRY(grGetProcAddress, GrProc, (char *procName)) { #define FN_NAME "grGetProcAddress" GrExtensionTuple *tuple; GrProc rv; tuple = &_extensionTable[0]; rv = 0; while( tuple->name ) { if ( !strcmp( procName, tuple->name ) ) { rv = tuple->proc; break; } tuple++; } return rv; #undef FN_NAME } /* grGetProcAddress */ /*------------------------------------------------------------------- Function: grQueryResolution Date: 07-May-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grQueryResolutions, FxI32, (const GlideResolution *resTemplate, GlideResolution *output)) { #define FN_NAME "grQueryResolution" #ifdef GLIDE_INIT_HWC FxU32 size = 0; FxU32 min_res = GR_MIN_RESOLUTION, max_res = GR_MAX_RESOLUTION, min_ref = GR_MIN_REFRESH, max_ref = GR_MAX_REFRESH, min_col = GR_MIN_COLOR_BUF, max_col = GR_MAX_COLOR_BUF, min_aux = GR_MIN_AUX_BUF, max_aux = GR_MAX_AUX_BUF; FxU32 i, j, k, l; extern ResEntry _resTable[]; GR_DCL_GC; FxU32 /* 0x10000 is the minimum interesting FIFO size */ fbmem = (gc->bInfo->h3Mem << 20) - gc->bInfo->min_tramSize - 0x10000; static char *resNames[] = { "GR_RESOLUTION_320x200", "GR_RESOLUTION_320x240", "GR_RESOLUTION_400x256", "GR_RESOLUTION_512x384", "GR_RESOLUTION_640x200", "GR_RESOLUTION_640x350", "GR_RESOLUTION_640x400", "GR_RESOLUTION_640x480", "GR_RESOLUTION_800x600", "GR_RESOLUTION_960x720", "GR_RESOLUTION_856x480", "GR_RESOLUTION_512x256", "GR_RESOLUTION_1024x768", "GR_RESOLUTION_1280x1024", "GR_RESOLUTION_1600x1200", "GR_RESOLUTION_400x300", "GR_RESOLUTION_1152x864", "GR_RESOLUTION_1280x960", "GR_RESOLUTION_1600x1024", "GR_RESOLUTION_1792x1344", "GR_RESOLUTION_1856x1392", "GR_RESOLUTION_1920x1440", "GR_RESOLUTION_2048x1536", "GR_RESOLUTION_2048x2048" }; GDBG_INFO(80, FN_NAME"(0x%x, 0x%x)\n", resTemplate, output); if (resTemplate->resolution != GR_QUERY_ANY) { if ((resTemplate->resolution >= GR_MIN_RESOLUTION) && (resTemplate->resolution <= GR_MAX_RESOLUTION)) { min_res = resTemplate->resolution; max_res = resTemplate->resolution; } else { goto __errExit; } } if (resTemplate->refresh != GR_QUERY_ANY) { if ((resTemplate->refresh >= GR_MIN_REFRESH) && (resTemplate->refresh <= GR_MAX_REFRESH)) { min_ref = resTemplate->refresh; max_ref = resTemplate->refresh; } else if (resTemplate->refresh != GR_REFRESH_NONE) { goto __errExit; } } if (resTemplate->numColorBuffers != GR_QUERY_ANY) { if ((resTemplate->numColorBuffers >= GR_MIN_COLOR_BUF) && (resTemplate->numColorBuffers <= GR_MAX_COLOR_BUF)) { min_col = resTemplate->numColorBuffers; max_col = resTemplate->numColorBuffers; } else { goto __errExit; } } if (resTemplate->numAuxBuffers != GR_QUERY_ANY) { if ((resTemplate->numAuxBuffers >= GR_MIN_AUX_BUF) && (resTemplate->numAuxBuffers <= GR_MAX_AUX_BUF)) { min_aux = resTemplate->numAuxBuffers; max_aux = resTemplate->numAuxBuffers; } else { goto __errExit; } } for (i = min_res; i <= max_res; i++) { GDBG_INFO(80, FN_NAME "Resolution = %s\n", resNames[i]); for (j = min_ref; j <= max_ref; j++) { FxBool resSuported; GDBG_INFO(80, FN_NAME ": _grResolutionRefresh passed\n"); resSuported = hwcResolutionSupported(gc->bInfo, i, j); GDBG_INFO(80, FN_NAME ": hwcResolutionSupported returned %s\n", resSuported ? "FXTRUE" : "FXFALSE"); if (resSuported) { GDBG_INFO(80, FN_NAME ": hwcResolutionSupported passed\n"); for (k = min_col; k <= max_col; k++) { for (l = min_aux; l <= max_aux; l++) { if ( /* NB: This calculation does not account for the tile restrictions or the padding, but the amount of memory configurations hide this, so we get away with it. */ (_resTable[i].xres * _resTable[i].yres * 2 * (k + l)) < fbmem) { GDBG_INFO(80, FN_NAME ": Sufficient memory\n"); size += 16; if (output != NULL) { output->resolution = i; output->refresh = j; output->numColorBuffers = k; output->numAuxBuffers = l; output++; } } } } } } } __errExit: return size; #else /* GLIDE_INIT_HWC */ FxU32 size = 16*4; if (output != NULL) { output->resolution = GR_RESOLUTION_640x480; output->refresh = GR_REFRESH_60Hz; output->numColorBuffers = 2; output->numAuxBuffers = 1; output++; output->resolution = GR_RESOLUTION_640x480; output->refresh = GR_REFRESH_60Hz; output->numColorBuffers = 2; output->numAuxBuffers = 0; output++; output->resolution = GR_RESOLUTION_640x480; output->refresh = GR_REFRESH_60Hz; output->numColorBuffers = 1; output->numAuxBuffers = 1; output++; output->resolution = GR_RESOLUTION_640x480; output->refresh = GR_REFRESH_60Hz; output->numColorBuffers = 1; output->numAuxBuffers = 0; } return size; #endif #undef FN_NAME } /* grQueryResolution */ #endif /* GLIDE3 */ glide3x/h5/glide3/src/diglide.c0100700000175300010010000003034007725034667015545 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/diglide.c,v 1.3.4.6 2003/07/24 03:51:07 anholt Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 11 3/02/99 2:02p Peter ** cleaned up implicit select for grGlideinit ** ** 10 2/18/99 3:39p Kcd ** Made grGetState definition match prototype. ** ** 9 8/29/98 2:28p Peter ** tls allocation if hw exists ** ** 8 8/03/98 6:37a Jdt ** multi-thread changes ** ** 7 7/16/98 8:14a Jdt ** fxcmd.h ** ** 6 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 4 4/22/98 4:57p Peter ** glide2x merge ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 2 1/19/98 8:00p Atai ** validate state in grGlideGetState() * * 1 1/16/98 4:29p Atai * create glide 3 src * * 33 1/07/98 10:22a Peter * lod dithering env var * * 32 1/06/98 3:53p Atai * remove grHint, modify grLfbWriteRegion and grGet * * 31 12/17/97 4:05p Atai * added grChromaRange(), grGammaCorrecionRGB(), grRest(), and grGet() * functions * * 30 12/09/97 12:20p Peter * mac glide port * * 29 12/01/97 5:46p Peter * fixed variable names in swizzle * * 28 12/01/97 5:17p Peter * h3 simulator happiness * * 27 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 26 11/14/97 5:02p Peter * more comdex stuff * * 25 11/14/97 12:09a Peter * comdex thing and some other stuff * * 24 11/12/97 2:27p Peter * simulator happiness w/o fifo * * 23 11/12/97 11:39a Dow * H3 Stuff * * 22 11/12/97 9:21a Dow * Changed CVG_FIFO to USE_PACKET_FIFO * * 21 11/04/97 4:00p Dow * Banshee Mods * * 20 11/03/97 3:43p Peter * h3/cvg cataclysm * * 19 10/16/97 3:40p Peter * packed rgb * * 18 9/20/97 10:53a Peter * keep track of palette stats * * 17 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 16 9/10/97 10:13p Peter * fifo logic from GaryT, non-normalized fp first cut * * 15 7/25/97 11:40a Peter * removed dHalf, change field name to match real use for cvg * * 14 7/08/97 2:48p Peter * started playing w/ h3 sim * * 13 6/30/97 3:20p Peter * error callback * * 12 6/23/97 4:43p Peter * cleaned up #defines etc for a nicer tree * ** */ #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #include "rcver.h" static char glideIdent[] = "@#%" VERSIONSTR ; /* the root of all EVIL */ struct _GlideRoot_s GR_CDECL _GlideRoot; /* This is global to speed up the function call wrappers */ /*--------------------------------------------------------------------------- ** */ void _grDisplayStats(void) { GR_DCL_GC; if (gc != NULL) { int frames = gc->stats.bufferSwaps; if (frames <= 0) frames = 1; gdbg_info(80,"GLIDE STATISTICS:\n"); gdbg_info(80," triangles processed: %7d tris drawn: %7d\n", gc->stats.trisProcessed, gc->stats.trisDrawn); gdbg_info(80," buffer swaps: %7d tris/frame: %7d , %d\n", gc->stats.bufferSwaps, gc->stats.trisProcessed/frames, gc->stats.trisDrawn/frames); gdbg_info(80," points: %7d pnts/frame: %7d\n", gc->stats.pointsDrawn, gc->stats.pointsDrawn/frames); gdbg_info(80," lines: %7d lines/frame: %7d\n", gc->stats.linesDrawn, gc->stats.linesDrawn/frames); gdbg_info(80," texture downloads: %7d texture bytes: %7d\n", gc->stats.texDownloads, gc->stats.texBytes); gdbg_info(80," palette downloads: %7d palette bytes: %7d\n", gc->stats.palDownloads, gc->stats.palBytes); gdbg_info(80," NCC downloads: %7d NCC bytes: %7d\n", gc->stats.nccDownloads, gc->stats.nccBytes); #if USE_PACKET_FIFO gdbg_info(80,"\tCommandFifo:\n"); gdbg_info(80,"\t\tWraps: %ld\n", gc->stats.fifoWraps); if (gc->stats.fifoWraps > 0) { gdbg_info(80,"\t\tAvg Drain Depth: %g\n", (double)gc->stats.fifoWrapDepth / gc->stats.fifoWraps); } gdbg_info(80,"\t\tStalls: %ld\n", gc->stats.fifoStalls); if (gc->stats.fifoStalls > 0) { gdbg_info(80,"\t\tAvg Stall Depth: %g\n", (double)gc->stats.fifoStallDepth / gc->stats.fifoStalls); } #endif /* USE_PACKET_FIFO */ } } #if !USE_PACKET_FIFO /* ** fifoFree is kept in bytes, each fifo entry is 8 bytes, but since there ** are headers involved, we assume an average of 2 registers per 8 bytes ** or 4 bytes of registers stored in every fifo entry */ void _grReCacheFifo(FxI32 n) { #if !(GLIDE_PLATFORM & GLIDE_HW_H3) GR_DCL_GC; gc->state.fifoFree = ((grSstStatus() >> SST_MEMFIFOLEVEL_SHIFT) & 0xffff)<<2; #if 0 gc->state.fifoFree -= gc->hwDep.sst1Dep.swFifoLWM + n; #endif #endif } FxI32 GR_CDECL _grSpinFifo(FxI32 n) { GR_DCL_GC; do { _grReCacheFifo(n); } while (gc->state.fifoFree < 0); return gc->state.fifoFree; } #endif /* !USE_PACKET_FIFO */ /*--------------------------------------------------------------------------- ** */ void _grSwizzleColor(GrColor_t *color) { GR_DCL_GC; FxU32 red, green, blue, alpha; switch(gc->state.color_format) { case GR_COLORFORMAT_ARGB: break; case GR_COLORFORMAT_ABGR: red = *color & 0x00ff; blue = (*color >> 16) & 0xff; *color &= 0xff00ff00; *color |= ((red << 16) | blue); break; case GR_COLORFORMAT_RGBA: blue = (*color & 0x0000ff00) >> 8; green = (*color & 0x00ff0000) >> 16; red = (*color & 0xff000000) >> 24; alpha = (*color & 0x000000ff); *color = (alpha << 24) | (red << 16) | (green << 8) | blue; break; case GR_COLORFORMAT_BGRA: blue = (*color & 0xff000000) >> 24; green = (*color & 0x00ff0000) >> 16; red = (*color & 0x0000ff00) >> 8; alpha = (*color & 0x000000ff); *color = (alpha << 24) | (red << 16) | (green << 8) | blue; break; default: GR_ASSERT(0); break; } } /* _grSwizzleColor */ /*--------------------------------------------------------------------------- ** grGlideGetVersion ** NOTE: allow this to be called before grGlideInit() */ GR_DIENTRY(grGlideGetVersion, void, (char version[80])) { GDBG_INFO(87,"grGlideGetVersion(0x%x) => \"%s\"\n",version,glideIdent+3); GR_ASSERT(version != NULL); strcpy(version,glideIdent+3); } /* grGlideGetVersion */ /*--------------------------------------------------------------------------- ** grGlideGetState */ GR_DIENTRY(grGlideGetState, void, (void *state)) { GR_BEGIN_NOFIFOCHECK("grGlideGetState",87); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",state); GR_ASSERT(state != NULL); /* GR_ASSERT(sizeof(struct _GrState_s) == GLIDE_STATE_PAD_SIZE); */ #if defined(GLIDE3) && defined(GLIDE3_ALPHA) _grValidateState(); #endif *((GrState *)state) = gc->state; GR_END(); } /* grGlideGetState */ #ifndef GLIDE3_ALPHA /*--------------------------------------------------------------------------- ** grHints */ GR_DIENTRY(grHints, void, (GrHint_t hintType, FxU32 hints)) { GR_BEGIN_NOFIFOCHECK("grHints",85); GDBG_INFO_MORE(gc->myLevel,"(%d,0x%x)\n",hintType,hints); switch (hintType) { case GR_HINT_STWHINT: if (gc->state.paramHints != hints) { gc->state.paramHints = hints; _grUpdateParamIndex(); } break; case GR_HINT_FIFOCHECKHINT: /* swFifoLWM is kept internally in bytes, hints are in fifo entries */ gc->state.checkFifo = hints; break; case GR_HINT_FPUPRECISION: hints ? double_precision_asm() : single_precision_asm(); break; case GR_HINT_ALLOW_MIPMAP_DITHER: /* Regardless of the game hint, force the user selection */ gc->state.allowLODdither = ((_GlideRoot.environment.texLodDither != 0) || hints); break; default: GR_CHECK_F(myName, 1, "invalid hints type"); } GR_END(); } /* grHints */ #endif /*--------------------------------------------------------------------------- ** grGlideInit */ GR_DIENTRY(grGlideInit, void, (void)) { GDBG_INIT(); GDBG_INFO(80,"grGlideInit()\n"); /* dBorca - play safe */ grErrorSetCallback(_grErrorDefaultCallback); /* KoolSmoky - let's detect glide devices *before* GETENV is called ** need to know where the devices are first if we want multimonitor ** capabilities. */ if ( !_grSstDetectResources() ) { /* Hack alert: * dBorca - Linux/DRI failed the above call, so bypass the next one */ #ifndef DRI_BUILD #ifdef GLIDE_INIT_HWC GrErrorCallback( hwcGetErrorString(), FXTRUE ); #endif #endif } /* KoolSmoky - if we have multiple sst devices, they will all use the * same environment values. Win32 will use device 0's registry. */ _GlideInitEnvironment(0); /* the main init code */ FXUNUSED(*glideIdent); #if GDBG_INFO_ON GDBG_ERROR_SET_CALLBACK(_grErrorCallback); #endif if (_GlideRoot.initialized) { initThreadStorage(); initCriticalSection(); /* NB: We need to select the default device here so that grGetXXX * routines work before grSstWinOpen or the surface attachment * routines are called. */ grSstSelect(0); } _grResetTriStats(); GDBG_INFO(281,"grGlideInit --done---------------------------------------\n"); } /* grGlideInit */ /*--------------------------------------------------------------------------- ** grGlideShamelessPlug - grGlideShamelessPlug ** ** Returns: ** ** Notes: ** */ #ifndef GLIDE3_ALPHA GR_DIENTRY(grGlideShamelessPlug, void, (const FxBool mode)) { GDBG_INFO(80,"grGlideShamelessPlug(%d)\n",mode); _GlideRoot.environment.shamelessPlug = mode; } /* grGlideShamelessPlug */ #endif /*--------------------------------------------------------------------------- ** grResetTriStats - Set triangle counters to zero. */ #if defined(GLIDE3) && defined(GLIDE3_ALPHA) void FX_CSTYLE _grResetTriStats(void) #else GR_DIENTRY(grResetTriStats, void, (void)) #endif { GR_DCL_GC; GDBG_INFO(80,"grResetTriStats()\n"); gc->stats.bufferSwaps = 0; gc->stats.linesDrawn = 0; gc->stats.trisProcessed = 0; gc->stats.trisDrawn = 0; gc->stats.texDownloads = 0; gc->stats.texBytes = 0; gc->stats.palDownloads = 0; gc->stats.palBytes = 0; } /* grResetTriStats */ /*--------------------------------------------------------------------------- ** grResetTriStats - Set triangle counters to zero. */ GR_DIENTRY(grTriStats, void, (FxU32 *trisProcessed, FxU32 *trisDrawn)) { GR_DCL_GC; GDBG_INFO(80,"grTriStats() => %d %d\n", gc->stats.trisProcessed, gc->stats.trisDrawn); *trisProcessed = gc->stats.trisProcessed; *trisDrawn = gc->stats.trisDrawn; } /* grTriStats */ void GR_CDECL _grFence(void) { GDBG_INFO(120,"\t\t\t\t\t\t\tFENCE\n"); P6FENCE; } glide3x/h5/glide3/src/disst.c0100700000175300010010000001453607725034667015303 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/disst.c,v 1.3.4.4 2003/07/07 23:29:04 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 10 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 9 3/01/99 3:12p Peter ** grSstSelect cannot call gr_dcl_gc because it may be setting a valid ** context in tls ** ** 8 7/04/98 5:06p Jdt ** ** 7 8/03/98 6:37a Jdt ** multi-thread changes ** ** 6 7/16/98 8:14a Jdt ** fxcmd.h ** ** 5 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 3 4/22/98 4:57p Peter ** glide2x merge ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 18 12/17/97 4:05p Atai * added grChromaRange(), grGammaCorrecionRGB(), grRest(), and grGet() * functions * * 17 12/09/97 12:20p Peter * mac glide port * * 16 11/19/97 2:49p Peter * env vars in registry for win32 * * 15 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 14 10/31/97 9:15a Peter * only lie about v2 boards * * 13 10/31/97 8:53a Peter * last lying change, really * * 12 9/05/97 5:29p Peter * changes for direct hw * * 11 6/20/97 9:56a Peter * better lines/pts, hopefully * * 10 6/02/97 4:09p Peter * Compile w/ gcc for Dural * * 9 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 8 5/21/97 6:04a Peter * * 7 5/02/97 2:07p Pgj * grSstScreenWidth/Height now FxU32 * * 6 3/17/97 6:25a Jdt * Added initDeviceSelect to grSstSelect() * * 5 3/09/97 10:31a Dow * Added GR_DIENTRY for di glide functions * * 4 3/04/97 9:08p Dow * Neutered multiplatform multiheaded monster * * 3 1/18/97 11:39p Dow * Changed location of _curGCFuncs * * 2 1/16/97 3:39p Dow * Added ref to _curGCFuncs during grSstSelect() * * 1 12/23/96 1:39p Dow * Changes for multiplatform ** */ #include #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" /*--------------------------------------------------------------------------- ** grSstQueryBoards ** ** NOTE: it is OK to call this routine before grGlideInit */ #ifndef GLIDE3_ALPHA GR_DIENTRY(grSstQueryBoards, FxBool, ( GrHwConfiguration *hwc )) { GDBG_INIT(); GDBG_INFO(80,"grSstQueryBoards(0x%x)\n",hwc); #if GLIDE_INIT_HAL hwc->num_sst = (_grSstDetectResources() ? _GlideRoot.hwConfig.num_sst : 0); #else /* !GLIDE_INIT_HAL */ hwc->num_sst = 1; #endif /* !GLIDE_INIT_HAL */ return FXTRUE; } /* grSstQueryBoards */ #endif /*--------------------------------------------------------------------------- ** grSstQueryHardware ** */ GR_DIENTRY(grSstQueryHardware, FxBool, ( GrHwConfiguration *hwc )) { FxBool retVal; GR_BEGIN_NOFIFOCHECK_RET("grSstQueryHardware",80); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",hwc); /* init and copy the data back to the user's structure */ retVal = _GlideRoot.hwConfig.num_sst > 0; *hwc = _GlideRoot.hwConfig; GR_RETURN(retVal); } /* grSstQueryHardware */ /*--------------------------------------------------------------------------- ** grSstSelect */ GR_DIENTRY(grSstSelect, void, ( int which )) { /* NB: We cannot use GR_DCL_GC here because we may be setting * a context into tls. */ GDBG_INFO(80, "grSstSelect(0x%X)\n", which); if ( which >= _GlideRoot.hwConfig.num_sst ) GrErrorCallback( "grSstSelect: non-existent SST", FXTRUE ); _GlideRoot.current_sst = which; setThreadValue( (FxU32)&_GlideRoot.GCs[_GlideRoot.current_sst] ); #ifdef GLIDE_MULTIPLATFORM _GlideRoot.curGCFuncs = _GlideRoot.curGC->gcFuncs; #endif } /* grSstSelect */ /*--------------------------------------------------------------------------- ** grSstScreenWidth */ GR_DIENTRY(grSstScreenWidth, int, (void)) { GR_DCL_GC; GR_ASSERT(gc != NULL); return gc->state.screen_width; } /* grSstScreenWidth */ /*--------------------------------------------------------------------------- ** grSstScreenHeight */ GR_DIENTRY(grSstScreenHeight, int, (void)) { GR_DCL_GC; GR_ASSERT(gc != NULL); return gc->state.screen_height; } /*--------------------------------------------------------------------------- ** grSstVidMode - override args to grSstOpen() */ GR_DIENTRY(grSstVidMode, void, (FxU32 whichSst, FxVideoTimingInfo* vidTimings)) { GDBG_INFO(80,"grSstVidMode(%d,0x%x)\n",whichSst,vidTimings); #ifdef GLIDE_DEBUG if (whichSst >= MAX_NUM_SST) { char errStr[1028]; sprintf(errStr, "grSstVidMode: %ld greater than MAX_NUM_SST (%d)\n", whichSst, MAX_NUM_SST); GrErrorCallback(errStr, FXTRUE); } #endif _GlideRoot.GCs[whichSst].vidTimings = vidTimings; } /* grSstVidMode */ glide3x/h5/glide3/src/distate.c0100700000175300010010000030175407725034667015613 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/distate.c,v 1.4.4.7 2003/08/26 15:41:34 koolsmoky Exp $ ** $Log: ** 33 3dfx 1.25.1.2.1.311/14/00 Jonny Cochrane Implement multisample LOD ** Dithering for 2x and 4x FSAA modes ** 32 3dfx 1.25.1.2.1.210/11/00 Brent Forced check in to enforce ** branching. ** 31 3dfx 1.25.1.2.1.109/26/00 Andy Hanson Add environment variable of ** glide group so they can do wacky things safely. ** 30 3dfx 1.25.1.2.1.009/19/00 Matt McClure Added a call to win_mode.c ** to enable OpenGL. ** 29 3dfx 1.25.1.2 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 28 3dfx 1.25.1.1 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 27 3dfx 1.25.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 26 3dfx 1.25 04/25/00 Kenneth Dyke Fixed non-compressed -> ** compressed texture chip bug workaround code. ** 25 3dfx 1.24 04/24/00 Kenneth Dyke Make sure we don't modify ** the stencil buffer when stencil mode is disabled. ** 24 3dfx 1.23 04/13/00 Kenneth Dyke Added support for new style ** 2-sample AA mode. ** 23 3dfx 1.22 03/30/00 Kenneth Dyke Added private grEnable() ** for OpenGL. ** 22 3dfx 1.21 03/23/00 Kenneth Dyke Keep state maintained ** across all chips. ** 21 3dfx 1.20 03/19/00 Kenneth Dyke Keep track of which TMU ** 'owns' the real TMU register state when in 2ppc mode. ** 20 3dfx 1.19 03/07/00 Kenneth Dyke Workaround for weird ** compressed texture quirk. ** 19 3dfx 1.18 02/28/00 Kenneth Dyke Fixed dither rotation stuff ** for 4-sample AA. We also no longer clobber the fog mode setting. ** ** 18 3dfx 1.17 02/22/00 Kenneth Dyke Disable 2PPC modes when ** palettized textures are in use until I find a way to make it fast. ** 17 3dfx 1.16 02/02/00 Kenneth Dyke Fixed per-TMU constant ** color values to not interfere with texture chroma keying. ** 16 3dfx 1.15 02/02/00 Kenneth Dyke Fixed triangle parameter ** problems related to 2PPC mode. ** 15 3dfx 1.14 02/02/00 Adam Briggs they say that if two people ** with braces kiss their braces can get stuck together ** 14 3dfx 1.13 02/01/00 Kenneth Dyke Added code to detect when ** TMU0 is in passthrough mode and to enabled 2PPC in that case. (Remap TMU1 ** to TMU0). ** 13 3dfx 1.12 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 12 3dfx 1.11 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 11 3dfx 1.10 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 10 3dfx 1.9 01/23/00 Adam Briggs set & recognize the SSTTYPE ** var for Voodoo4 ** 9 3dfx 1.8 01/18/00 Kenneth Dyke Pull AA jitter values from ** Glide environment. ** 8 3dfx 1.7 01/16/00 Kenneth Dyke Changes to enforce proper ** combine extension usage. ** 7 3dfx 1.6 10/25/99 Anthony tai mask off alpha stuff for ** combineMode ** 6 3dfx 1.5 10/25/99 Anthony tai only clean up the ** un-necessary ** 5 3dfx 1.4 10/22/99 Anthony tai clean up combineMode ** register if ext is not used ** 4 3dfx 1.3 10/21/99 Anthony tai fixed iterated rgb checking ** 3 3dfx 1.2 10/15/99 Anthony tai move 2ppc setting to state ** validation ** 2 3dfx 1.1 09/17/99 Adam Briggs Supported TEXTUREBUFFEREXT ** for Napalm 32bpp and AA modes. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 57 8/16/99 11:18a Adamb ** Merged in V3_OEM_100 fixes ** ** 56 7/27/99 2:23p Larryw ** Allow UMA to do its thing. ** ** 55 7/22/99 1:18p Atai ** added grTBufferMaskExt ** ** 54 7/21/99 4:06p Atai ** direct write hack and GR_AA_MULTI_SAMPLE ** ** 53 7/18/99 1:59p Atai ** added grAlphaBlendFunctionExt ** ** 52 7/14/99 5:07p Atai ** fixed stencil interface and some cc/ac stuff ** ** 51 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 50 7/12/99 4:01p Atai ** fixed warnings ** ** 49 7/08/99 8:48p Atai ** stencil interface update ** ** 48 7/06/99 2:45p Atai ** added gbc and 32 bpp color mask ** ** 47 6/29/99 7:19p Atai ** remove argument for enabling SST_CM_USE_COMBINE_MODE ** ** 45 6/27/99 12:44p Atai ** fixed CC and TCC ** ** 44 6/24/99 7:12p Atai ** added STENCIL and COMBINE extension ** ** 43 6/13/99 4:55p Atai ** fixed register mask ** ** 41 6/10/99 5:12p Atai ** fist pass CC and AC ext ** ** 40 6/09/99 2:35p Atai ** added combine mode bit and args defines ** ** 39 6/04/99 3:18p Atai ** stencilMode and stencilOp ** ** 38 6/04/99 11:00a Atai ** added stencil functions ** ** 37 5/28/99 10:19a Atai ** the triproc setup should use the invalid flavor ** ** 36 5/26/99 4:43p Kcd ** byte and word swap bits were reversed. ** ** 35 5/19/99 3:55p Denis ** ** 34 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a "tbext" comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 33 4/10/99 1:23p Atai ** fixed code to compile in packet fifo mode ** ** 32 4/07/99 7:18p Atai ** added uma extension ** ** 31 3/24/99 6:17p Peter ** streamlined (made more dangerouse) state validation ** ** 30 3/22/99 5:37p Peter ** added avenger to grChroma supported list ** ** 29 3/19/99 12:21p Atai ** update triproc ** ** 28 3/05/99 10:31p Peter ** coalesced texture state change nop into validate state ** ** 27 3/02/99 2:03p Peter ** removed no_check variant that led me astray ** ** 26 1/25/99 6:31p Peter ** removed overly restrictive assertion for depth buffer function vs mask ** ** 25 1/15/99 10:52a Peter ** cleanup lazy evaluation of fbzMode for grDepthMask and grColorMask ** ** 24 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 23 11/17/98 4:27p Atai ** fixed gc->triSetupProc for clip coords grDrawTriangle ** ** 22 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 21 9/08/98 7:19p Atai ** fix debug info. added underline for internal routines and some \n ** ** 20 8/30/98 10:55p Jdt ** remove invalidate macro ( promoted to fxglide.h ) ** ** 19 8/30/98 1:34p Dow ** State & other optimizations ** ** 18 7/18/98 12:23a Jdt ** Changes to reflect new shadow register structure. ** ** 17 7/16/98 8:15a Jdt ** fxcmd.h ** ** 16 7/13/98 10:43p Jdt ** Removed grSstControl()... ** ** ** 15 7/02/98 1:54p Atai ** grDepthBiasLevel argument is FxI32 ** ** 14 6/21/98 11:56a Atai ** fixed fogcoord paramindex ** ** 13 6/19/98 12:59p Atai ** fixed grDepthBiasLevel ** ** 12 6/11/98 6:04p Atai ** added aa case for OGL ** ** 11 6/10/98 12:53p Atai ** replace grSstControl with grEnable/grDisable(GR_PASSTHRU) ** ** 10 6/03/98 2:43p Atai ** fixed chromarange ** ** 9 5/29/98 6:39p Atai ** fix chromarange ** ** 8 5/05/98 2:22p Peter ** banshee is really banshee ** ** 7 4/30/98 10:34a Peter ** merged w/ cvg again ** ** 7 4/24/98 2:21p Atai ** call _grUpdateParamIndex() if the state is dirty ** ** 6 4/23/98 7:33p Atai ** grValidateState: send register in a group ** ** 5 2/24/98 6:01p Atai ** modify validatestate ** ** 4 1/30/98 1:19p Atai ** fixed chromarange ** ** 3 1/28/98 2:26p Atai ** fix grDisable GR_SHAMELESS_PLUG ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 17 1/13/98 12:42p Atai * fixed grtexinfo, grVertexLayout, and draw triangle * * 16 1/10/98 4:01p Atai * inititialize vertex layout, viewport, added defines * * 15 1/05/98 6:06p Atai * glide extension stuff * * 14 12/17/97 4:05p Atai * added grChromaRange(), grGammaCorrecionRGB(), grRest(), and grGet() * functions * * 13 12/16/97 11:38a Atai * added grChromaRange() * * 12 12/15/97 5:52p Atai * disable obsolete glide2 api for glide3 * * 10 12/12/97 1:30p Atai * remove fp z buffer * * 8 12/08/97 10:44a Atai * added entry point for grCoordinateSpace(), grDepthRange(), and * grViewport() * * 7 11/13/97 4:38p Atai * invalidate lfbMode and c0c1 * * 6 11/10/97 5:20p Atai * added factor for grAlphaCombine and remove extra _grChromakeyMode * * 5 11/07/97 11:22a Atai * remove GR_*_SMOOTH. use GR_SMOOTH * * 4 10/15/97 7:33a Dow * Made _grValidateState use central routine for writing data * * 3 10/14/97 4:18p Atai * added grEnable and grDisable * * 2 10/10/97 2:57p Dow * Minor adjustments * * 1 10/09/97 5:19p Dow * State Monster file */ #ifdef GLIDE3 #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" /*============================================================================= ** Replacement state routines. ** ** These routines store away their arguments, and mark a piece of glide state ** as invalid. The next time a rendering primitive is called, the state will ** be invalid, and grValidateState will be called. See that routine for more ** info. **===========================================================================*/ /* Some macros for use in this file only */ #define STOREARG_TMU(function, tmu, arg) \ gc->state.stateArgs.function ## Args.arg[tmu] = arg #define LOADARG_TMU(function, tmu, arg) \ gc->state.stateArgs.function ## Args.arg[tmu] #define STOREARG(function, arg) \ gc->state.stateArgs.function ## Args.arg = arg #define LOADARG(function, arg) \ gc->state.stateArgs.function ## Args.arg #define NOTVALID(regset) \ (gc->state.invalid & regset ## BIT) #define NOTVALID_TMU(tmu, regset) \ (gc->state.tmuInvalid[tmu] & regset ## BIT) #define SETVALID(regset) \ (gc->state.invalid &= ~(regset ## BIT)) #define ENABLEMODE(mode) \ gc->state.grEnableArgs.mode = GR_MODE_ENABLE; #define DISABLEMODE(mode) \ gc->state.grEnableArgs.mode = GR_MODE_DISABLE; /*------------------------------------------------------------------- Function: grAlphaBlendFunction Date: 06-Oct-97 Implementor(s): dow Description: Inform Glide that the Alpha Blend Function has been modified. Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grAlphaBlendFunction, void , (GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df) ) { #define FN_NAME "grAlphaBlendFunction" GR_BEGIN_NOFIFOCHECK("grAlphaBlendFunction\n", 87); /* Invalidate AlphaMode */ INVALIDATE(alphaMode) STOREARG(grAlphaBlendFunction, rgb_sf); STOREARG(grAlphaBlendFunction, rgb_df); STOREARG(grAlphaBlendFunction, alpha_sf); STOREARG(grAlphaBlendFunction, alpha_df); if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { GrAlphaBlendOp_t rgb_op = GR_BLEND_OP_ADD; GrAlphaBlendOp_t alpha_op = GR_BLEND_OP_ADD; INVALIDATE(fogMode); STOREARG(grAlphaBlendFunction, rgb_op); STOREARG(grAlphaBlendFunction, alpha_op); } #undef FN_NAME } /* grAlphaBlendFunction */ /*------------------------------------------------------------------- Function: grAlphaBlendFunctionExt Date: 18-July-99 Implementor(s): atai Description: Inform Glide that the Alpha Blend Function has been modified. Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grAlphaBlendFunctionExt, void , (GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendOp_t rgb_op, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df, GrAlphaBlendOp_t alpha_op) ) { #define FN_NAME "grAlphaBlendFunctionExt" GR_BEGIN_NOFIFOCHECK("grAlphaBlendFunctionExt\n", 87); /* Invalidate AlphaMode */ INVALIDATE(alphaMode); STOREARG(grAlphaBlendFunction, rgb_sf); STOREARG(grAlphaBlendFunction, rgb_df); STOREARG(grAlphaBlendFunction, alpha_sf); STOREARG(grAlphaBlendFunction, alpha_df); INVALIDATE(fogMode); STOREARG(grAlphaBlendFunction, rgb_op); STOREARG(grAlphaBlendFunction, alpha_op); #undef FN_NAME } /* grAlphaBlendFunctionExt */ /*------------------------------------------------------------------- Function: grAlphaTestFunction Date: 06-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grAlphaTestFunction, void , (GrCmpFnc_t fnc) ) { #define FN_NAME "grAlphaTestFunction" GR_BEGIN_NOFIFOCHECK("grAlphaTestFunction\n", 87); /* Invalidate AlphaMode */ INVALIDATE(alphaMode); STOREARG(grAlphaTestFunction, fnc); #undef FN_NAME } /* grAlphaTestFunction */ /*------------------------------------------------------------------- Function: grAlphaTestReferenceValue Date: 06-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grAlphaTestReferenceValue, void , (GrAlpha_t value) ) { #define FN_NAME "grAlphaTestReferenceValue" GR_BEGIN_NOFIFOCHECK("grAlphaTestReferenceValue\n", 87); INVALIDATE(alphaMode); STOREARG(grAlphaTestReferenceValue,value); #undef FN_NAME } /* grAlphaTestReferenceValue */ /*------------------------------------------------------------------- Function: grAlphaCombine Date: 06-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grAlphaCombine, void , (GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert) ) { #define FN_NAME "grAlphaCombine" GR_BEGIN_NOFIFOCHECK("grAlphaCombine\n", 85); INVALIDATE(fbzColorPath); INVALIDATE(tmuConfig); #if DEBUG_2PPC GDBG_PRINTF("grAlphaCombine(func=%x, factor=%x, local=%x, other=%x, invert=%d)\n", function,factor,local,other,invert); #endif gc->state.combineExtsInUse &= ~STATE_USING_CA; grDisable(GR_COMBINEEXT_MODE); STOREARG(grAlphaCombine, function); STOREARG(grAlphaCombine, factor); STOREARG(grAlphaCombine, local); STOREARG(grAlphaCombine, other); STOREARG(grAlphaCombine, invert); #undef FN_NAME } /* grAlphaCombine */ /*------------------------------------------------------------------- Function: grAlphaControlsITRGBLighting Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grAlphaControlsITRGBLighting, void , (FxBool enable) ) { #define FN_NAME "grAlphaControlsITRGBLighting" GR_BEGIN_NOFIFOCHECK("grAlphaControlsITRGBLighting\n",85); INVALIDATE(fbzColorPath); STOREARG(grAlphaControlsITRGBLighting, enable); #undef FN_NAME } /* grAlphaControlsITRGBLighting */ /*------------------------------------------------------------------- Function: grColorCombine Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grColorCombine, void , (GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert) ) { #define FN_NAME "grColorCombine" GR_BEGIN_NOFIFOCHECK("grColorCombine\n",85); INVALIDATE(fbzColorPath); INVALIDATE(tmuConfig); #if DEBUG_2PPC GDBG_PRINTF("grColorCombine(func=%x, factor=%x, local=%x, other=%x, invert=%d)\n", function,factor,local,other,invert); #endif gc->state.combineExtsInUse &= ~STATE_USING_CC; grDisable(GR_COMBINEEXT_MODE); STOREARG(grColorCombine, function); STOREARG(grColorCombine, factor); STOREARG(grColorCombine, local); STOREARG(grColorCombine, other); STOREARG(grColorCombine, invert); #undef FN_NAME } /* grColorCombine */ /*------------------------------------------------------------------- Function: grChromakeyMode Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grChromakeyMode, void , (GrChromakeyMode_t mode) ) { #define FN_NAME "grChromakeyMode" GR_BEGIN_NOFIFOCHECK("grChromakeyMode\n",85); INVALIDATE(fbzMode); STOREARG(grChromakeyMode, mode); #undef FN_NAME } /* grChromakeyMode */ /*------------------------------------------------------------------- Function: grChromaRangeMode Date: 05-Jan-98 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grChromaRangeMode, void , (GrChromakeyMode_t mode) ) { #define FN_NAME "grChromaRangeMode" GR_BEGIN_NOFIFOCHECK("grChromaRangeMode\n",85); /* ** We need to enable both fbzMode chromakeymode and chrmarange mdoe */ INVALIDATE(fbzMode); INVALIDATE(chromaRange); STOREARG(grChromaRange, mode); #undef FN_NAME } /* grChromaRangeMode */ /*------------------------------------------------------------------- Function: grChromaRange Date: 15-Dec-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grChromaRange, void , (GrColor_t color, GrColor_t range, GrChromaRangeMode_t match_mode) ) { #define FN_NAME "grChromaRange" GR_BEGIN_NOFIFOCHECK("grChromaRange\n",85); GR_CHECK_F(myName, ((_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo2) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Banshee) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo3) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo4)), "grChromaRange not supported."); INVALIDATE(chromaKey); INVALIDATE(chromaRange); STOREARG(grChromakeyValue, color); STOREARG(grChromaRange, range); STOREARG(grChromaRange, match_mode); #undef FN_NAME } /* grChromaRange */ /*------------------------------------------------------------------- Function: grChromakeyValue Date: 09-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_ENTRY(grChromakeyValue, void , (GrColor_t color) ) { #define FN_NAME "grChromakeyValue" GR_BEGIN_NOFIFOCHECK("grChromakeyMode\n",85); INVALIDATE(chromaKey); STOREARG(grChromakeyValue, color); #undef FN_NAME } /* grChromakeyValue */ /*------------------------------------------------------------------- Function: grDeptMask Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDepthMask, void , (FxBool enable) ) { #define FN_NAME "grDepthMask" GR_BEGIN_NOFIFOCHECK("grDepthMask\n", 85); INVALIDATE(fbzMode); STOREARG(grDepthMask, enable); #undef FN_NAME } /* grDeptMask */ /*------------------------------------------------------------------- Function: grDepthBufferFunction Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDepthBufferFunction, void , (GrCmpFnc_t fnc) ) { #define FN_NAME "grDepthBufferFunction" GR_BEGIN_NOFIFOCHECK("grDepthBufferFunction\n", 85); INVALIDATE(fbzMode); STOREARG(grDepthBufferFunction, fnc); #undef FN_NAME } /* grDepthBufferFunction */ /*------------------------------------------------------------------- Function: grDepthBufferMode Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDepthBufferMode, void , (GrDepthBufferMode_t mode) ) { #define FN_NAME "grDepthBufferMode" GR_BEGIN_NOFIFOCHECK("grDepthBufferMode\n", 85); INVALIDATE(fbzMode); STOREARG(grDepthBufferMode, mode); #undef FN_NAME } /* grDepthBufferMode */ /*------------------------------------------------------------------- Function: grStencilFunc Date: 03-June-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grStencilFunc, void , (GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask) ) { #define FN_NAME "grStencilFunc" GR_BEGIN_NOFIFOCHECK("grStencilFunc\n", 85); INVALIDATE(stencilMode); STOREARG(grStencilFunc, fnc); STOREARG(grStencilFunc, ref); STOREARG(grStencilFunc, mask); #undef FN_NAME } /* grStencilFunc */ /*------------------------------------------------------------------- Function: grStencilMask Date: 03-June-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grStencilMask, void , (GrStencil_t value) ) { #define FN_NAME "grStencilMask" GR_BEGIN_NOFIFOCHECK("grStencilMask\n", 85); INVALIDATE(stencilMode); STOREARG(grStencilMask, value); #undef FN_NAME } /* grStencilMask */ /*------------------------------------------------------------------- Function: grLfbConstantStencil Date: 03-June-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grLfbConstantStencil, void , (GrStencil_t value) ) { #define FN_NAME "grLfbConstantStencil" GR_BEGIN_NOFIFOCHECK("grLfbConstantStencil\n", 85); INVALIDATE(stencilMode); STOREARG(grLfbConstantStencil, value); #undef FN_NAME } /* grLfbConstantStencil */ /*------------------------------------------------------------------- Function: grStipplePattern Date: 23-Nov-2000 Implementor(s): alanh Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grStipplePattern, void , (GrStipplePattern_t stipple)) { #define FN_NAME "grStipplePattern" GR_BEGIN_NOFIFOCHECK("grStipplePattern\n", 85); INVALIDATE(stipple); STOREARG(grStipplePattern, stipple); #undef FN_NAME } /* grStipplePattern */ /*------------------------------------------------------------------- Function: grStencilOp Date: 03-June-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grStencilOp, void , (GrStencilOp_t stencil_fail, GrStencilOp_t depth_fail, GrStencilOp_t depth_pass) ) { #define FN_NAME "grStencilWriteMask" GR_BEGIN_NOFIFOCHECK("grStencilMode\n", 85); INVALIDATE(stencilOp); STOREARG(grStencilOp, stencil_fail); STOREARG(grStencilOp, depth_fail); STOREARG(grStencilOp, depth_pass); #undef FN_NAME } /* grStencilOp */ #if FX_GLIDE_NAPALM /*------------------------------------------------------------------- Function: grColorCombineExt Date: 08-June-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grColorCombineExt, void , (GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool c_invert, GrCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert) ) { #define FN_NAME "grColorCombineExt" GR_BEGIN_NOFIFOCHECK("grColorCombineExt\n",85); #if DEBUG_2PPC GDBG_PRINTF("grColorCombineExt(a=%x,am=%x,b=%x,bm=%x,c=%x,ci=%d,d=%x,di=%x,s=%d,i=%d)\n", a,a_mode,b,b_mode,c,c_invert,d,d_invert,shift,invert); #endif /* update ** cc_mselect (part of c), cc_add_clocal (part of d), cc_add_alocal (part of d) ** cc_invert_output (invert) */ INVALIDATE(fbzColorPath); /* update ** cc_otherselect (a), cc_localselect (b), cc_mselect_7 (part of c), ** cc_invert_other (a_mode), cc_invert_local (b_mode), cc_outshift (shift) ** bit(31) */ INVALIDATE(combineMode); INVALIDATE(tmuConfig); gc->state.combineExtsInUse |= STATE_USING_CC; grEnable(GR_COMBINEEXT_MODE); STOREARG(grColorCombineExt, a); STOREARG(grColorCombineExt, a_mode); STOREARG(grColorCombineExt, b); STOREARG(grColorCombineExt, b_mode); STOREARG(grColorCombineExt, c); STOREARG(grColorCombineExt, c_invert); STOREARG(grColorCombineExt, d); STOREARG(grColorCombineExt, d_invert); STOREARG(grColorCombineExt, shift); STOREARG(grColorCombineExt, invert); #undef FN_NAME } /* grColorCombineExt */ /*------------------------------------------------------------------- Function: grAlphaCombineExt Date: 08-June-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grAlphaCombineExt, void , (GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, GrACUColor_t c, FxBool c_invert, GrACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert) ) { #define FN_NAME "grAlphaCombineExt" GR_BEGIN_NOFIFOCHECK("grAlphaCombineExt\n",85); #if DEBUG_2PPC GDBG_PRINTF("grAlphaCombineExt(a=%x,am=%x,b=%x,bm=%x,c=%x,ci=%d,d=%x,di=%x,s=%d,i=%d)\n", a,a_mode,b,b_mode,c,c_invert,d,d_invert,shift,invert); #endif /* update ** cca_mselect (c), cca_add_clocal (part of d), cca_add_alocal (part of d) ** cca_invert_output (invert) */ INVALIDATE(fbzColorPath); /* update ** cca_otherselect (a), cca_localselect (b), cca_invert_other (a_mode), ** cca_invert_local (b_mode), cca_outshift (shift) ** bit (31) */ INVALIDATE(combineMode); INVALIDATE(tmuConfig); gc->state.combineExtsInUse |= STATE_USING_CA; grEnable(GR_COMBINEEXT_MODE); STOREARG(grAlphaCombineExt, a); STOREARG(grAlphaCombineExt, a_mode); STOREARG(grAlphaCombineExt, b); STOREARG(grAlphaCombineExt, b_mode); STOREARG(grAlphaCombineExt, c); STOREARG(grAlphaCombineExt, c_invert); STOREARG(grAlphaCombineExt, d); STOREARG(grAlphaCombineExt, d_invert); STOREARG(grAlphaCombineExt, shift); STOREARG(grAlphaCombineExt, invert); #undef FN_NAME } /* grAlphaCombineExt */ #endif /*------------------------------------------------------------------- Function: grStippleMode Date: 23-Nov-2000 Implementor(s): alanh Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grStippleMode, void , (GrStippleMode_t mode) ) { #define FN_NAME "grStippleMode" GR_BEGIN_NOFIFOCHECK("grStippleMode\n", 85); INVALIDATE(fbzMode); STOREARG(grStippleMode, mode); #undef FN_NAME } /* grStippleMode */ /*------------------------------------------------------------------- Function: grDitherMode Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDitherMode, void , (GrDitherMode_t mode) ) { #define FN_NAME "grDitherMode" GR_BEGIN_NOFIFOCHECK("grDitherMode\n", 85); INVALIDATE(fbzMode); STOREARG(grDitherMode, mode); #undef FN_NAME } /* grDitherMode */ /* TextureBuffer extension utility. ** Copied relevant part from _grValidateState. Kind of bad, but I figured ** it was better than calling _grValidateState itself. ** tbext */ void _grValidateClipState( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ) { #define FN_NAME "_grValidateClipState" #define STATE_REG_BASE (offsetof(SstRegs, fbzColorPath) >> 2UL) #define STATE_REG_END (offsetof(SstRegs, chromaRange) >> 2UL) #define STATE_REG_MASK(__regName) (0x01UL << ((offsetof(SstRegs, __regName) >> 2UL) - STATE_REG_BASE)) FxU32 mask = 0, writeShadow[STATE_REG_END - STATE_REG_BASE + 1]; GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); _grClipWindow( minx, miny, maxx, maxy ); writeShadow[0] = gc->state.shadow.clipLeftRight; writeShadow[1] = gc->state.shadow.clipBottomTop; mask |= (STATE_REG_MASK(clipLeftRight) | STATE_REG_MASK(clipBottomTop)); #if USE_PACKET_FIFO REG_GROUP_BEGIN(BROADCAST_ID, fbzColorPath, 2, mask); REG_GROUP_INDEX_SET(writeShadow[0]); REG_GROUP_INDEX_SET(writeShadow[1]); REG_GROUP_END(); #else /* !USE_PACKET_FIFO */ /* I'm not too sure about this one. */ /* GR_SET_EXPECTED_SIZE(reg_cnt, reg_cnt); */ GR_SET_EXPECTED_SIZE(2, 2); if (NOTVALID(clipRegs)) { REG_GROUP_BEGIN(BROADCAST_ID, clipLeftRight, 2, 0x3); REG_GROUP_SET(hw, clipLeftRight, gc->state.shadow.clipLeftRight); REG_GROUP_SET(hw, clipBottomTop, gc->state.shadow.clipBottomTop); REG_GROUP_END(); } GR_CHECK_SIZE(); #endif /* !USE_PACKET_FIFO */ #undef FN_NAME } /*------------------------------------------------------------------- Function: grRenderBuffer Date: 07-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grRenderBuffer, void , (GrBuffer_t buffer) ) { #define FN_NAME "grRenderBuffer" GR_BEGIN_NOFIFOCHECK("grRenderBuffer\n", 85); INVALIDATE(fbzMode); STOREARG(grRenderBuffer, buffer); /* tbext */ if ( buffer == GR_BUFFER_TEXTUREBUFFER_EXT ) { GR_CHECK_F(myName, !gc->textureBuffer.init, "GR_BUFFER_TEXTUREBUFFER_EXT mode not initialised (You need to call grTextureBuffer() at least once)"); if ( !gc->textureBuffer.prevState.valid ) { gc->textureBuffer.prevState.cwMinx = gc->state.clipwindowf_xmin; gc->textureBuffer.prevState.cwMaxx = gc->state.clipwindowf_xmax; gc->textureBuffer.prevState.cwMiny = gc->state.clipwindowf_ymin; gc->textureBuffer.prevState.cwMaxy = gc->state.clipwindowf_ymax; gc->textureBuffer.prevState.clipLeftRight = gc->state.shadow.clipLeftRight; gc->textureBuffer.prevState.clipBottomTop = gc->state.shadow.clipBottomTop; grClipWindow(0, 0, gc->textureBuffer.width, gc->textureBuffer.height); _grValidateClipState(0, 0, gc->textureBuffer.width, gc->textureBuffer.height); gc->textureBuffer.prevState.valid = FXTRUE; } /* endif !buffer->textureBuffer.prevState.valid */ // // AJB: Turn off AA for textureBuffers // #ifdef FX_GLIDE_NAPALM if (gc->grPixelSample > 1) { _grAAOffsetValue(_GlideRoot.environment.aaXOffset[0], _GlideRoot.environment.aaYOffset[0], 0, gc->chipCount - 1, FXTRUE, FXFALSE); } #endif gc->textureBuffer.on = FXTRUE; gc->curBuffer = 0xffffffff; } else /* buffer != GR_BUFFER_TEXTUREBUFFER_EXT */ { if ( gc->textureBuffer.on ) { gc->textureBuffer.on = FXFALSE; if ( gc->textureBuffer.prevState.valid ) { grClipWindow( (FxU32)gc->textureBuffer.prevState.cwMinx, (FxU32)gc->textureBuffer.prevState.cwMiny, (FxU32)gc->textureBuffer.prevState.cwMaxx, (FxU32)gc->textureBuffer.prevState.cwMaxy ); gc->curBuffer = 0xffffffff; _grValidateClipState( (FxU32)gc->textureBuffer.prevState.cwMinx, (FxU32)gc->textureBuffer.prevState.cwMiny, (FxU32)gc->textureBuffer.prevState.cwMaxx, (FxU32)gc->textureBuffer.prevState.cwMaxy ); /* Restore the stride */ REG_GROUP_BEGIN(BROADCAST_ID, colBufferStride, 1, 0x1); REG_GROUP_SET(hw, colBufferStride,gc->state.shadow.colBufferStride); REG_GROUP_END(); // // AJB: Turn AA back on if necessary // #ifdef FX_GLIDE_NAPALM if (gc->grPixelSample > 1) { if (!gc->state.grEnableArgs.aaMultisampleDisableCount) { _grAAOffsetValue(_GlideRoot.environment.aaXOffset[gc->sampleOffsetIndex], _GlideRoot.environment.aaYOffset[gc->sampleOffsetIndex], 0, gc->chipCount - 1, FXTRUE, gc->enableSecondaryBuffer) ; } } #endif gc->textureBuffer.prevState.valid = FXFALSE; } /* endif gc->textureBuffer.prevState.valid */ } /* endif gc->textureBuffer.on */ } /* endif buffer == GR_BUFFER_TEXTUREBUFFER_EXT */ #undef FN_NAME } /* grRenderBuffer */ /*------------------------------------------------------------------- Function: grColorMask Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_ENTRY(grColorMask, void , (FxBool rgb, FxBool alpha) ) { #define FN_NAME "grColorMask" GR_BEGIN_NOFIFOCHECK("grColorMask\n", 85); INVALIDATE(fbzMode); STOREARG(grColorMask, rgb); /* NB: The api is defined such that if depth buffering is enabled * the alpha mask parameter is ignored. So we need to track the call * order dependency between grColorMask and grDepthMask here. */ gc->state.stateArgs.grColorMaskArgs.alpha = ((LOADARG(grDepthMask, enable) && alpha) ? -1 : alpha); #undef FN_NAME } /* grColorMask */ /*------------------------------------------------------------------- Function: grColorMaskExt Date: 03-July-99 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grColorMaskExt, void , (FxBool r, FxBool g, FxBool b, FxBool a) ) { #define FN_NAME "grColorMaskExt" GR_BEGIN_NOFIFOCHECK("grColorMaskExt\n", 85); INVALIDATE(renderMode); STOREARG(grColorMaskExt, r); STOREARG(grColorMaskExt, g); STOREARG(grColorMaskExt, b); STOREARG(grColorMaskExt, a); #undef FN_NAME } /* grColorMaskExt */ /*------------------------------------------------------------------- Function: grSstOrigin Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grSstOrigin, void , (GrOriginLocation_t origin) ) { #define FN_NAME "grSstOrigin" GR_BEGIN_NOFIFOCHECK("grSstOrigin\n", 83); INVALIDATE(fbzMode); STOREARG(grSstOrigin, origin); #undef FN_NAME } /* grSstOrigin */ /*------------------------------------------------------------------- Function: grClipWindow Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grClipWindow, void , (FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy) ) { #define FN_NAME "grClipWindow" GR_BEGIN_NOFIFOCHECK("grClipWindow\n", 83); INVALIDATE(clipRegs); STOREARG(grClipWindow, minx); STOREARG(grClipWindow, miny); STOREARG(grClipWindow, maxx); STOREARG(grClipWindow, maxy); #undef FN_NAME } /* grClipWindow */ /*------------------------------------------------------------------- Function: grDepthBiasLevel Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDepthBiasLevel, void , (FxI32 level) ) { #define FN_NAME "grDepthBiasLevel" GR_BEGIN_NOFIFOCHECK("grDepthBiasLevel\n", 83); INVALIDATE(zaColor); if (gc->state.forced32BPP) level*=256; STOREARG(grDepthBiasLevel, level); #undef FN_NAME } /* grDepthBiasLevel */ /*------------------------------------------------------------------- Function: grFogMode Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grFogMode, void , (GrFogMode_t mode) ) { #define FN_NAME "grFogMode" GR_BEGIN_NOFIFOCHECK("grFogMode\n", 83); INVALIDATE(fogMode); STOREARG(grFogMode, mode); if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) INVALIDATE(fbzMode); #undef FN_NAME } /* grFogMode */ /*------------------------------------------------------------------- Function: grFogColorValue Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grFogColorValue, void , (GrColor_t color) ) { #define FN_NAME "grFogColorValue" GR_BEGIN_NOFIFOCHECK("grFogColorValue\n", 83); INVALIDATE(fogColor); STOREARG(grFogColorValue, color); #undef FN_NAME } /* grFogColorValue */ /*------------------------------------------------------------------- Function: grLfbWriteColorFormat Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grLfbWriteColorFormat, void , (GrColorFormat_t colorFormat) ) { #define FN_NAME "grLfbWriteColorFormat" GR_BEGIN_NOFIFOCHECK("grLfbWriteColorFormat\n", 82); INVALIDATE(lfbMode); STOREARG(grLfbWriteColorFormat, colorFormat); #undef FN_NAME } /* grLfbWriteColorFormat */ /*------------------------------------------------------------------- Function: grLfbWriteColorSwizzle Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grLfbWriteColorSwizzle, void , (FxBool swizzleBytes, FxBool swapWords) ) { #define FN_NAME "grLfbWriteColorSwizzle" GR_BEGIN_NOFIFOCHECK("grLfbWriteColorSwizzle\n", 82); INVALIDATE(lfbMode); STOREARG(grLfbWriteColorSwizzle, swizzleBytes); STOREARG(grLfbWriteColorSwizzle, swapWords); #undef FN_NAME } /* grLfbWriteColorSwizzle */ /*------------------------------------------------------------------- Function: grConstantColorValue Date: 08-Oct-97 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grConstantColorValue, void , (GrColor_t color) ) { #define FN_NAME "grConstantColorValue" GR_BEGIN_NOFIFOCHECK("grConstantColorValue\n", 85); INVALIDATE(c0c1); STOREARG(grConstantColorValue, color); #undef FN_NAME } /* grConstantColorValue */ /*==========================================================================*/ /*------------------------------------------------------------------- Function: grValidateTMUState Date: 25-January-2000 Implementor(s): kcd Description: State Validation: Once a rendering primitive has determined that the state is invalid, it calls this routine. grValidateState then goes through valid markers and flushes all invalid state. This routine handles the TMU specific register state. -------------------------------------------------------------------*/ #define COPY_TMU_STATE(_src, _dst, _var) \ gc->state.shadow.tmuState[_dst]._var = gc->state.tmuShadow[_src]._var; #define DEBUG_2PPC 0 void _grValidateTMUState() { #define FN_NAME "_grValidateTMUState" FxI32 tmu, tmuSource; FxU32 tmuMask; FxU32 tmuRequiredByDownstreamUnit, texturingRequiredByFBI; FxU32 doTMU0Passthrough, enable2PPC, palletizedTexture; FifoChipField chipField; SstRegs* tmuHw; GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X)\n", gc->state.invalid); /* Okay, if we are here then we know we have some amount of work to do. The first order of business is to figure out which TMUs are actually in use. First we check to see if the alpha or color combine units are set up in such a way that texturing is disabled. If texturing is in use, then we check to see whether or not the upstream TMU exists, and if so whether or not it is being used by the downstream TMU. This leaves us with a few cases to consider for different hardware targets: Banshee: TMU0 disabled: "Disable" TMU0 by forcing LOD to 1x1. TMU0 enabled: Update full TMU0 state. Voodoo3: TMU0 disabled/TMU1 disabled: "Disable" both TMUS with LOD trick. TMU0 enabled /TMU1 disabled: Update TMU0 state, "Disable" TMU1 TMU0 disabled/TMU1 enabled: "Disable" TMU1, Update TMU1 state TMU0 enabled /TMU1 enabled: Update TMU0 and TMU1 state Napalm: TMU0 disabled/TMU1 disabled: "Disable" both TMUS with LOD trick, sync TMU state and enable 2PPC. TMU0 enabled /TMU1 disabled: Clone TMU1 state to TMU0 and enable 2PPC mode. TMU0 disabled/TMU1 enabled: "Disable" TMU1, Update TMU1 state[1] TMU0 enabled /TMU1 enabled: Update TMU0 and TMU1 state. Note 1: It would be nice if we could do some magic in this case and rempap TMU1's state down to TMU0. We should be able to do this if UMA mode is enabled and TMU0 is only in passthrough mode. Implementation details: We let grTexCombine & friends do as much work as possible for computing TMU register values and for determining locally when a particular TMU needs to have it's LOD stuff forced down because that TMU is going to have texturing disabled. We process the TMUs in order from downstream to upstream. That way we can come back here and check the gc state flags to see how we should deal with each upstream TMU as we go. */ /* Copy over shadowed TMU state */ gc->state.tmuMask = gc->state.tmuMaskShadow; texturingRequiredByFBI = (gc->state.cc_requires_texture || gc->state.ac_requires_texture); tmuRequiredByDownstreamUnit = FXTRUE; /* Keep compiler from complaining */ doTMU0Passthrough = FXFALSE; enable2PPC = FXFALSE; palletizedTexture = FXFALSE; /* If TMU0 is in passthrough mode and TMU1 is doing texturing, then we remap TMU1's * register state to TMU0 and do the hardware specific TMU1 shutdown logic. */ if(IS_NAPALM(gc->bInfo->pciInfo.deviceID) && (gc->do2ppc) && (GR_TMUMASK_TMU0 & gc->state.tmuColorPassthrough & gc->state.tmuAlphaPassthrough) && (gc->state.tmuMask & GR_TMUMASK_TMU1)) { doTMU0Passthrough = FXTRUE; #if DEBUG_2PPC GDBG_PRINTF("Enabling TMU0 passthrough mode. cp: %08lx ap: %08lx tm: %08lx\n", gc->state.tmuColorPassthrough, gc->state.tmuAlphaPassthrough, gc->state.tmuMask); #endif } palletizedTexture = gc->state.palletizedTexture[0] | gc->state.palletizedTexture[1]; for(tmu = 0; tmu < gc->num_tmu; tmu++) { FxU32 texSubLodDitherTMU = tmu; tmuSource = tmu; chipField = (FifoChipField)(0x02UL << tmu); tmuHw = SST_TMU(hw, tmu); /* Generate mask for this TMU. */ tmuMask = GR_TMUMASK_TMU0 << tmu; /* If we're an upstream TMU, then look at the downstream TMU to see if it's using us or not... */ if(tmu > 0) { tmuRequiredByDownstreamUnit = (gc->state.tcc_requires_prev_texture[tmu - 1] || gc->state.tac_requires_prev_texture[tmu - 1]) && tmuRequiredByDownstreamUnit; } else { tmuRequiredByDownstreamUnit = texturingRequiredByFBI; } /* If texturing is enabled both globally and on this TMU, then update it's state. */ /* Note: We always do the more granular checks on TMU so that we force ourselves */ /* to update things such as the tLOD register if the texCombine code has deemed */ /* texturing to not be in use. This also guarantees that TMU0's state is updated */ /* in such a way that we can clone it's register values for TMU1 if we are doing */ /* 2PPC mode on Napalm. */ #if DEBUG_2PPC GDBG_PRINTF("TMU%d required by downstream unit: %d c: %d a: %d\n",tmu,tmuRequiredByDownstreamUnit, tmu > 0 ? gc->state.tcc_requires_prev_texture[tmu - 1] : gc->state.cc_requires_texture, tmu > 0 ? gc->state.tcc_requires_prev_texture[tmu - 1] : gc->state.ac_requires_texture); #endif if(tmuRequiredByDownstreamUnit && !doTMU0Passthrough || palletizedTexture) { #if DEBUG_2PPC GDBG_PRINTF("Setup TMU%d\n",tmu); #endif #if FX_GLIDE_NAPALM if(IS_NAPALM(gc->bInfo->pciInfo.deviceID) && gc->do2ppc) { /* Make sure 2PPC mode is disabled. */ _grTex2ppc(FXFALSE); #if DEBUG_2PPC GDBG_PRINTF("2PPC mode off\n"); #endif } #endif /* Update TMU register state from backup shadows, then update registers for real. */ /* For theoretical code performance reasons, I'm grouping the registers together */ /* In the groups that seem most likely to change at the same time. */ if(NOTVALID_TMU(tmu, textureMode)) { /* non-compressed -> compressed chip bug workaround. */ if((gc->state.tmuShadow[tmu].textureMode ^ gc->state.shadow.tmuState[tmu].textureMode) & SST_COMPRESSED_TEXTURES & gc->state.tmuShadow[tmu].textureMode) { GR_SET_EXPECTED_SIZE(sizeof(FxU32)*1, 1); GR_SET(eChipTMU0 | eChipTMU1, hw, nopCMD, 0); GR_CHECK_SIZE(); } COPY_TMU_STATE(tmu, tmu, textureMode); /* If this TMU is not using texturing then force it's LOD to 1x1 */ if((gc->state.tmuMask & tmuMask) == 0) { #if DEBUG_2PPC GDBG_PRINTF("TMU%d LOD forced to 1x1\n"); #endif gc->state.shadow.tmuState[tmu].tLOD = SST_TLOD_MINMAX_INT(8, 8); } else { COPY_TMU_STATE(tmu, tmu, tLOD); } COPY_TMU_STATE(tmu, tmu, tDetail); REG_GROUP_BEGIN(chipField, textureMode, 3, 0x07); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[tmu].textureMode); REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); REG_GROUP_SET(tmuHw, tDetail, gc->state.shadow.tmuState[tmu].tDetail); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d textureMode: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].textureMode); GDBG_PRINTF("TMU%d tLod: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].tLOD); GDBG_PRINTF("TMU%d tDetail: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].tDetail); #endif } REG_GROUP_END(); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { COPY_TMU_STATE(tmu, tmu, combineMode); REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuHw, combineMode, gc->state.shadow.tmuState[tmu].combineMode); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d combineMode: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].combineMode); #endif } REG_GROUP_END(); } } if(NOTVALID_TMU(tmu, texBaseAddr)) { COPY_TMU_STATE(tmu, tmu, texBaseAddr); COPY_TMU_STATE(tmu, tmu, texBaseAddr_1); COPY_TMU_STATE(tmu, tmu, texBaseAddr_2); COPY_TMU_STATE(tmu, tmu, texBaseAddr_3_8); REG_GROUP_BEGIN(chipField, texBaseAddr, 4, 0x0f); { REG_GROUP_SET(tmuHw, texBaseAddr, gc->state.shadow.tmuState[tmu].texBaseAddr); REG_GROUP_SET(tmuHw, texBaseAddr1, gc->state.shadow.tmuState[tmu].texBaseAddr_1); REG_GROUP_SET(tmuHw, texBaseAddr2, gc->state.shadow.tmuState[tmu].texBaseAddr_2); REG_GROUP_SET(tmuHw, texBaseAddr38, gc->state.shadow.tmuState[tmu].texBaseAddr_3_8); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d texBaseAddr: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].texBaseAddr); #endif } REG_GROUP_END(); } if(NOTVALID_TMU(tmu, texchroma)) { if(gc->state.shadow.tmuState[tmu].combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION) { gc->state.shadow.tmuState[tmu].texchromaKey = gc->state.tmuColor[tmu]; gc->state.shadow.tmuState[tmu].texchromaRange = gc->state.tmuColor[tmu]; } else { COPY_TMU_STATE(tmu, tmu, texchromaKey); COPY_TMU_STATE(tmu, tmu, texchromaRange); } REG_GROUP_BEGIN(chipField, chromaKey, 2, 0x03); { REG_GROUP_SET(tmuHw, chromaKey, gc->state.shadow.tmuState[tmu].texchromaKey); REG_GROUP_SET(tmuHw, chromaRange, gc->state.shadow.tmuState[tmu].texchromaRange); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d texchromakey %08lx\n",tmu,gc->state.shadow.tmuState[tmu].texchromaKey); GDBG_PRINTF("TMU%d texchromarng %08lx\n",tmu,gc->state.shadow.tmuState[tmu].texchromaRange); #endif } REG_GROUP_END(); } /* Mark TMU state as valid. */ gc->state.tmuInvalid[tmu] = 0; } else { #if DEBUG_2PPC GDBG_PRINTF("TMU%d not required by downstream units or passthrough enabled\n",tmu); #endif chipField = (FifoChipField)(0x02UL << tmu); tmuHw = SST_TMU(hw, tmu); #ifdef FX_GLIDE_NAPALM if ((IS_NAPALM(gc->bInfo->pciInfo.deviceID)) && (gc->do2ppc)) { if(tmu == 0 && doTMU0Passthrough) { #if DEBUG_2PPC GDBG_PRINTF("TMU1:s -> TMU0:r\n"); #endif /* non-compressed -> compressed chip bug workaround. */ if((gc->state.tmuShadow[GR_TMU1].textureMode ^ gc->state.shadow.tmuState[GR_TMU0].textureMode) & SST_COMPRESSED_TEXTURES & gc->state.tmuShadow[GR_TMU1].textureMode) { GR_SET_EXPECTED_SIZE(sizeof(FxU32)*1, 1); GR_SET(eChipTMU0 | eChipTMU1, hw, nopCMD, 0); GR_CHECK_SIZE(); } /* Copy current TMU1 shadow register state to TMU0 real register state. */ gc->state.shadow.tmuState[GR_TMU0].textureMode = gc->state.tmuShadow[GR_TMU1].textureMode; gc->state.shadow.tmuState[GR_TMU0].tLOD = gc->state.tmuShadow[GR_TMU1].tLOD; gc->state.shadow.tmuState[GR_TMU0].tDetail = gc->state.tmuShadow[GR_TMU1].tDetail; gc->state.shadow.tmuState[GR_TMU0].texBaseAddr = gc->state.tmuShadow[GR_TMU1].texBaseAddr; gc->state.shadow.tmuState[GR_TMU0].texBaseAddr_1 = gc->state.tmuShadow[GR_TMU1].texBaseAddr_1; gc->state.shadow.tmuState[GR_TMU0].texBaseAddr_2 = gc->state.tmuShadow[GR_TMU1].texBaseAddr_2; gc->state.shadow.tmuState[GR_TMU0].texBaseAddr_3_8 = gc->state.tmuShadow[GR_TMU1].texBaseAddr_3_8; gc->state.shadow.tmuState[GR_TMU0].combineMode = gc->state.tmuShadow[GR_TMU1].combineMode; if(gc->state.shadow.tmuState[GR_TMU0].combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION) { gc->state.shadow.tmuState[GR_TMU0].texchromaKey = gc->state.tmuColor[GR_TMU1]; gc->state.shadow.tmuState[GR_TMU0].texchromaRange = gc->state.tmuColor[GR_TMU1]; } else { gc->state.shadow.tmuState[GR_TMU0].texchromaKey = gc->state.tmuShadow[GR_TMU1].texchromaKey; gc->state.shadow.tmuState[GR_TMU0].texchromaRange = gc->state.tmuShadow[GR_TMU1].texchromaRange; } /* Flag all TMU0 registers as invalid */ gc->state.tmuInvalid[GR_TMU0] = 0xffffffff; texSubLodDitherTMU = GR_TMU1; } else if(tmu > 0) { #if DEBUG_2PPC GDBG_PRINTF("TMU0:r -> TMU1:r\n"); #endif /* non-compressed -> compressed chip bug workaround. */ if((gc->state.tmuShadow[GR_TMU0].textureMode ^ gc->state.shadow.tmuState[GR_TMU1].textureMode) & SST_COMPRESSED_TEXTURES & gc->state.tmuShadow[GR_TMU0].textureMode) { GR_SET_EXPECTED_SIZE(sizeof(FxU32)*1, 1); GR_SET(eChipTMU0 | eChipTMU1, hw, nopCMD, 0); GR_CHECK_SIZE(); } /* Copy current TMU0 real register state to TMU1 real register state and enable 2PPC mode. */ gc->state.shadow.tmuState[GR_TMU1].textureMode = gc->state.shadow.tmuState[GR_TMU0].textureMode; gc->state.shadow.tmuState[GR_TMU1].tLOD = gc->state.shadow.tmuState[GR_TMU0].tLOD; gc->state.shadow.tmuState[GR_TMU1].tDetail = gc->state.shadow.tmuState[GR_TMU0].tDetail; gc->state.shadow.tmuState[GR_TMU1].texBaseAddr = gc->state.shadow.tmuState[GR_TMU0].texBaseAddr; gc->state.shadow.tmuState[GR_TMU1].texBaseAddr_1 = gc->state.shadow.tmuState[GR_TMU0].texBaseAddr_1; gc->state.shadow.tmuState[GR_TMU1].texBaseAddr_2 = gc->state.shadow.tmuState[GR_TMU0].texBaseAddr_2; gc->state.shadow.tmuState[GR_TMU1].texBaseAddr_3_8 = gc->state.shadow.tmuState[GR_TMU0].texBaseAddr_3_8; gc->state.shadow.tmuState[GR_TMU1].texchromaKey = gc->state.shadow.tmuState[GR_TMU0].texchromaKey; gc->state.shadow.tmuState[GR_TMU1].texchromaRange = gc->state.shadow.tmuState[GR_TMU0].texchromaRange; gc->state.shadow.tmuState[GR_TMU1].combineMode = gc->state.shadow.tmuState[GR_TMU0].combineMode; /* Flag all TMU1 registers as invalid */ gc->state.tmuInvalid[tmu] = 0xffffffff; /* Now that we know that TMU1 is not being used and it's state matches TMU0, we can enable 2PPC mode. */ enable2PPC = FXTRUE; texSubLodDitherTMU = GR_TMU0; } else { #if DEBUG_2PPC GDBG_PRINTF("TMU0:s -> TMU0:r\n"); #endif /* non-compressed -> compressed chip bug workaround. */ if((gc->state.tmuShadow[GR_TMU0].textureMode ^ gc->state.shadow.tmuState[GR_TMU0].textureMode) & SST_COMPRESSED_TEXTURES & gc->state.tmuShadow[GR_TMU0].textureMode) { GR_SET_EXPECTED_SIZE(sizeof(FxU32)*1, 1); GR_SET(eChipTMU0 | eChipTMU1, hw, nopCMD, 0); GR_CHECK_SIZE(); } /* Just update TMU0's complete register state for now. */ gc->state.tmuInvalid[tmu] = 0; COPY_TMU_STATE(tmu, tmu, textureMode); /* If this TMU is not using texturing then set force it's LOD to 1x1 */ if((gc->state.tmuMask & tmuMask) == 0) { gc->state.shadow.tmuState[tmu].tLOD = SST_TLOD_MINMAX_INT(8, 8); INVALIDATE_TMU(tmu, textureMode); } else { COPY_TMU_STATE(tmu, tmu, tLOD); } COPY_TMU_STATE(tmu, tmu, tDetail); COPY_TMU_STATE(tmu, tmu, combineMode); COPY_TMU_STATE(tmu, tmu, texBaseAddr); COPY_TMU_STATE(tmu, tmu, texBaseAddr_1); COPY_TMU_STATE(tmu, tmu, texBaseAddr_2); COPY_TMU_STATE(tmu, tmu, texBaseAddr_3_8); if(gc->state.shadow.tmuState[tmu].combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION) { gc->state.shadow.tmuState[tmu].texchromaKey = gc->state.tmuColor[tmu]; gc->state.shadow.tmuState[tmu].texchromaRange = gc->state.tmuColor[tmu]; } else { COPY_TMU_STATE(tmu, tmu, texchromaKey); COPY_TMU_STATE(tmu, tmu, texchromaRange); } } /* This code is not yet optimal, as it will always update all of the TMU registers any time */ /* the combine state chages and the TMU is not in use. */ REG_GROUP_BEGIN(chipField, textureMode, 7, 0x7F); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[tmu].textureMode); REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); REG_GROUP_SET(tmuHw, tDetail, gc->state.shadow.tmuState[tmu].tDetail); REG_GROUP_SET(tmuHw, texBaseAddr, gc->state.shadow.tmuState[tmu].texBaseAddr); REG_GROUP_SET(tmuHw, texBaseAddr1, gc->state.shadow.tmuState[tmu].texBaseAddr_1); REG_GROUP_SET(tmuHw, texBaseAddr2, gc->state.shadow.tmuState[tmu].texBaseAddr_2); REG_GROUP_SET(tmuHw, texBaseAddr38, gc->state.shadow.tmuState[tmu].texBaseAddr_3_8); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d textureMode: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].textureMode); GDBG_PRINTF("TMU%d tLod: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].tLOD); GDBG_PRINTF("TMU%d tDetail: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].tDetail); GDBG_PRINTF("TMU%d texBaseAddr: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].texBaseAddr); #endif } REG_GROUP_END(); if(gc->state.per_tmu[texSubLodDitherTMU].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuHw, combineMode, gc->state.shadow.tmuState[tmu].combineMode); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d combineMode: %08lx\n",tmu,gc->state.shadow.tmuState[tmu].combineMode); #endif } REG_GROUP_END(); REG_GROUP_BEGIN(chipField, chromaKey, 2, 0x03); { REG_GROUP_SET(tmuHw, chromaKey, gc->state.shadow.tmuState[tmu].texchromaKey); REG_GROUP_SET(tmuHw, chromaRange, gc->state.shadow.tmuState[tmu].texchromaRange); #if DEBUG_2PPC && 1 GDBG_PRINTF("TMU%d texchromakey %08lx\n",tmu,gc->state.shadow.tmuState[tmu].texchromaKey); GDBG_PRINTF("TMU%d texchromarng %08lx\n",tmu,gc->state.shadow.tmuState[tmu].texchromaRange); #endif } REG_GROUP_END(); if(enable2PPC) { /* There are two cases, either we're using TMU0's state on both TMUs or we are using TMU1's state on both. We need to disabled the W,S,T parameters for the TMU that is not being used, otherwise bad things happen because when 2PPC mode is enabled, any writes that go to one TMU will get sent to both. */ if(doTMU0Passthrough) { gc->state.tmuMask &= ~GR_TMUMASK_TMU0; gc->state.mode2ppcTMU = GR_TMU1; } else { gc->state.tmuMask &= ~GR_TMUMASK_TMU1; gc->state.mode2ppcTMU = GR_TMU0; } _grTex2ppc(FXTRUE); } } else { #endif /* Set LOD on TMU to 1x1. */ SstRegs* tmuHw = SST_TMU(hw, tmu); /* GDBG_PRINTF("tmu[%d]: forced off because it's not in use by downstream unit.\n",tmu); */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); /* %%% NOTE: We use 8 here which is the hardware value for 1x1 LOD, rather than using a #define which isn't consistant between Glide2 and Glide3. */ GR_SET((0x02UL << tmu), tmuHw, tLOD, SST_TLOD_MINMAX_INT(8, 8)); GR_CHECK_SIZE(); /* Mark tLOD register as invalid so it gets set to the correct value if/when this TMU is re-enabled. */ INVALIDATE_TMU(tmu, textureMode); /* Update "real" register shadow too. */ gc->state.shadow.tmuState[tmu].tLOD = SST_TLOD_MINMAX_INT(8, 8); #ifdef FX_GLIDE_NAPALM } #endif } } #undef FN_NAME } /*------------------------------------------------------------------- Function: grValidateState Date: 08-Oct-97 Implementor(s): dow Description: State Validation: Once a rendering primitive has determined that the state is invalid, it calls this routine. grValidateState then goes through valid markers and flushes all invalid state. -------------------------------------------------------------------*/ void _grValidateState() { #define FN_NAME "_grValidateState" #define STATE_REG_BASE (offsetof(SstRegs, fbzColorPath) >> 2UL) #define STATE_REG_END (offsetof(SstRegs, chromaRange) >> 2UL) #define STATE_REG_MASK(__regName) (0x01UL << ((offsetof(SstRegs, __regName) >> 2UL) - STATE_REG_BASE)) FxU32 mask = 0, reg_cnt = 0, writeShadow[STATE_REG_END - STATE_REG_BASE + 1]; FxU32 alphaTestOptimization = FXFALSE, updateAlphaMode = FXFALSE; GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X)\n", gc->state.invalid); GR_ASSERT((gc->state.combineExtsInUse == 0) || (gc->state.combineExtsInUse == (STATE_USING_CC|STATE_USING_CA| STATE_USING_TCC|STATE_USING_TAC))); /* Make sure that state is maintained across all chips! */ if(gc->state.invalid) { _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); } /* NB: The values in the write shadow must be set in register order * for the unsafe reg_group write. */ if (NOTVALID(fbzColorPath)) { FxU32 oldTextureEnabled = gc->state.shadow.fbzColorPath & SST_ENTEXTUREMAP; #ifdef FX_GLIDE_NAPALM if (gc->state.grEnableArgs.combine_ext_mode == GR_MODE_ENABLE) { _grACExtfbzColorPath(LOADARG(grAlphaCombineExt, a), LOADARG(grAlphaCombineExt, a_mode), LOADARG(grAlphaCombineExt, b), LOADARG(grAlphaCombineExt, b_mode), LOADARG(grAlphaCombineExt, c), LOADARG(grAlphaCombineExt, c_invert), LOADARG(grAlphaCombineExt, d), LOADARG(grAlphaCombineExt, invert)); _grAlphaControlsITRGBLighting(LOADARG(grAlphaControlsITRGBLighting, enable)); _grCCExtfbzColorPath(LOADARG(grColorCombineExt, a), LOADARG(grColorCombineExt, a_mode), LOADARG(grColorCombineExt, b), LOADARG(grColorCombineExt, b_mode), LOADARG(grColorCombineExt, c), LOADARG(grColorCombineExt, c_invert), LOADARG(grColorCombineExt, d), LOADARG(grColorCombineExt, invert)); } else { FxU32 combineMode = gc->state.shadow.combineMode; FxU32 isCombineExt = (combineMode & SST_CM_USE_COMBINE_MODE); if (isCombineExt) { combineMode &= ~( SST_CM_CC_OTHERSELECT | SST_CM_CC_LOCALSELECT | SST_CM_CC_MSELECT_7 | SST_CM_CC_INVERT_OTHER | SST_CM_CC_INVERT_LOCAL | SST_CM_CC_OUTSHIFT | SST_CM_USE_COMBINE_MODE | SST_CM_CC_INVERT_ADD_LOCAL | SST_CM_CCA_OTHERSELECT | SST_CM_CCA_LOCALSELECT | SST_CM_CCA_INVERT_OTHER | SST_CM_CCA_INVERT_LOCAL | SST_CM_CCA_OUTSHIFT | SST_CM_USE_COMBINE_MODE | SST_CM_CCA_INVERT_ADD_LOCAL ); REG_GROUP_BEGIN(eChipFBI, combineMode, 1, 0x01); { REG_GROUP_SET(hw, combineMode, combineMode); } REG_GROUP_END(); gc->state.shadow.combineMode = combineMode; #if !USE_PACKET_FIFO { /* hack alert! for csim only */ int tmu; for(tmu = 0; tmu < gc->num_tmu; tmu++) { SstRegs* tmuregs = SST_TMU(hw, tmu); const FifoChipField chipField = (FifoChipField)(0x02UL << tmu); REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuregs, combineMode, gc->state.shadow.tmuState[tmu].combineMode); } REG_GROUP_END(); if (gc->do2ppc) tmu = gc->num_tmu; } } #endif } } #endif if (gc->state.grEnableArgs.combine_ext_mode == GR_MODE_DISABLE) { _grAlphaCombine(LOADARG(grAlphaCombine, function), LOADARG(grAlphaCombine, factor), LOADARG(grAlphaCombine, local), LOADARG(grAlphaCombine, other), LOADARG(grAlphaCombine, invert)); _grAlphaControlsITRGBLighting(LOADARG(grAlphaControlsITRGBLighting, enable)); _grColorCombine(LOADARG(grColorCombine, function), LOADARG(grColorCombine, factor), LOADARG(grColorCombine, local), LOADARG(grColorCombine, other), LOADARG(grColorCombine, invert)); } /* transition into/out of texturing ... add nopCMD */ if ((oldTextureEnabled ^ (gc->state.shadow.fbzColorPath & SST_ENTEXTUREMAP)) != 0x00UL) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0); GR_CHECK_SIZE(); } writeShadow[reg_cnt] = gc->state.shadow.fbzColorPath; mask |= STATE_REG_MASK(fbzColorPath); reg_cnt++; } /* %%KCD - We no longer include fogMode in the bulk register update * because we may have to send different values to different chips. */ #if 0 if (NOTVALID(fogMode)) { _grFogMode(LOADARG(grFogMode, mode)); writeShadow[reg_cnt] = gc->state.shadow.fogMode; mask |= STATE_REG_MASK(fogMode); reg_cnt++; } #endif /* Check for alpha test optimization */ if (NOTVALID(alphaMode) || NOTVALID(fbzMode) || NOTVALID(stencilMode)) { updateAlphaMode = FXTRUE; // KoolSmoky - need to recheck this. /*if((LOADARG(grAlphaBlendFunction, rgb_sf) == GR_BLEND_SRC_ALPHA) && (LOADARG(grAlphaBlendFunction, rgb_df) == GR_BLEND_ONE_MINUS_SRC_ALPHA) && (LOADARG(grAlphaBlendFunction, rgb_op) == GR_BLEND_OP_ADD) && (LOADARG(grDepthMask, enable) == FXFALSE) && ((LOADARG(grStencilMask, value) == 0x00) || (gc->state.grEnableArgs.stencil_mode == FXFALSE))) {*/ if(LOADARG(grDepthMask, enable) == FXFALSE) { if((LOADARG(grAlphaBlendFunction, rgb_df) == GR_BLEND_ONE_MINUS_SRC_ALPHA) && (LOADARG(grAlphaBlendFunction, rgb_op) == GR_BLEND_OP_ADD) && (LOADARG(grDepthMask, enable) == FXFALSE) && ((LOADARG(grStencilMask, value) == 0x00) || (gc->state.grEnableArgs.stencil_mode == FXFALSE))) { //GDBG_PRINTF("Alpha test optimization enabled.\n"); alphaTestOptimization = FXTRUE; } } else { //GDBG_PRINTF("Alpha test optimization disabled.\n"); } } if (NOTVALID(alphaMode) || updateAlphaMode) { _grAlphaBlendFunction(LOADARG(grAlphaBlendFunction, rgb_sf), LOADARG(grAlphaBlendFunction, rgb_df), LOADARG(grAlphaBlendFunction, alpha_sf), LOADARG(grAlphaBlendFunction, alpha_df)); _grAlphaTestFunction(LOADARG(grAlphaTestFunction, fnc)); _grAlphaTestReferenceValue(LOADARG(grAlphaTestReferenceValue, value)); /* If conditions are right, then we override alpha testing if it's * not already enabled. */ if(alphaTestOptimization && !(gc->state.shadow.alphaMode & SST_ENALPHAFUNC)) { gc->state.shadow.alphaMode &= ~(SST_ALPHAFUNC | SST_ENALPHAFUNC | SST_ALPHAREF); gc->state.shadow.alphaMode |= (SST_ENALPHAFUNC | SST_ALPHAFUNC_GT); } writeShadow[reg_cnt] = gc->state.shadow.alphaMode; mask |= STATE_REG_MASK(alphaMode); reg_cnt++; } if (NOTVALID(fbzMode)) { _grChromakeyMode(LOADARG(grChromakeyMode, mode)); _grChromaMode(LOADARG(grChromaRange, mode)); _grDepthBufferFunction(LOADARG(grDepthBufferFunction, fnc)); _grDepthBufferMode(LOADARG(grDepthBufferMode, mode)); _grDitherMode(LOADARG(grDitherMode, mode)); _grStippleMode(LOADARG(grStippleMode, mode)); _grSstOrigin(LOADARG(grSstOrigin, origin)); _grRenderBuffer(LOADARG(grRenderBuffer, buffer)); /* tbext */ if ( gc->textureBuffer.on ) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->textureBuffer.addr ); REG_GROUP_SET(hw,colBufferStride,gc->textureBuffer.stride ); REG_GROUP_END(); } /* NB: The alpha mask enable parameter to grColorMask is *DEFINED* * to be ignored if depth buffering is enabled. So we need to keep * track of the call order even when doing lazy state * evaluation. However, both alpha and depth buffering cannot be * enabled in fbzMode otherwise alpha buffering 'wins' and depth * writes don't happen correctly in the clear. We need to make * sure taht only one of them is active at once which is what the * old code actually wanted to do, but failed to do. * * Who defined the api to be this way? Ick! */ { const FxBool enableDepthMask = LOADARG(grDepthMask, enable), enableColorMask = LOADARG(grColorMask, rgb); const FxI32 enableAlphaMask = LOADARG(grColorMask, alpha); FxU32 fbzMode = (gc->state.shadow.fbzMode & ~(SST_RGBWRMASK | SST_ZAWRMASK | SST_ENALPHABUFFER)); #if GLIDE_DEBUG _grDepthMask(enableDepthMask); _grColorMask(enableColorMask, enableAlphaMask); #endif /* GLIDE_DEBUG */ if (enableColorMask) fbzMode |= SST_RGBWRMASK; if (enableDepthMask) { GR_CHECK_COMPATABILITY(FN_NAME, ((enableAlphaMask != 0) && (gc->state.shadow.fbzMode & SST_ENALPHABUFFER) && (gc->bInfo->h3pixelSize < 4)), "alpha writes enabled even though depth buffering"); if (gc->grAuxBuf != 0) fbzMode |= SST_ZAWRMASK; } else if (enableAlphaMask > 0) { GR_CHECK_COMPATABILITY(FN_NAME, ((fbzMode & SST_ENDEPTHBUFFER) && (gc->bInfo->h3pixelSize < 4)), "alpha writes enabled even though depth buffering"); GR_CHECK_COMPATABILITY(FN_NAME, (gc->grAuxBuf == 0), "cannot enable alpha buffering w/o allocating one"); fbzMode |= SST_ENALPHABUFFER | SST_ZAWRMASK; } /* Write back shadow */ gc->state.shadow.fbzMode = fbzMode; } writeShadow[reg_cnt] = gc->state.shadow.fbzMode; mask |= STATE_REG_MASK(fbzMode); reg_cnt++; } if (NOTVALID(lfbMode)) { FxU32 lfbMode = gc->state.shadow.lfbMode; lfbMode &= ~(SST_LFB_RGBALANES | SST_LFB_WRITE_SWAP16 | SST_LFB_WRITE_BYTESWAP); lfbMode |= ((LOADARG(grLfbWriteColorFormat, colorFormat) << SST_LFB_RGBALANES_SHIFT) | (LOADARG(grLfbWriteColorSwizzle, swizzleBytes) << 12UL) | (LOADARG(grLfbWriteColorSwizzle, swapWords) << 11UL)); #if GLIDE_DEBUG _grLfbWriteColorFormat(LOADARG(grLfbWriteColorFormat, colorFormat)); _grLfbWriteColorSwizzle(LOADARG(grLfbWriteColorSwizzle, swizzleBytes), LOADARG(grLfbWriteColorSwizzle, swapWords)); #endif /* GLIDE_DEBUG */ GR_ASSERT(lfbMode == gc->state.shadow.lfbMode); gc->state.shadow.lfbMode = lfbMode; writeShadow[reg_cnt] = lfbMode; mask |= STATE_REG_MASK(lfbMode); reg_cnt++; } if (NOTVALID(clipRegs)) { _grClipWindow(LOADARG(grClipWindow, minx), LOADARG(grClipWindow, miny), LOADARG(grClipWindow, maxx), LOADARG(grClipWindow, maxy)); writeShadow[reg_cnt + 0] = gc->state.shadow.clipLeftRight; writeShadow[reg_cnt + 1] = gc->state.shadow.clipBottomTop; mask |= (STATE_REG_MASK(clipLeftRight) | STATE_REG_MASK(clipBottomTop)); reg_cnt += 2; if (_GlideRoot.environment.guardbandclipping) { #ifdef FX_GLIDE_NAPALM REG_GROUP_BEGIN(BROADCAST_ID, clipLeftRight1, 2, 0x03); { REG_GROUP_SET(hw, clipLeftRight1, gc->state.shadow.clipLeftRight1); REG_GROUP_SET(hw, clipBottomTop1, gc->state.shadow.clipBottomTop1); } REG_GROUP_END(); #endif } } if (NOTVALID(fogColor)) { #if GLIDE_DEBUG _grFogColorValue(LOADARG(grFogColorValue, color)); #endif /* GLIDE_DEBUG */ gc->state.shadow.fogColor = LOADARG(grFogColorValue, color); _grSwizzleColor(&gc->state.shadow.fogColor); writeShadow[reg_cnt] = gc->state.shadow.fogColor; mask |= STATE_REG_MASK(fogColor); reg_cnt++; } if (NOTVALID(zaColor)) { FxU32 zaColor = gc->state.shadow.zaColor; zaColor &= ~SST_ZACOLOR_DEPTH; zaColor |= (LOADARG(grDepthBiasLevel, level) & SST_ZACOLOR_DEPTH); #if GLIDE_DEBUG _grDepthBiasLevel(LOADARG(grDepthBiasLevel, level)); #endif /* GLIDE_DEBUG */ //GR_ASSERT(zaColor == gc->state.shadow.zaColor); gc->state.shadow.zaColor = zaColor; writeShadow[reg_cnt] = zaColor; mask |= STATE_REG_MASK(zaColor); reg_cnt++; } if (NOTVALID(chromaKey)) { #if GLIDE_DEBUG _grChromakeyValue(LOADARG(grChromakeyValue, color)); #endif /* GLIDE_DEBUG */ gc->state.shadow.chromaKey = LOADARG(grChromakeyValue, color); _grSwizzleColor(&gc->state.shadow.chromaKey); writeShadow[reg_cnt] = gc->state.shadow.chromaKey; mask |= STATE_REG_MASK(chromaKey); reg_cnt++; } if (NOTVALID(chromaRange)) { FxU32 chromaRange = gc->state.shadow.chromaRange; #if GLIDE_DEBUG GrColor_t saveColorRange = LOADARG(grChromaRange, range); #endif chromaRange &= SST_ENCHROMARANGE; _grSwizzleColor(&LOADARG(grChromaRange, range)); chromaRange |= ((LOADARG(grChromaRange, range) & 0x00FFFFFFUL) | (LOADARG(grChromaRange, match_mode) << 24UL)); #if GLIDE_DEBUG _grChromaRange(saveColorRange, LOADARG(grChromaRange, match_mode)); #endif /* GLIDE_DEBUG */ GR_ASSERT(chromaRange == gc->state.shadow.chromaRange); gc->state.shadow.chromaRange = chromaRange; writeShadow[reg_cnt] = chromaRange; mask |= STATE_REG_MASK(chromaRange); reg_cnt++; } #ifdef FX_GLIDE_NAPALM if (NOTVALID(stencilMode)) { FxU32 stencilMode = gc->state.shadow.stencilMode; stencilMode &= ~(SST_STENCIL_FUNC | SST_STENCIL_REF | SST_STENCIL_MASK | SST_STENCIL_WMASK | SST_STENCIL_ENABLE); if(gc->state.grEnableArgs.stencil_mode) { stencilMode |= ( LOADARG(grStencilFunc, fnc) << SST_STENCIL_FUNC_SHIFT ) | ( LOADARG(grStencilFunc, ref) << SST_STENCIL_REF_SHIFT ) | ( LOADARG(grStencilFunc, mask) << SST_STENCIL_MASK_SHIFT ) | ( LOADARG(grStencilMask, value) << SST_STENCIL_WMASK_SHIFT ) | ( SST_STENCIL_ENABLE); } else { stencilMode = SST_STENCIL_MODE_DISABLE; } gc->state.shadow.stencilMode = stencilMode; REG_GROUP_BEGIN(BROADCAST_ID, stencilMode, 1, 0x01); { REG_GROUP_SET(hw, stencilMode, stencilMode); } REG_GROUP_END(); } if (NOTVALID(stipple)) { gc->state.shadow.stipple = LOADARG(grStipplePattern, stipple); REG_GROUP_BEGIN(BROADCAST_ID, stipple, 1, 0x01); { REG_GROUP_SET(hw, stipple, gc->state.shadow.stipple); } REG_GROUP_END(); } if (NOTVALID(stencilOp)) { FxU32 stencilOp = gc->state.shadow.stencilOp; stencilOp &= ~(SST_STENCIL_SFAIL_OP | SST_STENCIL_ZFAIL_OP | SST_STENCIL_ZPASS_OP); stencilOp |= (LOADARG(grStencilOp, stencil_fail) << SST_STENCIL_SFAIL_OP_SHIFT) | (LOADARG(grStencilOp, depth_fail) << SST_STENCIL_ZFAIL_OP_SHIFT) | (LOADARG(grStencilOp, depth_pass) << SST_STENCIL_ZPASS_OP_SHIFT); gc->state.shadow.stencilOp = stencilOp; REG_GROUP_BEGIN(BROADCAST_ID, stencilOp, 1, 0x01); { REG_GROUP_SET(hw, stencilOp, stencilOp); } REG_GROUP_END(); } if (NOTVALID(combineMode)) { _grCCExtcombineMode( LOADARG(grColorCombineExt, a), LOADARG(grColorCombineExt, a_mode), LOADARG(grColorCombineExt, b), LOADARG(grColorCombineExt, b_mode), LOADARG(grColorCombineExt, c), LOADARG(grColorCombineExt, d_invert), LOADARG(grColorCombineExt, shift) ); _grACExtcombineMode( LOADARG(grAlphaCombineExt, a), LOADARG(grAlphaCombineExt, a_mode), LOADARG(grAlphaCombineExt, b), LOADARG(grAlphaCombineExt, b_mode), LOADARG(grAlphaCombineExt, d_invert), LOADARG(grAlphaCombineExt, shift) ); gc->state.cc_requires_it_rgb = ( (LOADARG(grColorCombineExt, a) == GR_CMBX_ITRGB) | (LOADARG(grColorCombineExt, b) == GR_CMBX_ITRGB) | (LOADARG(grColorCombineExt, c) == GR_CMBX_ITRGB) | (LOADARG(grColorCombineExt, d) == GR_CMBX_ITRGB) ); gc->state.ac_requires_it_alpha = ( (LOADARG(grColorCombineExt, a) == GR_CMBX_ITALPHA) | (LOADARG(grColorCombineExt, b) == GR_CMBX_ITALPHA) | (LOADARG(grColorCombineExt, c) == GR_CMBX_ITALPHA) | (LOADARG(grAlphaCombineExt, a) == GR_CMBX_ITALPHA) | (LOADARG(grAlphaCombineExt, b) == GR_CMBX_ITALPHA) | (LOADARG(grAlphaCombineExt, c) == GR_CMBX_ITALPHA) | (LOADARG(grAlphaCombineExt, d) == GR_CMBX_ITALPHA) ); REG_GROUP_BEGIN(eChipFBI, combineMode, 1, 0x01); { REG_GROUP_SET(hw, combineMode, gc->state.shadow.combineMode); } REG_GROUP_END(); #if !USE_PACKET_FIFO { /* hack alert! for csim only */ int tmu; for(tmu = 0; tmu < gc->num_tmu; tmu++) { SstRegs* tmuregs = SST_TMU(hw, tmu); const FifoChipField chipField = (FifoChipField)(0x02UL << tmu); REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuregs, combineMode, gc->state.shadow.tmuState[tmu].combineMode); } REG_GROUP_END(); if (gc->do2ppc) tmu = gc->num_tmu; } } #endif } if (NOTVALID(renderMode)) { FxU32 renderMode = gc->state.shadow.renderMode; renderMode &= ~( SST_RM_RED_WMASK | SST_RM_GREEN_WMASK | SST_RM_BLUE_WMASK | SST_RM_ALPHA_WMASK ); renderMode |= (LOADARG(grColorMaskExt, r)) ? SST_RM_RED_WMASK : 0x0; renderMode |= (LOADARG(grColorMaskExt, g)) ? SST_RM_GREEN_WMASK : 0x0; renderMode |= (LOADARG(grColorMaskExt, b)) ? SST_RM_BLUE_WMASK : 0x0; renderMode |= (LOADARG(grColorMaskExt, a)) ? SST_RM_ALPHA_WMASK : 0x0; gc->state.shadow.renderMode = renderMode; REG_GROUP_BEGIN(eChipFBI, renderMode, 1, 0x01); { REG_GROUP_SET(hw, renderMode, renderMode); } REG_GROUP_END(); } #endif if (reg_cnt) { #if USE_PACKET_FIFO REG_GROUP_BEGIN(BROADCAST_ID, fbzColorPath, reg_cnt, mask); { FxU32 i; for(i = 0; i < reg_cnt; i++) { REG_GROUP_INDEX_SET(writeShadow[i]); } } REG_GROUP_END(); #else /* !USE_PACKET_FIFO */ { if (NOTVALID(fbzColorPath)) { REG_GROUP_BEGIN(eChipFBI, fbzColorPath, 1, 0x01); REG_GROUP_SET(hw, fbzColorPath, gc->state.shadow.fbzColorPath); REG_GROUP_END(); } if (NOTVALID(fogMode)) { REG_GROUP_BEGIN(eChipFBI, fogMode, 1, 0x01); REG_GROUP_SET(hw, fogMode, gc->state.shadow.fogMode); REG_GROUP_END(); } if (NOTVALID(alphaMode)) { REG_GROUP_BEGIN(eChipFBI, alphaMode, 1, 0x01); REG_GROUP_SET(hw, alphaMode, gc->state.shadow.alphaMode); REG_GROUP_END(); } if (NOTVALID(fbzMode)) { REG_GROUP_BEGIN(eChipFBI, fbzMode, 1, 0x01); REG_GROUP_SET(hw, fbzMode, gc->state.shadow.fbzMode); REG_GROUP_END(); } if (NOTVALID(lfbMode)) { REG_GROUP_BEGIN(eChipFBI, lfbMode, 1, 0x01); REG_GROUP_SET(hw, lfbMode, gc->state.shadow.lfbMode); REG_GROUP_END(); } if (NOTVALID(clipRegs)) { REG_GROUP_BEGIN(eChipFBI, clipLeftRight, 2, 0x03); REG_GROUP_SET(hw, clipLeftRight, gc->state.shadow.clipLeftRight); REG_GROUP_SET(hw, clipBottomTop, gc->state.shadow.clipBottomTop); REG_GROUP_END(); } if (NOTVALID(fogColor)) { REG_GROUP_BEGIN(eChipFBI, fogColor, 1, 0x01); REG_GROUP_SET(hw, fogColor, gc->state.shadow.fogColor); REG_GROUP_END(); } if (NOTVALID(zaColor)) { REG_GROUP_BEGIN(eChipFBI, zaColor, 1, 0x01); REG_GROUP_SET(hw, zaColor, gc->state.shadow.zaColor); REG_GROUP_END(); } if (NOTVALID(chromaKey)) { REG_GROUP_BEGIN(eChipFBI, chromaKey, 1, 0x01); REG_GROUP_SET(hw, chromaKey, gc->state.shadow.chromaKey); REG_GROUP_END(); } if (NOTVALID(chromaRange)) { REG_GROUP_BEGIN(eChipFBI, chromaRange, 1, 0x01); REG_GROUP_SET(hw, chromaRange, gc->state.shadow.chromaRange); REG_GROUP_END(); } } #endif /* !USE_PACKET_FIFO */ } if (NOTVALID(c0c1)) { // _grConstantColorValue(LOADARG(grConstantColorValue, color)); _grSwizzleColor(&LOADARG(grConstantColorValue, color)); gc->state.shadow.color0 = LOADARG(grConstantColorValue, color); gc->state.shadow.color1 = LOADARG(grConstantColorValue, color); REG_GROUP_BEGIN(BROADCAST_ID, c0, 2, 0x03); { REG_GROUP_SET(hw, c0, gc->state.shadow.color0); REG_GROUP_SET(hw, c1, gc->state.shadow.color1); } REG_GROUP_END(); } /* Now handle fogMode. Sigh. */ if (NOTVALID(fogMode)) { _grFogMode(LOADARG(grFogMode, mode)); if(gc->grPixelSample == 2) { if(gc->grSamplesPerChip == 2) { /* All chips get the same fogMode value */ FxU32 fogMode = gc->state.shadow.fogMode; fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= (2 << SST_DITHER_ROTATE_AA_SHIFT) | (2 << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; REG_GROUP_BEGIN(eChipFBI, fogMode, 1, 0x01); REG_GROUP_SET(hw, fogMode, fogMode); REG_GROUP_END(); } else { /* Even chips use one rotation, odd chips use the other one */ FxU32 chipIndex, fogMode; fogMode = gc->state.shadow.fogMode; for(chipIndex = 0; chipIndex < gc->chipCount; chipIndex++) { if(chipIndex & 1) { /* Sample 1 */ fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= (2 << SST_DITHER_ROTATE_SHIFT) | (2 << SST_DITHER_ROTATE_BLEND_SHIFT) | (2 << SST_DITHER_ROTATE_AA_SHIFT) | (2 << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; } else { /* Sample 0 */ fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= (0 << SST_DITHER_ROTATE_SHIFT) | (0 << SST_DITHER_ROTATE_BLEND_SHIFT) | (0 << SST_DITHER_ROTATE_AA_SHIFT) | (0 << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; } _grChipMask( 1L << chipIndex ); REG_GROUP_BEGIN(eChipFBI, fogMode, 1, 0x01); REG_GROUP_SET(hw, fogMode, fogMode); REG_GROUP_END(); } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); } } else if(gc->grPixelSample >= 4) { FxU32 chipIndex, fogMode; fogMode = gc->state.shadow.fogMode; for(chipIndex = 0; chipIndex < gc->chipCount; chipIndex++) { #if 1 /* KoolSmoky */ if(gc->grSamplesPerChip == 2) { if(chipIndex & 1) { /* Samples 2 and 3 */ fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= (2 << SST_DITHER_ROTATE_SHIFT) | (2 << SST_DITHER_ROTATE_BLEND_SHIFT) | (3 << SST_DITHER_ROTATE_AA_SHIFT) | (3 << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; } else { /* Samples 0 and 1 */ fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= (0 << SST_DITHER_ROTATE_SHIFT) | (0 << SST_DITHER_ROTATE_BLEND_SHIFT) | (1 << SST_DITHER_ROTATE_AA_SHIFT) | (1 << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; } } else { int rotNum = chipIndex & 3; fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= (rotNum << SST_DITHER_ROTATE_SHIFT) | (rotNum << SST_DITHER_ROTATE_BLEND_SHIFT); } #else /* Colourless */ /* Chip0Buf0=0, Chip0Buf1=2, Chip1Buf0=1, Chip1Buf1=3 */ /* Chip2Buf0=2, Chip2Buf1=0, Chip3Buf0=3, Chip3Buf1=1 */ fogMode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; fogMode |= ((chipIndex&3) << SST_DITHER_ROTATE_SHIFT) | ((chipIndex&3) << SST_DITHER_ROTATE_BLEND_SHIFT) | (((chipIndex+2)&3) << SST_DITHER_ROTATE_AA_SHIFT) | (((chipIndex+2)&3) << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; #endif _grChipMask( 1L << chipIndex ); REG_GROUP_BEGIN(eChipFBI, fogMode, 1, 0x01); REG_GROUP_SET(hw, fogMode, fogMode); REG_GROUP_END(); } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); } else { REG_GROUP_BEGIN(eChipFBI, fogMode, 1, 0x01); REG_GROUP_SET(hw, fogMode, gc->state.shadow.fogMode); REG_GROUP_END(); } } /* In this case, textureCombine is a "virtual" register that means something important changed that may affect TMU configuration. Since that code is pretty complicated, it has it's own routine up above. */ if(NOTVALID(tmuConfig)) { _grValidateTMUState(); } #if 0 if (gc->mode2ppc) _grTex2ppc(GR_TMU0, FXTRUE); #endif if (gc->state.invalid) { _grUpdateParamIndex(); _grChipMask(gc->chipmask); } gc->state.invalid = 0; /* ** NB: ** This code *always* clips on the host. This is because I beleive ** we've reached the point that any performance-concious person ** using Banshee will have a machine that is fast enough such that ** host-based culling is faster. * * dpc: What if the app has turned off culling? Why bother checking * and doing the branch away from the culling code if we don't * need to bother? I've put the cull/nocull variants back. */ gc->triSetupProc = CUR_TRI_PROC(FXFALSE, (gc->state.cull_mode != GR_CULL_DISABLE)); #undef FN_NAME } /* _grValidateState */ #define IARRAY(p,i) (*((FxU32 *)(p)+(i))) /*------------------------------------------------------------------- Function: grEnable Date: 10-Oct-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grEnable, void , (GrEnableMode_t mode) ) { #define FN_NAME "grEnable" GR_BEGIN_NOFIFOCHECK_NORET("grEnable\n", 85); switch (mode) { case GR_AA_ORDERED: gc->state.grEnableArgs.primitive_smooth_mode = GR_AA_ORDERED_POINTS_MASK | GR_AA_ORDERED_LINES_MASK | GR_AA_ORDERED_TRIANGLES_MASK; break; case GR_AA_ORDERED_POINTS_OGL: gc->state.grEnableArgs.primitive_smooth_mode |= GR_AA_ORDERED_POINTS_MASK; break; case GR_AA_ORDERED_LINES_OGL: gc->state.grEnableArgs.primitive_smooth_mode |= GR_AA_ORDERED_LINES_MASK; break; case GR_AA_ORDERED_TRIANGLES_OGL: gc->state.grEnableArgs.primitive_smooth_mode |= GR_AA_ORDERED_TRIANGLES_MASK; break; case GR_SHAMELESS_PLUG: ENABLEMODE(shameless_plug_mode); _GlideRoot.environment.shamelessPlug = GR_MODE_ENABLE; break; case GR_VIDEO_SMOOTHING: ENABLEMODE(video_smooth_mode); break; case GR_ALLOW_MIPMAP_DITHER: gc->state.allowLODdither = GR_MODE_ENABLE; break; case GR_PASSTHRU: break; case GR_TEXTURE_UMA_EXT: gc->state.grEnableArgs.texture_uma_mode = GR_MODE_ENABLE; if ((gc->num_tmu == 2) && (gc->open)) { gc->tmuMemInfo[0].tramOffset = gc->tmuMemInfo[1].tramOffset = gc->bInfo->tramOffset; gc->tmuMemInfo[0].tramSize = gc->tmuMemInfo[1].tramSize = gc->bInfo->tramSize; gc->tmu_state[0].total_mem = gc->tmu_state[1].total_mem = gc->tmuMemInfo[0].tramSize; } break; case GR_COMBINEEXT_MODE: gc->state.grEnableArgs.combine_ext_mode = GR_MODE_ENABLE; break; case GR_STENCIL_MODE_EXT: gc->state.grEnableArgs.stencil_mode = GR_MODE_ENABLE; INVALIDATE(stencilMode); break; #ifdef FX_GLIDE_NAPALM case GR_AA_MULTI_SAMPLE: { if (gc->state.grEnableArgs.aaMultisampleDisableCount) { gc->state.grEnableArgs.aaMultisampleDisableCount--; } if (!gc->state.grEnableArgs.aaMultisampleDisableCount) { _grAAOffsetValue(_GlideRoot.environment.aaXOffset[gc->sampleOffsetIndex], _GlideRoot.environment.aaYOffset[gc->sampleOffsetIndex], 0, gc->chipCount - 1, FXTRUE, gc->enableSecondaryBuffer) ; } } break; case GR_OPENGL_MODE_EXT: { #ifdef WIN32 /* EnableOpenGL - Win_Mode.c ** Allow minihwc to know about OpenGL */ /* KoolSmoky - the registry path should already be enumerated by now. */ void EnableOpenGL ( char *regpath ); EnableOpenGL( gc->bInfo->RegPath ); /* setup env to determine whether we are an OGL app */ _GlideRoot.environment.is_opengl=FXTRUE; #endif /* Set up some stuff that's affected by OpenGL's behaviour. */ _GlideRoot.environment.sliBandHeightForce = FXTRUE; } break; #endif } #undef FN_NAME } /* grEnable */ /*------------------------------------------------------------------- Function: grDisable Date: 10-Oct-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDisable, void , (GrEnableMode_t mode) ) { #define FN_NAME "grDisable" GR_BEGIN_NOFIFOCHECK("grDisable\n", 85); switch (mode) { case GR_AA_ORDERED: gc->state.grEnableArgs.primitive_smooth_mode = 0; break; case GR_AA_ORDERED_POINTS_OGL: gc->state.grEnableArgs.primitive_smooth_mode &= ~GR_AA_ORDERED_POINTS_MASK; break; case GR_AA_ORDERED_LINES_OGL: gc->state.grEnableArgs.primitive_smooth_mode &= ~GR_AA_ORDERED_LINES_MASK; break; case GR_AA_ORDERED_TRIANGLES_OGL: gc->state.grEnableArgs.primitive_smooth_mode &= ~GR_AA_ORDERED_TRIANGLES_MASK; break; case GR_SHAMELESS_PLUG: DISABLEMODE(shameless_plug_mode); _GlideRoot.environment.shamelessPlug = GR_MODE_DISABLE; break; case GR_VIDEO_SMOOTHING: DISABLEMODE(video_smooth_mode); break; case GR_ALLOW_MIPMAP_DITHER: gc->state.allowLODdither = GR_MODE_DISABLE; break; case GR_PASSTHRU: break; case GR_TEXTURE_UMA_EXT: gc->state.grEnableArgs.texture_uma_mode = GR_MODE_DISABLE; if ((gc->num_tmu == 2) && (gc->open)) { gc->tmuMemInfo[0].tramOffset = gc->bInfo->tramOffset; gc->tmuMemInfo[0].tramSize = gc->bInfo->tramSize >> 1; gc->tmu_state[0].total_mem = gc->tmuMemInfo[0].tramSize; gc->tmuMemInfo[1].tramOffset = gc->tmuMemInfo[0].tramOffset + gc->tmuMemInfo[0].tramSize; gc->tmuMemInfo[1].tramSize = (gc->bInfo->tramSize >> 1); gc->tmu_state[1].total_mem = gc->tmuMemInfo[1].tramSize; } break; case GR_COMBINEEXT_MODE: gc->state.grEnableArgs.combine_ext_mode = GR_MODE_DISABLE; break; case GR_STENCIL_MODE_EXT: gc->state.grEnableArgs.stencil_mode = GR_MODE_DISABLE; INVALIDATE(stencilMode); break; case GR_OPENGL_MODE_EXT: _GlideRoot.environment.is_opengl=FXFALSE; break; #ifdef FX_GLIDE_NAPALM case GR_AA_MULTI_SAMPLE: { if (!gc->state.grEnableArgs.aaMultisampleDisableCount) { _grAAOffsetValue(_GlideRoot.environment.aaXOffset[0], _GlideRoot.environment.aaYOffset[0], 0, gc->chipCount - 1, FXTRUE, gc->enableSecondaryBuffer) ; } gc->state.grEnableArgs.aaMultisampleDisableCount++; } break; #endif } #undef FN_NAME } /* grDisable */ /*------------------------------------------------------------------- Function: grCoordinateSpace Date: 01-Dec-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grCoordinateSpace, void , (GrCoordinateSpaceMode_t mode) ) { #define FN_NAME "grCoordinateSpace" GR_BEGIN_NOFIFOCHECK("grCoordinateSpace\n", 85); switch (mode) { case GR_WINDOW_COORDS: gc->state.grCoordinateSpaceArgs.coordinate_space_mode = GR_WINDOW_COORDS; break; case GR_CLIP_COORDS: gc->state.grCoordinateSpaceArgs.coordinate_space_mode = GR_CLIP_COORDS; break; } /* Select function vectors based on current coordinate system. These * can be further specialized for cull/no-cull. */ gc->archDispatchProcs.coorModeTriVector = (*_GlideRoot.deviceArchProcs.curTriProcs) + mode; gc->archDispatchProcs.drawVertexList = _GlideRoot.deviceArchProcs.curVertexListProcs[mode]; /* Update triangle proc based on the current culling mode */ grCullMode(gc->state.cull_mode); /* cull mode is not validated so we need to update triproc here */ gc->triSetupProc = CUR_TRI_PROC(FXTRUE, (gc->state.cull_mode != GR_CULL_DISABLE)); #undef FN_NAME } /* grCoordinateSpace */ /*------------------------------------------------------------------- Function: grDepthRange Date: 01-Dec-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grDepthRange, void , (FxFloat n, FxFloat f) ) { #define FN_NAME "grDepthRange" GR_BEGIN_NOFIFOCHECK("grDepthRange\n", 85); gc->state.Viewport.n = n; gc->state.Viewport.f = f; gc->state.Viewport.hdepth = (f - n) * 0.5f * 65535.f; gc->state.Viewport.oz = (f + n) * 0.5f * 65535.f; #undef FN_NAME } /* grDepthRange */ /*------------------------------------------------------------------- Function: grViewport Date: 01-Dec-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grViewport, void , (FxI32 x, FxI32 y, FxI32 width, FxI32 height) ) { #define FN_NAME "grViewport" GR_BEGIN_NOFIFOCHECK("grViewport\n", 85); gc->state.Viewport.ox = (FxFloat)(x + width * 0.5f); gc->state.Viewport.oy = (FxFloat)(y + height *0.5f); gc->state.Viewport.hwidth = width * 0.5f; gc->state.Viewport.hheight = height * 0.5f; #undef FN_NAME } /* grViewport */ #ifdef DRI_BUILD void _grInvalidateAll() { GR_DCL_GC; grGlideSetState(&gc->state); } #endif /* defined(DRI_BUILD) */ #endif /* GLIDE3 */ glide3x/h5/glide3/src/distrip.c0100700000175300010010000004047007725034667015627 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/distrip.c,v 1.3.4.2 2003/06/05 08:23:51 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 30 2/18/99 3:12p Kcd ** Removed useless cast that Codewarrior barfs on. ** ** 29 1/20/99 8:03p Peter ** fixed debug output of grVertexLayout ** ** 28 12/09/98 5:10p Atai ** set MAXLOD = MINLOD = 8 in _grUpdateParamIndex if ST1 is not used ** ** 27 12/09/98 2:02p Atai ** Added _grTexForceLod back. Set tLOD min = max = 8 for the 2nd TMU by ** default for Avenger to increase single texturing tri fillrate. ** ** 26 12/07/98 7:13p Atai ** same as previous one for grDrawVertexArray ** ** 25 12/07/98 4:54p Atai ** use trisetup routine for GR_TRIANGLES to enable software culling ** ** 24 12/03/98 11:26p Dow ** ** 23 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 22 9/29/98 2:33p Atai ** change color type if parameter is enabled ** ** 20 9/09/98 11:58a Atai ** fix grVertexLayout dbg msg ** ** 19 8/30/98 10:54p Jdt ** Call validation code when vertex layout changes. ** ** 18 8/03/98 6:38a Jdt ** moved stats into GC ** ** 17 7/16/98 8:15a Jdt ** fxcmd.h ** ** 16 6/11/98 6:04p Atai ** added aa case for OGL ** ** 15 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 14 5/29/98 11:45a Atai ** 1.added _EXT for extension #defines. ** 2. change GR_TEXBASE_* values ** 3. Remove GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB ** ** 13 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 11 4/21/98 1:34p Atai ** make 32 bit clean ** ** 10 4/17/98 10:59a Atai ** added grGlideGetVertexLayout and grGlideSetVertexLayout ** ** 9 3/21/98 11:31a Atai ** added GR_TRIANGLE_STRIP_CONTINUE and GR_TRIANGLE_FAN_CONTINUE ** ** 8 2/09/98 6:20p Atai ** remove aa strip and fan for grDrawVertexArrayContiguous ** ** 7 2/06/98 6:57p Atai ** rename grVertexArrayLinear to grDrawVertexArrayContiguous ** ** 6 2/05/98 6:19p Atai ** lazy evaluate for grVertexLayout ** ** 5 2/03/98 3:40p Atai ** remove aa strip/fan and code clean up ** ** 4 1/28/98 10:12a Atai ** update GrState size ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 14 1/08/98 4:58p Atai * tex table broadcast, grVertexLayout enable/disable, stq, and some * defines * * 13 12/12/97 10:59a Atai * clip space and viewport * * 12 12/08/97 10:42a Atai * added grDrawVertexArrayLinear() * * 11 11/21/97 6:05p Atai * use one datalist (tsuDataList) in glide3 * * 10 11/18/97 6:11p Peter * fixed glide3 effage * * 9 11/18/97 3:24p Atai * change grParameterData to grVertexLayout * define GR_PARAM_* * * 8 11/07/97 11:22a Atai * remove GR_*_SMOOTH. use GR_SMOOTH * * 7 11/06/97 6:10p Atai * update GrState size * rename grDrawArray to grDrawVertexArray * update _grDrawPoint and _grDrawVertexList * * 6 10/21/97 8:36p Atai * added gr_lines routines * use dword offset * * 5 10/17/97 2:11p Atai * added grContinueArray. We only support non aa mode for now. * * 4 10/14/97 4:34p Atai * filled out the calls to different drawarray routines * * 3 9/29/97 1:26p Dow * Fixed packed color strips/fans * * 2 9/26/97 10:24a Dow * Fixed state effage in Glide3 parameter data * * 1 9/23/97 2:04p Dow * DI code for strips ** */ #ifdef GLIDE3 #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #if HAL_CSIM #include #else #include #endif #endif /*------------------------------------------------------------------- Function: grVertexLayout Date: 17-Sep-97 Implementor(s): dow Library: Init Code for Description: This routine defines the format for vertex arrays. Arguments: param - Type of date-i.e. vertex, color, or texture info: GR_COLOR, GR_VERTEX, GR_TEXTURE0, GR_TEXTURE1 components - Which components are specified Valid Components: So, this table summarizes the legal combinations: Param Type Size Description ======================================================================================================= GR_PARAM_XY FxFloat 8 X and Y coordinates. Offset must be zero. GR_PARAM_Z FxFloat 4 Z coordinate. GR_PARAM_A FxFloat 4 Alpha value. GR_PARAM_RGB FxFloat 12 RGB triplet. GR_PARAM_PARGB FxU32 4 Packed ARGB. High-order byte is A, followed by R, G, and B. GR_PARAM_STn FxFloat 8 S and T coordinates for TMU , where n is in the range [0, TBD] GR_PARAM_Wn FxFloat 4 Return: Nothing ever. -------------------------------------------------------------------*/ GR_DIENTRY(grVertexLayout, void , (FxU32 param, FxI32 offset, FxU32 mode) ) { #define FN_NAME "grVertexLayout" GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x, 0x%x, %s)\n", param, offset, (mode == GR_PARAM_ENABLE) ? "Enable" : "Disable"); switch (param) { case GR_PARAM_XY: GR_CHECK_F(myName, (offset != 0), "Offset must be zero."); gc->state.vData.vertexInfo.offset = offset; gc->state.vData.vertexInfo.mode = mode; break; case GR_PARAM_Z: gc->state.vData.zInfo.offset = offset; gc->state.vData.zInfo.mode = mode; break; case GR_PARAM_W: gc->state.vData.wInfo.offset = offset; gc->state.vData.wInfo.mode = mode; break; case GR_PARAM_FOG_EXT: /* ** Fog coordinate is an extension in Glide3. It is supported in V2 and VB. ** If z-buffering, we use w iterator for fog coordinate. ** If w-buffering, we move the w iterator to floating point z and use w iterator for fog. */ gc->state.vData.fogInfo.offset = offset; gc->state.vData.fogInfo.mode = mode; break; case GR_PARAM_A: gc->state.vData.aInfo.offset = offset; if (mode == GR_PARAM_ENABLE) gc->state.vData.colorType = GR_FLOAT; gc->state.vData.aInfo.mode = mode; break; case GR_PARAM_RGB: gc->state.vData.rgbInfo.offset = offset; if (mode == GR_PARAM_ENABLE) gc->state.vData.colorType = GR_FLOAT; gc->state.vData.rgbInfo.mode = mode; break; case GR_PARAM_PARGB: gc->state.vData.pargbInfo.offset = offset; if (mode == GR_PARAM_ENABLE) gc->state.vData.colorType = GR_U8; gc->state.vData.pargbInfo.mode = mode; break; case GR_PARAM_ST0: gc->state.vData.st0Info.offset = offset; gc->state.vData.st0Info.mode = mode; break; case GR_PARAM_ST1: gc->state.vData.st1Info.offset = offset; gc->state.vData.st1Info.mode = mode; break; case GR_PARAM_Q: gc->state.vData.qInfo.offset = offset; gc->state.vData.qInfo.mode = mode; break; case GR_PARAM_Q0: gc->state.vData.q0Info.offset = offset; gc->state.vData.q0Info.mode = mode; break; case GR_PARAM_Q1: gc->state.vData.q1Info.offset = offset; gc->state.vData.q1Info.mode = mode; break; } INVALIDATE( vtxlayout ); GR_END(); #undef FN_NAME } /* grParameterData */ /*------------------------------------------------------------------- Function: grGlideGetVertexLayout Date: 16-Apr-98 Implementor(s): atai Library: Description: This routine gets the vertex layout Arguments: layout - vertexlayout Return: -------------------------------------------------------------------*/ GR_DIENTRY(grGlideGetVertexLayout, void , (void *layout) ) { #define FN_NAME "grGlideGetVertexLayout" GR_BEGIN_NOFIFOCHECK(FN_NAME, 87); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",layout); GR_ASSERT(layout != NULL); *((GrVertexLayout *)layout) = gc->state.vData; GR_END(); #undef FN_NAME } /* grGlideGetVertexLayout */ /*------------------------------------------------------------------- Function: grGlideSetVertexLayout Date: 16-Apr-98 Implementor(s): atai Library: Description: This routine sets the vertex layout Arguments: layout - vertexlayout Return: -------------------------------------------------------------------*/ GR_DIENTRY(grGlideSetVertexLayout, void , (const void *layout) ) { #define FN_NAME "grGlideSetVertexLayout" GR_BEGIN_NOFIFOCHECK(FN_NAME, 87); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",layout); GR_ASSERT(layout != NULL); gc->state.vData = *((GrVertexLayout *)layout); INVALIDATE( vtxlayout ); GR_END(); #undef FN_NAME } /* grGlideSetVertexLayout */ /*------------------------------------------------------------------- Function: grDrawVertexArray Date: 18-Sep-97 Implementor(s): dow Description: Arguments: mode: GR_POINTS, GR_LINE_STRIP, GR_POLYGON, GR_TRIANLGE_STRIP, GR_TRIANGLE_FAN, GR_TRIANGLES Return: Nothing ever -------------------------------------------------------------------*/ GR_DIENTRY(grDrawVertexArray, void , (FxU32 mode, FxU32 Count, void *pointers) ) { #define FN_NAME "grDrawVertexArray" GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(0x%x, 0x%x, 0x%x)\n", mode, Count, pointers); GR_FLUSH_STATE(); #ifdef GDBG_INFO_ON { FxU32 i; for (i = 0; i < Count; i++) GDBG_INFO(110, "%s: pointers[%d] = 0x%x\n", FN_NAME, i, ((float **)pointers)[i]); } #endif switch (mode) { case GR_POINTS: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_POINTS_MASK) _grAADrawPoints(GR_VTX_PTR_ARRAY, Count, pointers); else _grDrawPoints(GR_VTX_PTR_ARRAY, Count, pointers); break; case GR_LINE_STRIP: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINE_STRIP, Count, pointers); else _grDrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINE_STRIP, Count, pointers); break; case GR_LINES: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, Count, pointers); else _grDrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, Count, pointers); break; /* ** anti-alias does not apply to strip and fan */ case GR_TRIANGLE_STRIP: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_BDDDDD, kSetupStrip, GR_VTX_PTR_ARRAY, Count, pointers); gc->stats.trisProcessed+=(Count-2); break; case GR_POLYGON: case GR_TRIANGLE_FAN: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_BDDDDD, kSetupFan, GR_VTX_PTR_ARRAY, Count, pointers); gc->stats.trisProcessed+=(Count-2); break; case GR_TRIANGLE_STRIP_CONTINUE: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_DDDDDD, kSetupStrip, GR_VTX_PTR_ARRAY, Count, pointers); gc->stats.trisProcessed+=Count; break; case GR_TRIANGLE_FAN_CONTINUE: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_DDDDDD, kSetupFan, GR_VTX_PTR_ARRAY, Count, pointers); gc->stats.trisProcessed+=Count; break; case GR_TRIANGLES: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_TRIANGLES_MASK) if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) _grAADrawTriangles(GR_VTX_PTR_ARRAY, GR_TRIANGLES, Count, pointers); else _grAAVpDrawTriangles(GR_VTX_PTR_ARRAY, GR_TRIANGLES, Count, pointers); else { while ((int)Count >= 3) { grDrawTriangle(*(float **)pointers, *((float **)pointers+1), *((float **)pointers+2)); (float *)pointers += 3; Count -= 3; } } break; } #undef FN_NAME } /* grDrawVertexArray */ /*------------------------------------------------------------------- Function: grDrawVertexArrayContiguous Date: 04-Dec-97 Implementor(s): atai Description: Arguments: mode: GR_POINTS, GR_LINE_STRIP, GR_POLYGON, GR_TRIANLGE_STRIP, GR_TRIANGLE_FAN, GR_TRIANGLES Return: Nothing ever -------------------------------------------------------------------*/ GR_DIENTRY(grDrawVertexArrayContiguous, void , (FxU32 mode, FxU32 Count, void *pointers, FxU32 stride) ) { #define FN_NAME "grDrawVertexArrayContiguous" GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(0x%x, 0x%x, 0x%x)\n", mode, Count, pointers); GR_FLUSH_STATE(); #ifdef GDBG_INFO_ON { FxU32 i; for (i = 0; i < Count; i++) GDBG_INFO(110, "%s: pointers[%d] = 0x%x\n", FN_NAME, i, (int)pointers + gc->state.vData.vStride * i); } #endif gc->state.vData.vStride = stride >> 2; switch (mode) { case GR_POINTS: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_POINTS_MASK) _grAADrawPoints(GR_VTX_PTR, Count, pointers); else _grDrawPoints(GR_VTX_PTR, Count, pointers); break; case GR_LINE_STRIP: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR, GR_LINE_STRIP, Count, pointers); else _grDrawLineStrip(GR_VTX_PTR, GR_LINE_STRIP, Count, pointers); break; case GR_LINES: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR, GR_LINES, Count, pointers); else _grDrawLineStrip(GR_VTX_PTR, GR_LINES, Count, pointers); break; case GR_TRIANGLE_STRIP: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_BDDDDD, kSetupStrip, GR_VTX_PTR, Count, pointers); gc->stats.trisProcessed+=(Count-2); break; case GR_POLYGON: case GR_TRIANGLE_FAN: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_BDDDDD, kSetupFan, GR_VTX_PTR, Count, pointers); gc->stats.trisProcessed+=(Count-2); break; case GR_TRIANGLE_STRIP_CONTINUE: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_DDDDDD, kSetupStrip, GR_VTX_PTR, Count, pointers); gc->stats.trisProcessed+=Count; break; case GR_TRIANGLE_FAN_CONTINUE: (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_DDDDDD, kSetupFan, GR_VTX_PTR, Count, pointers); gc->stats.trisProcessed+=Count; break; case GR_TRIANGLES: if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_TRIANGLES_MASK) if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) _grAADrawTriangles(GR_VTX_PTR, GR_TRIANGLES, Count, pointers); else _grAAVpDrawTriangles(GR_VTX_PTR, GR_TRIANGLES, Count, pointers); else { void *b_ptr, *c_ptr; while ((int)Count >= 3) { b_ptr = (void *)((FxU32)pointers + stride); c_ptr = (void *)((FxU32)pointers + stride*2); TRISETUP(pointers, b_ptr, c_ptr); pointers = (void *)((FxU32)c_ptr + stride); Count -= 3; } } break; } #undef FN_NAME } /* grDrawVertexArrayContiguous */ #endif /* GLIDE3 */ glide3x/h5/glide3/src/ditex.c0100700000175300010010000026034007725034667015266 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/ditex.c,v 1.3.4.8 2003/08/21 08:49:54 dborca Exp $ ** $Log ** 10 3dfx 1.4.1.3.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 9 3dfx 1.4.1.3 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 8 3dfx 1.4.1.2 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 7 3dfx 1.4.1.1 06/15/00 Bill White Merged changes to support ** Linux. ** 6 3dfx 1.4.1.0 06/13/00 Adam Briggs fixes single pass trilinear ** for FXT1 ** 5 3dfx 1.4 02/10/00 Jonny Cochrane Fixes single pass trilinear ** filtering, PRS 12575 and 12566 ** 4 3dfx 1.3 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 3 3dfx 1.2 10/15/99 Anthony tai move 2ppc setting to state ** validation ** 2 3dfx 1.1 10/06/99 Anthony tai disable 2ppc if tmu1 is ** specified ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 38 9/03/99 17:41 Dwm ** Translate aspect ratios only once. (FXT1 format only). ** ** 37 8/25/99 8:44p Larryw ** Expand mipmap size and offset tables to accommodate FXT1. ** ** 36 8/19/99 7:55p Larryw ** FXT1 Tsplit changes. ** ** 35 8/18/99 3:20p Larryw ** FXT1 refinements. ** ** 34 8/05/99 5:03p Larryw ** FXT1 format works now. ** ** 33 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 31 7/26/99 4:56p Larryw ** Change GR_TEXFMT_ARGB_8888 from 0xf to 0x12. ** Adjust bytesPerTexel[] table accordingly. ** ** 30 7/22/99 8:14p Larryw ** Texture format byte-depth improvements ** ** 29 7/14/99 6:23p Larryw ** Remove obsolete G3_LOD_TRANSLATE() macro ** Define _grMipMapOffset[][] at compile time ** Fix 2k texture address-finding ** ** 28 7/12/99 6:27p Larryw ** Cleaner handling of tBig variable ** Filled in _grMipMapOffset[][] for 512+ sizes ** Fixed problems with grTexMipMapMode() ** ** 27 7/07/99 6:52p Larryw ** * 2k texture support ** * Reversed order of LOD tables ** * Added 512,1024, and 2048-sized entries in tables ** * Nullified G3_LOD_TRANSLATE() ** * Created _g3LodXlat() for where tLOD register is read/written ** * Misc cosmetic changes. ** ** 26 6/14/99 5:16p Larryw ** Added 32-bit texture format support. ** ** 25 6/01/99 12:36p Atai ** checks if we are in CSIM ** ** 24 5/28/99 3:46p Atai ** use rawLfb instead of tex_ptr for grTexMaxAddress ** ** 23 5/10/99 1:27p Stb_mmcclure ** Modified comment brackets in grTexMaxAddress ** ** 22 5/07/99 12:53p Dow ** My mods to Matts TexAddress fixes ** ** 21 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 20 3/24/99 6:17p Peter ** reduce nop flush for chain downloads ** ** 19 2/18/99 6:00p Peter ** sub alignment linear textures ** ** 18 2/10/99 2:34p Peter ** corrected alignment textures within an alignment unit ** ** 17 2/03/99 6:48p Atai ** fixed _grTexTextureMemRequired ** ** 16 2/02/99 4:38p Peter ** 16 byte texture alignmnet boundary, fxed assertion for 6666 palette ** downloads ** ** 15 1/25/99 6:32p Peter ** cleaned up some translation macros and tables ** ** 14 12/03/98 11:26p Dow ** ** 13 10/13/98 5:27p Peter ** 6666 format hack ** ** 12 10/09/98 2:44p Atai ** fixed 6666 palette ** ** 11 9/09/98 12:56p Atai ** relaxed 2mb texture address constraint for uma devices ** ** 10 7/16/98 8:15a Jdt ** fxcmd.h ** ** 9 6/22/98 3:35p Peter ** concatenation this way is evil ** ** 8 5/29/98 11:45a Atai ** 1.added _EXT for extension #defines. ** 2. change GR_TEXBASE_* values ** 3. Remove GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB ** ** 7 5/18/98 2:48p Atai ** Changed to do 16-byte increments instead of 8-byte ** ** 6 5/08/98 1:40p Peter ** merged Anthony's palette of Taco changes ** ** 4 4/22/98 4:57p Peter ** glide2x merge ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 2 1/18/98 12:03p Atai ** sync to rev 17 spec * * 1 1/16/98 4:29p Atai * create glide 3 src * * 16 1/13/98 12:42p Atai * fixed grtexinfo, grVertexLayout, and draw triangle * * 15 1/09/98 6:48p Atai * grTexInfo, GR_LOD_* and GR_ASPECT_* * * 13 12/09/97 12:20p Peter * mac glide port * * 12 12/02/97 9:49a Dow * Got rid of Texelfx rev 0 warning * * 11 11/20/97 6:58p Dow * Marked _grTexTextureMemRequired for movement * * 10 8/18/97 3:52p Peter * pre-hw arrival fixes/cleanup * * 9 6/02/97 4:09p Peter * Compile w/ gcc for Dural * * 8 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 7 5/21/97 6:04a Peter * * 6 3/15/97 8:09p Jdt * Remove grTexDownloadTable from this file because I added SST-1 only * code to it * * 5 3/09/97 10:31a Dow * Added GR_DIENTRY for di glide functions * * 4 2/12/97 2:09p Hanson * Hopefully removed the rest of my effage. * * 3 2/12/97 12:34p Dow * Fixed Hanson effage * * 2 1/18/97 11:41p Dow * Fixed Gary's "Last C Bug" analog * Fixed usage of _grMipMapOffset_Tsplit * * 1 12/23/96 1:39p Dow * Changes for multiplatform ** */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" /* * Number of Bits Per Texel based on the format. This needs to be * kept up to date with any changes to the GrTextureFormat_t type * (q.v.). NOTE that reserved types are undefined, ergo have depth 0. */ const FxU32 _grBitsPerTexel[] = { 0x08, /* GR_TEXFMT_8BIT == GR_TEXFMT_RGB_332 */ 0x08, /* GR_TEXFMT_YIQ_422 */ 0x08, /* GR_TEXFMT_ALPHA_8 */ 0x08, /* GR_TEXFMT_INTENSITY_8 */ 0x08, /* GR_TEXFMT_ALPHA_INTENSITY_44 */ 0x08, /* GR_TEXFMT_P_8 */ 0x08, /* GR_TEXFMT_RSVD0 == GR_TEXFMT_P_8_6666 */ 0x10, /* GR_TEXFMT_RSVD1 */ 0x10, /* GR_TEXFMT_16BIT == GR_TEXFMT_ARGB_8332 */ 0x10, /* GR_TEXFMT_AYIQ_8422 */ 0x10, /* GR_TEXFMT_RGB_565 */ 0x10, /* GR_TEXFMT_ARGB_1555 */ 0x10, /* GR_TEXFMT_ARGB_4444 */ 0x10, /* GR_TEXFMT_ALPHA_INTENSITY_88 */ 0x10, /* GR_TEXFMT_AP_88 */ 0x00, /* GR_TEXFMT_RSVD2 */ 0x00, /* */ 0x04, /* GR_TEXFMT_ARGB_CMP_FXT1 */ 0x20, /* GR_TEXFMT_ARGB_8888 */ 0x10, /* GR_TEXFMT_YUYV_422 */ 0x10, /* GR_TEXFMT_UYVY_422 */ 0x20, /* GR_TEXFMT_AYUV_444 */ 0x04, /* GR_TEXFMT_ARGB_CMP_DXT1 */ 0x08, /* GR_TEXFMT_ARGB_CMP_DXT2 */ 0x08, /* GR_TEXFMT_ARGB_CMP_DXT3 */ 0x08, /* GR_TEXFMT_ARGB_CMP_DXT4 */ 0x08 /* GR_TEXFMT_ARGB_CMP_DXT5 */ }; /* size in texels */ /* * NB - because we want Napalm's glide3 to be the same binary as * for Banshee and Voodoo3, and we need to add textures up to 2k, * it has become necessary to reverse all these tables w.r.t. LOD * and also stop using G3_LOD_TRANSLATE. - LEW 6/28/99 */ const FxU32 _grMipMapHostSize[4][GR_LOD_LOG2_2048+1] = { { /* 1:1 aspect ratio */ 1, /* 0 : 1x1 */ 4, /* 1 : 2x2 */ 16, /* 2 : 4x4 */ 64, /* 3 : 8x8 */ 256, /* 4 : 16x16 */ 1024, /* 5 : 32x32 */ 4096, /* 6 : 64x64 */ 16384, /* 7 : 128x128 */ 65536, /* 8 : 256x256 */ 262144, /* 9 : 512x512 */ 1048576, /* 10 : 1024x1024 */ 4194304, /* 11 : 2048x2048 */ }, { /* 2:1 aspect ratio */ 1, /* 0 : 1x1 */ 2, /* 1 : 2x1 */ 8, /* 2 : 4x2 */ 32, /* 3 : 8x4 */ 128, /* 4 : 16x8 */ 512, /* 5 : 32x16 */ 2048, /* 6 : 64x32 */ 8192, /* 7 : 128x64 */ 32768, /* 8 : 256x128 */ 131072, /* 9 : 512x256 */ 524288, /* 10 : 1024x512 */ 2097152, /* 11 : 2048x1024 */ }, { /* 4:1 aspect ratio */ 1, /* 0 : 1x1 */ 2, /* 1 : 2x1 */ 4, /* 2 : 4x1 */ 16, /* 3 : 8x2 */ 64, /* 4 : 16x4 */ 256, /* 5 : 32x8 */ 1024, /* 6 : 64x16 */ 4096, /* 7 : 128x32 */ 16384, /* 8 : 256x64 */ 65536, /* 9 : 512x128 */ 262144, /* 10 : 1024x256 */ 1048576, /* 11 : 2048x512 */ }, { /* 8:1 aspect ratio */ 1, /* 0 : 1x1 */ 2, /* 1 : 2x1 */ 4, /* 2 : 4x1 */ 8, /* 3 : 8x1 */ 32, /* 4 : 16x2 */ 128, /* 5 : 32x4 */ 512, /* 6 : 64x8 */ 2048, /* 7 : 128x16 */ 8192, /* 8 : 256x32 */ 32768, /* 9 : 512x64 */ 131072, /* 10 : 1024x128 */ 524288, /* 11 : 2048x256 */ } }; /* * Similar to _grMipMapHostSize[][] but for 4-bit fxt1 compressed * textures, where 8x4 is the minimum size. */ const FxU32 _grMipMapHostSizeCmp4Bit[7][GR_LOD_LOG2_2048+1] = { { /* 8:1 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 32, /* 3 : 8x4 */ 64, /* 4 : 16x4 */ 128, /* 5 : 32x4 */ 512, /* 6 : 64x8 */ 2048, /* 7 : 128x16 */ 8192, /* 8 : 256x32 */ 32768, /* 9 : 512x64 */ 131072, /* 10 : 1024x128 */ 524288, /* 11 : 2048x256 */ }, { /* 4:1 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 32, /* 3 : 8x4 */ 64, /* 4 : 16x4 */ 256, /* 5 : 32x8 */ 1024, /* 6 : 64x16 */ 4096, /* 7 : 128x32 */ 16384, /* 8 : 256x64 */ 65536, /* 9 : 512x128 */ 262144, /* 10 : 1024x256 */ 1048576, /* 11 : 2048x512 */ }, { /* 2:1 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 32, /* 3 : 8x4 */ 128, /* 4 : 16x8 */ 512, /* 5 : 32x16 */ 2048, /* 6 : 64x32 */ 8192, /* 7 : 128x64 */ 32768, /* 8 : 256x128 */ 131072, /* 9 : 512x256 */ 524288, /* 10 : 1024x512 */ 2097152, /* 11 : 2048x1024 */ }, { /* 1:1 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 64, /* 3 : 8x8 */ 256, /* 4 : 16x16 */ 1024, /* 5 : 32x32 */ 4096, /* 6 : 64x64 */ 16384, /* 7 : 128x128 */ 65536, /* 8 : 256x256 */ 262144, /* 9 : 512x512 */ 1048576, /* 10 : 1024x1024 */ 4194304, /* 11 : 2048x2048 */ }, { /* 1:2 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 64, /* 3 : 8x8 */ 128, /* 4 : 8x16 */ 512, /* 5 : 16x32 */ 2048, /* 6 : 32x64 */ 8192, /* 7 : 64x128 */ 32768, /* 8 : 128x256 */ 131072, /* 9 : 256x512 */ 524288, /* 10 : 512x1024 */ 2097152, /* 11 : 1024x2048 */ }, { /* 1:4 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 64, /* 3 : 8x8 */ 128, /* 4 : 8x16 */ 256, /* 5 : 8x32 */ 1024, /* 6 : 16x64 */ 4096, /* 7 : 32x128 */ 16384, /* 8 : 64x256 */ 65536, /* 9 : 128x512 */ 262144, /* 10 : 256x1024 */ 1048576, /* 11 : 512x2048 */ }, { /* 1:8 aspect ratio */ 32, /* 0 : 8x4 */ 32, /* 1 : 8x4 */ 32, /* 2 : 8x4 */ 64, /* 3 : 8x8 */ 128, /* 4 : 8x16 */ 256, /* 5 : 8x32 */ 512, /* 6 : 8x64 */ 2048, /* 7 : 16x128 */ 8192, /* 8 : 32x256 */ 32768, /* 9 : 64x512 */ 131072, /* 10 : 128x1024 */ 524288, /* 11 : 256x2048 */ }, }; /* * Similar to _grMipMapHostSize[][] but for 8-bit compressed * textures, where 4x4 is the minimum size. DXT2,3,4,5 */ const FxU32 _grMipMapHostSizeDXT[4][GR_LOD_LOG2_2048+1] = { { /* 8:1 aspect ratio */ 16, /* 0 : 4x4 */ 16, /* 1 : 4x4 */ 16, /* 2 : 4x4 */ 32, /* 3 : 8x4 */ 64, /* 4 : 16x4 */ 128, /* 5 : 32x4 */ 512, /* 6 : 64x8 */ 2048, /* 7 : 128x16 */ 8192, /* 8 : 256x32 */ 32768, /* 9 : 512x64 */ 131072, /* 10 : 1024x128 */ 524288, /* 11 : 2048x256 */ }, { /* 4:1 aspect ratio */ 16, /* 0 : 4x4 */ 16, /* 1 : 4x4 */ 16, /* 2 : 4x4 */ 32, /* 3 : 8x4 */ 64, /* 4 : 16x4 */ 256, /* 5 : 32x8 */ 1024, /* 6 : 64x16 */ 4096, /* 7 : 128x32 */ 16384, /* 8 : 256x64 */ 65536, /* 9 : 512x128 */ 262144, /* 10 : 1024x256 */ 1048576, /* 11 : 2048x512 */ }, { /* 2:1 aspect ratio */ 16, /* 0 : 4x4 */ 16, /* 1 : 4x4 */ 16, /* 2 : 4x4 */ 32, /* 3 : 8x4 */ 128, /* 4 : 16x8 */ 512, /* 5 : 32x16 */ 2048, /* 6 : 64x32 */ 8192, /* 7 : 128x64 */ 32768, /* 8 : 256x128 */ 131072, /* 9 : 512x256 */ 524288, /* 10 : 1024x512 */ 2097152, /* 11 : 2048x1024 */ }, { /* 1:1 aspect ratio */ 16, /* 0 : 4x4 */ 16, /* 1 : 4x4 */ 16, /* 2 : 4x4 */ 64, /* 3 : 8x8 */ 256, /* 4 : 16x16 */ 1024, /* 5 : 32x32 */ 4096, /* 6 : 64x64 */ 16384, /* 7 : 128x128 */ 65536, /* 8 : 256x256 */ 262144, /* 9 : 512x512 */ 1048576, /* 10 : 1024x1024 */ 4194304, /* 11 : 2048x2048 */ }, }; /* * Similar to _grMipMapHostWH[][], but for 4-bit compressed * textures, where 8x4 is the minimum size. FXT1,DXT1 */ const int _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) + 1] [GR_LOD_LOG2_2048 + 1][2] = { { /* GR_ASPECT_LOG2_8x1 */ { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 16 , 4 }, { 32 , 4 }, { 64 , 8 }, { 128 , 16 }, { 256 , 32 }, { 512 , 64 }, { 1024, 128 }, { 2048, 256 }, }, { /* GR_ASPECT_LOG2_4x1 */ { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 16 , 4 }, { 32 , 8 }, { 64 , 16 }, { 128 , 32 }, { 256 , 64 }, { 512 , 128 }, { 1024, 256 }, { 2048, 512 }, } , { /* GR_ASPECT_LOG2_2x1 */ { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 16 , 8 }, { 32 , 16 }, { 64 , 32 }, { 128 , 64 }, { 256 , 128 }, { 512 , 256 }, { 1024, 512 }, { 2048, 1024 }, }, { /* GR_ASPECT_LOG2_1x1 */ { 8 , 4 }, { 8 , 4 }, { 8 , 4 }, { 8 , 8 }, { 16 , 16 }, { 32 , 32 }, { 64 , 64 }, { 128 , 128 }, { 256 , 256 }, { 512 , 512 }, { 1024, 1024 }, { 2048, 2048 }, }, { /* GR_ASPECT_LOG2_1x2 */ { 8, 4 }, { 8, 4 }, { 8, 4 }, { 8, 8 }, { 8, 16 }, { 16, 32 }, { 32, 64 }, { 64, 128 }, { 128, 256 }, { 256, 512 }, { 512, 1024 }, { 1024, 2048 }, }, { /* GR_ASPECT_LOG2_1x4 */ { 8, 4 }, { 8, 4 }, { 8, 4 }, { 8, 8 }, { 8, 16 }, { 8, 32 }, { 16, 64 }, { 32, 128 }, { 64, 256 }, { 128, 512 }, { 256, 1024 }, { 512, 2048 }, }, { /* GR_ASPECT_LOG2_1x8 */ { 8, 4 }, { 8, 4 }, { 8, 4 }, { 8, 8 }, { 8, 16 }, { 8, 32 }, { 8, 64 }, { 16, 128 }, { 32, 256 }, { 64, 512 }, { 128, 1024 }, { 256, 2048 }, } }; /* * Similar to _grMipMapHostWH[][], but for 8-bit compressed * textures, where 4x4 is the minimum size. DXT2,3,4,5 */ const int _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) + 1] [GR_LOD_LOG2_2048 + 1][2] = { { /* GR_ASPECT_LOG2_8x1 */ { 4 , 4 }, { 4 , 4 }, { 4 , 4 }, { 8 , 4 }, { 16 , 4 }, { 32 , 4 }, { 64 , 8 }, { 128 , 16 }, { 256 , 32 }, { 512 , 64 }, { 1024, 128 }, { 2048, 256 }, }, { /* GR_ASPECT_LOG2_4x1 */ { 4 , 4 }, { 4 , 4 }, { 4 , 4 }, { 8 , 4 }, { 16 , 4 }, { 32 , 8 }, { 64 , 16 }, { 128 , 32 }, { 256 , 64 }, { 512 , 128 }, { 1024, 256 }, { 2048, 512 }, } , { /* GR_ASPECT_LOG2_2x1 */ { 4 , 4 }, { 4 , 4 }, { 4 , 4 }, { 8 , 4 }, { 16 , 8 }, { 32 , 16 }, { 64 , 32 }, { 128 , 64 }, { 256 , 128 }, { 512 , 256 }, { 1024, 512 }, { 2048, 1024 }, }, { /* GR_ASPECT_LOG2_1x1 */ { 4 , 4 }, { 4 , 4 }, { 4 , 4 }, { 8 , 8 }, { 16 , 16 }, { 32 , 32 }, { 64 , 64 }, { 128 , 128 }, { 256 , 256 }, { 512 , 512 }, { 1024, 1024 }, { 2048, 2048 }, }, { /* GR_ASPECT_LOG2_1x2 */ { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 8 }, { 8, 16 }, { 16, 32 }, { 32, 64 }, { 64, 128 }, { 128, 256 }, { 256, 512 }, { 512, 1024 }, { 1024, 2048 }, }, { /* GR_ASPECT_LOG2_1x4 */ { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 8 }, { 4, 16 }, { 8, 32 }, { 16, 64 }, { 32, 128 }, { 64, 256 }, { 128, 512 }, { 256, 1024 }, { 512, 2048 }, }, { /* GR_ASPECT_LOG2_1x8 */ { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 8 }, { 4, 16 }, { 4, 32 }, { 8, 64 }, { 16, 128 }, { 32, 256 }, { 64, 512 }, { 128, 1024 }, { 256, 2048 }, } }; const int _grMipMapHostWH[G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) + 1] [GR_LOD_LOG2_2048 + 1][2] = { { /* GR_ASPECT_LOG2_8x1 */ { 1 , 1 }, { 2 , 1 }, { 4 , 1 }, { 8 , 1 }, { 16 , 2 }, { 32 , 4 }, { 64 , 8 }, { 128 , 16 }, { 256 , 32 }, { 512 , 64 }, { 1024, 128 }, { 2048, 256 }, }, { /* GR_ASPECT_LOG2_4x1 */ { 1 , 1 }, { 2 , 1 }, { 4 , 1 }, { 8 , 2 }, { 16 , 4 }, { 32 , 8 }, { 64 , 16 }, { 128 , 32 }, { 256 , 64 }, { 512 , 128 }, { 1024, 256 }, { 2048, 512 }, } , { /* GR_ASPECT_LOG2_2x1 */ { 1 , 1 }, { 2 , 1 }, { 4 , 2 }, { 8 , 4 }, { 16 , 8 }, { 32 , 16 }, { 64 , 32 }, { 128 , 64 }, { 256 , 128 }, { 512 , 256 }, { 1024, 512 }, { 2048, 1024 }, }, { /* GR_ASPECT_LOG2_1x1 */ { 1 , 1 }, { 2 , 2 }, { 4 , 4 }, { 8 , 8 }, { 16 , 16 }, { 32 , 32 }, { 64 , 64 }, { 128 , 128 }, { 256 , 256 }, { 512 , 512 }, { 1024, 1024 }, { 2048, 2048 }, }, { /* GR_ASPECT_LOG2_1x2 */ { 1, 1 }, { 1, 2 }, { 2, 4 }, { 4, 8 }, { 8, 16 }, { 16, 32 }, { 32, 64 }, { 64, 128 }, { 128, 256 }, { 256, 512 }, { 512, 1024 }, { 1024, 2048 }, }, { /* GR_ASPECT_LOG2_1x4 */ { 1, 1 }, { 1, 2 }, { 1, 4 }, { 2, 8 }, { 4, 16 }, { 8, 32 }, { 16, 64 }, { 32, 128 }, { 64, 256 }, { 128, 512 }, { 256, 1024 }, { 512, 2048 }, }, { /* GR_ASPECT_LOG2_1x8 */ { 1, 1 }, { 1, 2 }, { 1, 4 }, { 1, 8 }, { 2, 16 }, { 4, 32 }, { 8, 64 }, { 16, 128 }, { 32, 256 }, { 64, 512 }, { 128, 1024 }, { 256, 2048 }, } }; /* translates GR_ASPECT_* to bits for the TLOD register */ const FxU32 _gr_aspect_xlate_table[] = { (3 << SST_LOD_ASPECT_SHIFT) | SST_LOD_S_IS_WIDER, (2 << SST_LOD_ASPECT_SHIFT) | SST_LOD_S_IS_WIDER, (1 << SST_LOD_ASPECT_SHIFT) | SST_LOD_S_IS_WIDER, 0 << SST_LOD_ASPECT_SHIFT, 1 << SST_LOD_ASPECT_SHIFT, 2 << SST_LOD_ASPECT_SHIFT, 3 << SST_LOD_ASPECT_SHIFT }; const FxU32 _gr_evenOdd_xlate_table[] = { 0xFFFFFFFF, /* invalid */ SST_LOD_TSPLIT, /* even */ SST_LOD_TSPLIT | SST_LOD_ODD, /* odd */ 0, /* both */ }; /* the size of each mipmap level in texels, 4 is the minimum no matter what */ /* index is [aspect_ratio][lod] */ static const FxU32 _grMipMapSize[4][16] = { { /* 8:1 aspect ratio */ 0x000004, /* 0 : 1x1 */ 0x000004, /* 1 : 2x1 */ 0x000008, /* 2 : 4x1 */ 0x000010, /* 3 : 8x1 */ 0x000020, /* 4 : 16x2 */ 0x000080, /* 5 : 32x4 */ 0x000200, /* 6 : 64x8 */ 0x000800, /* 7 : 128x16 */ 0x002000, /* 8 : 256x32 */ 0x008000, /* 9 : 512x64 */ 0x020000, /* 10 : 1024x128 */ 0x080000, /* 11 : 2048x256 */ }, { /* 4:1 aspect ratio */ 0x000004, /* 0 : 1x1 */ 0x000004, /* 1 : 2x1 */ 0x000008, /* 2 : 4x1 */ 0x000010, /* 3 : 8x2 */ 0x000040, /* 4 : 16x4 */ 0x000100, /* 5 : 32x8 */ 0x000400, /* 6 : 64x16 */ 0x001000, /* 7 : 128x32 */ 0x004000, /* 8 : 256x64 */ 0x010000, /* 9 : 512x128 */ 0x040000, /* 10 : 1024x256 */ 0x100000, /* 11 : 2048x512 */ }, { /* 2:1 aspect ratio */ 0x000004, /* 0 : 1x1 */ 0x000004, /* 1 : 2x1 */ 0x000008, /* 2 : 4x2 */ 0x000020, /* 3 : 8x4 */ 0x000080, /* 4 : 16x8 */ 0x000200, /* 5 : 32x16 */ 0x000800, /* 6 : 64x32 */ 0x002000, /* 7 : 128x64 */ 0x008000, /* 8 : 256x128 */ 0x020000, /* 9 : 512x256 */ 0x080000, /* 10 : 1024x512 */ 0x200000, /* 11 : 2048x1024 */ }, { /* 1:1 aspect ratio */ 0x000004, /* 0 : 1x1 */ 0x000004, /* 1 : 2x2 */ 0x000010, /* 2 : 4x4 */ 0x000040, /* 3 : 8x8 */ 0x000100, /* 4 : 16x16 */ 0x000400, /* 5 : 32x32 */ 0x001000, /* 6 : 64x64 */ 0x004000, /* 7 : 128x128 */ 0x010000, /* 8 : 256x256 */ 0x040000, /* 9 : 512x512 */ 0x100000, /* 10 : 1024x1024 */ 0x400000, /* 11 : 2048x2048 */ }, }; /* Similar to _grMipMapSize[][] but for 4-bit compressed formats. FXT1,DXT1 */ static const FxU32 _grMipMapSizeCmp4Bit[7][16] = { { /* 8:1 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000020, /* 3 : 8x4 */ 0x000040, /* 4 : 16x4 */ 0x000080, /* 5 : 32x4 */ 0x000200, /* 6 : 64x8 */ 0x000800, /* 7 : 128x16 */ 0x002000, /* 8 : 256x32 */ 0x008000, /* 9 : 512x64 */ 0x020000, /* 10 : 1024x128 */ 0x080000, /* 11 : 2048x256 */ }, { /* 4:1 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000020, /* 3 : 8x4 */ 0x000040, /* 4 : 16x4 */ 0x000100, /* 5 : 32x8 */ 0x000400, /* 6 : 64x16 */ 0x001000, /* 7 : 128x32 */ 0x004000, /* 8 : 256x64 */ 0x010000, /* 9 : 512x128 */ 0x040000, /* 10 : 1024x256 */ 0x100000, /* 11 : 2048x512 */ }, { /* 2:1 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000020, /* 3 : 8x4 */ 0x000080, /* 4 : 16x8 */ 0x000200, /* 5 : 32x16 */ 0x000800, /* 6 : 64x32 */ 0x002000, /* 7 : 128x64 */ 0x008000, /* 8 : 256x128 */ 0x020000, /* 9 : 512x256 */ 0x080000, /* 10 : 1024x512 */ 0x200000, /* 11 : 2048x1024 */ }, { /* 1:1 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000040, /* 3 : 8x8 */ 0x000100, /* 4 : 16x16 */ 0x000400, /* 5 : 32x32 */ 0x001000, /* 6 : 64x64 */ 0x004000, /* 7 : 128x128 */ 0x010000, /* 8 : 256x256 */ 0x040000, /* 9 : 512x512 */ 0x100000, /* 10 : 1024x1024 */ 0x400000, /* 11 : 2048x2048 */ }, { /* 1:2 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000040, /* 3 : 8x8 */ 0x000080, /* 4 : 8x16 */ 0x000200, /* 5 : 16x32 */ 0x000800, /* 6 : 32x64 */ 0x002000, /* 7 : 64x128 */ 0x008000, /* 8 : 128x256 */ 0x020000, /* 9 : 256x512 */ 0x080000, /* 10 : 512x1024 */ 0x200000, /* 11 : 1024x2048 */ }, { /* 1:4 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000040, /* 3 : 8x8 */ 0x000080, /* 4 : 8x16 */ 0x000100, /* 5 : 8x32 */ 0x000400, /* 6 : 16x64 */ 0x001000, /* 7 : 32x128 */ 0x004000, /* 8 : 64x256 */ 0x010000, /* 9 : 128x512 */ 0x040000, /* 10 : 256x1024 */ 0x100000, /* 11 : 512x2048 */ }, { /* 1:8 aspect ratio */ 0x000020, /* 0 : 8x4 */ 0x000020, /* 1 : 8x4 */ 0x000020, /* 2 : 8x4 */ 0x000040, /* 3 : 8x8 */ 0x000080, /* 4 : 8x16 */ 0x000100, /* 5 : 8x32 */ 0x000200, /* 6 : 8x64 */ 0x000800, /* 7 : 16x128 */ 0x002000, /* 8 : 32x256 */ 0x008000, /* 9 : 64x512 */ 0x020000, /* 10 : 128x1024 */ 0x080000, /* 11 : 256x2048 */ }, }; /* Similar to _grMipMapSize[][] but for 8-bit compressed formats. DXT2,3,4,5 */ static const FxU32 _grMipMapSizeDXT[4][16] = { { /* 8:1 aspect ratio */ 0x000010, /* 0 : 4x4 */ 0x000010, /* 1 : 4x4 */ 0x000010, /* 2 : 4x4 */ 0x000020, /* 3 : 8x4 */ 0x000040, /* 4 : 16x4 */ 0x000080, /* 5 : 32x4 */ 0x000200, /* 6 : 64x8 */ 0x000800, /* 7 : 128x16 */ 0x002000, /* 8 : 256x32 */ 0x008000, /* 9 : 512x64 */ 0x020000, /* 10 : 1024x128 */ 0x080000, /* 11 : 2048x256 */ }, { /* 4:1 aspect ratio */ 0x000010, /* 0 : 4x4 */ 0x000010, /* 1 : 4x4 */ 0x000010, /* 2 : 4x4 */ 0x000020, /* 3 : 8x4 */ 0x000040, /* 4 : 16x4 */ 0x000100, /* 5 : 32x8 */ 0x000400, /* 6 : 64x16 */ 0x001000, /* 7 : 128x32 */ 0x004000, /* 8 : 256x64 */ 0x010000, /* 9 : 512x128 */ 0x040000, /* 10 : 1024x256 */ 0x100000, /* 11 : 2048x512 */ }, { /* 2:1 aspect ratio */ 0x000010, /* 0 : 4x4 */ 0x000010, /* 1 : 4x4 */ 0x000010, /* 2 : 4x4 */ 0x000020, /* 3 : 8x4 */ 0x000080, /* 4 : 16x8 */ 0x000200, /* 5 : 32x16 */ 0x000800, /* 6 : 64x32 */ 0x002000, /* 7 : 128x64 */ 0x008000, /* 8 : 256x128 */ 0x020000, /* 9 : 512x256 */ 0x080000, /* 10 : 1024x512 */ 0x200000, /* 11 : 2048x1024 */ }, { /* 1:1 aspect ratio */ 0x000010, /* 0 : 4x4 */ 0x000010, /* 1 : 4x4 */ 0x000010, /* 2 : 4x4 */ 0x000040, /* 3 : 8x8 */ 0x000100, /* 4 : 16x16 */ 0x000400, /* 5 : 32x32 */ 0x001000, /* 6 : 64x64 */ 0x004000, /* 7 : 128x128 */ 0x010000, /* 8 : 256x256 */ 0x040000, /* 9 : 512x512 */ 0x100000, /* 10 : 1024x1024 */ 0x400000, /* 11 : 2048x2048 */ }, }; /* the offset from mipmap level 0 of each mipmap level in texels */ /* index is [aspect_ratio][lod] */ const FxI32 _grMipMapOffset[4][16] = { /* * The idea here is to add up the sizes of the mipmap levels and * store them as offsets from the beginning of the level whose * larger dimension is 256. To get the size of a particular mipmap * range, take the difference between two entries. Otherwise, take * one entry and consider it an offset from the 256xN level. To * accommodate big textures but not break old apps, use negative * offsets for the big texture entries. -LEW */ { /* 8:1 and 1:8 aspect ratios */ 10927, /* Sum(256x32, 128x16, 64x8, 32x4, 16x2, 8x1, 4x1, 2x1, 1x1) */ 10926, /* Sum(256x32, 128x16, 64x8, 32x4, 16x2, 8x1, 4x1, 2x1) */ 10924, /* Sum(256x32, 128x16, 64x8, 32x4, 16x2, 8x1, 4x1) */ 10920, /* Sum(256x32, 128x16, 64x8, 32x4, 16x2, 8x1) */ 10912, /* Sum(256x32, 128x16, 64x8, 32x4, 16x2) */ 10880, /* Sum(256x32, 128x16, 64x8, 32x4) */ 10752, /* Sum(256x32, 128x16, 64x8) */ 10240, /* Sum(256x32, 128x16) */ 8192, /* Sum(256x32) */ 0, /* Base address (beginning of 256x32 level) */ -32768, /* - Sum(512x64) */ -163840, /* - Sum(1024x128, 512x64) */ -688128, /* - Sum(2048x256, 1024x128, 512x64) */ }, { /* 4:1 and 1:4 aspect ratios */ 21847, /* Sum(256x64, 128x32, 64x16, 32x8, 16x4, 8x2, 4x1, 2x1, 1x1) */ 21846, /* Sum(256x64, 128x32, 64x16, 32x8, 16x4, 8x2, 4x1, 2x1) */ 21844, /* Sum(256x64, 128x32, 64x16, 32x8, 16x4, 8x2, 4x1) */ 21840, /* Sum(256x64, 128x32, 64x16, 32x8, 16x4, 8x2) */ 21824, /* Sum(256x64, 128x32, 64x16, 32x8, 16x4) */ 21760, /* Sum(256x64, 128x32, 64x16, 32x8) */ 21504, /* Sum(256x64, 128x32, 64x16) */ 20480, /* Sum(256x64, 128x32) */ 16384, /* Sum(256x64) */ 0, /* Base address (beginning of 256x64 level) */ -65536, /* - Sum(512x128) */ -327680, /* - Sum(1024x256, 512x128) */ -1376256, /* - Sum(2048x512, 1024x256, 512x128) */ }, { /* 2:1 and 1:2 aspect ratios */ 43691, /* Sum(256x128, 128x64, 64x32, 32x16, 16x8, 8x4, 4x2, 2x1, 1x1)*/ 43690, /* Sum(256x128, 128x64, 64x32, 32x16, 16x8, 8x4, 4x2, 2x1) */ 43688, /* Sum(256x128, 128x64, 64x32, 32x16, 16x8, 8x4, 4x2) */ 43680, /* Sum(256x128, 128x64, 64x32, 32x16, 16x8, 8x4) */ 43648, /* Sum(256x128, 128x64, 64x32, 32x16, 16x8) */ 43520, /* Sum(256x128, 128x64, 64x32, 32x16) */ 43008, /* Sum(256x128, 128x64, 64x32) */ 40960, /* Sum(256x128, 128x64) */ 32768, /* Sum(256x128) */ 0, /* Base address (beginning of 256x128 level) */ -131072, /* - Sum(512x256) */ -655360, /* - Sum(1024x512, 512x256) */ -2752512, /* - Sum(2048x1024, 1024x512, 512x256) */ }, { /* 1:1 aspect ratio */ 87381, /* Sum(256x256, 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2, 1)*/ 87380, /* Sum(256x256, 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2) */ 87376, /* Sum(256x256, 128x128, 64x64, 32x32, 16x16, 8x8, 4x4) */ 87360, /* Sum(256x256, 128x128, 64x64, 32x32, 16x16, 8x8) */ 87296, /* Sum(256x256, 128x128, 64x64, 32x32, 16x16) */ 87040, /* Sum(256x256, 128x128, 64x64, 32x32) */ 86016, /* Sum(256x256, 128x128, 64x64) */ 81920, /* Sum(256x256, 128x128) */ 65536, /* Sum(256x256) */ 0, /* Base address (beginning of 256x256 level) */ -262144, /* - Sum(512x512) */ -1310720, /* - Sum(1024x1024, 512x512) */ -5505024, /* - Sum(2048x2048, 1024x1024, 512x512) */ }, }; /* * Similar to _grMipMapOffset[][], but for 4-bit compressed * textures, where 8x4 is the minimum size. FXT1,DXT1 */ const FxI32 _grMipMapOffsetCmp4Bit[7][16] = { { /* 8:1 aspect ratio */ 11072, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4,8x4,8x4,8x4) */ 11040, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4,8x4,8x4) */ 11008, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4,8x4) */ 10976, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4) */ 10944, /* Sum(256x32,128x16,64x8,32x4,16x4) */ 10880, /* Sum(256x32,128x16,64x8,32x4) */ 10752, /* Sum(256x32,128x16,64x8) */ 10240, /* Sum(256x32,128x16) */ 8192, /* Sum(256x32) */ 0, /* Base address (beginning of 512x64 level) */ -32768, /* - Sum(512x64) */ -163840, /* - Sum(1024x128,512x64) */ -688128, /* - Sum(2048x256,1024x128,512x64) */ }, { /* 4:1 aspect ratio */ 21952, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4,8x4,8x4,8x4) */ 21920, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4,8x4,8x4) */ 21888, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4,8x4) */ 21856, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4) */ 21824, /* Sum(256x64,128x32,64x16,32x8,16x4) */ 21760, /* Sum(256x64,128x32,64x16,32x8) */ 21504, /* Sum(256x64,128x32,64x16) */ 20480, /* Sum(256x64,128x32) */ 16384, /* Sum(256x64) */ 0, /* Base address (beginning of 512x128 level) */ -65536, /* - Sum(512x128) */ -327680, /* - Sum(1024x256,512x128) */ -1376256, /* - Sum(2048x512,1024x256,512x128) */ }, { /* 2:1 aspect ratio */ 43776, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4,8x4,8x4,8x4) */ 43744, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4,8x4,8x4) */ 43712, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4,8x4) */ 43680, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4) */ 43648, /* Sum(256x128,128x64,64x32,32x16,16x8) */ 43520, /* Sum(256x128,128x64,64x32,32x16) */ 43008, /* Sum(256x128,128x64,64x32) */ 40960, /* Sum(256x128,128x64) */ 32768, /* Sum(256x128) */ 0, /* Base address (beginning of 512x256 level) */ -131072, /* - Sum(512x256) */ -655360, /* - Sum(1024x512,512x256) */ -2752512, /* - Sum(2048x1024,1024x512,512x256) */ }, { /* 1:1 aspect ratio */ 87456, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8,8x4,8x4,8x4) */ 87424, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8,8x4,8x4) */ 87392, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8,8x4) */ 87360, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8) */ 87296, /* Sum(256x256,128x128,64x64,32x32,16x16) */ 87040, /* Sum(256x256,128x128,64x64,32x32) */ 86016, /* Sum(256x256,128x128,64x64) */ 81920, /* Sum(256x256,128x128) */ 65536, /* Sum(256x256) */ 0, /* Base address (beginning of 512x512 level) */ -262144, /* - Sum(512x512) */ -1310720, /* - Sum(1024x1024,512x512) */ -5505024, /* - Sum(2048x2048,1024x1024,512x512) */ }, { /* 1:2 aspect ratio */ 43808, /* Sum(128x256,64x128,32x64,16x32,8x16,8x8,8x4,8x4,8x4) */ 43776, /* Sum(128x256,64x128,32x64,16x32,8x16,8x8,8x4,8x4) */ 43744, /* Sum(128x256,64x128,32x64,16x32,8x16,8x8,8x4) */ 43712, /* Sum(128x256,64x128,32x64,16x32,8x16,8x8) */ 43648, /* Sum(128x256,64x128,32x64,16x32,8x16) */ 43520, /* Sum(128x256,64x128,32x64,16x32) */ 43008, /* Sum(128x256,64x128,32x64) */ 40960, /* Sum(128x256,64x128) */ 32768, /* Sum(128x256) */ 0, /* Base address (beginning of 256x512 level) */ -131072, /* - Sum(256x512) */ -655360, /* - Sum(512x1024,256x512) */ -2752512, /* - Sum(1024x2048,512x1024,256x512) */ }, { /* 1:4 aspect ratio */ 22048, /* Sum(64x256,32x128,16x64,8x32,8x16,8x8,8x4,8x4,8x4) */ 22016, /* Sum(64x256,32x128,16x64,8x32,8x16,8x8,8x4,8x4) */ 21984, /* Sum(64x256,32x128,16x64,8x32,8x16,8x8,8x4) */ 21952, /* Sum(64x256,32x128,16x64,8x32,8x16,8x8) */ 21888, /* Sum(64x256,32x128,16x64,8x32,8x16) */ 21760, /* Sum(64x256,32x128,16x64,8x32) */ 21504, /* Sum(64x256,32x128,16x64) */ 20480, /* Sum(64x256,32x128) */ 16384, /* Sum(64x256) */ 0, /* Base address (beginning of 128x512 level) */ -65536, /* - Sum(128x512) */ -327680, /* - Sum(256x1024,128x512) */ -1376256, /* - Sum(512x2048,256x1024,128x512) */ }, { /* 1:8 aspect ratio */ 11296, /* Sum(32x256,16x128,8x64,8x32,8x16,8x8,8x4,8x4,8x4) */ 11264, /* Sum(32x256,16x128,8x64,8x32,8x16,8x8,8x4,8x4) */ 11232, /* Sum(32x256,16x128,8x64,8x32,8x16,8x8,8x4) */ 11200, /* Sum(32x256,16x128,8x64,8x32,8x16,8x8) */ 11136, /* Sum(32x256,16x128,8x64,8x32,8x16) */ 11008, /* Sum(32x256,16x128,8x64,8x32) */ 10752, /* Sum(32x256,16x128,8x64) */ 10240, /* Sum(32x256,16x128) */ 8192, /* Sum(32x256) */ 0, /* Base address (beginning of 64x512 level) */ -32768, /* - Sum(64x512) */ -163840, /* - Sum(128x1024,64x512) */ -688128, /* - Sum(256x2048,128x1024,64x512) */ }, }; /* * Similar to _grMipMapOffset[][], but for 8-bit compressed * textures, where 4x4 is the minimum size. DXT2,3,4,5 */ const FxI32 _grMipMapOffsetDXT[4][16] = { { /* 8:1 aspect ratio */ 11024, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4,4x4,4x4,4x4) */ 11008, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4,4x4,4x4) */ 10992, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4,4x4) */ 10976, /* Sum(256x32,128x16,64x8,32x4,16x4,8x4) */ 10944, /* Sum(256x32,128x16,64x8,32x4,16x4) */ 10880, /* Sum(256x32,128x16,64x8,32x4) */ 10752, /* Sum(256x32,128x16,64x8) */ 10240, /* Sum(256x32,128x16) */ 8192, /* Sum(256x32) */ 0, /* Base address (beginning of 512x64 level) */ -32768, /* - Sum(512x64) */ -163840, /* - Sum(1024x128,512x64) */ -688128, /* - Sum(2048x256,1024x128,512x64) */ }, { /* 4:1 aspect ratio */ 21904, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4,4x4,4x4,4x4) */ 21888, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4,4x4,4x4) */ 21872, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4,4x4) */ 21856, /* Sum(256x64,128x32,64x16,32x8,16x4,8x4) */ 21824, /* Sum(256x64,128x32,64x16,32x8,16x4) */ 21760, /* Sum(256x64,128x32,64x16,32x8) */ 21504, /* Sum(256x64,128x32,64x16) */ 20480, /* Sum(256x64,128x32) */ 16384, /* Sum(256x64) */ 0, /* Base address (beginning of 512x128 level) */ -65536, /* - Sum(512x128) */ -327680, /* - Sum(1024x256,512x128) */ -1376256, /* - Sum(2048x512,1024x256,512x128) */ }, { /* 2:1 aspect ratio */ 43728, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4,4x4,4x4,4x4) */ 43712, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4,4x4,4x4) */ 43696, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4,4x4) */ 43680, /* Sum(256x128,128x64,64x32,32x16,16x8,8x4) */ 43648, /* Sum(256x128,128x64,64x32,32x16,16x8) */ 43520, /* Sum(256x128,128x64,64x32,32x16) */ 43008, /* Sum(256x128,128x64,64x32) */ 40960, /* Sum(256x128,128x64) */ 32768, /* Sum(256x128) */ 0, /* Base address (beginning of 512x256 level) */ -131072, /* - Sum(512x256) */ -655360, /* - Sum(1024x512,512x256) */ -2752512, /* - Sum(2048x1024,1024x512,512x256) */ }, { /* 1:1 aspect ratio */ 87408, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8,4x4,4x4,4x4) */ 87392, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8,4x4,4x4) */ 87376, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8,4x4) */ 87360, /* Sum(256x256,128x128,64x64,32x32,16x16,8x8) */ 87296, /* Sum(256x256,128x128,64x64,32x32,16x16) */ 87040, /* Sum(256x256,128x128,64x64,32x32) */ 86016, /* Sum(256x256,128x128,64x64) */ 81920, /* Sum(256x256,128x128) */ 65536, /* Sum(256x256) */ 0, /* Base address (beginning of 512x512 level) */ -262144, /* - Sum(512x512) */ -1310720, /* - Sum(1024x1024,512x512) */ -5505024, /* - Sum(2048x2048,1024x1024,512x512) */ }, }; const FxI32 _grMipMapOffset_Tsplit[4][16] = { { /* 8:1 and 1:8 aspect ratios */ 8741, /* Sum(256x32, 64x8, 16x2, 4x1, 1x1) */ 2186, /* Sum(128x16, 32x4, 8x1, 2x1) */ 8740, /* Sum(256x32, 64x8, 16x2, 4x1) */ 2184, /* Sum(128x16, 32x4, 8x1) */ 8736, /* Sum(256x32, 64x8, 16x2) */ 2176, /* Sum(128x16, 32x4) */ 8704, /* Sum(256x32, 64x8) */ 2048, /* Sum(128x16) */ 8192, /* Sum(256x32) */ 0, /* Base address (beginning of 128x16 level) */ 0, /* Base address (beginning of 256x32 level) */ -32768, /* - Sum(512x64) */ -131072, /* - Sum(1024x128) */ -557056, /* - Sum(2048x256, 512x64) */ }, { /* 4:1 and 1:4 aspect ratios */ 17477, /* Sum(256x64, 64x16, 16x4, 4x1, 1x1) */ 4370, /* Sum(128x32, 32x8, 8x2, 2x1) */ 17476, /* Sum(256x64, 64x16, 16x4, 4x1) */ 4368, /* Sum(128x32, 32x8, 8x2) */ 17472, /* Sum(256x64, 64x16, 16x4) */ 4352, /* Sum(128x32, 32x8) */ 17408, /* Sum(256x64, 64x16) */ 4096, /* Sum(128x32) */ 16384, /* Sum(256x64) */ 0, /* Base address (beginning of 128x32 level) */ 0, /* Base address (beginning of 256x64 level) */ -65536, /* - Sum(512x128) */ -262144, /* - Sum(1024x256) */ -1114112, /* - Sum(2048x512, 512x128) */ }, { /* 2:1 and 1:2 aspect ratios */ 34953, /* Sum(256x128, 64x32, 16x8, 4x2, 1x1) */ 8738, /* Sum(128x64, 32x16, 8x4, 2x1) */ 34952, /* Sum(256x128, 64x32, 16x8, 4x2) */ 8736, /* Sum(128x64, 32x16, 8x4) */ 34944, /* Sum(256x128, 64x32, 16x8) */ 8704, /* Sum(128x64, 32x16) */ 34816, /* Sum(256x128, 64x32) */ 8192, /* Sum(128x64) */ 32768, /* Sum(256x128) */ 0, /* Base address (beginning of 128x64 level) */ 0, /* Base address (beginning of 256x128 level) */ -131072, /* - Sum(512x256) */ -524288, /* - Sum(1024x512) */ -2228224, /* - Sum(2048x1024, 512x256) */ }, { /* 1:1 aspect ratio */ 69905, /* Sum(256x256, 64x64, 16x16, 4x4, 1x1) */ 17476, /* Sum(128x128, 32x32, 8x8, 2x2) */ 69904, /* Sum(256x256, 64x64, 16x16, 4x4) */ 17472, /* Sum(128x128, 32x32, 8x8) */ 69888, /* Sum(256x256, 64x64, 16x16) */ 17408, /* Sum(128x128, 32x32) */ 69632, /* Sum(256x256, 64x64) */ 16384, /* Sum(128x128) */ 65536, /* Sum(256x256) */ 0, /* Base address (beginning of 128x128 level) */ 0, /* Base address (beginning of 256x256 level) */ -262144, /* - Sum(512x512) */ -1048576, /* - Sum(1024x1024) */ -4456448, /* - Sum(2048x2048, 512x512) */ }, }; /* * Similar to _grMipMapOffset_Tsplit[][], but for 4-bit compressed * textures, where 8x4 is the minimum size. FXT1,DXT1 */ const FxI32 _grMipMapOffset_TsplitCmp4Bit[7][16] = { { /* 8:1 aspect ratio */ 8832, /* Sum(256x32,64x8,16x4,8x4,8x4) */ 2240, /* Sum(128x16,32x4,8x4,8x4) */ 8800, /* Sum(256x32,64x8,16x4,8x4) */ 2208, /* Sum(128x16,32x4,8x4) */ 8768, /* Sum(256x32,64x8,16x4) */ 2176, /* Sum(128x16,32x4) */ 8704, /* Sum(256x32,64x8) */ 2048, /* Sum(128x16) */ 8192, /* Sum(256x32) */ 0, /* Base address (beginning of 128x16 level) */ 0, /* Base address (beginning of 256x32 level) */ -32768, /* - Sum(512x64) */ -131072, /* - Sum(1024x128) */ -557056, /* - Sum(2048x256,512x64) */ }, { /* 4:1 aspect ratio */ 17536, /* Sum(256x64,64x16,16x4,8x4,8x4) */ 4416, /* Sum(128x32,32x8,8x4,8x4) */ 17504, /* Sum(256x64,64x16,16x4,8x4) */ 4384, /* Sum(128x32,32x8,8x4) */ 17472, /* Sum(256x64,64x16,16x4) */ 4352, /* Sum(128x32,32x8) */ 17408, /* Sum(256x64,64x16) */ 4096, /* Sum(128x32) */ 16384, /* Sum(256x64) */ 0, /* Base address (beginning of 128x32 level) */ 0, /* Base address (beginning of 256x64 level) */ -65536, /* - Sum(512x128) */ -262144, /* - Sum(1024x256) */ -1114112, /* - Sum(2048x512,512x128) */ }, { /* 2:1 aspect ratio */ 35008, /* Sum(256x128,64x32,16x8,8x4,8x4) */ 8768, /* Sum(128x64,32x16,8x4,8x4) */ 34976, /* Sum(256x128,64x32,16x8,8x4) */ 8736, /* Sum(128x64,32x16,8x4) */ 34944, /* Sum(256x128,64x32,16x8) */ 8704, /* Sum(128x64,32x16) */ 34816, /* Sum(256x128,64x32) */ 8192, /* Sum(128x64) */ 32768, /* Sum(256x128) */ 0, /* Base address (beginning of 128x64 level) */ 0, /* Base address (beginning of 256x128 level) */ -131072, /* - Sum(512x256) */ -524288, /* - Sum(1024x512) */ -2228224, /* - Sum(2048x1024,512x256) */ }, { /* 1:1 aspect ratio */ 69952, /* Sum(256x256,64x64,16x16,8x4,8x4) */ 17504, /* Sum(128x128,32x32,8x8,8x4) */ 69920, /* Sum(256x256,64x64,16x16,8x4) */ 17472, /* Sum(128x128,32x32,8x8) */ 69888, /* Sum(256x256,64x64,16x16) */ 17408, /* Sum(128x128,32x32) */ 69632, /* Sum(256x256,64x64) */ 16384, /* Sum(128x128) */ 65536, /* Sum(256x256) */ 0, /* Base address (beginning of 128x128 level) */ 0, /* Base address (beginning of 256x256 level) */ -262144, /* - Sum(512x512) */ -1048576, /* - Sum(1024x1024) */ -4456448, /* - Sum(2048x2048,512x512) */ }, { /* 1:2 aspect ratio */ 35008, /* Sum(128x256,32x64,8x16,8x4,8x4) */ 8800, /* Sum(64x128,16x32,8x8,8x4) */ 34976, /* Sum(128x256,32x64,8x16,8x4) */ 8768, /* Sum(64x128,16x32,8x8) */ 34944, /* Sum(128x256,32x64,8x16) */ 8704, /* Sum(64x128,16x32) */ 34816, /* Sum(128x256,32x64) */ 8192, /* Sum(64x128) */ 32768, /* Sum(128x256) */ 0, /* Base address (beginning of 64x128 level) */ 0, /* Base address (beginning of 128x256 level) */ -131072, /* - Sum(256x512) */ -524288, /* - Sum(512x1024) */ -2228224, /* - Sum(1024x2048,256x512) */ }, { /* 1:4 aspect ratio */ 17600, /* Sum(64x256,16x64,8x16,8x4,8x4) */ 4448, /* Sum(32x128,8x32,8x8,8x4) */ 17568, /* Sum(64x256,16x64,8x16,8x4) */ 4416, /* Sum(32x128,8x32,8x8) */ 17536, /* Sum(64x256,16x64,8x16) */ 4352, /* Sum(32x128,8x32) */ 17408, /* Sum(64x256,16x64) */ 4096, /* Sum(32x128) */ 16384, /* Sum(64x256) */ 0, /* Base address (beginning of 32x128 level) */ 0, /* Base address (beginning of 64x256 level) */ -65536, /* - Sum(128x512) */ -262144, /* - Sum(256x1024) */ -1114112, /* - Sum(512x2048,128x512) */ }, { /* 1:8 aspect ratio */ 8896, /* Sum(32x256,8x64,8x16,8x4,8x4) */ 2400, /* Sum(16x128,8x32,8x8,8x4) */ 8864, /* Sum(32x256,8x64,8x16,8x4) */ 2368, /* Sum(16x128,8x32,8x8) */ 8832, /* Sum(32x256,8x64,8x16) */ 2304, /* Sum(16x128,8x32) */ 8704, /* Sum(32x256,8x64) */ 2048, /* Sum(16x128) */ 8192, /* Sum(32x256) */ 0, /* Base address (beginning of 16x128 level) */ 0, /* Base address (beginning of 32x256 level) */ -32768, /* - Sum(64x512) */ -131072, /* - Sum(128x1024) */ -557056, /* - Sum(256x2048,64x512) */ }, }; /* * Similar to _grMipMapOffset_Tsplit[][], but for 8-bit compressed * textures, where 4x4 is the minimum size. DXT2,3,4,5 */ const FxI32 _grMipMapOffset_TsplitDXT[4][16] = { { /* 8:1 aspect ratio */ 8800, /* Sum(256x32,64x8,16x4,4x4,4x4) */ 2224, /* Sum(128x16,32x4,8x4,4x4) */ 8784, /* Sum(256x32,64x8,16x4,4x4) */ 2208, /* Sum(128x16,32x4,8x4) */ 8768, /* Sum(256x32,64x8,16x4) */ 2176, /* Sum(128x16,32x4) */ 8704, /* Sum(256x32,64x8) */ 2048, /* Sum(128x16) */ 8192, /* Sum(256x32) */ 0, /* Base address (beginning of 128x16 level) */ 0, /* Base address (beginning of 256x32 level) */ -32768, /* - Sum(512x64) */ -131072, /* - Sum(1024x128) */ -557056, /* - Sum(2048x256,512x64) */ }, { /* 4:1 aspect ratio */ 17504, /* Sum(256x64,64x16,16x4,4x4,4x4) */ 4400, /* Sum(128x32,32x8,8x4,4x4) */ 17488, /* Sum(256x64,64x16,16x4,4x4) */ 4384, /* Sum(128x32,32x8,8x4) */ 17472, /* Sum(256x64,64x16,16x4) */ 4352, /* Sum(128x32,32x8) */ 17408, /* Sum(256x64,64x16) */ 4096, /* Sum(128x32) */ 16384, /* Sum(256x64) */ 0, /* Base address (beginning of 128x32 level) */ 0, /* Base address (beginning of 256x64 level) */ -65536, /* - Sum(512x128) */ -262144, /* - Sum(1024x256) */ -1114112, /* - Sum(2048x512,512x128) */ }, { /* 2:1 aspect ratio */ 34976, /* Sum(256x128,64x32,16x8,4x4,4x4) */ 8752, /* Sum(128x64,32x16,8x4,4x4) */ 34960, /* Sum(256x128,64x32,16x8,4x4) */ 8736, /* Sum(128x64,32x16,8x4) */ 34944, /* Sum(256x128,64x32,16x8) */ 8704, /* Sum(128x64,32x16) */ 34816, /* Sum(256x128,64x32) */ 8192, /* Sum(128x64) */ 32768, /* Sum(256x128) */ 0, /* Base address (beginning of 128x64 level) */ 0, /* Base address (beginning of 256x128 level) */ -131072, /* - Sum(512x256) */ -524288, /* - Sum(1024x512) */ -2228224, /* - Sum(2048x1024,512x256) */ }, { /* 1:1 aspect ratio */ 69920, /* Sum(256x256,64x64,16x16,4x4,4x4) */ 17488, /* Sum(128x128,32x32,8x8,4x4) */ 69904, /* Sum(256x256,64x64,16x16,4x4) */ 17472, /* Sum(128x128,32x32,8x8) */ 69888, /* Sum(256x256,64x64,16x16) */ 17408, /* Sum(128x128,32x32) */ 69632, /* Sum(256x256,64x64) */ 16384, /* Sum(128x128) */ 65536, /* Sum(256x256) */ 0, /* Base address (beginning of 128x128 level) */ 0, /* Base address (beginning of 256x256 level) */ -262144, /* - Sum(512x512) */ -1048576, /* - Sum(1024x1024) */ -4456448, /* - Sum(2048x2048,512x512) */ }, }; /*--------------------------------------------------------------------------- ** This is not DI anymore. Perhaps all of these size routines need ** to be in gtex.c now. */ FxU32 _grTexTextureMemRequired( GrLOD_t small_lod, GrLOD_t large_lod, GrAspectRatio_t aspect, GrTextureFormat_t format, FxU32 evenOdd, FxBool roundP, FxBool systemMem ) { #define FN_NAME "_grTexTextureMemRequired" FxU32 memrequired; GDBG_INFO(80,"_grTexTextureMemRequired(%d,%d, %d,%d, %d, %d, %d)\n", small_lod, large_lod, aspect, format, evenOdd, roundP, systemMem); GR_CHECK_W(FN_NAME, small_lod > large_lod, "small_lod bigger than large_lod" ); GR_CHECK_F(FN_NAME, evenOdd > GR_MIPMAPLEVELMASK_BOTH || evenOdd == 0, "invalid evenOdd mask" ); GR_CHECK_F(FN_NAME, _grBitsPerTexel[format] == 0, "invalid texture format"); switch(format) { case GR_TEXFMT_ARGB_CMP_FXT1: /* In this case, do not mirror the aspect ratios, as the minimum * size of a mipmap level is 8x4, so the tables are not symmetric * w.r.t. sign of the aspect ratio, so keep the sign. */ if ( evenOdd == GR_MIPMAPLEVELMASK_BOTH ) { memrequired = _grMipMapOffsetCmp4Bit[G3_ASPECT_TRANSLATE(aspect)] [small_lod]; memrequired -= _grMipMapOffsetCmp4Bit[G3_ASPECT_TRANSLATE(aspect)] [large_lod+1]; } else { memrequired = 0; /* construct XOR mask */ evenOdd = (evenOdd == GR_MIPMAPLEVELMASK_EVEN) ? 1 : 0; while (large_lod >= small_lod) { /* sum up all the mipmap levels */ if ((large_lod ^ evenOdd) & 1) /* that match the XOR mask */ memrequired += _grMipMapSizeCmp4Bit[G3_ASPECT_TRANSLATE(aspect)] [large_lod]; large_lod--; } } break; case GR_TEXFMT_ARGB_CMP_DXT1: /* XXX check this! */ if(systemMem) { /* calculating for system memory */ /* In this case, do not mirror the aspect ratios, as the minimum * size of a mipmap level is 8x4, so the tables are not symmetric * w.r.t. sign of the aspect ratio, so keep the sign. */ if ( evenOdd == GR_MIPMAPLEVELMASK_BOTH ) { memrequired = _grMipMapOffsetCmp4Bit[G3_ASPECT_TRANSLATE(aspect)][small_lod]; memrequired -= _grMipMapOffsetCmp4Bit[G3_ASPECT_TRANSLATE(aspect)][large_lod+1]; } else { memrequired = 0; /* construct XOR mask */ evenOdd = (evenOdd == GR_MIPMAPLEVELMASK_EVEN) ? 1 : 0; while (large_lod >= small_lod) { /* sum up all the mipmap levels */ if ((large_lod ^ evenOdd) & 1) { /* that match the XOR mask */ memrequired += _grMipMapSizeCmp4Bit[G3_ASPECT_TRANSLATE(aspect)][large_lod]; } large_lod--; } } } else { /* for texture memory on hardware */ /* allows us to mirror the aspect ratios because the table entries are the same */ if (aspect < GR_ASPECT_LOG2_1x1) { aspect = -aspect; } if ( evenOdd == GR_MIPMAPLEVELMASK_BOTH ) { memrequired = _grMipMapOffsetDXT[G3_ASPECT_TRANSLATE(aspect)][small_lod]; memrequired -= _grMipMapOffsetDXT[G3_ASPECT_TRANSLATE(aspect)][large_lod+1]; } else { memrequired = 0; /* construct XOR mask */ evenOdd = (evenOdd == GR_MIPMAPLEVELMASK_EVEN) ? 1 : 0; while (large_lod >= small_lod) { /* sum up all the mipmap levels */ if ((large_lod ^ evenOdd) & 1) { /* that match the XOR mask */ memrequired += _grMipMapSizeDXT[G3_ASPECT_TRANSLATE(aspect)][large_lod]; } large_lod--; } } } break; case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* DXT2,3,4,5 formats allow us to mirror the aspect ratios because the table entries are the same */ if (aspect < GR_ASPECT_LOG2_1x1) aspect = -aspect; if ( evenOdd == GR_MIPMAPLEVELMASK_BOTH ) { memrequired = _grMipMapOffsetDXT[G3_ASPECT_TRANSLATE(aspect)][small_lod]; memrequired -= _grMipMapOffsetDXT[G3_ASPECT_TRANSLATE(aspect)][large_lod+1]; } else { memrequired = 0; /* construct XOR mask */ evenOdd = (evenOdd == GR_MIPMAPLEVELMASK_EVEN) ? 1 : 0; while (large_lod >= small_lod) { /* sum up all the mipmap levels */ if ((large_lod ^ evenOdd) & 1) /* that match the XOR mask */ memrequired += _grMipMapSizeDXT[G3_ASPECT_TRANSLATE(aspect)][large_lod]; large_lod--; } } break; default: /* Non-FXT1 formats allow us to mirror the aspect ratios because the table entries are the same for, e.g., 1x8 as for 8x1 */ if (aspect < GR_ASPECT_LOG2_1x1) aspect = -aspect; if ( evenOdd == GR_MIPMAPLEVELMASK_BOTH ) { memrequired = _grMipMapOffset[G3_ASPECT_TRANSLATE(aspect)][small_lod]; memrequired -= _grMipMapOffset[G3_ASPECT_TRANSLATE(aspect)][large_lod+1]; } else { memrequired = 0; /* construct XOR mask */ evenOdd = (evenOdd == GR_MIPMAPLEVELMASK_EVEN) ? 1 : 0; while (large_lod >= small_lod) { /* sum up all the mipmap levels */ if ((large_lod ^ evenOdd) & 1) /* that match the XOR mask */ memrequired += _grMipMapSize[G3_ASPECT_TRANSLATE(aspect)][large_lod]; large_lod--; } } } /* convert from texels to bytes */ memrequired *= _grBitsPerTexel[format]; /* bits */ memrequired >>= 3; /* bytes */ if (roundP) { /* round up to hw alignment boundary */ memrequired += SST_TEXTURE_ALIGN_MASK; memrequired &= ~SST_TEXTURE_ALIGN_MASK; } return memrequired; #undef FN_NAME } /* _grTexTextureMemRequired */ #if 0 /* KoolSmoky - remove junk */ FxU16 _grTexFloatLODToFixedLOD( float value ) { float num_quarters; int new_value; num_quarters = ( value + .125F ) / .25F; new_value = ( int ) num_quarters; new_value &= 0x003F; return new_value; } /* _grTexFloatLODToFixedLOD */ #endif /*--------------------------------------------------------------------------- ** _grTexCalcBaseAddress */ FxU32 _grTexCalcBaseAddress( FxU32 start, GrLOD_t large_lod, GrAspectRatio_t aspect, GrTextureFormat_t format, FxU32 odd_even_mask ) { #define FN_NAME "_grTexCalcBaseAddress" FxU32 sum_of_lod_sizes; GR_DCL_GC; GR_CHECK_F(FN_NAME, _grBitsPerTexel[format] == 0, "invalid texture format"); switch(format) { case GR_TEXFMT_ARGB_CMP_FXT1: /* FXT1 format: Don't mirror the aspect ratios, because of the 8x4 limit */ if ( odd_even_mask == GR_MIPMAPLEVELMASK_BOTH ) { sum_of_lod_sizes = _grMipMapOffsetCmp4Bit[aspect] [large_lod + 1]; } else { if (((odd_even_mask == GR_MIPMAPLEVELMASK_EVEN) && (large_lod & 1)) || ((odd_even_mask == GR_MIPMAPLEVELMASK_ODD) && !(large_lod & 1))) large_lod += 1 ; else large_lod += 2 ; /* as it turns out, this is important for FXT1 as well */ sum_of_lod_sizes = _grMipMapOffset_TsplitCmp4Bit[aspect][large_lod]; } break; case GR_TEXFMT_ARGB_CMP_DXT1: /* XXX check this! */ case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* DXT2,3,4,5 format: mirror the aspect ratios */ if ( aspect > G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x1) ) aspect = G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) - aspect; if ( odd_even_mask == GR_MIPMAPLEVELMASK_BOTH ) { sum_of_lod_sizes = _grMipMapOffsetDXT[aspect][large_lod + 1]; } else { if (((odd_even_mask == GR_MIPMAPLEVELMASK_EVEN) && (large_lod & 1)) || ((odd_even_mask == GR_MIPMAPLEVELMASK_ODD) && !(large_lod & 1))) large_lod += 1 ; else large_lod += 2 ; sum_of_lod_sizes = _grMipMapOffset_TsplitDXT[aspect][large_lod]; } break; default: if ( aspect > G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x1) ) /* mirror aspect ratios */ aspect = G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) - aspect; if ( odd_even_mask == GR_MIPMAPLEVELMASK_BOTH ) { sum_of_lod_sizes = _grMipMapOffset[aspect][large_lod + 1]; } else { if (((odd_even_mask == GR_MIPMAPLEVELMASK_EVEN) && (large_lod & 1)) || ((odd_even_mask == GR_MIPMAPLEVELMASK_ODD) && !(large_lod & 1))) large_lod += 1; else /* jcochrane - original reading wrong offset values for single pass trilinear, tsplit across tmu's */ large_lod += 2; /* this is the correct offset for (even large lod && odd mipmap level) || (odd large lod && even mipmap level) */ sum_of_lod_sizes = _grMipMapOffset_Tsplit[aspect][large_lod]; } } /* Convert from texels to bytes */ sum_of_lod_sizes *= _grBitsPerTexel[format]; /* bits */ sum_of_lod_sizes >>= 3; /* bytes */ /* Clamp the size down. The hw is still going to use the complete * size computation, but it always starts from an aligned baseAddr * so we need to take this into account before doing the subtraction * otherwise we'll be on the wrong 'side' of the minimum aligned * allocation unit. */ sum_of_lod_sizes &= ~SST_TEXTURE_ALIGN_MASK; return ( start - sum_of_lod_sizes ); #undef FN_NAME } /* _grTexCalcBaseAddress */ /*--------------------------------------------------------------------------- ** grTexCalcMemRequired */ GR_DIENTRY(grTexCalcMemRequired, FxU32, ( GrLOD_t small_lod, GrLOD_t large_lod, GrAspectRatio_t aspect, GrTextureFormat_t format )) { FxU32 memrequired; memrequired = _grTexTextureMemRequired(small_lod, large_lod, aspect, format, GR_MIPMAPLEVELMASK_BOTH, FXTRUE, FXFALSE); GDBG_INFO(88,"grTexCalcMemRequired(%d,%d,%d,%d) => 0x%x(%d)\n", small_lod,large_lod,aspect,format,memrequired,memrequired); return memrequired; } /* grTexCalcMemRequired */ /*--------------------------------------------------------------------------- ** grTexDetailControl */ GR_DIENTRY(grTexDetailControl, void, ( GrChipID_t tmu, int lod_bias, FxU8 detail_scale, float detail_max )) { #define FN_NAME "grTexDetailControl" FxU32 tDetail; FxU32 dmax = ( FxU32 ) ( detail_max * _GlideRoot.pool.f255 ); FxU32 dscale = detail_scale; GR_BEGIN_NOFIFOCHECK("grTexDetailControl",88); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%g)\n",tmu,detail_scale,detail_max); GR_CHECK_TMU( FN_NAME, tmu ); GR_CHECK_F( myName, lod_bias < -32 || lod_bias > 31, "lod_bias out of range" ); GR_CHECK_F( myName, detail_scale > 7, "detail_scale out of range" ); GR_CHECK_F( myName, detail_max < 0.0 || detail_max > 1.0, "detail_max out of range" ); tDetail = ( ( lod_bias << SST_DETAIL_BIAS_SHIFT ) & SST_DETAIL_BIAS ); tDetail |= ( ( dmax << SST_DETAIL_MAX_SHIFT ) & SST_DETAIL_MAX ); tDetail |= ( ( dscale << SST_DETAIL_SCALE_SHIFT ) & SST_DETAIL_SCALE ); /* MULTIPLAT */ _grTexDetailControl( tmu, tDetail ); GR_END(); #undef FN_NAME } /* grTexDetailControl */ /* Matt M. - Richardson - (edited by CHD) ** ** Changes below fix PRS #585 ** Some games cause an error when launching with Glide3x o ** V3. This is a work around for an application fault. ** Games are calling grTexMinAddress before we get a call t ** winOpen. The code below replaces GR_BEGIN_NOFIFOCHECK_RET ** Note that this has been a somewhat common error for MaxAddress ** and MinAddress, so I've go a workaround in both places. */ GR_DIENTRY(grTexMinAddress, FxU32, ( GrChipID_t tmu )) { #define FN_NAME "grTexMinAddress" GR_DCL_GC; /* Initialize GC */ GR_DCL_HW_INIT; /* Declare *hw variable */ GR_DEBUG_DCL_INIT(); /* Declare debug variables */ if (!gc) /* If Gc is not valid, return 0 */ return 0; if (!gc->base_ptr) /* If we hit one of these, something didn't get called in the right */ return 0; /* order by the application. */ #if defined( GLIDE_INIT_HWC ) if (!gc->bInfo) return 0; #endif if (!gc->tex_ptr) return 0; GR_DEBUG_DCL_STAGE2("grTexMinAddress", 88); if (!gc->sstRegs) return 0; GR_DCL_HW_STAGE2; FXUNUSED(hw); #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) if (!gc->lostContext) return 0; if (gc->lostContext) { if (*gc->lostContext) { return 0; } } #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ GDBG_INFO_MORE(gc->myLevel,"(%d)\n",tmu); GR_CHECK_TMU(FN_NAME, tmu); FXUNUSED( tmu ); GR_RETURN(0); #undef FN_NAME } /* grTexMinAddress */ /*------------------------------------------------------------------- Function: grTexMaxAddress Date: 6/2 Implementor(s): GaryT Library: glide Description: Returns address of maximum extent of texture ram for a given TMU Arguments: tmu Return: the largest valid texture start Address -------------------------------------------------------------------*/ GR_DIENTRY(grTexMaxAddress, FxU32, ( GrChipID_t tmu )) { #define FN_NAME "grTexMaxAddress" GR_DCL_GC; /* Initialize GC */ GR_DCL_HW_INIT; /* Declare *hw variable */ GR_DEBUG_DCL_INIT(); /* Declare debug variables */ #define MIN_TEX_MEM 0x200000 /* Matt M. - Richardson - Changes below fix PRS #585 ** Some games cause an error when launching with Glide3x o ** V3. This is a work around for an application fault ** Games are calling grTexMinAddress before we get a call t ** winOpen. The code below replaces GR_BEGIN_NOFIFOCHECK_RET */ if (!gc) /* If Gc is not valid, return 0 */ return MIN_TEX_MEM; /* Always guaranteed */ if (!gc->base_ptr) /* If we hit one of these, something */ return MIN_TEX_MEM; /* didn't get called in the right */ /* order by the application. */ #if defined( GLIDE_INIT_HWC ) if (!gc->bInfo) return MIN_TEX_MEM; #endif if (!gc->rawLfb) /* since we use rawLfb for texture download */ return MIN_TEX_MEM; GR_DEBUG_DCL_STAGE2("grTexMaxAddress", 88); if (!gc->sstRegs) return 0; GR_DCL_HW_STAGE2; FXUNUSED(hw); #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) if (!gc->lostContext) return 0; if (gc->lostContext) { if (*gc->lostContext) { return 0; } } #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ GDBG_INFO_MORE(gc->myLevel,"(%d)\n",tmu); GR_CHECK_TMU(FN_NAME, tmu ); GR_RETURN(gc->tmu_state[tmu].total_mem - SST_TEXTURE_ALIGN); #undef FN_NAME } /* grTexMaxAddress */ /*------------------------------------------------------------------- Function: grTexTextureMemRequired Date: 6/2 Implementor(s): GaryMcT, Jdt Library: glide Description: Returns the tmu memory required to store the specified mipmap ( Gary and I don't like the name of this function, but are a little backed into a corner because of the existence of grTexMemRequired() which does not imply any distinction between texture memory and system ram ) Arguments: evenOdd - which set of mipmap levels are to be stored One of: GR_MIPMAPLEVELMASK_EVEN GR_MIPMAPLEVELMASK_ODD GR_MIPMAPLEVELMASK_BOTH info - pointer to GrTexInfo structure defining dimensions of texture Return: offset to be added to current texture base address to calculate next valid texture memory download location -------------------------------------------------------------------*/ GR_DIENTRY(grTexTextureMemRequired, FxU32, ( FxU32 evenOdd, GrTexInfo *info)) { FxU32 memrequired; GR_CHECK_F( "grTexTextureMemRequired", !info, "invalid info pointer" ); memrequired = _grTexTextureMemRequired( info->smallLodLog2, info->largeLodLog2, info->aspectRatioLog2, info->format, evenOdd, FXTRUE, FXFALSE ); GDBG_INFO(88,"grTexTextureMemRequired(%d,0x%x) => 0x%x(%d)\n", evenOdd,info,memrequired,memrequired); return memrequired; } /* grTexTextureMemRequired */ /*------------------------------------------------------------------- Function: grTexDownloadMipMap Date: 6/2 Implementor(s): GaryMcT, Jdt Library: glide Description: Downloads a texture mipmap to the specified tmu at the specified base address. Arguments: tmu - which tmu startAddress - starting address for texture download, evenOdd - which set of mipmap levels have been downloaded for the selected texture One of: GR_MIPMAPLEVELMASK_EVEN GR_MIPMAPLEVELMASK_ODD GR_MIPMAPLEVELMASK_BOTH info - pointer to GrTexInfo structure defining dimension of texture to be downloaded and containing texture data Return: none -------------------------------------------------------------------*/ GR_DIENTRY(grTexDownloadMipMap, void, ( GrChipID_t tmu, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info )) { #define FN_NAME "grTexDownloadMipMap" GrLOD_t lod; FxU8* src_base = info->data; const GrAspectRatio_t curAspectRatio = ((info->aspectRatioLog2 < 0) ? -info->aspectRatioLog2 : info->aspectRatioLog2); const FxU32 formatMult = _grBitsPerTexel[info->format]; GR_BEGIN_NOFIFOCHECK(FN_NAME, 89); GDBG_INFO_MORE(gc->myLevel, "(%d, 0x%X, 0x%X, 0x%X\n", tmu, startAddress, evenOdd, info); GR_CHECK_F(FN_NAME, formatMult == 0, "invalid texture format"); { GR_DCL_GC; const FxU32 size = grTexTextureMemRequired( evenOdd, info ); GR_CHECK_TMU( FN_NAME, tmu ); GR_CHECK_COMPATABILITY(FN_NAME, startAddress + size > gc->tmu_state[tmu].total_mem, "insufficient texture ram at startAddress" ); GR_CHECK_F(FN_NAME, evenOdd > 0x3, "evenOdd mask invalid" ); GR_CHECK_F(FN_NAME, !info, "info invalid" ); } { struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; /* Force a pixel flush which should force all of the * texture downloads to flush from internal fifos etc. */ GR_TEX_FLUSH_PRE(memInfo); /*--------------------------------------------------------------- Download one mipmap level at a time ---------------------------------------------------------------*/ for( lod = info->largeLodLog2; lod >= info->smallLodLog2; lod-- ) { /* ** note for glide3 lod translation: ** we are calling gr* routine so the lod data should remain the same */ grTexDownloadMipMapLevel(tmu, startAddress, lod, info->largeLodLog2, info->aspectRatioLog2, info->format, evenOdd, src_base); switch(info->format) { case GR_TEXFMT_ARGB_CMP_FXT1: case GR_TEXFMT_ARGB_CMP_DXT1: /* Note: in this case, we need to use info->aspectRatioLog2 * rather than curAspectRatio, because we need to keep the * sign of the apsect ratio in order to get the right size. */ src_base += ((_grMipMapHostSizeCmp4Bit [G3_ASPECT_TRANSLATE(info->aspectRatioLog2)][lod] * formatMult) >> 3); break; case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: src_base += ((_grMipMapHostSizeDXT[curAspectRatio][lod] * formatMult)>>3); break; default: src_base += ((_grMipMapHostSize[curAspectRatio][lod] * formatMult)>>3); } } /* Force a pixel flush which should force all of the * texture downloads to flush from internal fifos etc. */ GR_TEX_FLUSH_POST(memInfo); } #undef FN_NAME } /* grTexDownloadMipMap */ /*------------------------------------------------------------------- Function: grTexDownloadTablePartial Date: 6/3 Implementor(s): GaryT Library: glide Description: download part of a look up table data to a tmu Arguments: tmu - which tmu type - what type of table to download One of: GR_TEXTABLE_NCC0 GR_TEXTABLE_NCC1 GR_TEXTABLE_PALETTE void *data - pointer to table data Return: none -------------------------------------------------------------------*/ GR_DIENTRY(grTexDownloadTablePartial, void, ( GrTexTable_t type, void *data, int start, int end )) { #define FN_NAME "grTexDownloadTablePartial" GR_BEGIN_NOFIFOCHECK(FN_NAME, 89); GDBG_INFO_MORE(gc->myLevel, "(%d, 0x%X, %d, %d)\n",type,data,start,end); GR_CHECK_F(myName, type > GR_TEXTABLE_PALETTE_6666_EXT, "invalid table specified"); GR_CHECK_F(myName, !data, "invalid data pointer"); /* What type of palette is this? */ switch(type) { case GR_TEXTABLE_PALETTE: case GR_TEXTABLE_PALETTE_6666_EXT: _grTexDownloadPalette( GR_TMU0, type, (GuTexPalette *)data, start, end ); break; default: _grTexDownloadNccTable( GR_TMU0, type, (GuNccTable*)data, start, end ); } /* NB: Set the current palette type after we do the download because * the palette download code may need to know that there is a table * type change and do something hoopti. */ gc->state.tex_table = type; GR_END(); } /* grTexDownloadTablePartial */ /*--------------------------------------------------------------------------- ** grTexDownloadMipMapLevel */ GR_DIENTRY(grTexDownloadMipMapLevel, void, ( GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data )) { GR_BEGIN_NOFIFOCHECK("grTexDownloadMipMapLevel",89); GDBG_INFO_MORE(gc->myLevel,"(%d,0x%x, %d,%d,%d, %d,%d 0x%x)\n", tmu,startAddress,thisLod,largeLod,aspectRatio, format,evenOdd,data); /* ** note for glide3 lod translation: ** we are calling gr* routine so the lod data should remain the same */ switch(format) { case GR_TEXFMT_ARGB_CMP_FXT1: grTexDownloadMipMapLevelPartial(tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, 0, _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][1] - 1); break; /* Note: Unlike in other places, we put DXT1 here because it's min size * according to the app is actually 4x4 like the other DXTC mode */ case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: grTexDownloadMipMapLevelPartial(tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, 0, _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][1] - 1); break; default: grTexDownloadMipMapLevelPartial(tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, 0, _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][1] - 1); } GR_END(); } /* grTexDownloadMipmapLevel */ glide3x/h5/glide3/src/fifo.c0100700000175300010010000013356607725034667015105 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED * ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/fifo.c,v 1.4.4.5 2003/07/25 07:14:58 dborca Exp $ ** $Log: ** 14 3dfx 1.8.1.2.1.1 10/11/00 Brent Forced check in to enforce ** branching. ** 13 3dfx 1.8.1.2.1.0 07/21/00 Adam Briggs don't try to bump > 0xffff ** at a time ** 12 3dfx 1.8.1.2 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 11 3dfx 1.8.1.1 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 10 3dfx 1.8.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 9 3dfx 1.8 04/21/00 Kenneth Dyke Magic FX_GLIDE_NO_HW ** support. ** 8 3dfx 1.7 03/24/00 Chris Dow Added code to fence every n ** writes (not to exceed 0x10000) where n is either 0x10000 or indicated by ** the environment variable FX_GLIDE_FENCE_LIMIT ** ** 7 3dfx 1.6 02/25/00 Adam Briggs replaced call to ** hwcQueryContext with a reference to the lost context dword.. should yield ** an insignificant speedup. ** 6 3dfx 1.5 02/07/00 Kenneth Dyke Fixes for slave fifo ** checking. ** 5 3dfx 1.4 01/30/00 Adam Briggs get napalm status correctly ** 4 3dfx 1.3 01/23/00 Adam Briggs added some debugging output ** for slave chip fifos ** 3 3dfx 1.2 01/21/00 Adam Briggs some changes to get the ** correct linear mappings for slave regs and use them to sync the fifos in ** sli mode ** 2 3dfx 1.1 01/18/00 Kenneth Dyke Fifo check timeout debug ** level change. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 32 4/16/99 2:45p Kcd ** PCI Bump & Grind stuff for the Mac. ** ** 31 4/10/99 1:23p Atai ** fixed code to compile in packet fifo mode ** ** 30 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 28 4/01/99 7:55p Peter ** made names and comments more meaningful ** ** 27 3/19/99 11:46a Peter ** fifo info should validate stte ** ** 26 3/19/99 11:26a Peter ** expose direct fifo for gl ** ** 25 3/14/99 1:47p Peter ** cmd's bng optimization, really invoke gggoph ** ** 24 3/09/99 12:32p Kcd ** New & Improved tail chasing fifo for windowed Glide. ** ** 23 3/05/99 10:33p Peter ** fixed the surface fifo state race condition (thanks to Ken Dyke) ** ** 22 3/04/99 4:34p Kcd ** Conservative fix to prevent command buffers from being used before they ** have been issued. ** ** 21 3/02/99 2:04p Peter ** made error tracing output use consistent address bases for the fifo ** output ** ** 20 2/18/99 3:13p Kcd ** Fixed direct register accesses. ** ** 19 2/11/99 1:38p Atai ** sync buffer swap pending code, the right way. ** ** 18 2/02/99 4:39p Peter ** cleaned up wax commands, re-issue of commands needs to update fifo room ** ** 17 1/04/99 12:03p Peter ** use window contexts for sending state ** ** 16 12/23/98 2:01p Peter ** nt currently has mutexing problems via ddraw and extescape ** ** 15 12/11/98 1:36p Peter ** made grFlush's operation more obvious ** ** 14 11/30/98 6:57p Peter ** video memory fifo's ** ** 13 10/20/98 8:28p Peter ** shared files and fixed whackage ** ** 12 9/11/98 10:45p Jdt ** switch over to statically allocated in-memory fifo. ** ** 11 8/03/98 6:38a Jdt ** moved stats into gc ** ** 10 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 9 7/18/98 12:24a Jdt ** Added primitive state restoration buffer. ** ** ** 8 7/16/98 8:15a Jdt ** Working 1-window command fifo ( TACO_MEMORY_FIFO_HACK ) ** ** 7 7/05/98 5:05p Jdt ** Workaround for fifo strangeness. ** ** 6 7/01/98 12:40p Jdt ** protected hacks for Glide/Win ( FX_TACO_MEMORY_FIFO_HACK ) XX temporary ** ** 5 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 3 4/22/98 4:57p Peter ** glide2x merge ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 18 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 17 12/09/97 12:20p Peter * mac glide port * * 16 12/09/97 10:28a Peter * cleaned up some frofanity * * 15 12/05/97 4:26p Peter * watcom warnings * * 14 12/03/97 11:34a Peter * dos debugging * * 13 11/21/97 3:53p Peter * reset messages are controlled by gdbg_level * * 12 11/19/97 6:04p Peter * actually exit if not reset * * 11 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 10 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 9 11/15/97 9:20p Peter * I am the sorriest f*cker on the face of the planet * ** */ #include #include #if defined(__WIN32__) #include #endif #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if (GDBG_INFO_ON || _FIFODUMP) static const char* h3SstRegNames[] = { "status", "intrCtrl", "vAx", "vAy", "vBx", "vBy", "vCx", "vCx", "r", "g", "b", "z", "a", "s", "t", "w", "drdx", "dgdx", "dbdx", "dzdx", "dadx", "dsdx", "dtdx", "dwdx", "drdy", "dgdy", "dbdy", "dzdy", "dady", "dsdy", "dtdy", "dwdy", "triangleCMD", "reservedA", "FvAx", "FvAy", "FvBx", "FvBy", "FvCx", "FvCy", "Fr", "Fg", "Fb", "Fz", "Fa", "Fs", "Ft", "Fw", "Fdrdx", "Fdgdx", "Fdbdx", "Fdzdx", "Fdadx", "Fdsdx", "Fdtdx", "Fdwdx", "Fdrdy", "Fdgdy", "Fdbdy", "Fdzdy", "Fdady", "Fdsdy", "Fdtdy", "Fdwdy", "FtriangleCMD", "fbzColorPath", "fogMode", "alphaMode", "fbzMode", "lfbMode", "clipLeftRight", "clipBottomTop", "nopCMD", "fastfillCMD", "swapbufferCMD", "fogColor", "zaColor", "chromaKey", "chromaRange", "userIntrCmd", "stipple", "c0", "c1", "fbiPixelsIn", "fbiChromaFail", "fbiZfuncFail", "fbiAfuncFail", "fbiPixelsOut", "fogTable00", "fogTable01", "fogTable02", "fogTable03", "fogTable04", "fogTable05", "fogTable06", "fogTable07", "fogTable08", "fogTable09", "fogTable0a", "fogTable0b", "fogTable0c", "fogTable0d", "fogTable0e", "fogTable0f", "fogTable10", "fogTable11", "fogTable12", "fogTable13", "fogTable14", "fogTable15", "fogTable16", "fogTable17", "fogTable18", "fogTable19", "fogTable1a", "fogTable1b", "fogTable1c", "fogTable1d", "fogTable1e", "fogTable1f", "reservedB0", "reservedB1", "reservedB2", "colBufferAddr", "colBufferStride", "auxBufferAddr", "auxBufferStride", "reservedC", "clipLeftRight1", "clipBottomTop1", "reservedD0", "reservedD1", "reservedD2", "reservedD3", "reservedD4", "reservedD5", "reservedE0", "reservedE1", "reservedE2", "reservedE3", "reservedE4", "reservedE5", "reservedE6", "reservedE7", "reservedF0", "reservedF1", "reservedF2", "swapBufferPend", "leftOverlayBuf", "rightOverlayBuf", "fbiSwapHistory", "fbiTrianglesOut", "sSetupMode", "sVx", "sVy", "sARGB", "sRed", "sGreen", "sBlue", "sAlpha", "sVz", "sOowfbi", "sOow0", "sSow0", "sTow0", "sOow1", "sSow1", "sTow1", "sDrawTriCMD", "sBeginTriCMD", "reservedG0", "reservedG1", "reservedG2", "reservedG3", "reservedG4", "reservedG5", "reservedH0", "reservedH1", "reservedH2", "reservedH3", "reservedH4", "reservedH5", "reservedH6", "reservedH7", "reservedI0", "reservedI1", "reservedI2", "reservedI3", "reservedI4", "reservedI5", "reservedI6", "reservedI7", "textureMode", "tLOD", "tDetail", "texBaseAddr", "texBaseAddr1", "texBaseAddr2", "texBaseAddr38", "trexInit0", "trexInit1", "nccTable0-0", "nccTable0-1", "nccTable0-2", "nccTable0-3", "nccTable0-4", "nccTable0-5", "nccTable0-6", "nccTable0-7", "nccTable0-8", "nccTable0-9", "nccTable0-a", "nccTable0-b", "nccTable1-0", "nccTable1-1", "nccTable1-2", "nccTable1-3", "nccTable1-4", "nccTable1-5", "nccTable1-6", "nccTable1-7", "nccTable1-8", "nccTable1-9", "nccTable1-a", "nccTable1-b", "tChromaKeyMin", "tChromaKeyMax", }; static const char * h3SstIORegNames[] = { "status", "pciInit0", "sipMonitor", "lfbMemoryConfig", "miscInit0", "miscInit1", "dramInit0", "dramInit1", "agpInit", "tmuGbeInit", "vgaInit0", "vgaInit1", "dramCommand", "dramData", "reservedZ0" "reservedZ0" "pllCtrl0", "pllCtrl1", "pllCtrl2", "dacMode", "dacAddr", "dacData", "vidMaxRGBDelta", "vidProcCfg", "hwCurPatAddr", "hwCurLoc", "hwCurC0", "hwCurC1", "vidInFormat", "vidInStatus", "vidSerialParallelPort", "vidInXDecimDeltas", "vidInDecimInitErrs", "vidInYDecimDeltas", "vidPixelBufThold", "vidChromaMin", "vidChromaMax", "vidCurrentLine", "vidScreenSize", "vidOverlayStartCoords", "vidOverlayEndScreenCoord", "vidOverlayDudx", "vidOverlayDudxOffsetSrcWidth", "vidOverlayDvdy", "vgaRegister[0]", "vgaRegister[1]", "vgaRegister[2]", "vgaRegister[3]", "vgaRegister[4]", "vgaRegister[5]", "vgaRegister[6]", "vgaRegister[7]", "vgaRegister[8]", "vgaRegister[9]", "vgaRegister[a]", "vgaRegister[b]", "vidOverlayDvdyOffset", "vidDesktopStartAddr", "vidDesktopOverlayStride", "vidInAddr0", "vidInAddr1", "vidInAddr2", "vidInStride", "vidCurrOverlayStartAddr", } ; #define GEN_INDEX(a) ((((FxU32) a) - ((FxU32) gc->reg_ptr)) >> 2) #endif /* GDBG_INFO_ON || _FIFODUMP */ #if GDBG_INFO_ON void _grFifoWriteDebug(FxU32 addr, FxU32 val, FxU32 fifoPtr) { GR_DCL_GC; FxU32 index = GEN_INDEX(addr); GDBG_INFO(gc->myLevel + 199, "Storing to FIFO:\n"); GDBG_INFO(gc->myLevel + 199, " FIFO Ptr: 0x%x : 0x%X\n", fifoPtr, gc->cmdTransportInfo.fifoRoom); if (index <= 0xff) { GDBG_INFO(gc->myLevel + 199, " Reg Name: %s\n", h3SstRegNames[index]); GDBG_INFO(gc->myLevel + 199, " Reg Num: 0x%X\n", index); } else { const char* strP; const FxU32 offset = (addr - (FxU32)gc->reg_ptr); if (offset >= HW_TEXTURE_OFFSET) { strP = "Texture"; } else if (offset >= HW_LFB_OFFSET) { strP = "LFB"; index = addr; } else if (offset >= HW_FIFO_OFFSET) { strP = "Cmd FIFO"; } else { strP = "Woah!"; } GDBG_INFO(gc->myLevel + 199, " %s Addr: 0x%X\n", strP, index); } GDBG_INFO(gc->myLevel + 199, " Value: 0x%X 0x%X\n", (index << 2), val); #if !HAL_CSIM GDBG_INFO(120, " SET(0x%X, %ld(0x%X)) 0 %s (0x%X)\n", 0x10000000UL + (FxU32)(index << 2), val, val, h3SstRegNames[index & 0xFF], fifoPtr); #endif /* !HAL_CSIM */ } /* _grFifoWriteDebug */ void _grFifoFWriteDebug(FxU32 addr, float val, FxU32 fifoPtr) { GR_DCL_GC; FxU32 index = GEN_INDEX(addr); GDBG_INFO(gc->myLevel + 200, "Storing to FIFO:\n"); GDBG_INFO(gc->myLevel + 200, " FIFO Ptr: 0x%x\n", fifoPtr); if (index <= 0xff) { GDBG_INFO(gc->myLevel + 200, " Reg Name: %s\n", h3SstRegNames[index]); GDBG_INFO(gc->myLevel + 200, " Reg Num: 0x%x\n", index); } GDBG_INFO(gc->myLevel + 200, " Value: %4.2f\n", val); #if !HAL_CSIM GDBG_INFO(120, " SET(0x%X, %4.2f (0x%X)) 0 %s\n", 0x10000000UL + (FxU32)(index << 2), val, *(const FxU32*)&val, h3SstRegNames[index & 0xFF]); #endif /* !HAL_CSIM */ } /* _grFifoFWriteDebug */ void _grH3FifoDump_TriHdr(const FxU32 hdrVal) { GR_DCL_GC; /* Dump Packet Header */ GDBG_INFO(gc->myLevel + 200, "CMD Fifo Triangle Packet (0x%X)\n", hdrVal); GDBG_INFO(gc->myLevel + 200, " # Vertex: 0x%X\n", (hdrVal & SSTCP_PKT3_NUMVERTEX) >> SSTCP_PKT3_NUMVERTEX_SHIFT); GDBG_INFO(gc->myLevel + 200, " RGB: %s\n", (hdrVal & SSTCP_PKT3_PACKEDCOLOR) ? "Packed" : "Separate"); GDBG_INFO(gc->myLevel + 200, " StripMode: %s\n", (((hdrVal & (0x01 << 22)) == 0) ? "Strip" : "Fan")); GDBG_INFO(gc->myLevel + 200, " Culling: %s\n", (((hdrVal & (0x01 << 23)) == 0) ? "Disable" : "Enable")); GDBG_INFO(gc->myLevel + 200, " CullingSign: %s\n", (((hdrVal & (0x01 << 24)) == 0) ? "Positive" : "Negative")); GDBG_INFO(gc->myLevel + 200, " PingPongSign: %s\n", (((hdrVal & (0x01 << 25)) == 0) ? "Normal" : "Disable")); if (GDBG_GET_DEBUGLEVEL(gc->myLevel + 200)) { const FxU32 temp = (hdrVal & SSTCP_PKT3_PMASK); int i; GDBG_INFO(gc->myLevel + 200, " Params: X Y"); for(i = 10; i <= 17; i++) { static const char* paramSel[] = { "RGB", "Alpha", "Z", "Wb", "W0", "ST[0]", "W1", "ST[1]" }; if ((temp & (0x01UL << i)) != 0) GDBG_PRINTF("%s ", paramSel[i - 10]); } GDBG_INFO(gc->myLevel + 200, "\n"); } { const FxU32 temp = (hdrVal & SSTCP_PKT3_CMD) >> SSTCP_PKT3_CMD_SHIFT; const char* tempStr; switch(temp) { case 0x00: tempStr = "Independent"; break; case 0x01: tempStr = "NewStrip"; break; case 0x02: tempStr = "ContinueStrip"; break; default: tempStr = "Reserved"; break; } GDBG_INFO(gc->myLevel + 200, " Command: 0x%X(%s)\n", temp, tempStr); } } void _grErrorCallback(const char* const procName, const char* const format, va_list args) { GR_DCL_GC; static FxBool inProcP = FXFALSE; if (!inProcP) { static char errMsgBuf[1024]; inProcP = FXTRUE; { extern void (*GrErrorCallback)( const char *string, FxBool fatal ); vsprintf(errMsgBuf, format, args); (*GrErrorCallback)(errMsgBuf, (GETENV("FX_ERROR_FAIL", gc->bInfo->RegPath) != NULL)); } inProcP = FXFALSE; } } #endif /* GDBG_INFO_ON */ #if _FIFODUMP void _grFifoWriteDebugDump(FxU32 tmu, FxU32 addr, FxU32 val, FxU32 fifoPtr) { GR_DCL_GC; FxU32 index = GEN_INDEX(addr); GDBG_FD(444, "Storing to FIFO:\n"); GDBG_FD(444, " FIFO Ptr: 0x%x : 0x%X\n", fifoPtr, gc->cmdTransportInfo.fifoRoom); if (index <= 0xff) { GDBG_FD(444, " Reg Name: %s\n", h3SstRegNames[index]); GDBG_FD(444, " Reg Num: 0x%X\n", index); } else { const char* strP; const FxU32 offset = (addr - (FxU32)gc->reg_ptr); if (offset >= HW_TEXTURE_OFFSET) { strP = "Texture"; } else if (offset >= HW_LFB_OFFSET) { strP = "LFB"; index = addr; } else if (offset >= HW_FIFO_OFFSET) { strP = "Cmd FIFO"; } else { strP = "Woah!"; } GDBG_FD(444, " %s Addr: 0x%X\n", strP, index); } GDBG_FD(444, " Value: 0x%X 0x%X\n", (index << 2), val); #if !HAL_CSIM // GDBG_FD(0, " SET(0x%X, %ld(0x%X)) 0 %s (0x%X)\n", // 0x10000000UL + (FxU32)(index << 2), val, val, // h3SstRegNames[index & 0xFF], fifoPtr); #endif /* !HAL_CSIM */ } /* _grFifoWriteDebug */ void _grFifoFWriteDebugDump(FxU32 tmu, FxU32 addr, float val, FxU32 fifoPtr) { GR_DCL_GC; FxU32 index = GEN_INDEX(addr); GDBG_FD(444, "Storing to FIFO:\n"); GDBG_FD(444, " FIFO Ptr: 0x%x\n", fifoPtr); if (index <= 0xff) { GDBG_FD(444, " Reg Name: %s\n", h3SstRegNames[index]); GDBG_FD(444, " Reg Num: 0x%x\n", index); } GDBG_FD(444, " Value: 0x%X %4.2f\n", (index << 2), val); #if !HAL_CSIM // GDBG_FD(0, " SET(0x%X, %4.2f (0x%X)) 0 %s\n", // 0x10000000UL + (FxU32)(index << 2), val, *(const FxU32*)&val, // h3SstRegNames[index & 0xFF]); #endif /* !HAL_CSIM */ } /* _grFifoFWriteDebug */ #endif /* CMDFIFODUMP_PER_CHIP */ #if USE_PACKET_FIFO /* Routines privately exported so that the manufacturing diags * and other things can do register writes etc w/o having access * to the glide internals etc. */ extern void _grSet32(volatile FxU32* const sstAddr, const FxU32 val) { #define FN_NAME "_grSet32" GR_DCL_GC; GR_ASSERT(sstAddr >= gc->base_ptr); GR_ASSERT(sstAddr < &SST_TMU(gc->reg_ptr, GR_TMU0)->status); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET_INDEX(BROADCAST_ID, gc->reg_ptr, (sstAddr - gc->reg_ptr), val); GR_CHECK_SIZE(); #undef FN_NAME } extern FxU32 _grGet32(volatile FxU32* const sstAddr) { #define FN_NAME "_grGet32" GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 88); GDBG_INFO_MORE(gc->myLevel, "(0x%X)\n", sstAddr); GR_RETURN(GR_GET(*sstAddr)); #undef FN_NAME } /* _grGet32 */ #if FIFO_ASSERT_FULL const FxU32 kFifoCheckMask = 0xFFFF; FxU32 gFifoCheckCount = 0; #endif void _grBumpNGrind() { #define FN_NAME "_grCheckForBump" GR_BEGIN_NOFIFOCHECK(FN_NAME, 400); #ifdef HAL_CSIM /* WTF? If the csim cannot do agp so we should just be doing the * same thing that the non-csim case is doing. */ GR_CAGP_SET(bump, 0); #else /* !HAL_CSIM */ FIFO_CACHE_FLUSH(gc->cmdTransportInfo.fifoPtr); P6FENCE; /* AH FUK: the bump register can only handle a 16bit value */ while ((gc->cmdTransportInfo.fifoPtr - gc->cmdTransportInfo.lastBump) > 0xFFFFL) { GR_CAGP_SET(bump, 0xFFFFL); gc->cmdTransportInfo.lastBump += 0xFFFFL ; } if (gc->cmdTransportInfo.fifoPtr - gc->cmdTransportInfo.lastBump) GR_CAGP_SET(bump, gc->cmdTransportInfo.fifoPtr - gc->cmdTransportInfo.lastBump); gc->cmdTransportInfo.lastBump = gc->cmdTransportInfo.fifoPtr; gc->cmdTransportInfo.bumpPos = gc->cmdTransportInfo.fifoPtr + (gc->cmdTransportInfo.bumpSize); if (gc->cmdTransportInfo.bumpPos > gc->cmdTransportInfo.fifoEnd) gc->cmdTransportInfo.bumpPos = gc->cmdTransportInfo.fifoEnd; #endif /* !HAL_CSIM */ GR_ASSERT(gc->cmdTransportInfo.bumpPos != 0); GR_ASSERT(gc->cmdTransportInfo.lastBump != 0); #undef FN_NAME } /* _grCheckForBump */ struct cmdTransportInfo* FX_CALL _grCommandTransportInfo(void) { #define FN_NAME "_grCommandTransportInfo" GR_BEGIN_NOFIFOCHECK_NORET(FN_NAME"()\n", 98); /* validate the state so that the packet headers are correct */ if (gc->state.invalid) _grValidateState(); GR_RETURN(&gc->cmdTransportInfo); #undef FN_NAME } /* _grCommandTransportInfo */ void _FifoFlush( void ) { #define FN_NAME "_FifoFlush" GR_DCL_GC; _grCommandTransportMakeRoom(0, __FILE__, __LINE__); #undef FN_NAME } /* _FifoFlush */ FxU32 _grHwFifoPtrSlave(FxU32 slave, FxBool ignored); void FX_CALL _grCommandTransportMakeRoom(const FxI32 blockSize, const char* fName, const int fLine) { #define FN_NAME "_FifoMakeRoom" GR_BEGIN_NOFIFOCHECK(FN_NAME"()\n", 400); if ( gc->windowed ) { #if defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) struct cmdTransportInfo* gcFifo = &gc->cmdTransportInfo; HwcWinFifo fifo = gc->cmdTransportInfo.hwcFifoInfo; const FxU32 nextBufferIndex = gcFifo->curCommandBuf + gcFifo->numQueuedBuf, cmdBufferOffset = (gcFifo->hwcFifoInfo.cmdBuf.allocUnit * gcFifo->curCommandBuf); FxU32 buffersFree; /* Update to the currently writing command buffer */ fifo.cmdBuf.baseAddr += cmdBufferOffset; fifo.cmdBuf.hwOffset += cmdBufferOffset; fifo.cmdBuf.size = ((FxU32)gcFifo->fifoPtr - fifo.cmdBuf.baseAddr); fifo.stateBuf.baseAddr = (FxU32)gcFifo->stateBuffer; fifo.stateBuf.hwOffset += (gcFifo->hwcFifoInfo.stateBuf.allocUnit * gcFifo->curCommandBuf); fifo.stateBuf.size = sizeof(GrStateBuffer); { FxBool issueP; __tryFifoExecute: GR_WINFIFO_BEGIN(); { issueP = hwcExecuteWinFifo(gc->bInfo, gc->winContextId, &fifo, gcFifo->serialNumber + gcFifo->numQueuedBuf); } GR_WINFIFO_END(); /* Did we execute? */ if (issueP) { /* Update the issued command bookkeeping */ gcFifo->issuedSerialNumber = gcFifo->serialNumber + gcFifo->numQueuedBuf; /* Update us to next serial number */ gcFifo->serialNumber += gcFifo->numQueuedBuf; /* See if we have free buffers available */ buffersFree = gcFifo->numCommandBuf - (gcFifo->serialNumber - gcFifo->committedSerialNumber); /* If no buffers are free, then we must wait for some space to become available. */ while((FxI32)buffersFree <= 0) { gcFifo->committedSerialNumber = hwcExecuteStatusWinFifo(gc->bInfo, &gcFifo->hwcFifoInfo, gcFifo->serialNumber); buffersFree = gcFifo->numCommandBuf - (gcFifo->serialNumber - gcFifo->committedSerialNumber); } /* Do we have more buffers or do we need to wrap? */ GR_ASSERT(nextBufferIndex <= gcFifo->numCommandBuf); /* We should have at least one buffer free at this point */ if(nextBufferIndex == gcFifo->numCommandBuf) gcFifo->curCommandBuf = 0; else gcFifo->curCommandBuf = nextBufferIndex; /* Set the current fifo ptr in allocation blocks */ gcFifo->fifoPtr = (FxU32*)(gcFifo->hwcFifoInfo.cmdBuf.baseAddr + (gcFifo->hwcFifoInfo.cmdBuf.allocUnit * gcFifo->curCommandBuf)); /* Set the state buffer to be the 'next' one in the ready * list. This is the same index as the next buffer in the * command list. */ gcFifo->stateBuffer = (GrStateBuffer*)(gcFifo->hwcFifoInfo.stateBuf.baseAddr + (gcFifo->hwcFifoInfo.stateBuf.allocUnit * gcFifo->curCommandBuf)); /* Reset next execution size to be an allocation unit */ gcFifo->fifoRoom = gcFifo->hwcFifoInfo.cmdBuf.allocUnit - FIFO_END_ADJUST; gcFifo->numQueuedBuf = 0x01UL; /* Copy the state at the end of the last submitted command * buffer to be the state for the next command buffer. */ #if __POWERPC__ { FxU32 *src, *dst, i; src = (FxU32 *)&gc->state.shadow; dst = (FxU32 *)gcFifo->stateBuffer; for(i = 0; i < (sizeof(GrStateBuffer)/sizeof(FxU32)); i++) { SET(*dst++,*src++); } } #else memcpy(gcFifo->stateBuffer, &gc->state.shadow, sizeof(GrStateBuffer)); #endif } else { /* Didn't execute, but we can check to see if we have some * room to keep going. Otherwise we need to check again to see * if we can execute now. */ /* See if we have free buffers available */ buffersFree = (gcFifo->numCommandBuf - ((gcFifo->serialNumber + gcFifo->numQueuedBuf) - gcFifo->committedSerialNumber)); /* If no free buffers, get latest committed from memory (slow) and check again (but don't spin). */ if((FxI32)buffersFree <= 0) { gcFifo->committedSerialNumber = hwcExecuteStatusWinFifo(gc->bInfo, &gcFifo->hwcFifoInfo, gcFifo->serialNumber); buffersFree = (gcFifo->numCommandBuf - ((gcFifo->serialNumber + gcFifo->numQueuedBuf) - gcFifo->committedSerialNumber)); } /* If we have more free buffers and we can append, then do so */ if((buffersFree > 0) && (nextBufferIndex < gcFifo->numCommandBuf)) { gcFifo->numQueuedBuf++; gcFifo->fifoRoom += gcFifo->hwcFifoInfo.cmdBuf.allocUnit; } else { /* Well, we couldn't issue, and we didn't have any free space, so try * to issue again. */ goto __tryFifoExecute; } } } GR_SET_FIFO_PTR( 0, 0 ); #endif /* defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) */ } else { /* Check here to see if we have a valid context since the last time * we checked. This is to protect us from loosing our context before * we wrap check the current hw fifo pointer which is going to be the * 2d driver's fifo if we lost our context. */ #if defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) gc->contextP = !(*gc->lostContext) ; #else /* defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ gc->contextP = 1; /* always has context in CSIM */ #endif /* defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ if (gc->contextP) { FxU32 wrapAddr = 0x00UL; FxU32 checks; #if TACO_MEMORY_FIFO_HACK GR_ASSERT(blockSize >= 0); #else GR_ASSERT(blockSize > 0); #endif GR_ASSERT((FxU32)blockSize < gc->cmdTransportInfo.fifoSize); FIFO_ASSERT(); /* Nasty performance testing hack */ if(_GlideRoot.environment.noHW) { /* Cribbed from grSstWinOpen() */ struct cmdTransportInfo *gcFifo = &gc->cmdTransportInfo; gcFifo->roomToEnd = gcFifo->fifoSize - FIFO_END_ADJUST; gcFifo->fifoRoom = gcFifo->roomToReadPtr = gcFifo->roomToEnd - sizeof( FxU32 ); /* Set initial fifo state. hw read and sw write pointers at * start of the fifo. */ gcFifo->fifoPtr = gcFifo->fifoStart; gcFifo->fifoRead = HW_FIFO_PTR( FXTRUE ); return; } /* Update the roomToXXX values w/ the # of writes since the last * fifo stall/wrap. */ { const FxI32 writes = (MIN(gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd) - gc->cmdTransportInfo.fifoRoom); gc->cmdTransportInfo.roomToReadPtr -= writes; gc->cmdTransportInfo.roomToEnd -= writes; #if GDBG_INFO_ON GDBG_INFO_MORE(gc->myLevel, ": (%s : %d)\n" "\tfifoBlock: (0x%X : 0x%X)\n" "\tfifoRoom: (0x%X : 0x%X) : (0x%X : 0x%X)\n" "\tfifo hw: (0x%X : 0x%X)\n", ((fName == NULL) ? "Unknown" : fName), fLine, (((FxU32)gc->cmdTransportInfo.fifoPtr - (FxU32)gc->cmdTransportInfo.fifoStart) + (FxU32)gc->cmdTransportInfo.fifoOffset), blockSize, gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd, gc->cmdTransportInfo.fifoRoom, writes, HW_FIFO_PTR(FXTRUE) - (FxU32)gc->rawLfb, gc->cmdTransportInfo.fifoRead); #endif /* GDBG_INFO_ON */ ASSERT_FAULT_IMMED((gc->cmdTransportInfo.roomToReadPtr >= 0) && (gc->cmdTransportInfo.roomToEnd >= 0)); } /* Bump & Grind if called for */ if (!gc->cmdTransportInfo.autoBump) GR_BUMP_N_GRIND; checks = 0; again: /* do we need to stall? */ { FxU32 lastHwRead = gc->cmdTransportInfo.fifoRead; FxI32 roomToReadPtr = gc->cmdTransportInfo.roomToReadPtr; while (roomToReadPtr < blockSize) { FxU32 curReadPtr = HW_FIFO_PTR(FXTRUE); FxU32 curReadDist = curReadPtr - lastHwRead; /* Handle slave chips. This code lifted from cvg and modified * to deal with multiple slave chips. */ if(gc->chipCount > 1) { FxU32 slave; for(slave = 1; slave < gc->chipCount; slave++) { const FxU32 slaveReadPtr = _grHwFifoPtrSlave(slave, 0); const FxU32 slaveReadDist = (slaveReadPtr - lastHwRead); FxI32 distSlave = (FxI32)slaveReadDist; FxI32 distMaster = (FxI32)curReadDist; GR_ASSERT((slaveReadPtr >= (FxU32)gc->cmdTransportInfo.fifoStart) && (slaveReadPtr < (FxU32)gc->cmdTransportInfo.fifoEnd)); /* Get the actual absolute distance to the respective fifo ptrs */ if (distSlave < 0) distSlave += (FxI32)gc->cmdTransportInfo.fifoSize - FIFO_END_ADJUST; if (distMaster < 0) distMaster += (FxI32)gc->cmdTransportInfo.fifoSize - FIFO_END_ADJUST; /* Is this slave closer than the master? */ if (distSlave < distMaster) { curReadDist = slaveReadDist; curReadPtr = slaveReadPtr; } } } checks++; #ifdef GLIDE_DEBUG if (checks > 1000) { { const FxU32 baseAddrL = GR_CAGP_GET(baseAddrL), baseSize = GR_CAGP_GET(baseSize), readPtrL = GR_CAGP_GET(readPtrL), aMin = GR_CAGP_GET(aMin), aMax = GR_CAGP_GET(aMax), depth = GR_CAGP_GET(depth), holeCount = GR_CAGP_GET(holeCount); GDBG_INFO(80,"Fifo check timeout:\n"); GDBG_INFO(80,"\tbaseAddrL = 0x%x\n", baseAddrL); GDBG_INFO(80,"\tbaseSize = 0x%x\n", baseSize); GDBG_INFO(80,"\treadPtrL = 0x%x\n", readPtrL); GDBG_INFO(80,"\tdepth = 0x%x\n", depth); GDBG_INFO(80,"\tholeCount = 0x%x\n", holeCount); GDBG_INFO(80,"\taMin = 0x%x\n", aMin); GDBG_INFO(80,"\taMax = 0x%x\n", aMax); if ((readPtrL < (baseAddrL << 12)) || (readPtrL > ((baseAddrL + baseSize + 1) << 12))) { GDBG_PRINTF("FATAL ERROR: Read Pointer out of command buffer extents\n"); exit(-1); } } if (gc->chipCount > 1) { FxU32 chip ; for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) { const FxU32 baseAddrL = GR_SLAVE_CAGP_GET(chip, baseAddrL), baseSize = GR_SLAVE_CAGP_GET(chip, baseSize), readPtrL = GR_SLAVE_CAGP_GET(chip, readPtrL), aMin = GR_SLAVE_CAGP_GET(chip, aMin), aMax = GR_SLAVE_CAGP_GET(chip, aMax), depth = GR_SLAVE_CAGP_GET(chip, depth), holeCount = GR_SLAVE_CAGP_GET(chip, holeCount); GDBG_INFO(80,"Fifo check timeout slave 0x%x:\n", chip); GDBG_INFO(80,"\tbaseAddrL = 0x%x\n", baseAddrL); GDBG_INFO(80,"\tbaseSize = 0x%x\n", baseSize); GDBG_INFO(80,"\treadPtrL = 0x%x\n", readPtrL); GDBG_INFO(80,"\tdepth = 0x%x\n", depth); GDBG_INFO(80,"\tholeCount = 0x%x\n", holeCount); GDBG_INFO(80,"\taMin = 0x%x\n", aMin); GDBG_INFO(80,"\taMax = 0x%x\n", aMax); } } checks = 0; } #endif /* GLIDE_DEBUG */ GR_ASSERT((curReadPtr >= (FxU32)gc->cmdTransportInfo.fifoStart) && (curReadPtr < (FxU32)gc->cmdTransportInfo.fifoEnd)); roomToReadPtr += curReadDist; gc->stats.fifoStalls++; gc->stats.fifoStallDepth += GR_CAGP_GET(depth); /* Have we wrapped yet? */ if (lastHwRead > curReadPtr) roomToReadPtr += (FxI32)gc->cmdTransportInfo.fifoSize - FIFO_END_ADJUST; lastHwRead = curReadPtr; } GR_ASSERT((lastHwRead >= (FxU32)gc->cmdTransportInfo.fifoStart) && (lastHwRead < (FxU32)gc->cmdTransportInfo.fifoEnd)); /* Update cached copies */ gc->cmdTransportInfo.fifoRead = lastHwRead; gc->cmdTransportInfo.roomToReadPtr = roomToReadPtr; GDBG_INFO(gc->myLevel + 10, " Wait: (0x%X : 0x%X) : 0x%X\n", gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd, gc->cmdTransportInfo.fifoRead); } /* Do we need to wrap to front? */ if (gc->cmdTransportInfo.roomToEnd <= blockSize) { GDBG_INFO(gc->myLevel + 10, " Pre-Wrap: (0x%X : 0x%X) : 0x%X\n", gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd, gc->cmdTransportInfo.fifoRead); /* Set the jsr packet. * NB: This command must be fenced. */ FIFO_ASSERT(); { P6FENCE; if (!gc->cmdTransportInfo.autoBump) { #if __POWERPC__ && PCI_BUMP_N_GRIND SET_FIFO(*gc->cmdTransportInfo.fifoPtr++, gc->cmdTransportInfo.fifoJmpHdr[0]); FIFO_CACHE_FLUSH(gc->cmdTransportInfo.fifoPtr); GR_CAGP_SET(bump, 1); #else /* !__POWERPC__ && !PCI_BUMP_N_GRIND */ SET(*gc->cmdTransportInfo.fifoPtr++, gc->cmdTransportInfo.fifoJmpHdr[0]); /* KoolSmoky - is this correct? should we use SET_FIFO? */ SET(*gc->cmdTransportInfo.fifoPtr++, gc->cmdTransportInfo.fifoJmpHdr[1]); /* KoolSmoky - is this correct? should we use SET_FIFO? */ #ifdef HAL_CSIM GR_CAGP_SET(bump, 0); #else /* !defined(HAL_CSIM) */ GR_CAGP_SET(bump, 2); #endif #endif /* !__POWERPC__ && !PCI_BUMP_N_GRIND */ gc->cmdTransportInfo.lastBump = gc->cmdTransportInfo.fifoStart; } else { SET(*gc->cmdTransportInfo.fifoPtr, gc->cmdTransportInfo.fifoJmpHdr[0]); /* KoolSmoky - is this correct? should we use SET_FIFO? */ } } P6FENCE; wrapAddr = (FxU32)gc->cmdTransportInfo.fifoPtr; /* Update roomXXX fields for the actual wrap */ gc->cmdTransportInfo.roomToReadPtr -= gc->cmdTransportInfo.roomToEnd; gc->cmdTransportInfo.roomToEnd = gc->cmdTransportInfo.fifoSize - FIFO_END_ADJUST; #if GLIDE_USE_DEBUG_FIFO gc->stats.fifoWraps++; gc->stats.fifoWrapDepth += GR_GET(hw->cmdFifoDepth); #endif /* GLIDE_USE_DEBUG_FIFO */ /* Reset fifo ptr to start */ gc->cmdTransportInfo.fifoPtr = gc->cmdTransportInfo.fifoStart; /* We havn't really fenced here, but we set the lastFence for */ /* later calculations */ gc->cmdTransportInfo.lastFence = gc->cmdTransportInfo.fifoStart; GDBG_INFO(gc->myLevel + 10, " Post-Wrap: (0x%X : 0x%X) : 0x%X\n", gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd, gc->cmdTransportInfo.fifoRead); goto again; } /* compute room left */ gc->cmdTransportInfo.fifoRoom = MIN(gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd); GDBG_INFO(gc->myLevel, FN_NAME"_Done:\n" "\tfifoBlock: (0x%X : 0x%X)\n" "\tfifoRoom: (0x%X : 0x%X : 0x%X)\n" "\tfifo hw: (0x%X : 0x%X) : (0x%X : 0x%X : 0x%X)\n", (((FxU32)gc->cmdTransportInfo.fifoPtr - (FxU32)gc->cmdTransportInfo.fifoStart) + (FxU32)gc->cmdTransportInfo.fifoOffset), blockSize, gc->cmdTransportInfo.roomToReadPtr, gc->cmdTransportInfo.roomToEnd, gc->cmdTransportInfo.fifoRoom, HW_FIFO_PTR(FXTRUE) - (FxU32)gc->rawLfb, gc->cmdTransportInfo.fifoRead, GR_CAGP_GET(depth), GR_CAGP_GET(holeCount), GR_GET(hw->status)); FIFO_ASSERT(); } else { /* ** reset the function pointers when the context is gone */ GrTriSetupProcArchVector* curTriProcs = _GlideRoot.deviceArchProcs.curTriProcs; GrVertexListProc* curVertexListProcs = _GlideRoot.deviceArchProcs.curVertexListProcs; _GlideRoot.deviceArchProcs.curTriProcs = _GlideRoot.deviceArchProcs.nullTriProcs; _GlideRoot.deviceArchProcs.curVertexListProcs = _GlideRoot.deviceArchProcs.nullVertexListProcs; _GlideRoot.deviceArchProcs.nullTriProcs = curTriProcs; _GlideRoot.deviceArchProcs.nullVertexListProcs = curVertexListProcs; gc->archDispatchProcs.texDownloadProcs = _GlideRoot.deviceArchProcs.nullTexProcs; gc->archDispatchProcs.drawTrianglesProc = _GlideRoot.deviceArchProcs.nullDrawTrisProc; gc->archDispatchProcs.coorModeTriVector = (*_GlideRoot.deviceArchProcs.curTriProcs) + GR_WINDOW_COORDS; gc->archDispatchProcs.drawVertexList = _GlideRoot.deviceArchProcs.curVertexListProcs[GR_WINDOW_COORDS]; gc->triSetupProc = CUR_TRI_PROC(FXFALSE, (gc->state.cull_mode != GR_CULL_DISABLE)); } } GR_TRACE_EXIT(FN_NAME); #undef FN_NAME } void _grH3FifoDump_Linear(const FxU32* const linearPacketAddr) { #if GDBG_INFO_ON FXUNUSED(h3SstIORegNames); #endif } FxU32 _grHwFifoPtr(FxBool ignored) { FxU32 rVal = 0; FxU32 status, readPtrL1, readPtrL2; FxU32 chip ; /* AJB SLI MAYHEM */ GR_DCL_GC; FXUNUSED(ignored); if ( gc->windowed ) { rVal = 0; } else { if (0 && gc->chipCount > 1) { /* do { readPtrL1 = GET(gc->cRegs->cmdFifo0.readPtrL); for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) readPtrL1 = ((readPtrL1 > gc->slaveCRegs[chip]->cmdFifo0.readPtrL) ? readPtrL1 : gc->slaveCRegs[chip]->cmdFifo0.readPtrL) ; #if __POWERPC__ status = GET(gc->ioRegs->status); #else status = _grSstStatus(); #endif readPtrL2 = GET(gc->cRegs->cmdFifo0.readPtrL); for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) readPtrL2 = ((readPtrL2 < gc->slaveCRegs[chip]->cmdFifo0.readPtrL) ? readPtrL2 : gc->slaveCRegs[chip]->cmdFifo0.readPtrL) ; } while (readPtrL1 != readPtrL2); */ readPtrL2 = GET(gc->cRegs->cmdFifo0.readPtrL); #if __POWERPC__ status = GET(gc->ioRegs->status); #else status = _grSstStatus(); #endif for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) readPtrL2 = ((readPtrL2 < gc->slaveCRegs[chip]->cmdFifo0.readPtrL) ? readPtrL2 : gc->slaveCRegs[chip]->cmdFifo0.readPtrL) ; } else { do { readPtrL1 = GET(gc->cRegs->cmdFifo0.readPtrL); #if __POWERPC__ status = GET(gc->ioRegs->status); #else status = _grSstStatus(); #endif readPtrL2 = GET(gc->cRegs->cmdFifo0.readPtrL); } while (readPtrL1 != readPtrL2); } rVal = (((FxU32)gc->cmdTransportInfo.fifoStart) + readPtrL2 - (FxU32)gc->cmdTransportInfo.fifoOffset); } return rVal; } /* _grHwFifoPtr */ FxU32 _grHwFifoPtrSlave(FxU32 slave, FxBool ignored) { FxU32 rVal = 0; FxU32 status, readPtrL1, readPtrL2; GR_DCL_GC; FXUNUSED(ignored); do { readPtrL1 = GET(gc->slaveCRegs[slave-1]->cmdFifo0.readPtrL); status = GET(gc->slaveSstRegs[slave-1]->status); readPtrL2 = GET(gc->slaveCRegs[slave-1]->cmdFifo0.readPtrL); } while (readPtrL1 != readPtrL2); rVal = (((FxU32)gc->cmdTransportInfo.fifoStart) + readPtrL2 - (FxU32)gc->cmdTransportInfo.fifoOffset); return rVal; } /* _grHwFifoPtr */ #if defined( FIFO_ASSERT_FULL ) void _fifoAssertFull( void ) { GR_DCL_GC; if ( !gc->windowed ) { if ((gFifoCheckCount++ & kFifoCheckMask) == 0) { const FxU32 cmdFifoDepth = GR_GET(((SstRegs*)(gc->reg_ptr))->cmdFifoDepth); const FxU32 maxFifoDepth = ((gc->cmdTransportInfo.fifoSize - FIFO_END_ADJUST) >> 2); if(cmdFifoDepth > maxFifoDepth) { GDBG_PRINTF("cmdFifoDepth > size: 0x%X : 0x%Xn", cmdFifoDepth, maxFifoDepth); ASSERT_FAULT_IMMED(cmdFifoDepth <= maxFifoDepth); } else if (cmdFifoDepth + (gc->cmdTransportInfo.fifoRoom >> 2) > maxFifoDepth) { GDBG_PRINTF("cmdFifoDepth + fifoRoom > size: (0x%X : 0x%X) : 0x%Xn", cmdFifoDepth, (gc->cmdTransportInfo.fifoRoom >> 2), maxFifoDepth); ASSERT_FAULT_IMMED(cmdFifoDepth + (gc->cmdTransportInfo.fifoRoom >> 2) <= maxFifoDepth); } } ASSERT_FAULT_IMMED(HW_FIFO_PTR(FXTRUE) >= (FxU32)gc->cmdTransportInfo.fifoStart); ASSERT_FAULT_IMMED(HW_FIFO_PTR(FXTRUE) < (FxU32)gc->cmdTransportInfo.fifoEnd); ASSERT_FAULT_IMMED((FxU32)gc->cmdTransportInfo.fifoRoom < gc->cmdTransportInfo.fifoSize); ASSERT_FAULT_IMMED((FxU32)gc->cmdTransportInfo.fifoPtr < (FxU32)gc->cmdTransportInfo.fifoEnd); } } #endif #if GLIDE_DEBUG void _reg_group_begin_internal( FxU32 __chipId, FxU32 __regBase, FxU32 __groupNum, FxU32 __groupMask, FxU32 __pktHdr, FxU32 __checkP, volatile FxU32 *_regGroupFifoPtr ) { GR_DCL_GC; if ( !gc->windowed ) { GR_ASSERT(((__pktHdr) & 0xE0000000UL) == 0x00UL); FIFO_ASSERT(); GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) >= gc->cmdTransportInfo.fifoOffset); GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) < (gc->cmdTransportInfo.fifoOffset + gc->cmdTransportInfo.fifoSize)); GDBG_INFO(120, "REG_GROUP_BEGIN:\n"); GDBG_INFO(120, "\tFile: %s Line %d\n", __FILE__, __LINE__); GDBG_INFO(120, "\t_regGroupFifoPtr: 0x%x\n", (FxU32)_regGroupFifoPtr - (FxU32)gc->rawLfb); GDBG_INFO(120, "\t__pktHdr: 0x%x\n", __pktHdr); GDBG_INFO(120, "\t__groupNum: 0x%x\n", __groupNum); GDBG_INFO(120, "\t__groupMask: 0x%x\n", (__groupMask)); GDBG_INFO(120, "\t__chipId: 0x%x\n", __chipId); GDBG_INFO(120, "\t__regBase: 0x%x\n", __regBase); GDBG_INFO(120, "\tfifoPtr: 0x%x\n", (FxU32)gc->cmdTransportInfo.fifoPtr - (FxU32)gc->cmdTransportInfo.fifoStart - (FxU32)gc->rawLfb); GDBG_INFO(120, "\tfifoRoom: 0x%x\n", gc->cmdTransportInfo.fifoRoom); GDBG_INFO(120, "\treadPtrL: 0x%x\n", GET(gc->cRegs->cmdFifo0.readPtrL)); } } void _reg_group_begin_internal_wax( FxU32 __regBase, FxU32 __groupNum, FxU32 __groupMask, FxU32 __pktHdr, FxU32 __checkP, volatile FxU32 *__regGroupFifoPtr ) { GR_DCL_GC; if ( !gc->windowed ) { GR_ASSERT(((__pktHdr) & 0xE0000000UL) == 0x00UL); FIFO_ASSERT(); GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) >= gc->cmdTransportInfo.fifoOffset); GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) < (gc->cmdTransportInfo.fifoOffset + gc->cmdTransportInfo.fifoSize)); GDBG_INFO(220, "REG_GROUP_BEGIN_WAX:\n"); GDBG_INFO(220, "\tFile: %s Line %d\n", __FILE__, __LINE__); GDBG_INFO(220, "\t_regGroupFifoPtr: 0x%x\n", (FxU32)__regGroupFifoPtr - (FxU32)gc->rawLfb); GDBG_INFO(220, "\t__pktHdr: 0x%x\n", __pktHdr); GDBG_INFO(220, "\t__groupNum: 0x%x\n", __groupNum); GDBG_INFO(220, "\t__groupMask: 0x%x\n", (__groupMask)); GDBG_INFO(220, "\t__regBase: 0x%x\n", __regBase); GDBG_INFO(220, "\tfifoPtr: 0x%x\n", (FxU32)gc->cmdTransportInfo.fifoPtr - (FxU32)gc->cmdTransportInfo.fifoStart - (FxU32)gc->rawLfb); GDBG_INFO(220, "\tfifoRoom: 0x%x\n", gc->cmdTransportInfo.fifoRoom); GDBG_INFO(220, "\treadPtrL: 0x%x\n", GET(gc->cRegs->cmdFifo0.readPtrL)); GDBG_INFO(220, "\tStart Reg: 0x%x\n", (__pktHdr & 0x7fff) >> 3); GDBG_INFO(220, "\tReg Mask: 0x%x\n", (__pktHdr >> 15) & 0x3fff); GDBG_INFO(220, "\tReg Type: %s\n", ((__pktHdr >> 14) & 1) ? "2D" : "3D"); } } #endif /* GLIDE_DEBUG */ #endif /* USE_PACKET_FIFO */ #ifdef DRI_BUILD void _grImportFifo(int fifoPtr, int fifoRead) { struct cmdTransportInfo* gcFifo; FxU32 readPos; GR_DCL_GC; #if 1 int dummy, d; do { dummy=GET(gc->cRegs->cmdFifo0.depth); d=GET(gc->cRegs->cmdFifo0.depth); } while (dummy || d); do { dummy = GET(gc->cRegs->cmdFifo0.readPtrL); readPos = GET(gc->cRegs->cmdFifo0.readPtrL); } while (dummy!=readPos); gcFifo=&gc->cmdTransportInfo; readPos=readPos-gcFifo->fifoOffset; gcFifo->fifoPtr = gcFifo->fifoStart + (readPos>>2); gcFifo->fifoRead = (FxU32)gcFifo->fifoPtr; #else gcFifo=&gc->cmdTransportInfo; gcFifo->fifoPtr = gc->rawLfb+(fifoPtr>>2); gcFifo->fifoRead = ((int)gc->rawLfb)+fifoRead; #endif gcFifo->roomToReadPtr = gcFifo->fifoRead-((int)gcFifo->fifoPtr)-FIFO_END_ADJUST-sizeof(FxU32); if (gcFifo->roomToReadPtr<0) gcFifo->roomToReadPtr+=gcFifo->fifoSize; gcFifo->roomToEnd = gcFifo->fifoSize - ((gcFifo->fifoPtr-gcFifo->fifoStart)<<2) - FIFO_END_ADJUST; gcFifo->fifoRoom = MIN(gcFifo->roomToEnd, gcFifo->roomToReadPtr); if (!gc->cmdTransportInfo.autoBump) { gcFifo->lastBump = gcFifo->fifoPtr; gcFifo->bumpPos = gcFifo->fifoPtr + gcFifo->bumpSize; } } void _grExportFifo(int *fifoPtr, int *fifoRead) { struct cmdTransportInfo* gcFifo; GR_DCL_GC; gcFifo=&gc->cmdTransportInfo; *fifoPtr=(gcFifo->fifoPtr-gc->rawLfb)<<2; *fifoRead=(gcFifo->fifoRead-(int)gc->rawLfb); } int grFifoGetStalls() { GR_DCL_GC; return gc->stats.fifoStalls; } #endif /* defined(DRI_BUILD) */ glide3x/h5/glide3/src/fxbldno.c0100700000175300010010000000432307725034667015602 0ustar johndoeNone/* * THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY * PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT * TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX * INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE * DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). * THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A * FULL TEXT OF THE NON-WARRANTY PROVISIONS. * * USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO * RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN * TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, * AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR * SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF * THE UNITED STATES. * * COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED * * $Header: /cvsroot/glide/glide3x/h5/glide3/src/fxbldno.c,v 1.3.4.4 2003/08/21 08:49:11 dborca Exp $ * $Log: * 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce * branching. * 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the * Napalm Glide open source release. Changes include cleaned up offensive * comments and new legal headers. * 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator * $ * * 1 1/16/98 4:29p Atai * create glide 3 src * * 1 7/25/97 9:05a Pgj * generate fxbldno.h which defines BUILD_NUMBER * */ #include #include #include int main (int argc, char **argv) { struct tm locTime; time_t sysTime; char *build; time(&sysTime); locTime = *localtime(&sysTime); if ((build = getenv("BUILD_NUMBER")) != NULL) { printf("#define BUILD_NUMBER %s\n", build); printf("#define BUILD_NUMBER_STR \"%s\"\n", build); } else { unsigned short magic; magic = (locTime.tm_yday << 7) | (locTime.tm_hour << 2) | (locTime.tm_min / 15); printf("#define BUILD_NUMBER %d\n", magic); printf("#define BUILD_NUMBER_STR \"%d\"\n", magic); } return 0; } /* end main() */ glide3x/h5/glide3/src/fxcmd.h0100700000175300010010000021170607725034667015261 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** ** $Revision: 1.3.4.4 $ ** $Date: 2003/07/07 23:29:05 $ ** $Log: ** 7 3dfx 1.4.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 6 3dfx 1.4.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 5 3dfx 1.4 03/29/00 Chris Dow Moved check for fence to be ** nonconditional. ** 4 3dfx 1.3 03/24/00 Chris Dow Added code to fence every n ** writes (not to exceed 0x10000) where n is either 0x10000 or indicated by ** the environment variable FX_GLIDE_FENCE_LIMIT ** ** 3 3dfx 1.2 02/14/00 Kenneth Dyke Added macro to allow ** setting of slave CAGP registers. ** 2 3dfx 1.1 01/23/00 Adam Briggs define a handy macro for ** accessing slave chip command/agp regs ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 45 8/25/99 1:02p Atai ** fixed checkCounter ** ** 44 8/23/99 2:11p Kcd ** Mac & Debug fixes. ** ** 41 8/17/99 4:34p Kcd ** CHECK_FOR_BUMP addition (not used yet). ** Make sure to update checkCount same as count. ** ** 40 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 39 7/06/99 2:41p Atai ** added SET_FIFO to enable voodoo3 build in h5 tree ** ** 38 6/03/99 12:30p Kcd ** Clean up the sandbox ** ** 37 6/03/99 12:16p Kcd ** Fixed some MacOS compiler portability issues. ** ** 36 5/28/99 12:55p Atai ** fixed clip coord, fog coord ext with w-buffering ** ** 35 5/26/99 4:17p Kcd ** New LFB access macros (mainly for the benefit of PPC). ** ** 34 4/16/99 2:47p Kcd ** Magic PowerPC Bump & Grind Stuff. ** ** 33 4/05/99 8:25p Dow ** Alt tab mostly happy ** ** 32 4/04/99 4:56p Atai ** invert the contextP checking in GR_SET_EXPECTED_SIZE ** ** 31 4/01/99 7:55p Peter ** made names and comments more meaningful ** ** 30 3/31/99 9:02p Dow ** context loosing means no writing to hw ** ** 29 3/30/99 3:28p Atai ** added LINEAR_WRITE_SET_* for direct write ** ** 28 3/24/99 6:17p Peter ** streamlined (made more dangerouse) state validation ** ** 27 3/19/99 11:26a Peter ** expose direct fifo for gl ** ** 26 3/17/99 6:13p Peter ** fixed debug error w/ status bottleneck ** ** 25 3/17/99 5:08p Peter ** removed whacky stuff now that the command fifo threshold stuff appears ** to make all happy (including the k7) ** ** 24 3/14/99 1:47p Peter ** cmd's bng optimization, really invoke gggoph ** ** 23 3/12/99 5:43p Peter ** debug build happiness ** ** 22 3/12/99 2:27p Dow ** great-great-great grandson of packer workaround ** ** 21 3/10/99 10:42a Peter ** bump-n-grind workaround for katmai until the bug is better ** characterized ** ** 20 3/02/99 2:03p Peter ** removed no_check variant that led me astray ** ** 19 2/18/99 5:54p Peter ** removed no_tsu crapola ** ** 18 2/11/99 1:38p Atai ** sync buffer swap pending code, the right way. ** ** 17 2/02/99 4:39p Peter ** cleaned up wax commands, added assertion for alignmnet boundary ** ** 16 1/28/99 3:04p Atai ** fixed clip coord fog extension (c and asm version) ** ** 15 1/25/99 6:33p Peter ** removed some cruft I saw when cleaning up tiled textures ** ** 14 1/06/99 11:30a Peter ** cleanup trinalge dispatch code ** ** 13 11/30/98 6:57p Peter ** video memory fifo's ** ** 12 11/19/98 11:57a Atai ** fixed clip coords textured line ** ** 11 10/20/98 8:28p Peter ** shared files and fixed whackage ** ** 10 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 9 8/26/98 9:06p Jdt ** Removed all references to lfblockcount ** ** 8 8/18/98 4:30p Atai ** fixed aa triangle in clip coords ** ** 7 8/03/98 6:38a Jdt ** moved curvertexsize, stats, part of pool into gc ** ** 6 7/19/98 12:06p Jdt ** ** 5 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 4 7/18/98 12:50a Jdt ** fix retail build of glide3 with command fifo ** ** 3 7/18/98 12:25a Jdt ** Changes to reflect new shadow register structure ** ** 2 7/17/98 10:44a Atai ** fixed grTexNCCTable and clip coords st with aspect ratio ** ** 1 7/16/98 8:13a Jdt ** Separated out cmd fifo macros from fxglide.h ** */ #ifndef __FX_CMD_H__ #define __FX_CMD_H__ /*-------------------------------------------------------- Command Transport Macros and Functions --------------------------------------------------------*/ #if USE_PACKET_FIFO /* fifo.c */ extern void _grSet32(volatile FxU32* const sstAddr, const FxU32 val); extern FxU32 _grGet32(volatile FxU32* const sstAddr); #endif /* USE_PACKET_FIFO */ #if !USE_PACKET_FIFO /* NOTE: fifoFree is the number of entries, each is 8 bytes */ #define GR_CHECK_FOR_ROOM(n,p) \ do { \ FxI32 fifoFree = gc->state.fifoFree - (n); \ if (fifoFree < 0) \ fifoFree = _grSpinFifo(n); \ gc->state.fifoFree = fifoFree;\ } while(0) #define GR_WINFIFO_BEGIN() #define GR_WINFIFO_END() #elif USE_PACKET_FIFO /* Stuff to manage the command fifo on cvg * * NB: All of the addresses are in 'virtual' address space, and the * sizes are in bytes. */ /* The Voodoo^2 fifo is 4 byte aligned */ #define FIFO_ALIGN_MASK 0x03 /* We need some slop in the fifo for writing some bookkeeping data * since we don't let the fifo autowrap. Its actually a little bit * bigger just in case someone does not read this comment. * * Fullscreen: * 1 jmp (1 32-bit word) * Windowed: * pci: ret (1 32-bit word) * agp: jmp (2 32-bit words) */ #define FIFO_END_ADJUST (sizeof(FxU32) << 3) /* NB: This should be used sparingly because it does a 'real' hw read * which is *SLOW*. */ FxU32 _grHwFifoPtr(FxBool); #define HW_FIFO_PTR(a) _grHwFifoPtr(a) #if FIFO_ASSERT_FULL #define FIFO_ASSERT() { \ extern void _fifoAssertFull( void ); \ _fifoAssertFull(); \ } #else /* !FIFO_ASSERT_FULL */ #define FIFO_ASSERT() \ ASSERT_FAULT_IMMED((FxU32)gc->cmdTransportInfo.fifoRoom < gc->cmdTransportInfo.fifoSize); \ ASSERT_FAULT_IMMED((FxU32)gc->cmdTransportInfo.fifoPtr < (FxU32)gc->cmdTransportInfo.fifoEnd) #endif /* !FIFO_ASSERT_FULL */ #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #define GR_WINFIFO_BEGIN() beginCriticalSection() #define GR_WINFIFO_END() endCriticalSection() #else /* !(GLIDE_PLATFORM & GLIDE_OS_WIN32) */ #define GR_WINFIFO_BEGIN() #define GR_WINFIFO_END() #endif /* !(GLIDE_PLATFORM & GLIDE_OS_WIN32) */ extern struct cmdTransportInfo* FX_CALL _grCommandTransportInfo(void); extern void FX_CALL _grCommandTransportMakeRoom(const FxI32 blockSize, const char* fName, const int fLine); extern void _FifoFlush( void ); #if __POWERPC__ && PCI_BUMP_N_GRIND #define FIFO_CACHE_FLUSH(d) __dcbf(d,-4) #else #define FIFO_CACHE_FLUSH(d) #endif #ifndef GLIDE_DEBUG #define GR_BUMP_N_GRIND \ do { \ FIFO_CACHE_FLUSH(gc->cmdTransportInfo.fifoPtr);\ P6FENCE; \ GR_CAGP_SET(bump, gc->cmdTransportInfo.fifoPtr - gc->cmdTransportInfo.lastBump); \ gc->cmdTransportInfo.lastBump = gc->cmdTransportInfo.fifoPtr; \ gc->cmdTransportInfo.bumpPos = gc->cmdTransportInfo.fifoPtr + gc->cmdTransportInfo.bumpSize; \ if (gc->cmdTransportInfo.bumpPos > gc->cmdTransportInfo.fifoEnd) \ gc->cmdTransportInfo.bumpPos = gc->cmdTransportInfo.fifoEnd; \ } while(0) #else /* fifo.c */ extern void _grBumpNGrind(void); #define GR_BUMP_N_GRIND _grBumpNGrind() #endif #define CHECK_FOR_BUMP \ if (!gc->cmdTransportInfo.autoBump && \ (gc->cmdTransportInfo.fifoPtr > gc->cmdTransportInfo.bumpPos)) \ GR_BUMP_N_GRIND; /* Due to a feature in the hole-counting hardware, we must fence every 64K writes, so if the routine will cross that line, we fence and set a new gcFifo->lastFence value */ #define GR_CHECK_FOR_FENCE(__writeSize) \ do {\ const FxU32 locWriteSize = __writeSize >> 2;\ if (((gc->cmdTransportInfo.fifoPtr + locWriteSize) -\ gc->cmdTransportInfo.lastFence) >= _GlideRoot.environment.fenceLimit) {\ GDBG_INFO(80, "Fencing at 0%x after 0x%x writes\n", gc->cmdTransportInfo.fifoPtr, gc->cmdTransportInfo.fifoPtr - gc->cmdTransportInfo.lastFence);\ P6FENCE;\ gc->cmdTransportInfo.lastFence = gc->cmdTransportInfo.fifoPtr;\ }\ } while (0) #define GR_CHECK_FOR_ROOM(__n, __p) \ do { \ const FxU32 writeSize = (__n) + ((__p) * sizeof(FxU32)); /* Adjust for size of hdrs */ \ ASSERT(((FxU32)(gc->cmdTransportInfo.fifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ ASSERT(writeSize < gc->cmdTransportInfo.fifoSize - sizeof(FxU32)); \ FIFO_ASSERT(); \ if (gc->cmdTransportInfo.fifoRoom < (FxI32)writeSize) { \ GDBG_INFO(280, "Fifo Addr Check: (0x%X : 0x%X)\n", \ gc->cmdTransportInfo.fifoRoom, writeSize); \ _grCommandTransportMakeRoom(writeSize, __FILE__, __LINE__); \ } \ GR_CHECK_FOR_FENCE(writeSize);\ ASSERT((FxU32)gc->cmdTransportInfo.fifoRoom >= writeSize); \ FIFO_ASSERT(); \ } while(0) #else #error "GR_CHECK_FOR_ROOM not defined" #endif #if GLIDE_SANITY_SIZE #if USE_PACKET_FIFO #define GR_CHECK_FIFO_PTR() \ if (gc->cmdTransportInfo.autoBump) {\ if((FxU32)gc->cmdTransportInfo.fifoPtr != gc->checkPtr + gc->checkCounter)\ GDBG_ERROR("GR_ASSERT_FIFO", "(%s : %d) : " \ "fifoPtr should be 0x%X (0x%X : 0x%X) but is 0x%X\n", \ __FILE__, __LINE__, gc->checkPtr + gc->checkCounter, \ gc->checkPtr, gc->checkCounter, gc->cmdTransportInfo.fifoPtr);\ ASSERT_FAULT_IMMED((FxU32)gc->cmdTransportInfo.fifoPtr == gc->checkPtr + gc->checkCounter);\ } #define GR_SET_FIFO_PTR(__n, __p) \ gc->checkPtr = (FxU32)gc->cmdTransportInfo.fifoPtr; \ gc->checkCounter = ((__n) + ((__p) << 2)) #else #define GR_CHECK_FIFO_PTR() #define GR_SET_FIFO_PTR(__n, __p) #endif # define GR_CHECK_SIZE() \ if(gc->counter != gc->expected_counter) \ GDBG_ERROR("GR_ASSERT_SIZE","byte counter should be %d but is %d\n", \ gc->expected_counter,gc->counter); \ GR_CHECK_FIFO_PTR(); \ gc->checkPtr = (FxU32)gc->cmdTransportInfo.fifoPtr; \ gc->checkCounter = 0; \ ASSERT(gc->counter == gc->expected_counter); \ gc->counter = gc->expected_counter = 0 # define GR_CHECK_SIZE_DIRECT() \ if(gc->counter != gc->expected_counter) \ GDBG_ERROR("GR_ASSERT_SIZE","byte counter should be %d but is %d\n", \ gc->expected_counter,gc->counter); \ gc->checkCounter = 0; \ ASSERT(gc->counter == gc->expected_counter); \ gc->counter = gc->expected_counter = 0 # define GR_SET_EXPECTED_SIZE(n,p) \ ASSERT(gc->counter == 0); \ ASSERT(gc->expected_counter == 0); \ GR_CHECK_FOR_ROOM(n,p); \ if (gc->contextP) { \ gc->expected_counter = n; \ GR_SET_FIFO_PTR(n, p); \ } # define GR_INC_SIZE(n) gc->counter += n #else /* define to do nothing */ # define GR_CHECK_SIZE() # define GR_CHECK_SIZE_DIRECT() # define GR_SET_EXPECTED_SIZE(n,p) GR_CHECK_FOR_ROOM(n,p) # define GR_INC_SIZE(n) # define GR_SET_FIFO_PTR(__n, __p) #endif #if USE_PACKET_FIFO #if GLIDE_DEBUG void _grFifoWriteDebug(FxU32 addr, FxU32 val, FxU32 fifoPtr); #define DEBUGFIFOWRITE(a,b,c) \ _grFifoWriteDebug((FxU32) a, (FxU32) b, (FxU32) c) void _grFifoFWriteDebug(FxU32 addr, float val, FxU32 fifoPtr); #define DEBUGFIFOFWRITE(a,b,c) \ _grFifoFWriteDebug((FxU32) a, (float) b, (FxU32) c) extern void _reg_group_begin_internal_wax( FxU32 regBase, FxU32 groupNum, FxU32 groupMask, FxU32 pktHdr, FxU32 checkP, volatile FxU32 *regGroupFifoPtr ); extern void _reg_group_begin_internal( FxU32 chipId, FxU32 regBase, FxU32 groupNum, FxU32 groupMask, FxU32 pktHdr, FxU32 checkP, volatile FxU32 *regGroupFifoPtr); #define DBG_CALL( X ) X #else /* ~GDBG_INFO_ON */ #define DEBUGFIFOWRITE(a,b,c) #define DEBUGFIFOFWRITE(a,b,c) #define DBG_CALL( X ) #endif /* !GDBG_INFO_ON */ #endif /* USE_PACKET_FIFO */ #if _FIFODUMP void _grFifoWriteDebugDump(FxU32 tmu, FxU32 addr, FxU32 val, FxU32 fifoPtr); #define FIFODUMP(a,b,c,d) \ _grFifoWriteDebugDump((FxU32) a, (FxU32) b, (FxU32) c, (FxU32) d) void _grFifoFWriteDebugDump(FxU32 tmu, FxU32 addr, float val, FxU32 fifoPtr); #define FIFOFDUMP(a,b,c,d) \ _grFifoFWriteDebugDump((FxU32) a, (FxU32) b, (float) c, (FxU32) d) #else #define FIFODUMP(a,b,c,d) #define FIFOFDUMP(a,b,c,d) #endif /* _FIFODUMP */ /* HW Setting macros. We redefine the default macros to: * - add extra tracing * - work around hw bugs * - talk to teh csim * - do platform specific whacky things. */ #if HAL_CSIM /* If going through simulator make sure it sees the writes * since our 'hw pointer' is not a real address. */ # undef GET # undef GET16 # undef SET # undef SET16 # undef SETF # undef SET_FIFO # undef SETF_FIFO # define GET(s) halLoad32(&(s)) # define GET16(s) halLoad16(&(s)) # define SET(d, s) halStore32((volatile void*)&(d), (FxU32)(s)) # define SET16(d, s) halStore16((volatile void*)&(d), (FxU16)(s)) # define SETF(d, s) halStore32f((volatile void*)&(d), (s)) # define SET_FIFO(d, s) halStore32((volatile void *)&(d), (FxU32)(s)) # define SETF_FIFO(d, s) halStore32f((volatile void *)&(d), (s)) #else /* !HAL_CSIM */ # if SET_SWIZZLEHACK # undef GET # undef GET16 # undef SET # undef SET16 # undef SETF # undef SET_FIFO # undef SETF_FIFO extern FxU32 swizzleRead32(volatile FxU32 *s); extern FxU16 swizzleRead16(volatile FxU16 *s); extern void swizzleWrite32(volatile FxU32 *d, FxU32 s); extern void swizzleWrite16(volatile FxU16 *d, FxU16 s); extern void swizzleWriteF(volatile FxU32 *d, FxFloat s); extern void swizzleWriteLinear8(volatile FxU32 *d, FxU32 s); # define GET(s) swizzleRead32(&(s)) # define GET16(s) swizzleRead16((FxU16 *)&(s)) # define SET(d, s) swizzleWrite32(&(d),(s)) # define SET_FIFO(d, s) swizzleWrite32(&(d),(s)) # define SET16(d, s) swizzleWrite16((FxU16 *)&(d),(s)) # define SETF(d, s) swizzleWriteF((volatile FxU32 *)&(d),(s)) # define SETF_FIFO(d, s) swizzleWriteF((volatile FxU32 *)&(d),(s)) # elif SET_BSWAP # undef GET # undef GET16 # undef SET # undef SET16 # undef SETF # undef SET_FIFO # undef SETF_FIFO # if __POWERPC__ && (defined(__MWERKS__) || defined(__MRC__)) # define LWBRX(d, x) __lwbrx(d, x) # define STWBRX(s, d, x) __stwbrx(s, d, x) # define STHBRX(s, d, x) __sthbrx(s, d, x) # else /* !__POWERPC__ && !defined(__MWERKS__) */ # error "Define LWBRX/STWBRX macros" # endif /* !__POWERPC__ && !defined(__MWERKS__) */ # if defined(__MRC__) # define GET(s) __lwbrx( (volatile void*)&(s), 0 ) # define GET16(s) __lwbrx( (volatile void*)&(s), 0 ) # else /* !defined(__MRC__) */ # define GET(s) __lwbrx( (void*)&(s), 0 ) # define GET16(s) __lwbrx( (void*)&(s), 0 ) # endif /* !defined(__MRC__) */ # define SET(d, s) __stwbrx( s, (void*)&(d), 0) # define SET16(d, s) __sthbrx( s, (void*)&(d), 0 ) # if !SLOW_SETF # define SETF(d, s) __stwbrx( *((FxU32 *)&s), (void *)&(d), 0) # else /* !FAST_SETF */ # define SETF(d, s) { \ volatile union { float f; FxU32 u; } _u; \ _u.f = (s); \ __stwbrx( _u.u, (void*)&(d), 0 ); \ } # endif # if PCI_BUMP_N_GRIND # define SET_FIFO(d,s) setFifo((FxU32 *)&(d), s) # if !SLOW_SETF # define SETF_FIFO(d,s) setFifo((FxU32 *)&(d), *(FxU32 *)&(s)) # else # define SETF_FIFO(d,s) setFifoF(&(d), s) # endif # define SET_LINEAR_8(d, s) setFifo8((FxU32 *)&(d), (s)) # else /* !PCI_BUMP_N_GRIND */ # define SET_FIFO(d,s) SET(d,s) # define SETF_FIFO(d,s) SETF(d,s) # define SET_LINEAR_8(d, s) ((d) = (s)) # endif /* !PCI_BUMP_N_GRIND */ # define SET_LINEAR(d, s) SET_FIFO((d), (s)) # define SET_LINEAR_16(d, s) SET_FIFO((d), ((((FxU32)(s)) >> 16UL) | \ (((FxU32)(s)) << 16UL))) # define SET_LFB(d,s) ((d) = (s)) # define SET_LFB_16(d,s) ((d) = (s)) # define GET_LFB(s) __rlwinm(GET(s),16,0,31) # define GET_LFB_16(s) GET16(s) # else /* !SET_BSWAP */ # undef GET # undef GET16 # undef SET_FIFO # undef SETF_FIFO # define GET(s) s # define GET16(s) s # define SET_FIFO(d,s) SET(d,s) # define SETF_FIFO(d,s) SETF(d,s) # endif /* !SET_BSWAP */ #endif /* HW Access macros */ #if GLIDE_USE_DEBUG_FIFO #define kDebugFifoSize 0x1000UL #endif /* GLIDE_USE_DEBUG_FIFO */ /* If there wasn't a platform defined SET_LINEAR_XXX then just use * the default SET for the rest of the hw writes. */ #ifndef SET_LINEAR #define SET_LINEAR(__addr, __val) SET_FIFO(__addr, __val) #define SET_LINEAR_16(__addr, __val) SET_FIFO(__addr, __val) #define SET_LINEAR_8(__addr, __val) SET_FIFO(__addr, __val) #endif /* !defined(SET_LINEAR) */ /* If there wasn't a platform defined SET_LFB_XXX then just use * the default SET/GET for the rest of the hw writes. */ #ifndef SET_LFB #define SET_LFB(d, s) SET(d, s) #define SET_LFB_16(d, s) SET16(d, s) #define GET_LFB(s) GET(s) #define GET_LFB_16(s) GET16(s) #endif /* !defined(SET_LFB) */ /* Extract the fp exponent from a floating point value. * NB: The value passed to this macro must be convertable * into an l-value. */ #define kFPExpMask 0x7F800000UL #define kFPZeroMask 0x80000000UL #define kFPExpShift 0x17UL #define FP_FLOAT_EXP(__fpVal) ((FxU32)(((*(const FxU32*)(&(__fpVal))) & kFPExpMask) >> kFPExpShift)) #define FP_FLOAT_ZERO(__fpVal) (((*(const FxU32*)(&(__fpVal))) & ~kFPZeroMask) == 0x00) /* The two most commonly defined macros in the known universe */ #define MIN(__x, __y) (((__x) < (__y)) ? (__x) : (__y)) #define MAX(__x, __y) (((__x) < (__y)) ? (__y) : (__x)) /* Simple macro to make selecting a value against a boolean flag * simpler w/o a conditional. * * NB: This requires that the boolean value being passed in be the * result of one of the standard relational operators. */ #define MaskSelect(__b, __val) (~(((FxU32)(__b)) - 1UL) & (__val)) /* Chipfield ids that glide uses. */ #define kChipFieldShift (8UL + 3UL) typedef enum { eChipBroadcast = 0x00UL, eChipFBI = 0x01UL, eChipTMU0 = 0x02UL, eChipTMU1 = 0x04UL, eChipTMU2 = 0x08UL, eChipAltBroadcast = 0x0FUL, } FifoChipField; #define BROADCAST_ID eChipBroadcast #define WAX_ID FX_BIT(14) /* Although these are named reg_group_xxx they are generic options for * grouping register writes and should be fine w/ and w/o the fifo * being enabled. */ #if GLIDE_DEBUG #define REG_GROUP_DCL(__regMask, __regBase, __groupNum, __checkP) \ const FxBool _checkP = (__checkP); \ const FxU32 _groupNum = (__groupNum);\ const FxU32 _regMask = (__regMask); \ FxU32 _regCheckMask = (__regMask); \ FxU32 _regBase = offsetof(SstRegs, __regBase) #define REG_GROUP_DCL_WAX(__regMask, __regBase, __groupNum, __checkP) \ const FxBool _checkP = (__checkP); \ const FxU32 _groupNum = (__groupNum);\ const FxU32 _regMask = (__regMask); \ FxU32 _regCheckMask = (__regMask); \ FxU32 _regBase = offsetof(SstGRegs, __regBase) #define REG_GROUP_ASSERT(__regAddr, __val, __floatP) \ { \ const FxU32 curRegAddr = offsetof(SstRegs, __regAddr); \ const FxU32 curRegIndex = (curRegAddr - _regBase) >> 2; \ const FxU32 curRegBit = (0x01UL << curRegIndex); \ const float floatVal = (const float)(__val); \ GDBG_INFO(gc->myLevel + 200, "\t(0x%X : 0x%X) : 0x%X\n", \ curRegIndex, curRegAddr, *(const FxU32*)&floatVal); \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ GR_ASSERT((_regMask & curRegBit) == curRegBit); /* reg allocated in mask */ \ if (curRegIndex > 0) \ GR_ASSERT(((0xFFFFFFFFUL >> (32 - curRegIndex)) & _regCheckMask) == 0x00); /* All previous regs done */ \ _regCheckMask ^= curRegBit; /* Mark current reg */ \ } #define REG_GROUP_ASSERT_WAX(__regAddr, __val, __floatP) \ { \ const FxU32 curRegAddr = offsetof(SstGRegs, __regAddr); \ const FxU32 curRegIndex = (curRegAddr - _regBase) >> 2; \ const FxU32 curRegBit = (0x01UL << curRegIndex); \ const float floatVal = (const float)(__val); \ GDBG_INFO(220, "\t(0x%X : 0x%X) : 0x%X\n", \ curRegIndex, curRegAddr, *(const FxU32*)&floatVal); \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ GR_ASSERT((_regMask & curRegBit) == curRegBit); /* reg allocated in mask */ \ if (curRegIndex > 0) \ GR_ASSERT(((0xFFFFFFFFUL >> (32 - curRegIndex)) & _regCheckMask) == 0x00); /* All previous regs done */ \ _regCheckMask ^= curRegBit; /* Mark current reg */ \ } #else /* !GDBG_INFO_ON */ #define REG_GROUP_DCL(__regMask, __regBase, __groupNum, __checkP) #define REG_GROUP_DCL_WAX(__regMask, __regBase, __groupNum, __checkP) #define REG_GROUP_ASSERT(__regAddr, __val, __floatP) #define REG_GROUP_ASSERT_WAX(__regAddr, __val, __floatP) #endif /* !GDBG_INFO_ON */ #if GLIDE_HW_TRI_SETUP enum { kSetupStrip = 0x00, kSetupFan = 0x01, kSetupCullDisable = 0x00, kSetupCullEnable = 0x02, kSetupCullPositive = 0x00, kSetupCullNegative = 0x04, kSetupPingPongNorm = 0x00, kSetupPingPongDisable = 0x08 }; #define GR_CULL_MASK 0xff7fffff #else enum { kSetupStrip = 0x00, kSetupFan = 0x01, }; #endif /* GLIDE_HW_TRI_SETUP */ #define REGNUM(__reg) (offsetof(SstRegs, __reg) >> 2) #define REGNUM_WAX(_reg) (offsetof(SstGRegs, __reg) >> 2) #define PACKET_HEADER_ADD(__start, __reg, __header) \ do {\ GDBG_PRINTF("%x, %x\n", REGNUM(__reg), REGNUM(__start));\ GR_ASSERT((REGNUM(__reg) - REGNUM(__start)) <= 14);\ __header |= ((1 << (REGNUM(__reg) - REGNUM(__start))) << 15);\ } while (0) #if USE_PACKET_FIFO #define REGNUM(__reg) (offsetof(SstRegs, __reg) >> 2) #define REGNUM_WAX(_reg) (offsetof(SstGRegs, __reg) >> 2) /* The shift below is a bit tricky. Watch out! */ #define FIFO_REG(__chipField, __field) \ (GR_ASSERT(((FxU32)(__chipField)) < 0x10UL), \ ((((FxU32)offsetof(SstRegs, __field)) << 1) | (((FxU32)(__chipField)) << kChipFieldShift))) /* And here's the WAX version */ /* The shift below is a bit tricky. Watch out! */ #define FIFO_REG_WAX(__field) ((((FxU32)offsetof(SstGRegs, __field)) << 1) | SSTCP_PKT4_2D) /* The REG_GROUP_XXX macros do writes to a monotonically increasing * set of registers. There are three flavors of the macros w/ * different restrictions etc. * * NB: Care must be taken to order the REG_GROUP_SET macro uses to * match the actual register order, otherwise all hell breaks loose. */ /* Write to __groupNum registers (max 14) starting at __regBase under * the control of __groupMask (lsb->msb). */ #define REG_GROUP_BEGIN(__chipId, __regBase, __groupNum, __groupMask) \ GR_ASSERT(((__groupNum) >= 1) && ((__groupNum) <= 21)); \ GR_ASSERT(((__groupMask) & (SSTCP_PKT4_MASK >> SSTCP_PKT4_MASK_SHIFT)) != 0x00); \ GR_SET_EXPECTED_SIZE(sizeof(FxU32) * (__groupNum), 1); \ REG_GROUP_BEGIN_INTERNAL(__chipId, __regBase, __groupNum, \ __groupMask, (((__groupMask) << SSTCP_PKT4_MASK_SHIFT) | \ FIFO_REG(__chipId, __regBase) | \ SSTCP_PKT4), \ FXTRUE) #define REG_GROUP_BEGIN_WAX(__regBase, __groupNum, __groupMask) \ GR_ASSERT(((__groupNum) >= 1) && ((__groupNum) <= 21)); \ GR_ASSERT(((__groupMask) & (SSTCP_PKT4_MASK >> SSTCP_PKT4_MASK_SHIFT)) != 0x00); \ GR_SET_EXPECTED_SIZE(sizeof(FxU32) * (__groupNum), 1); \ REG_GROUP_BEGIN_INTERNAL_WAX(__regBase, __groupNum, __groupMask, \ (((__groupMask) << SSTCP_PKT4_MASK_SHIFT) | FIFO_REG_WAX(__regBase) | \ SSTCP_PKT4), FXTRUE) /* Register writes (<= 32) sequentially starting at __regBase */ #define REG_GROUP_LONG_BEGIN(__chipId, __regBase, __groupNum) \ GR_ASSERT(((__groupNum) >= 1) && ((__groupNum) <= 32)); \ GR_SET_EXPECTED_SIZE(sizeof(FxU32) * (__groupNum), 1); \ REG_GROUP_BEGIN_INTERNAL(__chipId, __regBase, __groupNum, \ (0xFFFFFFFF >> (32 - (__groupNum))), \ (((__groupNum) << SSTCP_PKT1_NWORDS_SHIFT) | \ FIFO_REG(__chipId, __regBase) | \ SSTCP_INC | \ SSTCP_PKT1), \ FXTRUE) #define REG_GROUP_BEGIN_INTERNAL(__chipId, __regBase, __groupNum, __groupMask,\ __pktHdr, __checkP) \ if (gc->contextP) { \ GR_DCL_GC; \ volatile FxU32* _regGroupFifoPtr = gc->cmdTransportInfo.fifoPtr; \ REG_GROUP_DCL(__groupMask, __regBase, __groupNum, __checkP); \ DBG_CALL( _reg_group_begin_internal( __chipId, offsetof(SstRegs, __regBase), __groupNum, \ __groupMask, __pktHdr, __checkP, \ _regGroupFifoPtr ) ); \ SET_FIFO(*_regGroupFifoPtr++, (__pktHdr)); #define REG_GROUP_BEGIN_INTERNAL_WAX(__regBase, __groupNum, \ __groupMask, __pktHdr, __checkP) \ if (gc->contextP) { \ GR_DCL_GC; \ volatile FxU32* _regGroupFifoPtr = gc->cmdTransportInfo.fifoPtr; \ REG_GROUP_DCL_WAX(__groupMask, __regBase, __groupNum, __checkP); \ DBG_CALL( _reg_group_begin_internal_wax( offsetof(SstGRegs, __regBase), __groupNum,\ __groupMask, __pktHdr, __checkP,\ _regGroupFifoPtr ) ); \ SET_FIFO(*_regGroupFifoPtr++, (__pktHdr)); #define REG_GROUP_SET(__regBase, __regAddr, __val) \ do { \ REG_GROUP_ASSERT(__regAddr, __val, FXFALSE); \ FXUNUSED(__regBase); \ if ( !gc->windowed ) { \ GDBG_INFO(120, "fifoReadPtr(HW): 0x%x\n", \ GET(gc->cRegs->cmdFifo0.readPtrL)); \ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) >= \ gc->cmdTransportInfo.fifoOffset); \ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) < \ (gc->cmdTransportInfo.fifoOffset + \ gc->cmdTransportInfo.fifoSize)); \ GDBG_INFO(120, "REG_GROUP_SET:\n"); \ } \ GDBG_INFO(120, "\tFile: %s Line %d\n", __FILE__, __LINE__); \ GDBG_INFO(120, "\tfifoPtr: 0x%x, Val: 0x%x\n", (FxU32) _regGroupFifoPtr - (FxU32)gc->rawLfb, __val);\ SET_FIFO(*_regGroupFifoPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) /* NB: This is a completely unsafe variant if you know that you built * your packet header correctly. You have been warned. */ #define REG_GROUP_INDEX_SET(__val) \ do { \ if ( !gc->windowed ) { \ GDBG_INFO(120, "fifoReadPtr(HW): 0x%x\n", \ GET(gc->cRegs->cmdFifo0.readPtrL)); \ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) >= \ gc->cmdTransportInfo.fifoOffset); \ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) < \ (gc->cmdTransportInfo.fifoOffset + \ gc->cmdTransportInfo.fifoSize)); \ GDBG_INFO(120, "REG_GROUP_SET:\n"); \ } \ GDBG_INFO(120, "\tFile: %s Line %d\n", __FILE__, __LINE__); \ GDBG_INFO(120, "\tfifoPtr: 0x%x, Val: 0x%x\n", (FxU32) _regGroupFifoPtr - (FxU32)gc->rawLfb, __val);\ SET_FIFO(*_regGroupFifoPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define REG_GROUP_SET_WAX(__regBase, __regAddr, __val) \ do { \ REG_GROUP_ASSERT_WAX(__regAddr, __val, FXFALSE); \ FXUNUSED(__regBase); \ if ( !gc->windowed ) { \ GDBG_INFO(220, "fifoReadPtr(HW): 0x%x\n", gc->cRegs->cmdFifo0.readPtrL);\ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) >= gc->cmdTransportInfo.fifoOffset);\ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) < (gc->cmdTransportInfo.fifoOffset + gc->cmdTransportInfo.fifoSize));\ } \ GDBG_INFO(220, "REG_GROUP_SET_WAX:\n");\ GDBG_INFO(220, "\tFile: %s Line %d\n", __FILE__, __LINE__);\ GDBG_INFO(220, "\tfifoPtr: 0x%x, Val: 0x%x\n", (FxU32) _regGroupFifoPtr - (FxU32)gc->rawLfb, __val);\ SET_FIFO(*_regGroupFifoPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define REG_GROUP_SETF(__regBase, __regAddr, __val) \ do { \ REG_GROUP_ASSERT(__regAddr, __val, FXTRUE); \ FXUNUSED(__regBase); \ SETF_FIFO(*(FxFloat*)_regGroupFifoPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxFloat)); \ } while(0) #if GLIDE_FP_CLAMP #define REG_GROUP_SETF_CLAMP(__regBase, __regAddr, __val) \ do { \ const FxU32 fpClampVal = FP_FLOAT_CLAMP(__val); \ REG_GROUP_ASSERT(__regAddr, fpClampVal, FXTRUE); \ FXUNUSED(__regBase); \ SETF_FIFO(*(FxFloat*)_regGroupFifoPtr++, fpClampVal); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #else #define REG_GROUP_SETF_CLAMP(__regBase, __regAddr, __val) \ REG_GROUP_SETF(__regBase, __regAddr, __val) #endif #define REG_GROUP_END() \ ASSERT(_checkP); \ ASSERT((((FxU32)_regGroupFifoPtr - (FxU32)gc->cmdTransportInfo.fifoPtr) >> 2) == _groupNum + 1); \ gc->cmdTransportInfo.fifoRoom -= ((FxU32)_regGroupFifoPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); \ gc->cmdTransportInfo.fifoPtr = (FxU32*)_regGroupFifoPtr; \ GDBG_INFO(gc->myLevel + 200, "\tGroupEnd: (0x%X : 0x%X)\n", \ gc->cmdTransportInfo.fifoPtr, gc->cmdTransportInfo.fifoRoom); \ FIFO_ASSERT(); \ } \ GR_CHECK_SIZE() #define STORE_FIFO(__chipId, __base, __field, __val) \ do { \ if (gc->contextP) { \ FxU32* curFifoPtr = gc->cmdTransportInfo.fifoPtr; \ FXUNUSED(__base); \ GR_ASSERT(((FxU32)(curFifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ DEBUGFIFOWRITE(&((SstRegs*)(__base))->__field, __val, curFifoPtr); \ FIFODUMP(__chipId, &((SstRegs*)(__base))->__field, __val, curFifoPtr); \ SET_FIFO(*curFifoPtr++, ((0x01 << SSTCP_PKT1_NWORDS_SHIFT) | /* size (32bit words) */ \ FIFO_REG(__chipId, __field) | /* chip[14:10] num[9:3] */ \ SSTCP_PKT1)); /* type (1) */ \ SET_FIFO(*curFifoPtr++, __val); \ gc->cmdTransportInfo.fifoPtr += 2; \ gc->cmdTransportInfo.fifoRoom -= (sizeof(FxU32) << 1); \ FIFO_ASSERT(); \ GR_INC_SIZE(sizeof(FxU32)); /* Size of actual write not including header */ \ } \ } while(0) #define STORE_FIFO_WAX(__chipId, __base, __field, __val) \ do { \ if (gc->contextP) { \ FxU32* curFifoPtr = gc->cmdTransportInfo.fifoPtr; \ FXUNUSED(__base); \ GR_ASSERT(((FxU32)(curFifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ DEBUGFIFOWRITE(&((SstGRegs*)(__base))->__field, __val, curFifoPtr); \ FIFODUMP(__chipId, &((SstRegs*)(__base))->__field, __val, curFifoPtr); \ SET_FIFO(*curFifoPtr++,\ ((0x01 << SSTCP_PKT1_NWORDS_SHIFT) | /* size (32bit words) */ \ FIFO_REG_WAX(__field) | /* chip[14:10] num[9:3] */ \ SSTCP_PKT1 | FXBIT(14))); /* type (1) */ \ SET_FIFO(*curFifoPtr++, __val); \ gc->cmdTransportInfo.fifoPtr += 2; \ gc->cmdTransportInfo.fifoRoom -= (sizeof(FxU32) << 1); \ FIFO_ASSERT(); \ GR_INC_SIZE(sizeof(FxU32)); /* Size of actual write not including header */ \ } \ } while(0) #define STORE_FIFO_INDEX(__chipId, __base, __regIndex, __val) \ do { \ if (gc->contextP) { \ FxU32* curFifoPtr = gc->cmdTransportInfo.fifoPtr; \ FXUNUSED(__base); \ GR_ASSERT(((FxU32)(curFifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ DEBUGFIFOWRITE(&((FxU32*)(__base))[__regIndex], __val, curFifoPtr); \ FIFODUMP(__chipId, &((FxU32*)(__base))[__regIndex], __val, curFifoPtr); \ SET_FIFO(*curFifoPtr++, ((0x01 << SSTCP_PKT1_NWORDS_SHIFT) | /* size (32bit words) */ \ ((__chipId) << kChipFieldShift) | /* chip[14:10] */ \ ((__regIndex) << 3) | /* Reg Num[9:3] */ \ SSTCP_PKT1)); /* type (1) */ \ SET_FIFO(*curFifoPtr++, __val); \ gc->cmdTransportInfo.fifoPtr += 2; \ gc->cmdTransportInfo.fifoRoom -= (sizeof(FxU32) << 1); \ FIFO_ASSERT(); \ GR_INC_SIZE(sizeof(FxU32)); /* Size of actual write not including header */ \ } \ } while(0) #define STOREF_FIFO_INDEX(__chipId, __base, __regIndex, __val) \ do { \ if (gc->contextP) { \ FxU32* curFifoPtr = gc->cmdTransportInfo.fifoPtr; \ FXUNUSED(__base); \ GR_ASSERT(((FxU32)(curFifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ DEBUGFIFOFWRITE(&((FxU32*)(__base))[__regIndex], __val, curFifoPtr); \ FIFOFDUMP(__chipId, &((FxU32*)(__base))[__regIndex], __val, curFifoPtr); \ SET_FIFO(*curFifoPtr++, ((0x01 << SSTCP_PKT1_NWORDS_SHIFT) | /* size (32bit words) */ \ ((__chipId) << kChipFieldShift) | /* chip[14:10] */ \ ((__regIndex) << 3) | /* Reg Num[9:3] */ \ SSTCP_PKT1)); /* type (1) */ \ SETF_FIFO(*curFifoPtr++, __val); \ gc->cmdTransportInfo.fifoPtr += 2; \ gc->cmdTransportInfo.fifoRoom -= (sizeof(FxU32) << 1); \ FIFO_ASSERT(); \ GR_INC_SIZE(sizeof(FxU32)); /* Size of actual write not including header */ \ } \ } while(0) #define STORE16_FIFO(__chipId, __base, __field, __val) \ do { \ if (gc->contextP) { \ FxU32* curFifoPtr = gc->cmdTransportInfo.fifoPtr; \ const FxU32 temp32 = (((FxU32)(__val)) & 0x0000FFFF); \ FXUNUSED(__base); \ ASSERT(((FxU32)(curFifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ DEBUGFIFOWRITE(&((SstRegs*)(__base))->__field, __val, curFifoPtr); \ FIFODUMP(__chipId, &((SstRegs*)(__base))->__field, __val, curFifoPtr); \ SET_FIFO(*curFifoPtr++, ((0x01 << SSTCP_PKT1_NWORDS_SHIFT) | /* size (32bit words) */ \ FIFO_REG(__chipId, __field) | /* chip[14:10] num[9:3] */ \ SSTCP_PKT1)); /* type (1) */ \ SET_FIFO(*curFifoPtr++, temp32); \ gc->cmdTransportInfo.fifoPtr += 2; \ gc->cmdTransportInfo.fifoRoom -= (sizeof(FxU32) << 1); \ FIFO_ASSERT(); \ GR_INC_SIZE(sizeof(FxU32)); /* Size of actual write not including header */ \ } \ } while(0) #define STOREF_FIFO(__chipId, __base, __field, __val) \ do { \ if (gc->contextP) { \ FxU32* curFifoPtr = gc->cmdTransportInfo.fifoPtr; \ FXUNUSED(__base); \ ASSERT(((FxU32)(curFifoPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ DEBUGFIFOFWRITE(&((SstRegs*)(__base))->__field, __val, curFifoPtr); \ FIFOFDUMP(__chipId, &((SstRegs*)(__base))->__field, __val, curFifoPtr); \ SET_FIFO(*curFifoPtr++, ((0x01 << SSTCP_PKT1_NWORDS_SHIFT) | /* size (32bit words) */ \ FIFO_REG(__chipId, __field) | /* chip[14:10] num[9:3] */ \ SSTCP_PKT1)); /* type (1) */ \ SETF_FIFO(*(FxFloat*)curFifoPtr, __val); \ curFifoPtr++; \ gc->cmdTransportInfo.fifoPtr += 2; \ gc->cmdTransportInfo.fifoRoom -= (sizeof(FxU32) << 1); \ FIFO_ASSERT(); \ GR_INC_SIZE(sizeof(FxU32)); /* Size of actual write not including header */ \ } \ } while(0) /* There are now three different flavors of the packet 3 macros for * your coding pleasure. In increasing order of complexity and control * they are TRI_BEGIN, TRI_STRIP_BEGIN, TRI_PACKET_BEGIN. * * NB: All of these macros must be terminated w/ a matching invocation of * TRI_END otherwise all sorts of hell will break loose. * * TRI_BEGIN: * The simplest form that draws a single indepependent triangle whose * parameters and culling are all the glide defaults for grDrawTriangle. * * TRI_STRIP_BEGIN: * setupMode: [kSetupStrip | kSetupFan]. Culling defaults to the current * glide setting, w/ strips/fans defaulting to ping-pong culling * nVertex: The number of vertices for the current packet (max 15). * vertexSize: Size in bytes of the parameters for the vertices making up * the current packet. * cmd: [SSTCP_PKT3_BDDBDD (Independent) * SSTCP_PKT3_BDDDDD (Start strip/fan) * SSTCP_PKT3_DDDDDD (Continue strip)] * * TRI_PACKET_BEGIN: * setupMode: The same as with TRI_STRIP_BEGIN, except that the caller * needs to specify the culling bits kSetupCullXXX/kSetupPingPongXXX. * params: Bits matching the descriptin of the sMode register describing * which parameters are specified in the packet. * nVertex: See TRI_STRIP_BEGIN. * vertexSize: See TRI_STRIP_BEGIN. * cmd: See TRI_STRIP_BEGIN. */ #define TRI_PACKET_BEGIN(__setupMode, __params, __nVertex, __vertexSize, __cmd) \ if (gc->contextP) { \ FxU32* tPackPtr = gc->cmdTransportInfo.fifoPtr; \ const FxU32 packetVal = (((__setupMode) << SSTCP_PKT3_SMODE_SHIFT) | /* [27:22] */ \ (__params) | /* pack[28] params[21:10] */ \ ((__nVertex) << SSTCP_PKT3_NUMVERTEX_SHIFT) | /* [9:6] */ \ (__cmd) | /* command [5:3] */ \ SSTCP_PKT3); /* type [2:0] */ \ TRI_ASSERT_DECL(__nVertex, __vertexSize, packetVal); \ SET_FIFO(*tPackPtr++, packetVal) #define TRI_STRIP_BEGIN(__setupMode, __nVertex, __vertexSize, __cmd) \ if (gc->contextP) { \ FxU32* tPackPtr = gc->cmdTransportInfo.fifoPtr; \ const FxU32 packetVal = (((__setupMode) << SSTCP_PKT3_SMODE_SHIFT) | /* [27:22] */ \ ((__nVertex) << SSTCP_PKT3_NUMVERTEX_SHIFT) | /* [9:6] */ \ (__cmd) | /* command [5:3] */ \ gc->cmdTransportInfo.cullStripHdr); \ TRI_ASSERT_DECL(__nVertex, __vertexSize, packetVal); \ SET_FIFO(*tPackPtr++, packetVal) #define TRI_BEGIN() \ if (gc->contextP) { \ FxU32* tPackPtr = gc->cmdTransportInfo.fifoPtr; \ TRI_ASSERT_DECL(3, gc->curVertexSize, gc->cmdTransportInfo.triPacketHdr); \ SET_FIFO(*tPackPtr++, gc->cmdTransportInfo.triPacketHdr) #if GDBG_INFO_ON extern void _grH3FifoDump_TriHdr(const FxU32 triPacketHdr); extern void _grH3FifoDump_Linear(const FxU32* const linearPacketAddr); #define DEBUGFIFODUMP_TRI(__packetAddr) _grH3FifoDump_TriHdr(__packetAddr) #define DEBUGFIFODUMP_LINEAR(__packetAddr) _grH3FifoDump_Linear(__packetAddr) #define TRI_ASSERT_DECL(__nVerts, __vertSize, __packetHdr) \ const FxU32 nVertex = (__nVerts); \ const FxU32 sVertex = (__vertSize); \ FxU32 pCount = 0; \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ GR_ASSERT(((FxU32)(tPackPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_ASSERT((((__nVerts) * (__vertSize)) + sizeof(FxU32)) <= (FxU32)gc->cmdTransportInfo.fifoRoom); \ GR_ASSERT((((FxU32)tPackPtr) + ((__nVerts) * (__vertSize)) + sizeof(FxU32)) < \ (FxU32)gc->cmdTransportInfo.fifoEnd); \ GR_ASSERT(nVertex < 0x10); \ GR_ASSERT(nVertex > 0x00); \ GR_ASSERT(((__packetHdr) & 0xE0000000UL) == 0x00UL); \ FIFO_ASSERT(); \ GDBG_INFO(120, "Triangle(0x%X): (0x%X : 0x%X)\n", (__packetHdr), __nVerts, __vertSize); \ DEBUGFIFODUMP_TRI(__packetHdr) #define CLAMP_DUMP(__val, __floatVal) \ pCount++; \ GDBG_INFO(gc->myLevel + 200, "\t(0x%X) : V#: 0x%X - P#: 0x%X - ParamVal: (%f : 0x%X)\n", \ (FxU32)tPackPtr, \ ((FxU32)tPackPtr - ((FxU32)gc->cmdTransportInfo.fifoPtr + sizeof(FxU32))) / sVertex, \ (((FxU32)tPackPtr - ((FxU32)gc->cmdTransportInfo.fifoPtr + sizeof(FxU32))) % sVertex) >> 2, \ (((__val) < 786432.875) ? (__val) : ((__val) - 786432.875)), \ (__floatVal)) #define SETF_DUMP(__val) \ pCount++; \ GDBG_INFO(gc->myLevel + 200, "\t(0x%X) : V#: 0x%X - P#: 0x%X - ParamVal: %f\n", \ (FxU32)tPackPtr, \ ((FxU32)tPackPtr - ((FxU32)gc->cmdTransportInfo.fifoPtr + sizeof(FxU32))) / sVertex, \ (((FxU32)tPackPtr - ((FxU32)gc->cmdTransportInfo.fifoPtr + sizeof(FxU32))) % sVertex) >> 2, \ (((__val) < 786432.875) ? (__val) : ((__val) - 786432.875))) #define SET_DUMP(__val) \ pCount++; \ GDBG_INFO(gc->myLevel + 200, "\t(0x%X) : V#: 0x%X - P#: 0x%X - ParamVal: 0x%X\n", \ (FxU32)tPackPtr, \ ((FxU32)tPackPtr - ((FxU32)gc->cmdTransportInfo.fifoPtr + sizeof(FxU32))) / sVertex, \ (((FxU32)tPackPtr - ((FxU32)gc->cmdTransportInfo.fifoPtr + sizeof(FxU32))) % sVertex) >> 2, \ (__val)) #define TRI_ASSERT() \ GR_ASSERT(pCount == (nVertex * (sVertex >> 2))); \ ASSERT(((FxU32)tPackPtr - (FxU32)gc->cmdTransportInfo.fifoPtr) == (nVertex * sVertex) + sizeof(FxU32)) #else /* !GDBG_INFO_ON */ #define DEBUGFIFODUMP_TRI(__packetAddr) #define DEBUGFIFODUMP_LINEAR(__packetAddr) #define CLAMP_DUMP(__val, __floatVal) #define SETF_DUMP(__val) #define SET_DUMP(__val) #define TRI_ASSERT_DECL(__nVerts, __vertSize, __packetHdr) #define TRI_ASSERT() #endif /* !GDBG_INFO_ON */ /* Get the integer representation of the color component. Currently, * following in the 'Glide is not an API for kids' tradition we'll * probably do something silly like wrap around zero. */ #if GLIDE_PACKED_RGB #define RGBA_COMP(__fpVal, __fpBias, __fpShift, __fpMask) \ ((gc->pool.ftemp1 = (float)((float)(__fpVal + (float)(__fpBias))), \ GR_ASSERT((__fpVal) >= 0.0f), \ GR_ASSERT((__fpVal) < 256.0f), \ (((*(const FxU32*)&gc->pool.ftemp1) & (__fpMask)) << (__fpShift))) #define RGBA_COMP_CLAMP(__fpVal, __compToken) \ RGBA_COMP(__fpVal, kPackBias##__compToken, kPackShift##__compToken, kPackMask##__compToken) #endif /* GLIDE_PACKED_RGB */ /* First stage tsu-subtractor chec/fix. * Mmm..... sequence operator. */ #if GLIDE_FP_CLAMP #define kFPClampThreshold 0x20UL #define FP_FLOAT_CLAMP(__fpVal) ((FP_FLOAT_EXP(__fpVal) < kFPClampThreshold) \ ? (gc->stats.tsuValClamp++, 0x00UL) \ : *(const FxU32*)(&(__fpVal))) #define TRI_SETF_CLAMP(__val) \ do { \ const FxU32 floatCastVal = FP_FLOAT_CLAMP(__val); \ CLAMP_DUMP(__val, floatCastVal); \ SET_FIFO(*tPackPtr++, floatCastVal); \ GR_INC_SIZE(sizeof(FxFloat)); \ } while(0) #else #define TRI_SETF_CLAMP(__val) \ TRI_SETF(__val) #endif #define TRI_SETF(__val) \ do { \ SETF_DUMP(__val); \ SETF_FIFO(*tPackPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxFloat)); \ } while(0) #define TRI_SET(__val) \ do { \ SET_DUMP(__val); \ SET_FIFO(*tPackPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define TRI_END \ TRI_ASSERT(); \ gc->cmdTransportInfo.fifoRoom -= ((FxU32)tPackPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); \ gc->cmdTransportInfo.fifoPtr = tPackPtr; \ GDBG_INFO(gc->myLevel + 200, "\tTriEnd: (0x%X : 0x%X)\n", tPackPtr, gc->cmdTransportInfo.fifoRoom); \ FIFO_ASSERT(); \ } #ifdef FAST_C_CLIP //******************************************* //* CPU STANDARD ROUTINES * //******************************************* #define AMG_TRISETXY(a)\ tPackPtr[0]=a[0];\ tPackPtr[1]=a[1];\ tPackPtr+=2;\ #define AMG_TRISETPARAM(a)\ tPackPtr[0]=a;\ tPackPtr++;\ #define AMG_TRISETXYNOADD(a,b)\ tPackPtr[b]=a[0];\ tPackPtr[b+1]=a[1];\ #define AMG_TRISETPARAMNOADD(a,b)\ tPackPtr[b]=a;\ #define AMG_TRIFIFOADD\ tPackPtr++; #define AMG_TRIFIFOADDVALUE(a)\ tPackPtr+=a; #define AMG_TRIFIFOMEMSET(i)\ while(i!=20)\ {\ tPackPtr[i]=0;\ i++;\ }\ #define AMG_GR_SET_EXPECTED_SIZE(n,p) \ GR_CHECK_FOR_ROOM(n,p); \ #define AMG_TRI_STRIP_BEGIN(tPackPtr,packetVal) \ tPackPtr = gc->cmdTransportInfo.fifoPtr; \ packetVal= 0x0c0 + gc->cmdTransportInfo.cullStripHdr; \ tPackPtr[0]=packetVal; \ tPackPtr++; \ #define AMG_TRI_END(tPackPtr)\ gc->cmdTransportInfo.fifoRoom -= ((FxU32)tPackPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); \ gc->cmdTransportInfo.fifoPtr = tPackPtr; \ //******************************************* //* MMX ROUTINES * //******************************************* #define AMG_FLUSHMMX() \ __asm \ {\ __asm emms \ }\ #define AMG_TRISETXYMMX(a,b,c,v2,v3)\ __asm \ {\ __asm mov esi,tPackPtr \ __asm mov edi,a \ __asm mov edx,b \ __asm mov eax,c \ __asm mov ebx,v2 \ __asm mov ecx,v3 \ __asm movq mm1,[edi] \ __asm movq mm2,[edx] \ __asm movq mm3,[eax] \ __asm movq [esi],mm1 \ __asm movq [esi+ebx*4],mm2 \ __asm movq [esi+ecx*4],mm3 \ }\ #endif /* FAST_C_CLIP */ #define FIFO_LINEAR_WRITE_BEGIN(__numWords, __type, __addr, __maskW2, __maskWN, __f, __l) \ { \ FxU32* packetPtr = gc->cmdTransportInfo.fifoPtr; \ const FxU32 __writeSize = (__numWords); /* Add size of packet header */ \ const FxU32 hdr1 = ((__type) | \ (((FxU32)(__maskW2)) << SSTCP_PKT5_BYTEN_W2_SHIFT) | \ (((FxU32)(__maskWN)) << SSTCP_PKT5_BYTEN_WN_SHIFT) | \ (__writeSize << SSTCP_PKT5_NWORDS_SHIFT) | \ SSTCP_PKT5); \ const FxU32 hdr2 = ((FxU32)(__addr)) & SSTCP_PKT5_BASEADDR; \ GR_CHECK_COMPATABILITY(FN_NAME, \ !gc->open, \ "Called before grSstWinOpen()"); \ GR_ASSERT(((FxU32)(packetPtr) & FIFO_ALIGN_MASK) == 0); /* alignment */ \ GR_ASSERT((__numWords) > 0); /* packet size */ \ GR_ASSERT((__numWords) < ((0x01 << 19) - 2)); \ GR_ASSERT((((FxU32)(__numWords) + 2) << 2) <= (FxU32)gc->cmdTransportInfo.fifoRoom); \ GR_ASSERT(((FxU32)packetPtr + (((__numWords) + 2) << 2)) < \ (FxU32)gc->cmdTransportInfo.fifoEnd); \ GR_ASSERT((hdr2 & 0xE0000000UL) == 0x00UL); \ GR_ASSERT(((__addr) & 0x03UL) == 0x00UL); \ FIFO_ASSERT(); \ GDBG_INFO(120, "LinearWrite(0x%X : 0x%X)\n", hdr1, hdr2); \ GDBG_INFO(gc->myLevel + 200, "\tFile: %s - Line: %ld\n", __f, __l); \ GDBG_INFO(gc->myLevel + 200, "\tType: 0x%X\n", (FxU32)(__type)); \ GDBG_INFO(gc->myLevel + 200, "\tAddr: 0x%X\n", (FxU32)(__addr)); \ GDBG_INFO(gc->myLevel + 200, "\tMaskW2: 0x%X\n", (FxU32)(__maskW2)); \ GDBG_INFO(gc->myLevel + 200, "\tMaskWN: 0x%X\n", (FxU32)(__maskWN)); \ GDBG_INFO(gc->myLevel + 200, "\twriteSize: 0x%X\n", __writeSize); \ GDBG_INFO(gc->myLevel + 200, "\thdr 1: 0x%X\n", hdr1); \ GDBG_INFO(gc->myLevel + 200, "\thdr 2: 0x%X\n", hdr2); \ SET_FIFO(*packetPtr++, hdr1); \ SET_FIFO(*packetPtr++, hdr2); \ GR_INC_SIZE(sizeof(FxU32)) #define FIFO_LINEAR_WRITE_SET(__val) \ do { \ GDBG_INFO(gc->myLevel + 205, "\t0x%X : 0x%X\n", packetPtr, (__val)); \ GDBG_INFO(120, "fifoPtr: 0x%x, val: 0x%x\n\n", packetPtr, __val);\ if ( !gc->windowed ) { \ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) >= gc->cmdTransportInfo.fifoOffset);\ GR_ASSERT(GET(gc->cRegs->cmdFifo0.readPtrL) < (gc->cmdTransportInfo.fifoOffset + gc->cmdTransportInfo.fifoSize));\ } \ SET_LINEAR(*packetPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define FIFO_LINEAR_WRITE_SET_16(__val) \ do { \ GDBG_INFO(gc->myLevel + 205, "\t0x%X : 0x%X\n", packetPtr, (__val)); \ SET_LINEAR_16(*packetPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define FIFO_LINEAR_WRITE_SET_8(__val) \ do { \ GDBG_INFO(gc->myLevel + 205, "\t0x%X : 0x%X\n", packetPtr, (__val)); \ SET_LINEAR_8(*packetPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define FIFO_LINEAR_WRITE_END \ DEBUGFIFODUMP_LINEAR(gc->cmdTransportInfo.fifoPtr); \ GR_ASSERT((((FxU32)packetPtr - (FxU32)gc->cmdTransportInfo.fifoPtr) >> 2) == __writeSize + 2); \ gc->cmdTransportInfo.fifoRoom -= ((FxU32)packetPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); \ gc->cmdTransportInfo.fifoPtr = packetPtr; \ GDBG_INFO(gc->myLevel + 200, "\tLinearEnd: (0x%X : 0x%X)\n", \ packetPtr, gc->cmdTransportInfo.fifoRoom); \ FIFO_ASSERT(); \ } # define GR_GET(s) GET(s) # define GR_CAGP_GET(__reg) GET(gc->cRegs->cmdFifo0.__reg) # define GR_SLAVE_CAGP_GET(__slave, __reg) GET(gc->slaveCRegs[__slave]->cmdFifo0.__reg) # define GR_CAGP_SET(__reg, __val) SET(gc->cRegs->cmdFifo0.__reg, __val) # define GR_SLAVE_CAGP_SET(__slave, __reg, __val) SET(gc->slaveCRegs[__slave]->cmdFifo0.__reg, __val) # define GR_GET16(s) ((FxU16)GET16(s)) # define GR_SET(c, h, f, s) STORE_FIFO(c, h, f, s) # define GR_SET_WAX(c, h, f, s) STORE_FIFO_WAX(c, h, f, s) # define GR_SET_INDEX(c, h, r, s) STORE_FIFO_INDEX(c, h, r, s) # define GR_SET16(c, h, f, s) STORE16_FIFO(c, h, f, s) # define GR_SETF(c, h, f, s) STOREF_FIFO(c, h, f, s) # define GR_SETF_INDEX(c, h, r, s) STOREF_FIFO_INDEX(c, h, r, s) # define GR_SET_DIRECT(__bc, __hw, __reg, __val) SET(gc->sstRegs->__reg, __val) # define GR_SET_IO(c, h, f, s) SET(gc->ioRegs->f, s) #else /* !USE_PACKET_FIFO */ # ifndef DIRECT_IO # define GR_GET(s) GET(s) # define GR_CAGP_GET(__reg) GET(gc->cRegs->cmdFifo0.__reg) # define GR_GET16(s) ((FxU16)GET16(s)) # define GR_SET(c, h, f, s) do {SET((h)->f, s); GR_INC_SIZE(4);} while(0) # define GR_SET_INDEX(c, h, r, s) do {SET(((FxU32*)(h))[r], s); GR_INC_SIZE(sizeof(FxU32));} while(0) # define GR_SETF(c, h, f, s) do {SETF(h->f, s); GR_INC_SIZE(4);} while(0) # define GR_SETF_INDEX(c, h, r, s) do {SETF(((FxU32*)(h))[r], s); GR_INC_SIZE(sizeof(FxU32));} while(0) # define GR_SET16(c, h, f, s) do {SET16((h)->f, s); GR_INC_SIZE(2);} while(0) # define GR_SET_IO(c,h,f,s) GR_SET(c, h, f, s) # define GR_SET_DIRECT(c,h,f,s) GR_SET(c, h, f, s) # else # define GR_GET(s) GET(s) # define GR_CAGP_GET(__reg) gc->cRegs->cmdFifo0.reg # define GR_GET16(s) ((FxU16)GET16(s)) # define GR_SET(c, h, f, s) {(gc->sstRegs)->f = s; GR_INC_SIZE(4);} # define GR_SETF(c, h, f, s) {((volatile float) (gc->sstRegs)->f) = (float) (s); GR_INC_SIZE(4);} # define GR_SET_INDEX(c, h, r, s) {((FxU32 *)((gc->sstRegs)[r] = s; GR_INC_SIZE(4);} # define GR_SETF_INDEX(c, h, r, s) {((volatile float *)(gc->sstRegs))[r] = (float) (s); GR_INC_SIZE(4);} # define GR_SET16(c, h, f, s) {*((FxU16 *)((gc->sstRegs)->f)) = s; GR_INC_SIZE(4);} # define GR_SET_DIRECT(__b, __ptr, __reg, __val) \ {\ __ptr->__reg = __val;\ GR_INC_SIZE(4);\ } # define GR_SET_IO(c, h, f, s) (gc->ioRegs)->f = s # endif #define GR_BUMP_N_GRIND #endif /* !USE_PACKET_FIFO */ /* Macros to do linear writes to lfb/tex memory. * * LINEAR_WRITE_BEGIN - Setup stuff for the linear write. * * numWords: The number of words to actually write to the destination * address. This does *NOT* include the packet headers etc for any * command fifos etc. * * type: One of the kLinearWriteXXX enum values above. This can * control what the legal values for addr and maskXX are. * * addr: Base address to the start the write. * * maskXX: Control what bytes in a write are active, these are active * low. W2 controls the masking of the first 32bit word written, and * WN controls all of the other writes. * * LINEAR_WRITE_SET - Writes are done in 32-bit increments, and must * be properly aligned etc. This can only be used inside of a * LINEAR_WRITE_BEGIN/LINEAR_WRITE_END pair. * * LINEAR_WRITE_EDGE - Write to a 16-bit value to an address. The * address must be aligned for at 16-bit access, and should not appear * within a LINEAR_WRITE_BEGIN/LINEAR_WRITE_END pair. * * LINEAR_WRITE_END - Finish off any stuff for the linear write. */ #if USE_PACKET_FIFO #define LINEAR_WRITE_BEGIN(__numWords, __type, __addr, __maskW2, __maskWN) \ { \ GR_SET_EXPECTED_SIZE(((FxU32)((__numWords) + 1UL) << 2UL), 1); \ FIFO_LINEAR_WRITE_BEGIN(__numWords, __type, __addr, __maskW2, __maskWN, __FILE__, __LINE__) #define LINEAR_WRITE_SET(__addr, __val) \ FIFO_LINEAR_WRITE_SET(__val) #define LINEAR_WRITE_SET_16(__addr, __val) \ FIFO_LINEAR_WRITE_SET_16(__val) #define LINEAR_WRITE_SET_8(__addr, __val) \ FIFO_LINEAR_WRITE_SET_8(__val) #define LINEAR_WRITE_END() \ FIFO_LINEAR_WRITE_END \ GR_CHECK_SIZE(); \ } /* Macro to write the edge cases of a linear write, for example to the * lfb w/ a 16-bit pixel value. We do some address manipulation here * since the cmd fifo only addresses 32-bit quantities, but allows us * to mask of crap for the actual write. */ #if (GLIDE_PLATFORM & GLIDE_HW_CVG) #define FIFO_LINEAR_EDGE_MASK_ADJUST(__mask) ((~(__mask)) & 0x0FUL) #define FIFO_LINEAR_EDGE_SET(__val) FIFO_LINEAR_WRITE_SET((((__val) & 0xFFFF0000UL) >> 16UL) | \ (((__val) & 0x0000FFFFUL) << 16UL)) #else /* !(GLIDE_PLATFORM & GLIDE_HW_CVG) */ #define FIFO_LINEAR_EDGE_SET(__val) FIFO_LINEAR_WRITE_SET(__val) #define FIFO_LINEAR_EDGE_MASK_ADJUST(__mask) (__mask) #endif #define LINEAR_WRITE_EDGE(__type, __addr, __val, __valBytes) \ do { \ const FxU32 edgeAddr = (FxU32)(((FxU32)__addr) & 0x03UL); \ GR_ASSERT((__valBytes) <= sizeof(FxU32)); \ GR_ASSERT((((FxU32)(__addr)) + (__valBytes)) <= ((((FxU32)(__addr)) & ~0x03UL) + sizeof(FxU32))); \ LINEAR_WRITE_BEGIN(1, __type, ((FxU32)__addr & ~0x03UL), \ FIFO_LINEAR_EDGE_MASK_ADJUST((0xF0UL | (0x0FUL >> (__valBytes))) >> edgeAddr), \ 0x00); \ FIFO_LINEAR_EDGE_SET(((FxU32)(__val)) << (((sizeof(FxU32) - edgeAddr) << 3UL) - \ ((__valBytes) << 3UL))); \ LINEAR_WRITE_END(); \ } while(0) #else /* !USE_PACKET_FIFO */ # define LINEAR_WRITE_BEGIN(__numWords, __type, __addr, __maskW2, __maskWN) \ { \ GR_SET_EXPECTED_SIZE(((__numWords) << 2), (__numWords)) # define LINEAR_WRITE_SET(__addr, __val) \ do { \ FxU32* tempAddr = (FxU32*)((FxU32)(__addr) + (FxU32)gc->rawLfb); \ SET(*tempAddr, __val); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) # define LINEAR_WRITE_SET_16(__addr, __val)\ LINEAR_WRITE_SET(__addr, (FxU32) __val) # define LINEAR_WRITE_SET_8(__addr, __val) \ LINEAR_WRITE_SET(__addr, (FxU32) __val) # define LINEAR_WRITE_EDGE(__type, __addr, __val, __isLeftP) \ do { \ FxU32* tempAddr = (FxU32*)(__addr); \ SET16(*tempAddr, __val); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) # define LINEAR_WRITE_END() \ GR_CHECK_SIZE(); \ } /* The REG_GROUP_XXX macros do writes to a monotonically increasing * set of registers. There are three flavors of the macros w/ * different restrictions etc. * * NB: Care must be taken to order the REG_GROUP_SET macro uses to * match the actual register order, otherwise all hell breaks loose. */ /* Write to __groupNum registers (max 14) starting at __regBase under * the control of __groupMask (lsb->msb). */ #define REG_GROUP_BEGIN(__chipId, __regBase, __groupNum, __groupMask) \ GR_ASSERT(((__groupNum) >= 1) && ((__groupNum) <= 21)); \ GR_ASSERT(((__groupMask) & (SSTCP_PKT4_MASK >> SSTCP_PKT4_MASK_SHIFT)) != 0x00); \ GR_SET_EXPECTED_SIZE(sizeof(FxU32) * (__groupNum), 1); \ REG_GROUP_BEGIN_INTERNAL(__regBase, __groupNum, __groupMask, FXTRUE) #define REG_GROUP_BEGIN_WAX(__chipId, __regBase, __groupNum, __groupMask) \ GR_ASSERT(((__groupNum) >= 1) && ((__groupNum) <= 21)); \ GR_ASSERT(((__groupMask) & (SSTCP_PKT4_MASK >> SSTCP_PKT4_MASK_SHIFT)) != 0x00); \ GR_SET_EXPECTED_SIZE(sizeof(FxU32) * (__groupNum), 1); \ REG_GROUP_BEGIN_INTERNAL_WAX(__regBase, __groupNum, __groupMask, FXTRUE) /* Register writes (<= 32) sequentially starting at __regBase */ #define REG_GROUP_LONG_BEGIN(__chipId, __regBase, __groupNum) \ GR_ASSERT(((__groupNum) >= 1) && ((__groupNum) <= 32)); \ GR_SET_EXPECTED_SIZE(sizeof(FxU32) * (__groupNum), 1); \ REG_GROUP_BEGIN_INTERNAL(__regBase, __groupNum, (0xFFFFFFFF >> (32 - (__groupNum))), FXTRUE) #define REG_GROUP_BEGIN_INTERNAL(__regBase, __groupNum, __groupMask, __checkP) \ { \ GR_DCL_GC; \ REG_GROUP_DCL(__groupMask, __regBase, __groupNum, __checkP); \ GDBG_INFO(gc->myLevel + 100, "REG_GROUP_BEGIN: (0x%X : 0x%X)\n", \ (__groupMask), offsetof(SstRegs, __regBase) >> 2) #define REG_GROUP_BEGIN_INTERNAL_WAX(__regBase, __groupNum, __groupMask, __checkP) \ { \ GR_DCL_GC; \ REG_GROUP_DCL_WAX(__groupMask, __regBase, __groupNum, __checkP); \ GDBG_INFO(220, "REG_GROUP_BEGIN_WAX: (0x%X : 0x%X)\n", \ (__groupMask), offsetof(SstGRegs, __regBase) >> 2) #define REG_GROUP_SET(__regBase, __regAddr, __val) \ do { \ REG_GROUP_ASSERT(__regAddr, __val, FXFALSE); \ SET(((SstRegs*)(__regBase))->__regAddr, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define REG_GROUP_SET_WAX(__regBase, __regAddr, __val) \ do { \ SET(((SstGRegs*)((FxU32) __regBase + SST_2D_OFFSET))->__regAddr, (__val)); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #define REG_GROUP_SETF(__regBase, __regAddr, __val) \ do { \ REG_GROUP_ASSERT(__regAddr, __val, FXTRUE); \ SETF(((SstRegs*)(__regBase))->__regAddr, (__val)); \ GR_INC_SIZE(sizeof(FxFloat)); \ } while(0) #if GLIDE_FP_CLAMP #define REG_GROUP_SETF_CLAMP(__regBase, __regAddr, __val) \ do { \ const FxU32 fpClampVal = FP_FLOAT_CLAMP(__val); \ REG_GROUP_ASSERT(__regAddr, fpClampVal, FXTRUE); \ SET(((FxU32*)(__regBase))[offsetof(SstRegs, __regAddr) >> 2], fpClampVal); \ GR_INC_SIZE(sizeof(FxU32)); \ } while(0) #else #define REG_GROUP_SETF_CLAMP(__regBase, __regAddr, __val) \ REG_GROUP_SETF(__regBase, __regAddr, __val) #endif #define REG_GROUP_END() \ ASSERT(_checkP); \ } \ GR_CHECK_SIZE() #endif /* !USE_PACKET_FIFO */ #ifdef GLIDE3 /* ** Macro to handle clip space and viewport stuff */ #define TRI_SETF_SCALE_ADVANCE(_ptr,_scaler) \ TRI_SETF(FARRAY(_ptr, i)*_scaler); dataElem++; i = gc->tsuDataList[dataElem] #define DA_SETF_SCALE_ADVANCE(_ptr,_scaler) \ DA_SETF(FARRAY(_ptr, i)*_scaler); dataElem++; i = gc->tsuDataList[dataElem] #define DA_VP_SETFS(_s,_oow) \ { \ FxI32 i, dataElem=0; \ i = gc->tsuDataList[dataElem]; \ if (gc->state.paramIndex & (STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA)) { \ if (gc->state.vData.colorType == GR_FLOAT) { \ if (gc->state.paramIndex & STATE_REQUIRES_IT_DRGB) { \ DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ } \ if (gc->state.paramIndex & STATE_REQUIRES_IT_ALPHA) { \ DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ } \ } \ else { \ DA_SETF(FARRAY(_s, i)); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ } \ if (gc->state.paramIndex & STATE_REQUIRES_OOZ) { \ if (gc->state.shadow.fbzMode & SST_DEPTH_FLOAT_SEL) { \ if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ DA_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ } else { \ DA_SETF(gc->state.depth_range*(1.f-_oow)); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ else { \ DA_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth + gc->state.Viewport.oz); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ } \ if (gc->state.paramIndex & STATE_REQUIRES_OOW_FBI) { \ if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { \ DA_SETF(FARRAY(_s, gc->state.vData.fogInfo.offset)*_oow); \ } \ else if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ DA_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ } else { \ DA_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_W_TMU0) { \ if (gc->state.vData.q0Info.mode == GR_PARAM_ENABLE) { \ DA_SETF(FARRAY(_s, gc->state.vData.q0Info.offset)*_oow); \ } \ else { \ DA_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU0) { \ DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[0].s_scale); \ DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[0].t_scale); \ } \ if (gc->state.paramIndex & STATE_REQUIRES_W_TMU1) { \ if (gc->state.vData.q1Info.mode == GR_PARAM_ENABLE) { \ DA_SETF(FARRAY(_s, gc->state.vData.q1Info.offset)*_oow); \ } \ else { \ DA_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU1) { \ DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[1].s_scale); \ DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[1].t_scale); \ } \ } #define TRI_VP_SETFS(_s,_oow) \ { \ FxI32 i, dataElem=0; \ i = gc->tsuDataList[dataElem]; \ if (gc->state.paramIndex & (STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA)) { \ if (gc->state.vData.colorType == GR_FLOAT) { \ if (gc->state.paramIndex & STATE_REQUIRES_IT_DRGB) { \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ } \ if (gc->state.paramIndex & STATE_REQUIRES_IT_ALPHA) { \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ } \ } \ else { \ TRI_SETF(FARRAY(_s, i)); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ } \ if (gc->state.paramIndex & STATE_REQUIRES_OOZ) { \ if (gc->state.shadow.fbzMode & SST_DEPTH_FLOAT_SEL) { \ if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ } else { \ TRI_SETF(gc->state.depth_range*(1.f-_oow)); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ else { \ TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth+gc->state.Viewport.oz); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ } \ if (gc->state.paramIndex & STATE_REQUIRES_OOW_FBI) { \ if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.fogInfo.offset)*_oow); \ } \ else if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ } else { \ TRI_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_W_TMU0) { \ if (gc->state.vData.q0Info.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.q0Info.offset)*_oow); \ } else { \ TRI_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU0) { \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[0].s_scale); \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[0].t_scale); \ } \ if (gc->state.paramIndex & STATE_REQUIRES_W_TMU1) { \ if (gc->state.vData.q1Info.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.q1Info.offset)*_oow); \ } \ else { \ TRI_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU1) { \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[1].s_scale); \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[1].t_scale); \ } \ } #define AA_TRI_VP_SETFS(_s,_oow) \ { \ FxI32 i, dataElem=0; \ i = gc->tsuDataList[dataElem]; \ if (gc->state.paramIndex & (STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA)) { \ if (gc->state.vData.colorType == GR_FLOAT) { \ if (gc->state.paramIndex & STATE_REQUIRES_IT_DRGB) { \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ TRI_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ } \ TRI_SETF(0.0f); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ else { \ FxU32 argb; \ argb = *((FxU32 *)((int)_s + i)) & 0x00ffffff; \ TRI_SETF(*((float *)&argb)); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ } \ if (gc->state.paramIndex & STATE_REQUIRES_OOZ) { \ if (gc->state.shadow.fbzMode & SST_DEPTH_FLOAT_SEL) { \ if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ } else { \ TRI_SETF(gc->state.depth_range*(1.f-_oow)); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ else { \ TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth+gc->state.Viewport.oz); \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ } \ if (gc->state.paramIndex & STATE_REQUIRES_OOW_FBI) { \ if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.fogInfo.offset)*_oow); \ } \ else if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ } else { \ TRI_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_W_TMU0) { \ if (gc->state.vData.q0Info.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.q0Info.offset)*_oow); \ } \ else { \ TRI_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU0) { \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[0].s_scale); \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[0].t_scale); \ } \ if (gc->state.paramIndex & STATE_REQUIRES_W_TMU1) { \ if (gc->state.vData.q1Info.mode == GR_PARAM_ENABLE) { \ TRI_SETF(FARRAY(_s, gc->state.vData.q1Info.offset)*_oow); \ } \ else { \ TRI_SETF(_oow); \ } \ dataElem++; \ i = gc->tsuDataList[dataElem]; \ } \ if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU1) { \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[1].s_scale); \ TRI_SETF_SCALE_ADVANCE(_s,_oow*gc->state.per_tmu[1].t_scale); \ } \ } #endif #endif /* __FX_CMD_H__ */ glide3x/h5/glide3/src/fxgasm.c0100700000175300010010000002245207725034667015436 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Revision: 1.3.4.6 $ ** $Date: 2003/07/24 03:51:08 $ ** ** $Log: */ #include #include #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" /*---------------------------------------------------------------------- * macros for creating assembler offset files *----------------------------------------------------------------------*/ #if 1 /* defined(NASM) - default */ #define NEWLINE printf("\n") #define COMMENT printf(";----------------------------------------------------------------------\n") #define HEADER(str) NEWLINE; COMMENT; \ printf("; Assembler offsets for %s struct\n",str);\ COMMENT; NEWLINE #define OFFSET(p,o,pname) if (hex) \ printf("%s\tequ %08xh\n",pname,((int)&p.o)-(int)&p); \ else printf("%s\tequ %10d\n",pname,((int)&p.o)-(int)&p) #define OFFSET2(p,o,pname) if (hex) \ printf("%s\tequ %08xh\n",pname,((int)&o)-(int)&p); \ else printf("%s\tequ %10d\n",pname,((int)&o)-(int)&p) #define SIZEOF(p,pname) if (hex) \ printf("SIZEOF_%s\tequ %08lxh\n",pname,sizeof(p)); \ else printf("SIZEOF_%s\tequ %10ld\n",pname,sizeof(p)) #else /* !NASM */ #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) #define NEWLINE printf("\n") #define COMMENT printf(";----------------------------------------------------------------------\n") #define HEADER(str) NEWLINE; COMMENT; \ printf("; Assembler offsets for %s struct\n",str);\ COMMENT; NEWLINE #define OFFSET(p,o,pname) if (hex) \ printf("%s\t= %08xh\n",pname,((int)&p.o)-(int)&p); \ else printf("%s\t= %10d\n",pname,((int)&p.o)-(int)&p) #define OFFSET2(p,o,pname) if (hex) \ printf("%s\t= %08xh\n",pname,((int)&o)-(int)&p); \ else printf("%s\t= %10d\n",pname,((int)&o)-(int)&p) #define SIZEOF(p,pname) if (hex) \ printf("SIZEOF_%s\t= %08xh\n",pname,sizeof(p)); \ else printf("SIZEOF_%s\t= %10d\n",pname,sizeof(p)) #else /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined (__DJGPP__) */ #define NEWLINE printf("\n"); #define COMMENT printf("/*----------------------------------------------------------------------*/\n") #define HEADER(str) NEWLINE; COMMENT; \ printf("/* Assembler offsets for %s struct */\n",str);\ COMMENT; NEWLINE #define OFFSET(p,o,pname) if (hex) \ printf("#define %s 0x%08x\n",pname,((int)&p.o)-(int)&p); \ else printf("#define %s %10d\n",pname,((int)&p.o)-(int)&p) #define OFFSET2(p,o,pname) if (hex) \ printf("#define %s 0x%08x\n",pname,((int)&o)-(int)&p); \ else printf("#define %s %10d\n",pname,((int)&o)-(int)&p) #define SIZEOF(p,pname) if (hex) \ printf("#define SIZEOF_%s 0x%08x\n",pname,sizeof(p)); \ else printf("#define SIZEOF_%s %10d\n",pname,sizeof(p)) #endif /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined (__DJGPP__) */ #endif /* defined(NASM)*/ int main (int argc, char **argv) { int hex=0; /* default is print in decimal */ static struct _GlideRoot_s gr; static GrGC gc; #if !GLIDE_HW_TRI_SETUP static SstRegs sst; static struct dataList_s dl; #endif /* !GLIDE_HW_TRI_SETUP */ if (argc > 1) { if (strcmp("-inline", argv[1]) == 0) { SstRegs dummyRegs = { 0x00UL }; printf("#ifndef __FX_INLINE_H__\n"); printf("#define __FX_INLINE_H__\n"); printf("\n"); printf("#define kTriProcOffset 0x%lXUL\n", offsetof(struct GrGC_s, triSetupProc)); printf("/* The # of 2-byte entries in the hw fog table */\n"); printf("#define kInternalFogTableEntryCount 0x%lXUL\n", sizeof(dummyRegs.fogTable) >> 1); printf("#define kTLSOffset 0x%lXUL\n", offsetof(struct _GlideRoot_s, tlsOffset)); printf("#define kLostContextOffset 0x%lxUL\n", offsetof(GrGC, lostContext)); printf("\n"); printf("#endif /* __FX_INLINE_H__ */\n"); return 0; } hex = 1; } #if !GLIDE_HW_TRI_SETUP printf("SST_CHIP_MASK = 0%xh\n",SST_CHIP_MASK); #endif HEADER ("SSTREGS"); NEWLINE; HEADER ("GC"); OFFSET (gc,base_ptr,"base_ptr\t"); OFFSET (gc,reg_ptr,"reg_ptr\t\t"); OFFSET (gc,lfb_ptr,"lfb_ptr\t\t"); OFFSET (gc,state.cull_mode,"cull_mode\t"); #ifndef GLIDE3 OFFSET (gc, regDataList,"regDataList\t"); #endif #ifdef GLIDE_DEBUG OFFSET (gc,checkPtr,"checkPtr\t\t"); #endif OFFSET (gc, tsuDataList,"tsuDataList\t"); OFFSET (gc, cmdTransportInfo.triPacketHdr, "triPacketHdr"); OFFSET (gc, cmdTransportInfo.cullStripHdr, "cullStripHdr"); OFFSET (gc, cmdTransportInfo.paramMask, "paramMask"); OFFSET (gc, cmdTransportInfo.fifoStart, "fifoStart"); OFFSET (gc, cmdTransportInfo.fifoEnd, "fifoEnd"); OFFSET (gc, cmdTransportInfo.fifoOffset, "fifoOffset"); OFFSET (gc, cmdTransportInfo.fifoSize, "fifoSize"); OFFSET (gc, cmdTransportInfo.fifoJmpHdr, "fifoJmpHdr"); OFFSET (gc, cmdTransportInfo.fifoPtr, "fifoPtr"); OFFSET (gc, cmdTransportInfo.fifoRead, "fifoRead"); OFFSET (gc, cmdTransportInfo.fifoRoom, "fifoRoom"); OFFSET (gc, cmdTransportInfo.roomToReadPtr, "roomToReadPtr"); OFFSET (gc, cmdTransportInfo.roomToEnd, "roomToEnd"); OFFSET (gc, cmdTransportInfo.lfbLockCount, "lfbLockCount"); OFFSET (gc, archDispatchProcs.triSetupProc, "triSetupProc"); OFFSET (gc, archDispatchProcs.drawTrianglesProc, "drawTrianglesProc"); OFFSET (gc, archDispatchProcs.triSetupProc, "drawVertexList"); /* for Glide3 strip routine */ OFFSET (gc, state.vData.vSize, "vertexSize"); OFFSET (gc, state.vData.vStride, "vertexStride"); OFFSET (gc, state.invalid, "invalid"); OFFSET (gc, state.grCoordinateSpaceArgs.coordinate_space_mode, "CoordinateSpace"); #ifdef GLIDE_VERTEX_TABLE OFFSET (gc, state.vTable, "vTable"); #endif /* for Glide3 clip coordinate */ OFFSET (gc, state.paramIndex, "paramIndex"); OFFSET (gc, state.Viewport.hwidth, "vp_hwidth"); OFFSET (gc, state.Viewport.hheight, "vp_hheight"); OFFSET (gc, state.Viewport.hdepth, "vp_hdepth"); OFFSET (gc, state.Viewport.ox, "vp_ox"); OFFSET (gc, state.Viewport.oy, "vp_oy"); OFFSET (gc, state.Viewport.oz, "vp_oz"); OFFSET (gc, state.vData.colorType, "colorType"); OFFSET (gc, state.vData.wInfo.offset, "wInfo_offset"); OFFSET (gc, state.vData.qInfo.mode, "qInfo_mode"); OFFSET (gc, state.vData.qInfo.offset, "qInfo_offset"); OFFSET (gc, state.vData.q0Info.offset, "q0Info_offset"); OFFSET (gc, state.vData.q1Info.offset, "q1Info_offset"); OFFSET (gc, state.vData.q0Info.mode, "q0Info_mode"); OFFSET (gc, state.vData.q1Info.mode, "q1Info_mode"); OFFSET (gc, state.vData.fogInfo.offset, "fogInfo_offset"); OFFSET (gc, state.vData.fogInfo.mode, "fogInfo_mode"); OFFSET (gc, state.depth_range, "depth_range"); OFFSET (gc, state.per_tmu[0].s_scale, "tmu0_s_scale"); OFFSET (gc, state.per_tmu[0].t_scale, "tmu0_t_scale"); OFFSET (gc, state.per_tmu[1].s_scale, "tmu1_s_scale"); OFFSET (gc, state.per_tmu[1].t_scale, "tmu1_t_scale"); OFFSET (gc, state.shadow.fbzMode, "fbi_fbzMode"); OFFSET (gc, curTriSize, "curTriSize\t"); OFFSET (gc, stats.trisProcessed, "trisProcessed\t"); OFFSET (gc, stats.trisDrawn, "trisDrawn\t"); OFFSET (gc, lostContext, "lostContext\t"); OFFSET (gc, windowed, "windowed\t"); #ifdef GLIDE_INIT_HWC OFFSET (gc, bInfo, "bInfo\t"); #endif #if GLIDE_PACKED_RGB OFFSET (gc, pool.ftemp1, "fTemp1"); OFFSET (gc, pool.ftemp2, "fTemp2"); #endif HEADER ("GlideRoot"); OFFSET (gr,p6Fencer,"p6Fencer\t"); OFFSET (gr,current_sst,"current_sst\t"); OFFSET (gr,CPUType,"CPUType\t\t"); OFFSET (gr,tlsOffset,"tlsOffset\t\t"); OFFSET (gr, pool.f255,"pool_f255"); OFFSET (gr, pool.f1,"pool_f1"); SIZEOF (gr.GCs[0].state,"GrState\t"); SIZEOF (gr.GCs[0],"GC\t"); NEWLINE; #if GLIDE_PACKED_RGB OFFSET (gr, pool.fBiasHi,"fBiasHi"); OFFSET (gr, pool.fBiasLo,"fBiasLo"); #endif /* (GLIDE_PLATFORM & GLIDE_HW_CVG) && GLIDE_PACKED_RGB */ SIZEOF (gr,"GlideRoot"); NEWLINE; #if !GLIDE_HW_TRI_SETUP HEADER ("dataList"); OFFSET (dl,i,"dl_i\t\t"); OFFSET (dl,addr,"dl_addr\t\t"); SIZEOF (dl,"dataList\t"); NEWLINE; #endif /* !GLIDE_HW_TRI_SETUP */ return 0; } glide3x/h5/glide3/src/fxglide.h0100700000175300010010000032530007725034667015576 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Header: fxglide.h, 44, 6/15/2000 9:18:11 AM, Bill White ** $Log: ** 44 3dfx 1.42.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 43 3dfx 1.42 04/21/00 Kenneth Dyke Magic FX_GLIDE_NO_HW ** support. ** 42 3dfx 1.41 04/13/00 Kenneth Dyke Added support for new style ** 2-sample AA mode. ** 41 3dfx 1.40 04/10/00 Kenneth Dyke Added magical screenshot ** hotkey. ** 40 3dfx 1.39 04/04/00 Kenneth Dyke Fixed addressing for large ** tiled textures. ** 39 3dfx 1.38 03/25/00 Adam Briggs added support for ** SSTH3_SLI_AA_CONFIGURATION (the env var the control panel uses to force AA ** modes) ** 38 3dfx 1.37 03/24/00 Chris Dow Added code to fence every n ** writes (not to exceed 0x10000) where n is either 0x10000 or indicated by ** the environment variable FX_GLIDE_FENCE_LIMIT ** ** 37 3dfx 1.36 03/23/00 Kenneth Dyke Added tracking for whether ** or not the stencil buffer has ever been cleared. ** 36 3dfx 1.35 03/21/00 Kenneth Dyke Added variable to allow Y ** origin swapping SLI band height clamp to be disabled. ** 35 3dfx 1.34 03/19/00 Kenneth Dyke Made mode2ppc stuff part of ** the Glide state. ** 34 3dfx 1.33 03/16/00 Kenneth Dyke User-adjustable LOD bias ** value. ** 33 3dfx 1.32 03/14/00 Adam Briggs enable analog sli in 2X ** modes or when forced ** 32 3dfx 1.31 03/08/00 Kenneth Dyke Remove bad hwInitP flag. ** 31 3dfx 1.30 03/07/00 Kenneth Dyke Workaround for weird ** compressed texture quirk. ** 30 3dfx 1.29 03/06/00 Kenneth Dyke Added backdoor hack to ** toggle AA on and off on the fly. ** 29 3dfx 1.28 02/22/00 Kenneth Dyke Added flag to keep track of ** whether or not paletted textures are in use. ** 28 3dfx 1.27 02/18/00 Adam Briggs added FX_GLIDE_WAX_ON var ** which must be set to 1 to enable the newly uncommented SLI WAX buffer ** clears ** 27 3dfx 1.26 02/02/00 Kenneth Dyke Fixed per-TMU constant ** color values to not interfere with texture chroma keying. ** 26 3dfx 1.25 02/02/00 Kenneth Dyke Fix parameter setup issue ** with 2PPC modes. ** 25 3dfx 1.24 02/01/00 Kenneth Dyke Added code to detect when ** TMU0 is in passthrough mode and to enabled 2PPC in that case. (Remap TMU1 ** to TMU0). ** 24 3dfx 1.23 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 23 3dfx 1.22 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 22 3dfx 1.21 01/23/00 Adam Briggs set & recognize the SSTTYPE ** var for Voodoo4 ** 21 3dfx 1.20 01/21/00 Adam Briggs some changes to get the ** correct linear mappings for slave regs and use them to sync the fifos in ** sli mode ** 20 3dfx 1.19 01/18/00 Kenneth Dyke Added default AA jitter ** values to Glide environment. ** 19 3dfx 1.18 01/16/00 Kenneth Dyke Added column width stuff. ** 18 3dfx 1.17 01/16/00 Kenneth Dyke Added support to track ** combine extension usage. ** 17 3dfx 1.16 01/07/00 Adam Briggs Moved freeThreadStorage ** from grShutdown to the DllMain process detach code. This fixes PRS#12190, ** 12192 and 12196. ** 16 3dfx 1.15 01/04/00 Adam Briggs changed grGetGammaTable to ** be an extension called grGetGammaTableExt ** 15 3dfx 1.14 12/10/99 Leo Galway Reset GR_MAX_RESOLUTION to ** 0x17 as result of new mode info breaking builds for V3 and V2 from 3dfx ** view. ** 14 3dfx 1.13 12/08/99 Leo Galway Upped GR_MAX_RESOLUTION to ** compensate for added mode information (1600x1280, 1792x1440, 1920x1080, ** 1920x1200, 2046x1536 ). ** 13 3dfx 1.12 11/22/99 Adam Briggs Made separate TRISETUP ** macros for msvc 4x, msvc6 retail and msvc6 debug... fixes some crashing. ** 12 3dfx 1.11 11/10/99 Adam Briggs Made grBufferClear(Ext) ** cooperate with linear surfaces & texture buffers ** 11 3dfx 1.10 11/09/99 Adam Briggs Added support for reading ** the Status reg on slave chips in order to form a more perfect flush ** function. ** 10 3dfx 1.9 11/08/99 Larry warner Changes to enable building ** with MSVC 6. ** 9 3dfx 1.8 11/05/99 Anthony tai added ** FX_GLIDE_SWAPPENDINGCOUNT. Default=1. Range 0-3 ** 8 3dfx 1.7 10/20/99 Anthony tai remove un-used tmu register ** shadow ** 7 3dfx 1.6 10/15/99 Anthony tai move 2ppc setting to state ** validation ** 6 3dfx 1.5 10/08/99 Adam Briggs Supported FX_GLIDE_BPP & ** FX_GLIDE_AA_SAMPLE environment vars so the user can override the pixel ** format in grSstWinOpen calls ** 5 3dfx 1.4 10/06/99 Anthony tai disable 2ppc if tmu1 is ** specified ** 4 3dfx 1.3 09/22/99 Larry warner Created download procedures ** for FXT1 format. ** 3 3dfx 1.2 09/22/99 Adam Briggs Added ** grConstantColorValueExt... not yet tested. ** 2 3dfx 1.1 09/17/99 Anthony tai fixed 2ppc and tmumask for ** texture color/alpha combine extension ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 164 9/03/99 4:32p Atai ** disable aaCtrl and sliCtrl in winclose ** ** 163 8/25/99 8:44p Larryw ** Expand mipmap size and offset tables to accommodate FXT1. ** ** 162 8/20/99 4:56p Atai ** fixed packet4 register bit mask for window glide ** ** 161 8/19/99 7:55p Larryw ** FXT1 Tsplit changes. ** ** 160 8/18/99 3:20p Larryw ** FXT1 refinements. ** ** 159 8/17/99 5:10p Kcd ** sync rather than eieio for P6FENCE on PPC. ** ** 158 8/16/99 11:18a Adamb ** Merged in V3_OEM_100 fixes ** ** 157 8/05/99 5:03p Larryw ** FXT1 format works now. ** ** 156 7/30/99 1:22p Kcd ** Custom TRISETUP macro for PowerPC. ** ** 155 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 154 7/26/99 12:11p Atai ** initialize pci registers for sli/aa ** ** 153 7/23/99 2:01p Atai ** change tbuffer interface to grTBufferWriteMaskExt ** ** 152 7/22/99 8:14p Larryw ** Texture format byte-depth improvements ** ** 151 7/22/99 1:18p Atai ** added grTBufferMaskExt ** ** 149 7/19/99 2:52p Atai ** added variable for sli ** ** 148 7/18/99 1:59p Atai ** added grAlphaBlendFunctionExt ** ** 146 7/16/99 10:59a Atai ** remove un-supported mode ** fixed tcc, tac problem ** ** 145 7/14/99 6:23p Larryw ** Remove obsolete G3_LOD_TRANSLATE() macro ** Define _grMipMapOffset[][] at compile time ** Fix 2k texture address-finding ** ** 144 7/14/99 5:07p Atai ** fixed stencil interface and some cc/ac stuff ** ** 143 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 142 7/08/99 8:48p Atai ** stencil interface update ** ** 141 7/07/99 6:52p Larryw ** * 2k texture support ** * Reversed order of LOD tables ** * Added 512,1024, and 2048-sized entries in tables ** * Nullified G3_LOD_TRANSLATE() ** * Created _g3LodXlat() for where tLOD register is read/written ** * Misc cosmetic changes. ** ** 140 7/06/99 2:43p Atai ** added grcolormaskext and gbc variables ** ** 139 6/29/99 7:19p Atai ** remove argument for enabling SST_CM_USE_COMBINE_MODE ** ** 138 6/29/99 2:52p Atai ** added invert mode for COMBINE ext c and d term ** ** 137 6/27/99 12:44p Atai ** fixed CC and TCC ** ** 136 6/24/99 7:18p Atai ** added coombine_ext_mode and 2 buffers per chip ** ** 135 6/14/99 5:54p Larryw ** Added support for 32-bit textures. ** ** 134 6/14/99 2:05p Atai ** added grPixelFormat and grPixelSample. ** ** 133 6/13/99 6:07p Atai ** remove aa type for winopen ext ** ** 131 6/10/99 5:12p Atai ** fist pass CC and AC ext ** ** 130 6/09/99 5:23p Atai ** added _grChipMask ** ** 129 6/09/99 2:35p Atai ** added combine mode bit and args defines ** ** 128 6/08/99 6:03p Stb_sbrooks ** Added fifoSize environment var ** ** 127 6/08/99 5:48p Atai ** place holder ** ** 124 6/04/99 11:16a Atai ** added #include "h3ext.h" ** ** 122 6/03/99 6:16p Atai ** added stencil typedef and prototype ** ** 121 6/03/99 5:22p Russp ** Add in some ifdef'd code to allow variable texture alignment ** ** 120 6/03/99 4:46p Atai ** added NAPALM_ZDEPTHVALUE_NEAREST and NAPALM_WDEPTHVALUE_FARTHEST ** ** 119 6/03/99 4:26p Atai ** added device id #defs ** ** 118 6/03/99 12:16p Kcd ** Wrong SET_ macro being used for FIFO write. ** ** 117 6/03/99 11:18a Atai ** force deviceID to 7 for code development ** ** 116 6/01/99 2:34p Atai ** Added grSstWinOpenExt ** ** 115 5/28/99 12:55p Atai ** fixed clip coord, fog coord ext with w-buffering ** ** 114 5/24/99 2:49p Jamesb ** Added ptrLostContext field to exported command transport struct. ** ** 113 5/19/99 3:55p Denis ** ** 112 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a "tbext" comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 111 5/07/99 12:53p Dow ** My mods to Matts TexAddress fixes ** ** 110 4/09/99 4:22p Dow ** Fixes for lost surfaces ** ** 109 4/07/99 7:18p Atai ** added uma extension ** ** 108 4/06/99 2:43p Dow ** Let alt-tab and surface extension live in peace ** ** 107 4/05/99 8:25p Dow ** Alt tab mostly happy ** ** 106 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 104 4/01/99 7:55p Peter ** made names and comments more meaningful ** ** 103 3/31/99 9:02p Dow ** context loosing means no writing to hw ** ** 102 3/30/99 3:20p Atai ** place holder for texture and fifofree defs ** ** 101 3/24/99 6:17p Peter ** removed rle cruft ** ** 100 3/19/99 3:18p Peter ** warning about fifo extension ** ** 99 3/19/99 11:53a Peter ** re-ordered struct for exposing to gl ** ** 98 3/19/99 11:26a Peter ** expose direct fifo for gl ** ** 97 3/14/99 1:48p Peter ** really invoke gggsoph ** ** 96 3/11/99 6:38p Dow ** Resolution help ** ** 95 3/11/99 6:07p Dow ** Upped GR_MAX_RESOLUTION ** ** 94 3/10/99 10:42a Peter ** detect katmai-ness ** ** 93 3/09/99 12:49p Kcd ** oops. ** ** 92 3/09/99 12:33p Kcd ** Added committedSerialNumebr to command transport struct. ** ** 91 2/23/99 3:10p Peter ** h3 has a direct gamma table ** ** 90 2/19/99 8:03p Peter ** new splash crapola ** ** 89 2/18/99 5:56p Peter ** cleaned up more of the random texture tables ** ** 88 2/18/99 4:06p Kcd ** Faster getThreadValueFast for MacOS. ** ** 87 2/18/99 3:38p Kcd ** Mac happiness. ** ** 86 2/11/99 1:38p Atai ** sync buffer swap pending code, the right way. ** ** 85 2/09/99 2:08p Atai ** change buffer size to 4 ** ** 84 2/08/99 2:16p Peter ** single buffering is allowed ** ** 83 2/02/99 4:38p Peter ** 16 byte texture alignmnet boundary ** ** 82 1/25/99 6:35p Peter ** tiled texture cleanup ** ** 81 1/20/99 10:54a Dow ** Voodoo 3 id for apps ** ** 80 1/15/99 10:52a Peter ** cleanup lazy evaluation of fbzMode for grDepthMask and grColorMask ** ** 79 1/14/99 7:48p Peter ** cleanedup bytes per texel stuff ** ** 78 1/06/99 11:30a Peter ** cleanup trinalge dispatch code ** ** 77 1/04/99 12:03p Peter ** use window contexts for sending state ** ** 76 12/23/98 2:01p Peter ** nt currently has mutexing problems via ddraw and extescape ** ** 75 12/14/98 6:19p Dow ** Fixed for current surface extension spec ** ** 74 12/11/98 1:37p Peter ** thread tracing ** ** 73 12/07/98 11:33a Peter ** norbert's re-fixes of my merge ** ** 72 12/03/98 9:37a Dow ** Added reserved enumerant for RAM type ** ** 71 11/30/98 6:57p Peter ** video memory fifo's ** ** 70 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 69 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 68 11/09/98 5:07p Dow ** Texturing from tiled rendered surfaces works now ** ** 67 11/02/98 5:34p Peter ** tls per thread for fullscreen contexts ** ** 66 10/20/98 8:28p Peter ** shared files and fixed whackage ** ** 65 10/14/98 3:38p Dow ** Gamma stuff ** ** 64 10/14/98 1:47p Jdt ** Add texture chroma to hw state restore buffer. ** ** 63 10/13/98 5:27p Peter ** 6666 format hack ** ** 62 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 61 10/09/98 3:32p Atai ** move texchroma key shadow ** ** 60 10/09/98 2:44p Atai ** fixed 6666 palette ** ** 59 9/30/98 12:59p Atai ** added texchromakey and texchromarange for shadow state ** ** 58 9/11/98 10:45p Jdt ** Switch over to statically allocated in-memory fifo. ** ** 57 9/04/98 11:35a Peter ** re-open fix for nt (thanks to taco/rob/nt bob) ** ** 56 8/31/98 10:33a Peter ** asm w/ debugging ** ** 55 8/30/98 10:54p Jdt ** promote INVALIDATE macro to global dominion ** ** 54 8/30/98 1:34p Dow ** State & other optimizations ** ** 53 8/29/98 8:12p Dow ** Clip optimization ** ** 52 8/29/98 4:34p Dow ** thread optimization stuff ** ** 51 8/27/98 9:27p Atai ** fix env variable for glide3x ** ** 50 7/01/98 8:40a Jdt ** removed gc arg from trisetup functions ** ** 49 8/03/98 6:34a Jdt ** Changes for multi-thread ** ** 48 8/02/98 5:01p Dow ** Glide Surface Extension ** ** 46 7/21/98 7:41p Jdt ** fixed palettes ** ** 45 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 44 7/18/98 12:25a Jdt ** Some clean up and new shadow register structure to support state ** restoration. ** */ /* ** fxglide.h ** ** Internal declarations for use inside Glide. ** ** GLIDE_LIB: Defined if building the Glide Library. This macro ** should ONLY be defined by a makefile intended to build ** GLIDE.LIB or glide.a. ** ** HAL_CSIM: Defined if GLIDE should use the software simulator. An ** application is responsible for defining this macro. ** ** GLIDE_NUM_TMU: Number of physical TMUs installed. Valid values are 1 ** and 2. If this macro is not defined by the application ** it is automatically set to the value 2. ** */ #ifndef __FXGLIDE_H__ #define __FXGLIDE_H__ /* ----------------------------------------------------------------------- INCLUDE FILES ----------------------------------------------------------------------- */ /* standard */ #include #include #include #include #include /* 3dfx */ #include <3dfx.h> #include #include #include #include /* local */ #define GR_CDECL #include "g3ext.h" #include "fxcmd.h" #include "gsfc.h" /* conditional */ #if defined( GLIDE_INIT_HAL ) #include #include #else #include #define HWC_BASE_ADDR_MASK 0x03UL #endif /* defined ( GLIDE_INIT_HAL ) */ #include "fxsplash.h" #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #define WIN32_LEANER_AND_MEANER #include #else FxBool fxSplashInit (FxU32 hWnd, FxU32 screenWidth, FxU32 screenHeight, FxU32 numColBuf, FxU32 numAuxBuf, GrColorFormat_t colorFormat); void fxSplashShutdown (void); void fxSplash (float x, float y, float w, float h, FxU32 frameNumber); const void *fxSplashPlug (FxU32* w, FxU32* h, FxI32* strideInBytes, GrLfbWriteMode_t* format); #endif /* (GLIDE_PLATFORM & GLIDE_OS_WIN32) */ /* ----------------------------------------------------------------------- Manifest Constants ----------------------------------------------------------------------- */ #define MAX_NUM_SST 4 #define MAX_NUM_CONTEXTS 16 #define VOODOO_GAMMA_TABLE_SIZE 256 #define SST1_BITS_DEPTH 16 #define SST1_ZDEPTHVALUE_NEAREST 0xFFFF #define SST1_ZDEPTHVALUE_FARTHEST 0x0000 #define SST1_WDEPTHVALUE_NEAREST 0x0000 #define SST1_WDEPTHVALUE_FARTHEST 0xFFFF #define NAPALM_ZDEPTHVALUE_NEAREST 0xFFFFFF #define NAPALM_WDEPTHVALUE_FARTHEST 0xFFFFFF /* Internal define so that we don't have to use the stupid reserved * bits identifier in the code since no one knows what that means. */ #define GR_TEXFMT_P_8_RGBA GR_TEXFMT_RSVD0 #define GR_MAX_RESOLUTION 0x17 #define GR_MAX_REFRESH 8 #define GR_MAX_COLOR_BUF 3 #define GR_MAX_AUX_BUF 1 #define GR_MIN_RESOLUTION 0 #define GR_MIN_REFRESH 0 #define GR_MIN_COLOR_BUF 1 #define GR_MIN_AUX_BUF 0 #define GR_AA_ORDERED_OGL 0x00010000 #define GR_AA_ORDERED_POINTS_OGL GR_AA_ORDERED_OGL+1 #define GR_AA_ORDERED_LINES_OGL GR_AA_ORDERED_OGL+2 #define GR_AA_ORDERED_TRIANGLES_OGL GR_AA_ORDERED_OGL+3 #define GR_AA_ORDERED_POINTS_MASK 0x01 #define GR_AA_ORDERED_LINES_MASK 0x02 #define GR_AA_ORDERED_TRIANGLES_MASK 0x04 /* ----------------------------------------------------------------------- Code Macros ----------------------------------------------------------------------- */ #undef GETENV #if (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) #define GETENV(a, b) hwcGetenv(a) #else #define GETENV(a, b) hwcGetenvEx(a, b) #endif /* ----------------------------------------------------------------------- Internal Enumerated Types ----------------------------------------------------------------------- */ typedef int GrSstType; #define GR_SSTTYPE_VOODOO 0 #define GR_SSTTYPE_SST96 1 #define GR_SSTTYPE_AT3D 2 #define GR_SSTTYPE_Voodoo2 3 #define GR_SSTTYPE_Banshee 4 #define GR_SSTTYPE_Voodoo3 5 #define GR_SSTTYPE_Voodoo4 6 /* * gregk 5/3/99 * Constants defined for SSTH3_ALPHADITHERMODE registry key */ #define OPTIMAL 1 #define SHARPER 2 #define SMOOTHER 3 /* ----------------------------------------------------------------------- Internal Structures ----------------------------------------------------------------------- */ typedef struct { GrScreenResolution_t resolution; FxU32 xres; FxU32 yres; } ResEntry; typedef struct GrTMUConfig_St { int tmuRev; /* Rev of Texelfx chip */ int tmuRam; /* 1, 2, or 4 MB */ } GrTMUConfig_t; typedef struct GrVoodooConfig_St { int fbRam; /* 1, 2, or 4 MB */ int fbiRev; /* Rev of Pixelfx chip */ int nTexelfx; /* How many texelFX chips are there? */ FxBool sliDetect; /* Is it a scan-line interleaved board? */ GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */ } GrVoodooConfig_t; typedef struct GrSst96Config_St { int fbRam; /* How much? */ int nTexelfx; GrTMUConfig_t tmuConfig; } GrSst96Config_t; typedef GrVoodooConfig_t GrVoodoo2Config_t; typedef struct GrAT3DConfig_St { int rev; } GrAT3DConfig_t; typedef struct { int num_sst; /* # of HW units in the system */ struct { GrSstType type; /* Which hardware is it? */ union SstBoard_u { GrVoodooConfig_t VoodooConfig; GrSst96Config_t SST96Config; GrAT3DConfig_t AT3DConfig; GrVoodoo2Config_t Voodoo2Config; } sstBoard; } SSTs[MAX_NUM_SST]; /* configuration for each board */ } GrHwConfiguration; /* ** ----------------------------------------------------------------------- ** STUFF FOR STRIPS ** ----------------------------------------------------------------------- */ #define GR_COLOR_OFFSET_RED (0 << 2) #define GR_COLOR_OFFSET_GREEN (1 << 2) #define GR_COLOR_OFFSET_BLUE (2 << 2) #define GR_COLOR_OFFSET_ALPHA (3 << 2) #define GR_VERTEX_OFFSET_X (0 << 2) #define GR_VERTEX_OFFSET_Y (1 << 2) #define GR_VERTEX_OFFSET_Z (2 << 2) #define GR_VERTEX_OFFSET_WFBI (3 << 2) #define GR_TEXTURE_OFFSET_S (0 << 2) #define GR_TEXTURE_OFFSET_T (1 << 2) #define GR_TEXTURE_OFFSET_W (2 << 2) #define GR_DLIST_END 0x00 #define GR_VTX_PTR 0x00 #define GR_VTX_PTR_ARRAY 0x01 #define GR_SCALE_OOW 0x00 #define GR_SCALE_COLOR 0x01 #define GR_SCALE_STW 0x02 typedef struct { FxU32 mode; /* enable / disable */ FxI32 offset; /* offset to the parameter data */ } GrVParamInfo; typedef struct { GrVParamInfo vertexInfo, /* xy */ zInfo, /* z(ooz) */ wInfo, /* w(oow) */ aInfo, /* a float */ fogInfo, /* fog */ rgbInfo, /* rgb float */ pargbInfo, /* pargb byte */ st0Info, /* st0 */ st1Info, /* st1 */ qInfo, /* q */ q0Info, /* q0 */ q1Info; /* q1 */ FxU32 vStride, /* vertex stride */ vSize; /* vertex size */ FxU32 colorType; /* float or byte */ } GrVertexLayout; /*============================================================ ** State Monster Stuff: **============================================================*/ #define GR_FLUSH_STATE() \ if (gc->state.invalid) _grValidateState(); /* internal enable/disable mode */ #define GR_COMBINEEXT_MODE 0x80000001 #define GR_AA_MULTI_SAMPLE 0x80000002 /* Look in distate.c:grValidateState (NOTVALID macro) to see how these are used I wanted to keep the mixed-case register names here, and that's why they are mixed case */ #define alphaModeBIT FXBIT(0) #define fbzColorPathBIT FXBIT(1) #define fbzModeBIT FXBIT(2) #define chromaKeyBIT FXBIT(3) #define clipRegsBIT FXBIT(4) #define zaColorBIT FXBIT(5) #define fogModeBIT FXBIT(6) #define fogColorBIT FXBIT(7) #define lfbModeBIT FXBIT(8) #define c0c1BIT FXBIT(9) #define chromaRangeBIT FXBIT(10) #define stencilModeBIT FXBIT(11) #define stencilOpBIT FXBIT(12) #define combineModeBIT FXBIT(13) #define renderModeBIT FXBIT(14) #define tmuConfigBIT FXBIT(15) #define stippleBIT FXBIT(16) /* Similar bits for TMU registers */ #define textureModeBIT FXBIT(0) #define texBaseAddrBIT FXBIT(1) #define texchromaBIT FXBIT(2) /* ** lazy evaluate vertexlayout. ** it is not part of the registers so we add the bit in MSB */ #define vtxlayoutBIT FXBIT(31) /*============================================================ ** Video Stuff: **============================================================*/ #define VRETRACEMASK 0x00000fff #define HRETRACEPOS 16 struct tmuState_s { #define OOOO_OOOO_OIII_IIII 0x007f #define SR_MASK_4 OOOO_OOOO_OIII_IIII FxU32 texPkt4Hdr_0; FxU32 textureMode; /* 0x300 ( 0 ) */ FxU32 tLOD; /* 0x304 ( 1 ) */ FxU32 tDetail; /* 0x308 ( 2 ) */ FxU32 texBaseAddr; /* 0x30C ( 3 ) */ FxU32 texBaseAddr_1; /* 0x310 ( 4 ) */ FxU32 texBaseAddr_2; /* 0x314 ( 5 ) */ FxU32 texBaseAddr_3_8; /* 0x318 ( 6 ) */ /* ----------- end packet -------------*/ #define OOOO_OOOO_OOOO_OOII 0x0002 #define SR_MASK_5 OOOO_OOOO_OOOO_OOII FxU32 texPkt4Hdr_1; FxU32 texchromaKey; FxU32 texchromaRange; /* ----------- end packet -------------*/ #define SR_WORDS_6 24 FxU32 texPkt1Hdr_2; FxU32 nccTable0[12]; FxU32 nccTable1[12]; /* ----------- end packet -------------*/ #ifdef FX_GLIDE_NAPALM #define OOOO_OOOO_OOOO_OOOI 0x0001 #define SR_MASK_7 OOOO_OOOO_OOOO_OOOI FxU32 texPkt4Hdr_3; FxU32 combineMode; /* ----------- end packet -------------*/ #endif /* FX_GLIDE_NAPALM */ }; /*-------------------------------------------------------------------------- State Restoration Buffer --------------------------------------------------------------------------*/ typedef struct { #define OOII_IIOO_OIII_IIII 0x3C7f #define SR_MASK_0 OOII_IIOO_OIII_IIII #define SR_ADDR_0 ((FxU32) &((( SstRegs* )0)->fbzColorPath)) FxU32 pkt4Hdr_0; FxU32 fbzColorPath; /* 0x104 ( 0 ) */ FxU32 fogMode; /* 0x108 ( 1 ) */ FxU32 alphaMode; /* 0x10C ( 2 ) */ FxU32 fbzMode; /* 0x110 ( 3 ) */ FxU32 lfbMode; /* 0x114 ( 4 ) */ FxU32 clipLeftRight; /* 0x118 ( 5 ) */ FxU32 clipBottomTop; /* 0x11C ( 6 ) */ /* space */ FxU32 fogColor; /* 0x12C ( 10 ) */ FxU32 zaColor; /* 0x130 ( 11 ) */ FxU32 chromaKey; /* 0x134 ( 12 ) */ FxU32 chromaRange; /* 0x138 ( 13 ) */ /* ----------- end packet -------------*/ #define OOOO_OOOO_OOOO_OIII 0x0007 #define SR_MASK_1 OOOO_OOOO_OOOO_OIII #define SR_ADDR_1 ((FxU32) &((( SstRegs* )0)->stipple)) FxU32 pkt4Hdr_1; FxU32 stipple; /* 0x140 ( 15 ) */ FxU32 color0; /* 0x144 ( 16 ) */ FxU32 color1; /* 0x148 ( 17 ) */ /* ----------- end packet -------------*/ #define SR_WORDS_2 32 #define SR_ADDR_2 ((FxU32) &((( SstRegs* )0)->fogTable[0])) FxU32 pkt1Hdr_2; FxU32 fogTable[32]; /* ----------- end packet -------------*/ #ifdef FX_GLIDE_NAPALM #define OOII_IIII_IIII_IIII 0x3fff #define SR_MASK_3 OOII_IIII_IIII_IIII #define SR_ADDR_3 ((FxU32) &((( SstRegs* )0)->renderMode)) FxU32 pkt4Hdr_3; FxU32 renderMode; /* 0x1E0 ( 0 ) */ FxU32 stencilMode; /* 0x1E4 ( 1 ) */ FxU32 stencilOp; /* 0x1E8 ( 2 ) */ FxU32 colBufferAddr; /* 0x1EC ( 3 ) */ FxU32 colBufferStride; /* 0x1F0 ( 4 ) */ FxU32 auxBufferAddr; /* 0x1F4 ( 5 ) */ FxU32 auxBufferStride; /* 0x1F8 ( 6 ) */ FxU32 fbiStenciltestFail; /* 0x1FC ( 7 ) */ FxU32 clipLeftRight1; /* 0x200 ( 8 ) */ FxU32 clipBottomTop1; /* 0x204 ( 9 ) */ FxU32 combineMode; /* 0x208 ( 10 ) */ FxU32 sliCtrl; /* 0x20C ( 11 ) */ FxU32 aaCtrl; /* 0x210 ( 12 ) */ FxU32 chipMask; /* 0x214 ( 13 ) */ /* ----------- end packet -------------*/ #else /* !FX_GLIDE_NAPALM */ #define OOOO_OOOO_OOOO_IIII 0x000f #define SR_MASK_3 OOOO_OOOO_OOOO_IIII #define SR_ADDR_3 ((FxU32) &((( SstRegs* )0)->colBufferAddr)) FxU32 pkt4Hdr_3; FxU32 colBufferAddr; /* 0x1EC ( 0 ) */ FxU32 colBufferStride; /* 0x1F0 ( 1 ) */ FxU32 auxBufferAddr; /* 0x1F4 ( 2 ) */ FxU32 auxBufferStride; /* 0x1F8 ( 3 ) */ /* ----------- end packet -------------*/ #endif /* FX_GLIDE_NAPALM */ struct tmuState_s tmuState[GLIDE_NUM_TMU]; struct PaletteRow { #define SR_WORDS_P 8 #define SR_ADDR_P ((FxU32) &((( SstRegs* )0)->nccTable0[4])) FxU32 pkt1Hdr_P; FxU32 data[8]; /* ----------- end packet -------------*/ } paletteRow[32]; } GrStateBuffer; /*==========================================================================*/ /* ** GrState ** ** This structure comprises the entire queryable state in Glide. ** ** Two types of data qualify for inclusion here: ** ** API State - cull-mode ** Chip State - hw register state ** ** Not included: ** any volatile data: eg fifo setup, colBufferAddr, etc */ typedef struct { FxU32 cull_mode; /* cull neg, cull pos, don't cull */ FxU32 paramIndex; /* Index into array containing parameter indeces to be sent ot the triangle setup code */ #if GLIDE_INIT_HAL FxI32 fifoFree; /* # free entries in FIFO */ #endif FxU32 tmuMask; /* Tells the paramIndex updater which TMUs need values */ FxU32 tcctmuMask; /* Tells the paramIndex updater which TMUs need values - for tcc */ FxU32 tactmuMask; /* Tells the paramIndex updater which TMUs need values - for tac */ FxU32 combineExtsInUse; /* Tells us which combine extensions are in use by the application. */ FxU32 tmuColorPassthrough; /* TMU color combine is in passthrough */ FxU32 tmuAlphaPassthrough; /* TMU alpha combine is in passthrough */ GrStateBuffer shadow; /* shadow of all hw state registers */ struct tmuState_s tmuShadow[GLIDE_NUM_TMU]; /* shadow of TMU registers */ GrColor_t tmuColor[GLIDE_NUM_TMU]; /* Shadow of TMU constant color values */ FxU32 tmuMaskShadow; /* Intermediate tmuMask value before grValidateTMUState() */ /* We run into a bad situation when the color buffer and aux buffers are not the same size. Thus, we need to clip to the intersection of the two rectangles. */ struct wClipping_s { /* Windowed clipping */ FxBool colBufferSet, auxBufferSet; struct colBufferClip_s { FxU32 width, height; } colClip; struct auxBufferClip_s { FxU32 width, height; } auxClip; struct winClip_s { FxU32 width, height; } winClip; } wClipping; struct PerTmuState { float s_scale; float t_scale; FxU32 mmMode; FxU32 smallLod; FxU32 largeLod; FxU32 evenOdd; FxU32 nccTable; FxU32 textureMode; FxU32 tLOD; FxBool texSubLodDither; } per_tmu[GLIDE_NUM_TMU]; float depth_range; FxU32 tbufferMask; FxBool /* Values needed to determine which */ ac_requires_it_alpha, /* parameters need gradients computed */ ac_requires_texture, /* when drawing triangles */ cc_requires_it_rgb, cc_requires_texture, allowLODdither, /* allow LOD dithering */ mode2ppc, mode2ppcTMU, checkFifo; /* Check fifo status as specified by hints */ FxBool /* Values needed to determine which */ tac_requires_it_alpha[GLIDE_NUM_TMU], /* parameters need gradients computed */ tac_requires_texture[GLIDE_NUM_TMU], /* when drawing triangles */ tac_requires_prev_texture[GLIDE_NUM_TMU], tac_requires_constant_color[GLIDE_NUM_TMU], tcc_requires_it_alpha[GLIDE_NUM_TMU], tcc_requires_it_rgb[GLIDE_NUM_TMU], tcc_requires_texture[GLIDE_NUM_TMU], tcc_requires_prev_texture[GLIDE_NUM_TMU], tcc_requires_constant_color[GLIDE_NUM_TMU], palletizedTexture[GLIDE_NUM_TMU]; FxU32 lfb_constant_depth; /* Constant value for depth buffer (LFBs) */ GrAlpha_t lfb_constant_alpha; /* Constant value for alpha buffer (LFBs) */ FxU32 num_buffers; /* 2 or 3 */ GrColorFormat_t color_format; /* ARGB, RGBA, etc. */ GrOriginLocation_t /* lower left, upper left */ origin; GrTexTable_t tex_table; /* Current palette type - ncc vs palette */ float clipwindowf_xmin, clipwindowf_ymin, /* Clipping info */ clipwindowf_xmax, clipwindowf_ymax; FxU32 screen_width, screen_height; /* Screen width and height */ /* viewport and clip space coordinate related stuff */ struct { float n, f; FxFloat ox, oy, oz; FxFloat hwidth, hheight, hdepth; } Viewport; /* Strip Stuff */ GrVertexLayout vData; /*============================================================ ** State Monster Stuff: **============================================================*/ /* ** The following DWORD is used to determine what state (if any) needs to ** be flushed when a rendering primative occurs. */ FxU32 invalid; /* invalid contains bits representing: alphaMode register: modified by grAlphaBlendFunction, grAlphaTestFunction, grAlphaTestReferenceValue fbzColorPath register: modified by grAlphaCombine, grAlphaControlsITRGBLighting, grColorCombine fbzMode register: modified by grChromaKeyMode, grDepthBufferFunction, grDeptBufferMode, grDepthMask, grDitherMode, grRenderBuffer, grSstOrigin, grColorMask chromaKey register: modified by grChromaKeyValue clipLeftRight, clipBottomTop registers: modified by grClipWindow zaColor register: modified by grDepthBiasLevel fogMode register: modified by grFogMode fogColor register: modified by grFocColorValue lfbMode register: modified by grLfbWriteColorFormat, grLfbWriteColorSwizzle c0 & c1 registers: modified by grConstanColorValue */ FxU32 tmuInvalid[GLIDE_NUM_TMU]; FxU32 tmuNop; /* ** Argument storage for State Monster: ** ** NOTE that the data structure element names are IDENTICAL to the function ** argment names. This is very important, as there are macros in distate.c ** that require that. */ struct { struct { GrAlphaBlendFnc_t rgb_sf; GrAlphaBlendFnc_t rgb_df; GrAlphaBlendFnc_t alpha_sf; GrAlphaBlendFnc_t alpha_df; GrAlphaBlendOp_t rgb_op; GrAlphaBlendOp_t alpha_op; } grAlphaBlendFunctionArgs; struct { GrCmpFnc_t fnc; } grAlphaTestFunctionArgs; struct { GrAlpha_t value; } grAlphaTestReferenceValueArgs; struct { GrCombineFunction_t function; GrCombineFactor_t factor; GrCombineLocal_t local; GrCombineOther_t other; FxBool invert; } grAlphaCombineArgs; struct { FxBool enable; } grAlphaControlsITRGBLightingArgs; struct { GrCombineFunction_t function; GrCombineFactor_t factor; GrCombineLocal_t local; GrCombineOther_t other; FxBool invert; } grColorCombineArgs; struct { FxBool rgb; FxI32 alpha; } grColorMaskArgs; struct { FxBool enable; } grDepthMaskArgs; struct { GrChromakeyMode_t mode; } grChromakeyModeArgs; struct { GrColor_t color; } grChromakeyValueArgs; struct { GrColor_t range; GrChromaRangeMode_t mode; GrChromaRangeMode_t match_mode; } grChromaRangeArgs; struct { GrCmpFnc_t fnc; } grDepthBufferFunctionArgs; struct { GrDepthBufferMode_t mode; } grDepthBufferModeArgs; struct { GrDitherMode_t mode; } grDitherModeArgs; struct { GrStippleMode_t mode; } grStippleModeArgs; struct { GrStipplePattern_t stipple; } grStipplePatternArgs; struct { GrBuffer_t buffer; } grRenderBufferArgs; struct { GrOriginLocation_t origin; } grSstOriginArgs; struct { FxU32 minx; FxU32 miny; FxU32 maxx; FxU32 maxy; } grClipWindowArgs; struct { FxU32 level; } grDepthBiasLevelArgs; struct { GrFogMode_t mode; } grFogModeArgs; struct { GrColor_t color; } grFogColorValueArgs; struct { GrColorFormat_t colorFormat; } grLfbWriteColorFormatArgs; struct { FxBool swizzleBytes; FxBool swapWords; } grLfbWriteColorSwizzleArgs; struct { GrColor_t color; } grConstantColorValueArgs; struct { GrCmpFnc_t fnc; GrStencil_t ref; GrStencil_t mask; } grStencilFuncArgs; struct { GrStencil_t value; } grStencilMaskArgs; struct { GrStencil_t value; } grLfbConstantStencilArgs; struct { GrStencilOp_t stencil_fail; GrStencilOp_t depth_fail; GrStencilOp_t depth_pass; } grStencilOpArgs; struct { GrCCUColor_t a; GrCombineMode_t a_mode; GrCCUColor_t b; GrCombineMode_t b_mode; GrCCUColor_t c; FxBool c_invert; GrCCUColor_t d; FxBool d_invert; FxU32 shift; FxBool invert; } grColorCombineExtArgs; struct { GrACUColor_t a; GrCombineMode_t a_mode; GrACUColor_t b; GrCombineMode_t b_mode; GrACUColor_t c; FxBool c_invert; GrACUColor_t d; FxBool d_invert; FxU32 shift; FxBool invert; } grAlphaCombineExtArgs; struct { GrCombineFunction_t rgb_function[GLIDE_NUM_TMU]; GrCombineFactor_t rgb_factor[GLIDE_NUM_TMU]; GrCombineFunction_t alpha_function[GLIDE_NUM_TMU]; GrCombineFactor_t alpha_factor[GLIDE_NUM_TMU]; FxBool rgb_invert[GLIDE_NUM_TMU]; FxBool alpha_invert[GLIDE_NUM_TMU]; } grTexCombineArgs; struct { GrTCCUColor_t a[GLIDE_NUM_TMU]; GrCombineMode_t a_mode[GLIDE_NUM_TMU]; GrTCCUColor_t b[GLIDE_NUM_TMU]; GrCombineMode_t b_mode[GLIDE_NUM_TMU]; GrTCCUColor_t c[GLIDE_NUM_TMU]; FxBool c_invert[GLIDE_NUM_TMU]; GrTCCUColor_t d[GLIDE_NUM_TMU]; FxBool d_invert[GLIDE_NUM_TMU]; FxU32 shift[GLIDE_NUM_TMU]; FxBool invert[GLIDE_NUM_TMU]; } grTexColorCombineExtArgs; struct { GrTACUColor_t a[GLIDE_NUM_TMU]; GrCombineMode_t a_mode[GLIDE_NUM_TMU]; GrTACUColor_t b[GLIDE_NUM_TMU]; GrCombineMode_t b_mode[GLIDE_NUM_TMU]; GrTACUColor_t c[GLIDE_NUM_TMU]; FxBool c_invert[GLIDE_NUM_TMU]; GrTACUColor_t d[GLIDE_NUM_TMU]; FxBool d_invert[GLIDE_NUM_TMU]; FxU32 shift[GLIDE_NUM_TMU]; FxBool invert[GLIDE_NUM_TMU]; } grTexAlphaCombineExtArgs; struct { GrColor_t value ; } grConstantColorValueExtArgs ; struct { FxBool r; FxBool g; FxBool b; FxBool a; } grColorMaskExtArgs; } stateArgs; struct{ GrEnableMode_t primitive_smooth_mode; GrEnableMode_t shameless_plug_mode; GrEnableMode_t video_smooth_mode; GrEnableMode_t texture_uma_mode; GrEnableMode_t combine_ext_mode; GrEnableMode_t stencil_mode; FxU32 aaMultisampleDisableCount; } grEnableArgs; struct{ GrCoordinateSpaceMode_t coordinate_space_mode; } grCoordinateSpaceArgs; FxU32 forced32BPP; } GrState; /* ** Private GR_GET enumerants: */ #define GR_MEMTYPE GR_GET_RESERVED_1 /* gpci.c * * Set of procs for the current cpu type. These are selected out of * the _archXXXX proc list that is selected at grGlideInit time. */ typedef FxI32 (FX_CALL* GrTriSetupProc)(const void *a, const void *b, const void *c); typedef void (FX_CALL* GrVertexListProc)(FxU32 pkType, FxU32 type, FxI32 mode, FxI32 count, void* ptrs); typedef void (FX_CALL* GrDrawTrianglesProc)(FxI32 mode, FxI32 count, void* vPtrs); /* [grState valid bit][cull/no cull mode] */ typedef GrTriSetupProc GrTriSetupProcVector[2][2]; /* [Coordinate mode - window/clip] */ typedef GrTriSetupProcVector GrTriSetupProcArchVector[2]; /* Decalrations of the dispatchable procs found in xdraw2.asm and * xtexdl.c for teh triangle and texture download procs respectively. * * NB: These procs have the special calling convention that the current * gc is nabbed from tls and passed in edx. Screw w/ this at your * own peril. You have been warned. */ extern FxI32 FX_CALL _trisetup_Default_win_cull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_Default_win_cull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_Default_win_nocull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_Default_win_nocull_valid(const void*, const void*, const void*); /* Only one specialziation exists so far */ extern FxI32 FX_CALL _vptrisetup_cull(const void*, const void*, const void*); /* Routine to call into the architecture specialized version of * _grDrawTriangles if there is no specialized version of the * grDrawTriangle routine for clip coordinates. */ extern FxI32 FX_CALL _trisetup_clip_coor_thunk(const void*, const void*, const void*); #if GL_SSE extern FxI32 FX_CALL _trisetup_SSE_clip_coor_thunk(const void*, const void*, const void*); #endif /* GL_SSE */ extern void FX_CALL _grDrawTriangles_Default(FxI32, FxI32, void*); void FX_CSTYLE _drawvertexlist(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _vpdrawvertexlist(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); #if GL_AMD3D extern FxI32 FX_CALL _trisetup_3DNow_win_cull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_win_cull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_win_nocull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_win_nocull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_clip_cull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_clip_cull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_clip_nocull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_3DNow_clip_nocull_valid(const void*, const void*, const void*); extern void FX_CALL _grDrawTriangles_3DNow(FxI32, FxI32, void*); void FX_CSTYLE _grDrawVertexList_3DNow_Window(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _grDrawVertexList_3DNow_Clip(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); #endif /* GL_AMD3D */ #if GL_SSE extern FxI32 FX_CALL _trisetup_SSE_win_cull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_win_cull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_win_nocull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_win_nocull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_clip_cull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_clip_cull_valid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_clip_nocull_invalid(const void*, const void*, const void*); extern FxI32 FX_CALL _trisetup_SSE_clip_nocull_valid(const void*, const void*, const void*); extern void FX_CALL _grDrawTriangles_SSE(FxI32, FxI32, void*); void FX_CSTYLE _grDrawVertexList_SSE_Window(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _grDrawVertexList_SSE_Clip(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); #endif /* GL_SSE */ #ifdef __GNUC__ /* Define this structure otherwise it assumes the structure only exists within the function */ struct GrGC_s; #endif /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) */ /* _GlideRoot.curTexProcs is an array of (possibly specialized) * function pointers indexed by texture format size (8/16 bits for * pre-Napalm, 4/8/16/32 for Napalm) and texture line width (1/2/4/>4). * * xtexdl.c */ typedef void (FX_CALL* GrTexDownloadProc)(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); typedef GrTexDownloadProc GrTexDownloadProcVector[4][5]; extern void FX_CALL _grTexDownload_Default_4_4(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_4_8(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_4_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_8_1(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_8_2(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_8_4(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_8_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_16_1(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_16_2(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_16_4(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_16_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_32_1(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_Default_32_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); #if GL_AMD3D /* xtexdl.asm */ extern void FX_CALL _grTexDownload_3DNow_MMX(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); #endif /* GL_AMD3D */ #if GL_MMX /* xtexdl.asm */ extern void FX_CALL _grTexDownload_MMX(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); #endif #if GL_SSE2 /* xtexdl.asm */ extern void FX_CALL _grTexDownload_SSE2_64(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); extern void FX_CALL _grTexDownload_SSE2_128(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData); #endif typedef struct GrGC_s { struct { FxU32 bufferSwaps; /* number of buffer swaps */ FxU32 pointsDrawn; FxU32 linesDrawn; FxU32 trisProcessed; FxU32 trisDrawn; FxU32 othertrisDrawn; FxU32 texDownloads; /* number of texDownload calls */ FxU32 texBytes; /* number of texture bytes downloaded */ FxU32 palDownloads; /* number of palette download calls */ FxU32 palBytes; /* number of palette bytes downloaded */ FxU32 nccDownloads; /* # of NCC palette download calls */ FxU32 nccBytes; /* # of NCC palette bytes downloaded */ #if USE_PACKET_FIFO FxU32 fifoWraps; FxU32 fifoWrapDepth; FxU32 fifoStalls; FxU32 fifoStallDepth; #endif /* USE_PACKET_FIFO */ } stats; struct { float ftemp1, ftemp2; /* temps to convert floats to ints */ } pool; #if GLIDE_HW_TRI_SETUP FxI32 curVertexSize; /* Size in bytes of a single vertex's parameters */ #endif FxI32 curTriSize; /* the size in bytes of the current triangle */ FxU32 orgSW, orgSH; /* Original Screen width & Height */ FxU32 totBuffers, strideInTiles, heightInTiles, bufferStride, bufSizeInTiles, bufSize, fbOffset, *base_ptr, /* base address of SST */ *reg_ptr, /* pointer to base of SST registers */ *tex_ptr, /* texture memory address */ *lfb_ptr; /* linear frame buffer address */ FxU32 is_master; FxU32 chipCount; FxU32 sliCount; FxU32 sliBandHeight; #ifdef HAL_CSIM HalInfo *halInfo; #endif struct GrTmuMemInfo { /* Information for keeping track of the characteristics of the * memory 'surfaces'. (We use 'surfaces' here not in the surface * extension sense, but in the region sense). * * xxxTiled: Is this logical memory location in a tiled region? * xxxStride: The stride to the next logical 'line' in a given * region. This is in the units based on the respective * xxxTiled field. */ FxU32 tramOffset, tramSize, tramLfbAddr; FxU32 texStrideTiles, texStrideBytes; FxBool texTiled; /* Information about how to flush the textures and an * downloads from any internal hw fifos. * * flushCount: If > 0 then the flush operations should be * performed using the pre/post flush packets. * This should initially be set to 1 in the hw * init stuff and then will be decremented in * the multiple level downloads so the lower * levels know not to worry about the flush. * xxxPacket: The actual packet data need to flush the * textures and internal pixel fifo's * pre: * pkt1 header: wax command * command = nop | go * post: * pkt1 header: texBaseAddr * ~user texBaseAddr * pkt1 header: nopCMD * 0 * pkt1 header: texBaseAddr * user texBaseAddr * pkt1 header: wax command * command = nop | go */ #if USE_PACKET_FIFO # define GR_TEX_FLUSH_WRITE(__writeCount, __writeData) \ if (gc->contextP) { \ GR_SET_EXPECTED_SIZE((__writeCount) * sizeof(FxU32), 0); \ { \ FxU32 \ *curFifoPtr = gc->cmdTransportInfo.fifoPtr, \ *curPktData = __writeData, \ i; \ for(i = 0; i < (__writeCount); i++) { \ SET_FIFO(*curFifoPtr++, *curPktData++); \ } \ GR_INC_SIZE((__writeCount) * sizeof(FxU32)); \ gc->cmdTransportInfo.fifoRoom -= ((FxU32)curFifoPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); \ gc->cmdTransportInfo.fifoPtr = curFifoPtr; \ } \ GR_CHECK_SIZE(); \ } # define TEX_FLUSH_COUNT_PRE 2 # define TEX_FLUSH_COUNT_POST 8 # define GR_TEX_FLUSH_PRE(__tmuMemInfo) \ do { \ if ((__tmuMemInfo)->flushCount > 0) { \ GR_TEX_FLUSH_WRITE(TEX_FLUSH_COUNT_PRE, (__tmuMemInfo)->prePacket); \ } \ (__tmuMemInfo)->flushCount--; \ } while(0) # define GR_TEX_FLUSH_POST(__tmuMemInfo) \ do { \ (__tmuMemInfo)->flushCount++; \ if ((__tmuMemInfo)->flushCount > 0) { \ GR_TEX_FLUSH_WRITE(TEX_FLUSH_COUNT_POST, (__tmuMemInfo)->postPacket); \ } \ } while(0) #else /* !USE_PACKET_FIFO */ /* temp defs */ # define TEX_FLUSH_COUNT_PRE 2 # define TEX_FLUSH_COUNT_POST 8 # define GR_TEX_FLUSH_PRE(__tmuMemInfo) # define GR_TEX_FLUSH_POST(__tmuMemInfo) #endif /* !USE_PACKET_FIFO */ FxI32 flushCount; FxU32 prePacket[TEX_FLUSH_COUNT_PRE], postPacket[TEX_FLUSH_COUNT_POST]; } tmuMemInfo[GLIDE_NUM_TMU]; hwcBoardInfo *bInfo; #ifdef GLIDE_INIT_HWC FxU32 winContextId; #endif #if GLIDE_MULTIPLATFORM GrGCFuncs gcFuncs; #endif #define kMaxVertexParam (20 + (12 * GLIDE_NUM_TMU) + 3) #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP struct dataList_s { int i; FxFloat* addr; } regDataList[kMaxVertexParam]; int tsuDataList[kMaxVertexParam]; #ifdef FAST_C_CLIP int tsuDataListByte[kMaxVertexParam]; #endif #else int tsuDataList[kMaxVertexParam]; #ifdef FAST_C_CLIP int tsuDataListByte[kMaxVertexParam]; #endif #endif #ifdef GLIDE3_SCALER int tsuDataListScaler[kMaxVertexParam]; #endif GrState state; /* state of Glide/SST */ /* Here beginneth the Swap Pending Workaround (tm) */ #define MAX_BUFF_PENDING 0x7 FxU32 swapsPending, /* swaps in unexecuted region of FIFO */ lastSwapCheck, /* Position at last check */ curSwap, /* Position in the array below */ bufferSwaps[MAX_BUFF_PENDING];/* Position in FIFO of buffer swaps */ /* Here endeth the Swap Pending Workaround */ struct { /* Current triangle rendering proc specialized for culling/no * culling and viewport/window coordinates. */ GrTriSetupProc triSetupProc; GrDrawTrianglesProc drawTrianglesProc; GrVertexListProc drawVertexList; /* Vector to choose triangle rendering proc from based on the * cull/no-cull mode and whether or not the state is valid. This * vector is specialized on viewport vs window coordinates. */ GrTriSetupProcVector* coorModeTriVector; /* Vector of texture download procs specialized by size * and processor vendor type. */ GrTexDownloadProcVector* texDownloadProcs; } archDispatchProcs; /* NB: This structure is exported via the COMMAND_TRANSPORT * extension which is shared w/ cvg glide3 as well. Care must be * taken to make the structures compatible and to inform the OpenGL * team (the only users of the extension) of any changes. */ struct cmdTransportInfo { FxU32 triPacketHdr; /* Pre-computed packet header for * independent triangles. */ FxU32 cullStripHdr; /* Pre-computed packet header for generic * case of packet 3 triangles. This needs * command type and # of vertices to be complete. */ FxU32 paramMask; /* Mask for specifying parameters of * non-triangle packets. The parameter * bits[21:10] mimic the packet3 header * controlling which fields are sent, and * pc[28] controls whether any color * information is sent as packed. */ FxU32* fifoPtr; /* Current write pointer into fifo */ FxU32 fifoRead; /* Last known hw read ptr. * If on an sli enabled system this will be * the 'closest' hw read ptr of the sli * master and slave. */ /* Fifo checking information. In units of usuable bytes until * the appropriate condition. */ FxI32 fifoRoom; /* Space until next fifo check */ FxBool autoBump; /* Are we auto bumping (aka hole counting?) */ FxU32 *lastBump, /* Last ptr where we bumped. */ *bumpPos; /* Next place to bump */ FxU32 bumpSize; /* # of DWORDS per bump */ FxU32 **ptrLostContext; /* Internal bookkeeping information - Everything after this point * is not exposed via the COMMAND_TRANSPORT extension */ /* Basic command fifo characteristics. These should be * considered logically const after their initialization. */ FxU32* fifoStart; /* Virtual address of start of fifo */ FxU32* fifoEnd; /* Virtual address of fba fifo */ FxU32 fifoOffset; /* Offset from hw base to fifo start */ FxU32 fifoSize; /* Size in bytes of the fifo */ FxU32 fifoJmpHdr[2];/* Type0 packet for jmp to fifo start * only first DWORD is used for memory * fifo--both are used for AGP FIFO */ /* NB: These are only valid for the fullscreen case */ FxI32 roomToReadPtr;/* Bytes until last known hw ptr */ FxI32 roomToEnd; /* # of bytes until last usable address before fifoEnd */ FxU32 lfbLockCount; /* Have we done an lfb lock? Count of the locks. */ #if GLIDE_INIT_HWC GrStateBuffer* stateBuffer; HwcWinFifo hwcFifoInfo; FxU32 numCommandBuf, /* # of command buffers */ curCommandBuf, /* Current command buffer waiting to issue */ numQueuedBuf, /* # of command buffers waiting to issue */ serialNumber, /* Current serial # */ issuedSerialNumber, /* Last issued command buffer # */ committedSerialNumber; /* Last known committed buffer */ /* This is the backing store that gets used if we are not abled to * allocate surface storage for the fifo information. */ /* <=32k bytes -- don't want segment overflow in 16-bit driver*/ #define WINDOW_FIFO_SIZE_IN_DWORDS 0x2000 FxU32 windowedFifo[WINDOW_FIFO_SIZE_IN_DWORDS]; GrStateBuffer windowedState; #endif /* GLIDE_INIT_HWC */ FxU32 *lastFence; /* Either beginning of the fifo (at start or after a wrap), or the last place we fenced. Fencing must occur every 64K writes. */ } cmdTransportInfo; FxI32 (FX_CALL *triSetupProc)(const void *a, const void *b, const void *c); SstIORegs *ioRegs; /* I/O remap regs */ SstCRegs *cRegs; /* AGP/Cmd xfer/misc regs */ SstGRegs *gRegs; /* 2D regs */ SstRegs *sstRegs; /* Graphics Regs (3D Regs) */ SstRegs *slaveSstRegs[3] ; /* AJB - ptrs to slave chips */ SstCRegs *slaveCRegs[3] ; /* AJB - ptrs to slave chips cmd regs */ FxU32 *rawLfb, nBuffers, curBuffer, frontBuffer, backBuffer, buffers0[4], buffers1[4], lfbBuffers[4]; /* Tile relative addresses of the color/aux * buffers for lfbReads. */ FxU32 lockPtrs[2]; /* pointers to locked buffers */ FxU32 fbStride; FxBool colTiled, // AJB - grBufferClear needs to know when target surfaces auxTiled ; // are linear in windowed & fullscreen glide. /* TextureBuffer extension ** Used for Rendering into a Texture. ** tbext */ struct { FxBool init; FxBool on; FxU32 addr; FxI32 stride; FxU32 width, height; struct { FxBool valid; float cwMinx, cwMiny, cwMaxx, cwMaxy; /* ClipWindow Min/Max */ FxU32 clipLeftRight, clipBottomTop; } prevState; } textureBuffer; /* tbext. TODO: remove the prevState member? */ struct { FxBool init; FxBool on; FxU32 addr; FxI32 stride; FxU32 width, height; struct { FxBool valid; float cwMinx, cwMiny, cwMaxx, cwMaxy; /* ClipWindow Min/Max */ FxU32 clipLeftRight, clipBottomTop; } prevState; } textureAuxBuffer; struct { FxU32 freemem_base; FxU32 total_mem; FxU32 next_ncc_table; GrMipMapId_t ncc_mmids[2]; const GuNccTable *ncc_table[2]; } tmu_state[GLIDE_NUM_TMU]; int grSstRez, /* Video Resolution of board */ grSstRefresh, /* Video Refresh of board */ fbuf_size, /* in MB */ num_tmu, /* number of TMUs attached */ grColBuf, grAuxBuf, grHwnd; int grPixelFormat; /* Specific pixel format */ int grPixelSample; /* Total number of AA samples */ int grPixelSize; /* Pixel size in bytes */ int grSamplesPerChip; /* Numbef of AA samples per chip */ int sampleOffsetIndex; /* Which index do we use for AA offsets? */ int enableSecondaryBuffer; /* Whether or not secondary AA buffer is in use. */ FxBool do2ppc; FxU32 chipmask; FxU32 stencilCleared; #ifndef GLIDE3_ALPHA struct { GrMipMapInfo data[MAX_MIPMAPS_PER_SST]; GrMipMapId_t free_mmid; } mm_table; /* mip map table */ #endif FxBool tmuLodDisable[GLIDE_NUM_TMU]; /* DEBUG and SANITY variables */ FxI32 myLevel; /* debug level */ FxI32 counter; /* counts bytes sent to HW */ FxI32 expected_counter; /* the number of bytes expected to be sent */ FxU32 checkCounter; FxU32 checkPtr; FxVideoTimingInfo* vidTimings;/* init code overrides */ /* Has GC Been Opened? * * NB: The following fields are similar, but subtly different. * Make sure that you keep their meanings differentiated when * messing w/ their values because various internacl bits of glide * make various assumptions about their values. * * hwInitP: Is the hw mapping active? Some OS's (notably NT) require * that the driver keep track of mappings on a per process * basis. This flag indicates whether or not glide thinks that it * has a mapping allocated w/ the driver via hwcMapBoard. This is * only meaningful for a fullscreen application. * * %%KCD: hwInitP is inherently broken for apps that switch back * and forth between fullscreen and windowed, since different * GC's are used in those cases, which means the hwInitP flag * won't carry over. So, hwcBoardInfo now has an isMapped * flag that keeps track of whether a given board is mapped or * not, so it can be kept track of the right way. * * open: Does the application have an fullscreen context open. * Fullscreen: grSstWinOpen/grSstWinClose * Surface Extension: grSurfaceCreateContext/grSurfaceReleaseContext * * contextP: This indicates whether glide thinks that its fsem * context is still valid. This can become false if the app looses * its context due to some os interaction (alt-tab on win32 * platforns), but this does not affect the state of gc->open. */ FxBool /* hwInitP, */ open, contextP; FxU32 * lostContext; FxBool auxRendering; /* Is an aux rendering surface current? */ FxBool windowed; /* is this a fullscreen or windowed gc */ #ifdef GLIDE_INIT_HWC hwcBufferDesc tBuffer, /* Texture Buuffer */ *arBuffer; /* Aux Rendering Buffer */ GrSurface_t curSurface, /* Current rendering surface */ auxSurface, /* Aux buffer surface */ texSurface[GLIDE_NUM_TMU]; /* Current texture surface */ #endif /* GLIDE_INIT_HWC */ /* Splash screen/shameless plug crap */ struct { #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) HMODULE moduleHandle; #endif /* (GLIDE_PLATFORM & GLIDE_OS_WIN32) */ GrSplashInitProc initProc; GrSplashShutdownProc shutdownProc; GrSplashProc splashProc; GrSplashPlugProc plugProc; } pluginInfo; } GrGC; /* ** The Root Of All EVIL! ** ** The root of all Glide data, all global data is in here ** stuff near the top is accessed a lot */ struct _GlideRoot_s { int p6Fencer; /* xchg to here to keep this in cache!!! */ FxU32 tlsIndex; FxU32 tlsOffset; int current_sst; FxI32 windowsInit; /* Is the fullscreen part of glide initialized? */ _p_info CPUType; /* CPUID */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP FxU32 paramCount; FxI32 curTriSizeNoGradient; /* special for _trisetup_nogradients */ FxI32 curTriSize; /* the size in bytes of the current triangle */ #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ #if GLIDE_MULTIPLATFORM GrGCFuncs curGCFuncs; /* Current dd Function pointer table */ #endif int initialized; struct { /* constant pool (minimizes cache misses) */ float f0; float fHalf; float f1; float f255; #if GLIDE_PACKED_RGB #define kPackBiasA _GlideRoot.pool.fBiasHi #define kPackBiasR _GlideRoot.pool.fBiasHi #define kPackBiasG _GlideRoot.pool.fBiasHi #define kPackBiasB _GlideRoot.pool.fBiasLo #define kPackShiftA 16UL #define kPackShiftR 8UL #define kPackShiftG 0UL #define kPackShiftB 0UL #define kPackMaskA 0x00FF00UL #define kPackMaskR 0x00FF00UL #define kPackMaskG 0x00FF00UL #define kPackMaskB 0x00FFUL float fBiasHi; float fBiasLo; #endif /* GLIDE_PACKED_RGB */ } pool; struct { /* environment data */ FxBool ignoreReopen; FxBool triBoundsCheck; /* check triangle bounds */ FxBool noSplash; /* don't draw it */ FxU32 fifoSize; /* specifies fifo size in windowed glide mode */ FxBool shamelessPlug; /* translucent 3Dfx logo in lower right */ FxI32 swapInterval; /* swapinterval override */ FxI32 swFifoLWM; FxU32 snapshot; /* register trace snapshot */ FxBool disableDitherSub; /* Turn off dither subtraction? */ FxBool texLodDither; /* Always do lod-dithering */ FxI32 tmuMemory; /* tmuMemory */ float gammaR, gammaG, gammaB; /* Gamma settings */ FxBool useAppGamma; /* enable(1)(default)/disable(0) application gamma control */ FxBool guardbandclipping; /* enable gbc */ FxI32 do2ppc; /* enable 2ppc */ FxU32 band2ppc; /* 2ppc band */ FxU32 sliBandHeight; /* sli band height */ FxI32 swapPendingCount; /* pending buffer swap count */ FxI32 forceOldAA; /* Force AA to use SLI when possible */ FxI32 waxon ; /* Enable use of WAX */ FxU32 aaToggleKey; /* Raw Key code for AA toggle */ FxU32 aaScreenshotKey; /* Raw Key code for AA toggle */ FxI32 analogSli ; /* force digital or analog sli */ FxI32 lodBias; /* User-adjustable lod bias value (signed) */ FxU32 sliBandHeightForce; /* Force user-specified band height */ FxU32 is_opengl; /* specify whether we are opengl app or not */ FxU32 noHW; /* Disable HW writes */ /* Force alternate buffer strategy */ FxI32 nColorBuffer; FxI32 nAuxBuffer; FxBool autoBump; /* Auto bump or do it manually? */ FxU32 bumpSize; FxU32 forceSingleChip ; /* force off SLI */ FxU32 outputBpp ; /* force 16/32bpp rendering */ FxU32 aaSample ; /* force 2/4 sample anti-aliasing */ FxU32 columnWidth; /* 'n' in columns of n */ /* Anti-aliasing default perturbation values */ FxU32 aaXOffset[13][8]; /* increase arrays for 8xaa */ FxU32 aaYOffset[13][8]; /* Limit number of writes between fences */ FxI32 fenceLimit; FxBool texSubLodDither; /* always do subsample mipmap dithering */ FxBool aaClip; /* clean out AA garbage */ float aaPixelOffset; /* AA jitter pixel offset */ float aaJitterDisp; /* AA jitter dispersity */ double aaGridRotation; /* AA grid rotation */ FxBool forceAutoBump; /* force Auto bump? */ #if CHECK_SLAVE_SWAPCMD FxU32 checkSlaveSwapCMD; /* check swap commands across all chips */ #endif #if TACO_MEMORY_FIFO_HACK FxBool memFIFOHack; /* flush FIFO as much as possible */ #endif FxU32 oglLfbLockHack; /* Enables disable hack to get around forced 32bit problems in OpenGL */ FxU32 useHwcAAforLfbRead; /* Specifies whether to use HwcAAReadRegion for read Locks and LfbReadRegion calls */ FxU32 ditherHwcAA; /* Specifies whether to use HwcAAReadRegion should dither */ } environment; GrHwConfiguration hwConfig; GrGC GCs[MAX_NUM_SST]; /* one GC per board */ GrGC surfaceGCs[MAX_NUM_CONTEXTS]; GrGC *surfaceGCHeap[MAX_NUM_CONTEXTS]; struct { GrTriSetupProcArchVector* curTriProcs; GrDrawTrianglesProc curDrawTrisProc; GrVertexListProc* curVertexListProcs; GrTexDownloadProcVector* curTexProcs; #define PROC_SELECT_TRISETUP(__procVector, __cullMode) (__procVector)[(__cullMode) != GR_CULL_DISABLE] #define PROC_SELECT_TEXDOWNLOAD() _GlideRoot.curTexProcs GrTriSetupProcArchVector* nullTriProcs; GrDrawTrianglesProc nullDrawTrisProc; GrVertexListProc* nullVertexListProcs; GrTexDownloadProcVector* nullTexProcs; } deviceArchProcs; #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #define OS_WIN32_95 0 #define OS_WIN32_98 1 #define OS_WIN32_ME 2 #define OS_WIN32_NT4 3 #define OS_WIN32_2K 4 #define OS_WIN32_XP 5 FxI32 OS; #endif }; extern struct _GlideRoot_s GR_CDECL _GlideRoot; #if GLIDE_MULTIPLATFORM extern GrGCFuncs _curGCFuncs; #endif #if defined( __MSC__ ) /* Turn off the no return value warning for the function definition. * * NB: The function returns a value so that we can use it in places * that require a value via the comma operator w/o resorting to casts * everywhere the macro is invoked. * * NB: I checked the compiled code to make sure that it was inlined * everywhere that we would possibly care that it was inlines. */ # pragma warning(disable : 4035) __inline FxU32 _grP6Fence(void) { __asm xchg eax, _GlideRoot.p6Fencer } # define P6FENCE _grP6Fence() # pragma warning(default : 4035) #elif defined(macintosh) && defined(__POWERPC__) && defined(__MWERKS__) # define P6FENCE __sync() #elif defined(__GNUC__) && defined(__i386__) /* * This is the __linux__ code. */ #define P6FENCE asm("xchg %%eax, %0" : : "m" (_GlideRoot.p6Fencer) : "eax"); #else /* !defined ( P6FENCE ) */ # error "P6 Fencing code needs to be added for this compiler" #endif /* !defined ( P6FENCE ) */ /*==========================================================================*/ /* Macros for declaring functions */ #define GR_DDFUNC(name, type, args) \ type FX_CSTYLE name args #define GR_EXT_ENTRY( name, type, args ) \ type FX_CSTYLE name args #define GR_ENTRY(name, type, args) \ type FX_CSTYLE name args //FX_EXPORT type FX_CSTYLE name args #define GR_FAST_ENTRY(name, type, args) \ __declspec naked FX_EXPORT type FX_CSTYLE name args #define GR_DIENTRY(name, type, args) \ type FX_CSTYLE name args #ifdef GLIDE3 #define GR_STATE_ENTRY(name, type, args) \ type _ ## name args #else #define GR_STATE_ENTRY(name, type, args) \ GR_ENTRY(name, type, args) #endif /*==========================================================================*/ #define STATE_REQUIRES_IT_DRGB FXBIT(0) #define STATE_REQUIRES_IT_DRGB_SHIFT 0 #define STATE_REQUIRES_IT_ALPHA FXBIT(1) #define STATE_REQUIRES_IT_ALPHA_SHIFT 1 #define STATE_REQUIRES_OOZ FXBIT(2) #define STATE_REQUIRES_OOZ_SHIFT 2 #define STATE_REQUIRES_OOW_FBI FXBIT(3) #define STATE_REQUIRES_OOW_FBI_SHIFT 3 #define STATE_REQUIRES_W_TMU0 FXBIT(4) #define STATE_REQUIRES_W_TMU0_SHIFT 4 #define STATE_REQUIRES_ST_TMU0 FXBIT(5) #define STATE_REQUIRES_ST_TMU0_SHIFT 5 #define STATE_REQUIRES_W_TMU1 FXBIT(6) #define STATE_REQUIRES_W_TMU1_SHIFT 6 #define STATE_REQUIRES_ST_TMU1 FXBIT(7) #define STATE_REQUIRES_ST_TMU1_SHIFT 7 #define STATE_REQUIRES_W_TMU2 FXBIT(8) #define STATE_REQUIRES_W_TMU2_SHIFT 8 #define STATE_REQUIRES_ST_TMU2 FXBIT(9) #define STATE_REQUIRES_ST_TMU2_SHIFT 9 #define GR_TMUMASK_TMU0 FXBIT(GR_TMU0) #define GR_TMUMASK_TMU1 FXBIT(GR_TMU1) #define GR_TMUMASK_TMU2 FXBIT(GR_TMU2) #define STATE_USING_CC FXBIT(0) #define STATE_USING_CA FXBIT(1) #define STATE_USING_TCC FXBIT(2) #define STATE_USING_TAC FXBIT(3) /* ** Parameter gradient offsets ** ** These are the offsets (in bytes)of the DPDX and DPDY registers from ** from the P register */ #ifdef GLIDE_USE_ALT_REGMAP #define DPDX_OFFSET 0x4 #define DPDY_OFFSET 0x8 #else #define DPDX_OFFSET 0x20 #define DPDY_OFFSET 0x40 #endif #if (GLIDE_PLATFORM & GLIDE_HW_SST1) #define GLIDE_DRIVER_NAME "Voodoo Graphics" #elif (GLIDE_PLATFORM & GLIDE_HW_SST96) #define GLIDE_DRIVER_NAME "Voodoo Rush" #elif (GLIDE_PLATFORM & GLIDE_HW_CVG) #define GLIDE_DRIVER_NAME "Voodoo^2" #elif (GLIDE_PLATFORM & GLIDE_HW_H3) #define GLIDE_DRIVER_NAME "Banshee" #else #define GLIDE_DRIVER_NAME "HOOPTI???" #endif /*==========================================================================*/ #ifndef FX_GLIDE_NO_FUNC_PROTO /* NB: These routines are generally in asm (see xdraw2.inc), and have * their own internally defined calling conventions. The gc pointer * will be setup by the caller and will be in edx and that stack will * be configured as: return address, vertex a, vertex b, vertex c. */ FxI32 FX_CSTYLE _trisetup_cull(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup_cull_noclip(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup_noclip(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup_cull_valid(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup_valid(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup_cull_noclip_valid(const void *va, const void *vb, const void *vc ); FxI32 FX_CSTYLE _trisetup_noclip_valid(const void *va, const void *vb, const void *vc ); #define TRISETUP_NORGB(__cullMode) (((__cullMode) == GR_CULL_DISABLE) \ ? _trisetup \ : _trisetup_cull) #define TRISETUP_NORGB_NOCLIP(__cullMode) (((__cullMode) == GR_CULL_DISABLE) \ ? _trisetup_noclip \ : _trisetup_cull_noclip) #define TRISETUP_RGB(__cullMode) TRISETUP_NORGB(__cullMode) #define TRISETUP_ARGB(__cullMode) TRISETUP_NORGB(__cullMode) #if defined( __MSC__ ) #if (_MSC_VER < 1200) // TRISETUP Macro for pre-msvc 6.0 #define TRISETUP \ __asm { mov edx, gc }; \ (*gc->triSetupProc) #else // _MSC_VER // TRISETUP Macro for msvc 6 or later #ifdef GLIDE_DEBUG // MSVC6 Debug does funny stuff, so push our parms inline #define TRISETUP(_a, _b, _c) \ __asm { \ __asm mov edx, gc \ __asm mov eax, _c \ __asm push eax \ __asm mov ebx, _b \ __asm push ebx \ __asm mov ecx, _a \ __asm push ecx \ } \ ((FxI32 (*)(void))*gc->triSetupProc)() #else // GLIDE_DEBUG // MSVC6 Retail does funny stuff too, but Larry figured it out: #define TRISETUP(_a, _b, _c) \ __asm { mov edx, gc }; \ ((FxI32 (*)(const void *va, const void *vb, const void *vc, GrGC *gc))*gc->triSetupProc)(_a, _b, _c, gc) #endif // GLIDE_DEBUG #endif // _MSC_VER #elif defined(__POWERPC__) #define TRISETUP(_a, _b, _c) \ ((FxI32 (*)(const void *va, const void *vb, const void *vc, GrGC *gc))*gc->triSetupProc)(_a, _b, _c, gc) #elif (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) #define TRISETUP \ __asm(""::"d"(gc)); \ (*gc->triSetupProc) #else /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) */ #define TRISETUP \ (*gc->triSetupProc) #endif void _grValidateState(); void FX_CSTYLE _grDrawVertexList(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers); void _grAlphaBlendFunction( GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df ); void _grAlphaTestFunction( GrCmpFnc_t function ); void _grAlphaTestReferenceValue( GrAlpha_t value ); void _grAlphaCombine( GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert ); void _grAlphaControlsITRGBLighting( FxBool enable ); void _grColorCombine( GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert ); void FX_CALL grGetGammaTable(FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue); void FX_CALL grChromaRangeMode(GrChromaRangeMode_t mode); void FX_CALL grChromaRange( GrColor_t min, GrColor_t max , GrChromaRangeMode_t mode); void FX_CALL grTexChromaMode(GrChipID_t tmu, GrTexChromakeyMode_t mode); void FX_CALL grTexChromaRange(GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode); /* ** Napalm extension */ GrContext_t FX_CALL grSstWinOpenExt( FxU32 hWnd, GrScreenResolution_t resolution, GrScreenRefresh_t refresh, GrColorFormat_t format, GrOriginLocation_t origin, GrPixelFormat_t pixelformat, int nColBuffers, int nAuxBuffers); void FX_CALL grStencilFunc(GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask); void FX_CALL grStencilMask(GrStencil_t write_mask); void FX_CALL grStipplePattern( GrStipplePattern_t stipple); void FX_CALL grStencilOp( GrStencilOp_t stencil_fail, GrStencilOp_t depth_fail, GrStencilOp_t depth_pass); void FX_CALL grBufferClearExt( GrColor_t color, GrAlpha_t alpha, FxU32 depth, GrStencil_t stencil); void FX_CALL grLfbConstantStencil(GrStencil_t mode); void FX_CALL grColorCombineExt( GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool c_invert, GrCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); void FX_CALL grAlphaCombineExt( GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, GrACUColor_t c, FxBool c_invert, GrACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); void FX_CALL grTexColorCombineExt( GrChipID_t tmu, GrTCCUColor_t a, GrCombineMode_t a_mode, GrTCCUColor_t b, GrCombineMode_t b_mode, GrTCCUColor_t c, FxBool c_invert, GrTCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); void FX_CALL grTexAlphaCombineExt( GrChipID_t tmu, GrTACUColor_t a, GrCombineMode_t a_mode, GrTACUColor_t b, GrCombineMode_t b_mode, GrTACUColor_t c, FxBool c_invert, GrTACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); void FX_CALL grConstantColorValueExt( GrChipID_t tmu, GrColor_t value) ; void FX_CALL grColorMaskExt( FxBool r, FxBool g, FxBool b, FxBool a ); void FX_CALL grAlphaBlendFunctionExt( GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendOp_t rgb_op, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df, GrAlphaBlendOp_t alpha_op ); void FX_CALL grTBufferWriteMaskExt( FxU32 mask ); /* end of Napalm extension */ void _grChipMask(FxU32 mask); void _grTex2ppc(FxBool enable); void _grAAOffsetValue(FxU32 *xOffset, FxU32 *yOffset, FxU32 minchipid, FxU32 maxchipid, FxBool enablePrimary, FxBool enableSecondary); void _grEnableSliCtrl(void); void _grDisableSliCtrl(void); void _grRenderMode(FxU32 pixelformat); void _grChromaMode( GrChromaRangeMode_t mode ); void _grChromakeyMode( GrChromakeyMode_t mode ); /* tbext */ void FX_CALL grTextureBuffer( GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask ); void FX_CALL grTextureAuxBuffer( GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask ); void FX_CALL grAuxBuffer( GrBuffer_t buffer ); void _grValidateClipState( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ); #if GLIDE_DEBUG /* These are only called for debug builds for tracing because their * handling is special cased in _grValidateState because of the * interdependency between the calls. */ void _grDepthMask( FxBool mask ); void _grColorMask( FxBool rgb, FxBool a ); void _grLfbWriteColorFormat(GrColorFormat_t colorFormat); void _grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords); void _grFogColorValue( GrColor_t fogcolor ); void _grDepthBiasLevel( FxI32 level ); void _grChromakeyValue( GrColor_t color ); void _grChromaRange( GrColor_t max , GrChromaRangeMode_t mode); #endif /* GLIDE_DEBUG */ void _grDepthBufferFunction( GrCmpFnc_t function ); void _grDepthBufferMode( GrDepthBufferMode_t mode ); void _grDitherMode( GrDitherMode_t mode ); void _grStippleMode( GrStippleMode_t mode ); void _grRenderBuffer( GrBuffer_t buffer ); void _grSstOrigin(GrOriginLocation_t origin); void _grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ); void _grFogMode( GrFogMode_t mode ); void _grConstantColorValue( GrColor_t value ); void FX_CSTYLE _grDrawPoints(FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _grDrawLineStrip(FxI32 mode, FxI32 count, FxI32 ltype, void *pointers); void FX_CSTYLE _grAADrawPoints(FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _grAADrawLineStrip(FxI32 mode, FxI32 ltype, FxI32 count, void *pointers); void FX_CSTYLE _grAADrawLines(FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _grAADrawTriangles(FxI32 mode, FxI32 ttype, FxI32 count, void *pointers); void FX_CSTYLE _grAAVpDrawTriangles(FxI32 mode, FxI32 ttype, FxI32 count, void *pointers); void FX_CSTYLE _grAADrawVertexList(FxU32 type, FxI32 mode, FxI32 count, void *pointers); void FX_CSTYLE _guTexMemReset(void); int FX_CSTYLE _grBufferNumPending(void); FxBool FX_CSTYLE _grSstIsBusy(void); void FX_CSTYLE _grSstResetPerfStats(void); void FX_CSTYLE _grResetTriStats(void); FxU32 FX_CSTYLE _grSstStatus(void); FxU32 FX_CSTYLE _grSstVideoLine(void); FxBool FX_CSTYLE _grSstVRetraceOn(void); #endif /* FX_GLIDE_NO_FUNC_PROTO */ /*==========================================================================*/ /* ** thread stuff */ #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #define W95_TEB_PTR 0x18 #define W95_TEB_TLS_OFFSET 0x88 #define W95_TLS_INDEX_TO_OFFSET(i) ((i)*sizeof(DWORD)+W95_TEB_TLS_OFFSET) #define WNT_TEB_PTR 0x18 #define WNT_TEB_TLS_OFFSET 0xE10 #define WNT_TLS_INDEX_TO_OFFSET(i) ((i)*sizeof(DWORD)+WNT_TEB_TLS_OFFSET) #ifdef __GNUC__ extern __inline FxU32 getThreadValueFast (void) { FxU32 t; __asm __volatile (" \ mov %%fs:(%0), %%eax; \ add %1, %%eax; \ mov (%%eax), %%eax; \ ":"=a"(t):"i"(WNT_TEB_PTR), "g"(_GlideRoot.tlsOffset)); return t; } #else /* __GNUC__ */ #define __GR_GET_TLSC_VALUE() \ __asm { \ __asm mov eax, DWORD PTR fs:[WNT_TEB_PTR] \ __asm add eax, DWORD PTR _GlideRoot.tlsOffset \ __asm mov eax, DWORD PTR [eax] \ } #pragma warning (4:4035) /* No return value */ __inline FxU32 getThreadValueFast() { __asm { __asm mov eax, DWORD PTR fs:[WNT_TEB_PTR] __asm add eax, DWORD PTR _GlideRoot.tlsOffset __asm mov eax, DWORD PTR [eax] } } #pragma warning (3:4035) #endif /* __GNUC__ */ #endif #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) extern FxU32 _threadValueMacOS; __inline FxU32 getThreadValueFast() { return _threadValueMacOS; } #endif #if (GLIDE_PLATFORM & GLIDE_OS_UNIX) extern FxU32 threadValueLinux; #define getThreadValueFast() threadValueLinux #endif /* defined(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ #ifdef __DJGPP__ extern FxU32 threadValueDJGPP; #define getThreadValueFast() threadValueDJGPP #endif /* defined(__DJGPP__) */ #define CUR_TRI_PROC(__checkValidP, __cullP) \ (*gc->archDispatchProcs.coorModeTriVector)[__checkValidP][__cullP] #define INVALIDATE(regset) {\ gc->state.invalid |= regset ## BIT; \ gc->triSetupProc = CUR_TRI_PROC(FXTRUE, (gc->state.cull_mode != GR_CULL_DISABLE)); \ } #define INVALIDATE_TMU(tmu, regset) {\ INVALIDATE(tmuConfig); \ gc->state.tmuInvalid[tmu] |= regset ## BIT; \ } void initThreadStorage( void ); void freeThreadStorage( void ); void setThreadValue( FxU32 value ); FxU32 getThreadValueSLOW( void ); void initCriticalSection( void ); void beginCriticalSection( void ); void endCriticalSection( void ); /*==========================================================================*/ /* ** function prototypes */ void _grClipNormalizeAndGenerateRegValues(FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy, FxU32 *clipLeftRight, FxU32 *clipBottomTop); void _grSwizzleColor(GrColor_t *color); void _grDisplayStats(void); void _GlideInitEnvironment(int which); void FX_CSTYLE _grColorCombineDelta0Mode(FxBool delta0Mode); void _doGrErrorCallback(const char *name, const char *msg, FxBool fatal); void _grErrorDefaultCallback(const char *s, FxBool fatal); #ifdef __WIN32__ void _grErrorWindowsCallback(const char *s, FxBool fatal); #endif /* __WIN32__ */ extern void (*GrErrorCallback)(const char *string, FxBool fatal); void GR_CDECL _grFence(void); void FX_CSTYLE _grCCExtfbzColorPath(GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool c_invert, GrCCUColor_t d, FxBool invert); void FX_CSTYLE _grACExtfbzColorPath(GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, GrACUColor_t c, FxBool c_invert, GrACUColor_t d, FxBool invert); void FX_CSTYLE _grCCExtcombineMode(GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool d_invert, FxU32 shift); void FX_CSTYLE _grACExtcombineMode(GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, FxBool d_invert, FxU32 shift); void FX_CSTYLE _grTexColorCombineExt(GrChipID_t tmu, GrTCCUColor_t a, GrCombineMode_t a_mode, GrTCCUColor_t b, GrCombineMode_t b_mode, GrTCCUColor_t c, FxBool c_invert, GrTCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); void FX_CSTYLE _grTexAlphaCombineExt(GrChipID_t tmu, GrTACUColor_t a, GrCombineMode_t a_mode, GrTACUColor_t b, GrCombineMode_t b_mode, GrTACUColor_t c, FxBool c_invert, GrTACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); void FX_CSTYLE _grRebuildDataList(void); void _grReCacheFifo(FxI32 n); FxI32 GR_CDECL _grSpinFifo(FxI32 n); void _grShamelessPlug(void); FxBool _grSstDetectResources(void); #if 0 /* KoolSmoky - remove junk */ FxU16 _grTexFloatLODToFixedLOD(float value); #endif void FX_CSTYLE _grTexDetailControl(GrChipID_t tmu, FxU32 detail); void FX_CSTYLE _grTexDownloadNccTable(GrChipID_t tmu, FxU32 which, const GuNccTable *ncc_table, int start, int end); void FX_CSTYLE _grTexDownloadPalette(GrChipID_t tmu, GrTexTable_t type, GuTexPalette *pal, int start, int end); FxU32 _grTexCalcBaseAddress(FxU32 start_address, GrLOD_t largeLod, GrAspectRatio_t aspect, GrTextureFormat_t fmt, FxU32 odd_even_mask); FxI32 _grTexCalcBaseAddressTiled(GrChipID_t tmu, FxU32 start_address, GrAspectRatio_t aspect, GrLOD_t largeLod, GrTextureFormat_t fmt, FxU32 odd_even_mask); void _grTexForceLod(GrChipID_t tmu, int value); FxU32 _grTexCalcMipmapLevelOffsetTiled(GrChipID_t tmu, GrLOD_t lod, GrLOD_t largeLOD, GrAspectRatio_t ar, GrTextureFormat_t fmt, FxU32 evenOdd, FxU32 *tileXreturn, FxU32 *tileYreturn); FxU32 _grTexTextureMemRequired(GrLOD_t small_lod, GrLOD_t large_lod, GrAspectRatio_t aspect, GrTextureFormat_t format, FxU32 evenOdd, FxBool roundP, FxBool systemMem); void FX_CSTYLE _grUpdateParamIndex(void); /* ddgump.c */ void FX_CSTYLE _gumpTexCombineFunction(int virtual_tmu); /* disst.c - this is an un-documented external for arcade developers */ extern FX_ENTRY void FX_CALL grSstVidMode(FxU32 whichSst, FxVideoTimingInfo* vidTimings); /* glfb.c */ extern FxBool _grLfbWriteRegion(FxBool pixPipelineP, GrBuffer_t dst_buffer, FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, FxU32 src_width, FxU32 src_height, FxI32 src_stride, const void *src_data); /* gglide.c - Flushes the current state in gc->state.fbi_config to the hw. */ extern void _grFlushCommonStateRegs(void); /* gsst.c */ extern void initGC( GrGC *gc ); extern void assertDefaultState( void ); /*==========================================================================*/ /* GMT: have to figure out when to include this and when not to */ #if defined(GLIDE_DEBUG) || defined(GLIDE_ASSERT) || defined(GLIDE_SANITY_ASSERT) || defined(GLIDE_SANITY_SIZE) #define DEBUG_MODE 1 #include #endif #define GR_DCL_GC GrGC *gc = (GrGC*)getThreadValueFast() #define GR_DCL_HW_INIT SstRegs *hw #define GR_DCL_HW_STAGE2 hw = (SstRegs *)gc->sstRegs #define GR_DCL_HW SstRegs *hw = (SstRegs *)gc->sstRegs #ifdef DEBUG_MODE #define ASSERT(exp) GR_ASSERT(exp) #define GR_DEBUG_DCL_INIT() \ FxI32 saveLevel; \ char* myName #define GR_DEBUG_DCL_STAGE2(name,level) \ GR_ASSERT(gc != NULL); \ saveLevel = gc->myLevel; \ myName = name; \ gc->myLevel = level; \ gc->checkPtr = (FxU32)gc->cmdTransportInfo.fifoPtr; \ GDBG_INFO(gc->myLevel,myName); \ FXUNUSED(saveLevel); \ FXUNUSED(hw); \ FXUNUSED(saveLevel) #define GR_DEBUG_DCL(name,level) \ const FxI32 saveLevel = gc->myLevel; \ const char* myName = name; \ GR_ASSERT(gc != NULL); \ gc->myLevel = level; \ gc->checkPtr = (FxU32)gc->cmdTransportInfo.fifoPtr; \ GDBG_INFO(gc->myLevel,myName); \ FXUNUSED(saveLevel); \ FXUNUSED(hw); \ FXUNUSED(saveLevel) #define GR_TRACE_EXIT(__n) \ gc->myLevel = saveLevel; \ GDBG_INFO(281, "%s --done---------------------------------------\n", __n) #define GR_TRACE_RETURN(__l, __n, __v) \ gc->myLevel = saveLevel; \ GDBG_INFO((__l), "%s() => 0x%x---------------------\n", (__n), (__v), (__v)) #else /* !DEBUG_MODE */ #define ASSERT(exp) #define GR_DEBUG_DCL_INIT() #define GR_DEBUG_DCL_STAGE2(name, level) #define GR_DEBUG_DCL(name, level) #define GR_TRACE_EXIT(__n) #define GR_TRACE_RETURN(__l, __n, __v) #endif /* !DEBUG_MODE */ #include #if WINXP_ALT_TAB_FIX #define HWCQUERYCONTEXTXP() if (!(gc->windowed || hwcQueryContextXP(gc->bInfo))) return; #define HWCQUERYCONTEXTXP_RET() if (!(gc->windowed || hwcQueryContextXP(gc->bInfo))) return 0; #else /* WINXP_ALT_TAB_FIX */ #define HWCQUERYCONTEXTXP() #define HWCQUERYCONTEXTXP_RET() #endif/* WINXP_ALT_TAB_FIX */ #ifdef GLIDE_ALT_TAB #define GR_BEGIN_NOFIFOCHECK(name,level) \ GR_DCL_GC; \ GR_DCL_HW; \ GR_DEBUG_DCL(name, level); \ FXUNUSED(hw); \ if (!gc) \ return; \ if (gc->lostContext) { \ if (*gc->lostContext) { \ return;\ }\ HWCQUERYCONTEXTXP(); \ } #define GR_BEGIN_NOFIFOCHECK_RET(name,level) \ GR_DCL_GC; \ GR_DCL_HW; \ GR_DEBUG_DCL(name, level); \ FXUNUSED(hw); \ if (!gc) \ return 0; \ if (gc->lostContext) {\ if (*gc->lostContext) { \ return 0;\ }\ HWCQUERYCONTEXTXP_RET(); \ } #define GR_BEGIN_NOFIFOCHECK_NORET(name,level) \ GR_DCL_GC; \ GR_DCL_HW; \ GR_DEBUG_DCL(name, level); \ FXUNUSED(hw) #else #define GR_BEGIN_NOFIFOCHECK(name,level) \ GR_DCL_GC; \ GR_DCL_HW; \ GR_DEBUG_DCL(name, level); \ FXUNUSED(hw) #define GR_BEGIN_NOFIFOCHECK_RET(name,level) \ GR_DCL_GC; \ GR_DCL_HW; \ GR_DEBUG_DCL(name, level); \ FXUNUSED(hw) #define GR_BEGIN_NOFIFOCHECK_NORET(name,level) \ GR_DCL_GC; \ GR_DCL_HW; \ GR_DEBUG_DCL(name, level); \ FXUNUSED(hw) #endif #define GR_BEGIN(name,level,size, packetNum) \ GR_BEGIN_NOFIFOCHECK(name,level); \ GR_SET_EXPECTED_SIZE(size, packetNum) #define GR_END() {GR_CHECK_SIZE(); GR_TRACE_EXIT(myName);} #define GR_RETURN(val) \ do { \ if (GDBG_GET_DEBUGLEVEL(gc->myLevel)) { \ GR_CHECK_SIZE(); \ } else { \ GR_END(); \ } \ GR_TRACE_RETURN(gc->myLevel, myName, val); \ return val; \ } while (0) #if defined(GLIDE_SANITY_ASSERT) #define GR_ASSERT(exp) ((void)((!(exp)) ? (_grAssert(#exp, __FILE__, __LINE__),0) : 0xFFFFFFFF)) #else #define GR_ASSERT(exp) ((void)(0 && ((FxU32)(exp)))) #endif #define INTERNAL_CHECK(__name, __cond, __msg, __fatalP) \ if (__cond) _doGrErrorCallback(__name, __msg, __fatalP) #if defined(GLIDE_DEBUG) #define GR_CHECK_F(name,condition,msg) INTERNAL_CHECK(name, condition, msg, FXTRUE) #define GR_CHECK_W(name,condition,msg) INTERNAL_CHECK(name, condition, msg, FXFALSE) #else #define GR_CHECK_F(name,condition,msg) #define GR_CHECK_W(name,condition,msg) #endif #if GLIDE_CHECK_COMPATABILITY #define GR_CHECK_COMPATABILITY(__name, __cond, __msg) INTERNAL_CHECK(__name, __cond, __msg, FXTRUE) #else #define GR_CHECK_COMPATABILITY(__name, __cond, __msg) GR_CHECK_F(__name, __cond, __msg) #endif /* !GLIDE_CHECK_COMPATABILITY */ /* macro define some basic and common GLIDE debug checks */ #define GR_CHECK_TMU(name,tmu) \ GR_CHECK_COMPATABILITY(name, tmu < GR_TMU0 || tmu >= gc->num_tmu , "invalid TMU specified") void _grAssert(char *, char *, int); #if ASSERT_FAULT #define ASSERT_FAULT_IMMED(__x) if (!(__x)) { \ *(FxU32*)NULL = 0; \ _grAssert(#__x, __FILE__, __LINE__); \ } #else #define ASSERT_FAULT_IMMED(__x) GR_ASSERT(__x) #endif /* Offsets to 'virtual' addresses in the hw */ #if (GLIDE_PLATFORM & GLIDE_HW_CVG) #define HW_REGISTER_OFFSET SST_3D_OFFSET #define HW_FIFO_OFFSET 0x00200000UL #elif (GLIDE_PLATFORM & GLIDE_HW_H3) #define HW_IO_REG_REMAP SST_IO_OFFSET #define HW_CMD_AGP_OFFSET SST_CMDAGP_OFFSET #define HW_2D_REG_OFFSET SST_2D_OFFSET #define HW_3D_REG_OFFSET SST_3D_OFFSET #define HW_REGISTER_OFFSET HW_3D_REG_OFFSET #else #error "Must define virtual address spaces for this hw" #endif #define HW_FIFO_OFFSET 0x00200000UL #define HW_LFB_OFFSET SST_LFB_OFFSET #define HW_TEXTURE_OFFSET SST_TEX_OFFSET #ifdef GLIDE_TEST_TEXTURE_ALIGNMENT extern FxU32 SST_TEXTURE_ALIGN; #else #define SST_TEXTURE_ALIGN 0x10UL #endif #define SST_TEXTURE_ALIGN_MASK (SST_TEXTURE_ALIGN - 0x01UL) #if (GLIDE_PLATFORM & GLIDE_HW_CVG) || (GLIDE_PLATFORM & GLIDE_HW_H3) #define HW_BASE_PTR(__b) (__b) #else #error "Need HW_BASE_PTR to convert hw address into board address." #endif #define HW_REG_PTR(__b) ((FxU32*)(((FxU32)(__b)) + HW_REGISTER_OFFSET)) #define HW_LFB_PTR(__b) ((FxU32*)(((FxU32)(__b)) + HW_LFB_OFFSET)) #define HW_TEX_PTR(__b) ((FxU32*)(((FxU32)(__b)) + HW_TEXTURE_OFFSET)) /* access a floating point array with a byte index */ #define FARRAY(p,i) (*(float *)((i)+(int)(p))) #define ArraySize(__a) (sizeof(__a) / sizeof((__a)[0])) #if GDBG_INFO_ON /* cvg.c */ extern void _grErrorCallback(const char* const procName, const char* const format, va_list args); #endif /* The translation macros convert from the reasonable log2 formats to * the somewhat whacked (For those of us coming back to sst1 things * from sst2 w/ its saner lms notation) sst1 lod format. The api and * internal functions pass log2 values, but we convert to lod values * when writing things out to the hw or to index the legacy size * tables listed below. * * G3_LOD_TRANSLATE() is now undefined. Use _g3LodXlat() if necessary. */ #define G3_ASPECT_TRANSLATE(__aspect) (0x3 - (__aspect)) /* ditex.c - * Lookup tables to do translations from various aspect ratio/lod * sizes to more meaningful things like bytes. */ extern const FxU32 _grBitsPerTexel[]; extern const int _grMipMapHostWH[G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) + 1] [GR_LOD_LOG2_2048 + 1][2]; extern const int _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) + 1][GR_LOD_LOG2_2048 + 1][2]; extern const int _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(GR_ASPECT_LOG2_1x8) + 1][GR_LOD_LOG2_2048 + 1][2]; extern const FxU32 _grMipMapHostSize[][12]; extern const FxU32 _grMipMapHostSizeCmp4Bit[][12]; extern const FxU32 _grMipMapHostSizeDXT[][12]; extern const FxI32 _grMipMapOffset[4][16]; extern const FxI32 _grMipMapOffsetCmp4Bit[7][16]; extern const FxI32 _grMipMapOffsetDXT[4][16]; extern const FxI32 _grMipMapOffset_Tsplit[4][16]; extern const FxI32 _grMipMapOffset_TsplitCmp4Bit[7][16]; extern const FxI32 _grMipMapOffset_TsplitDXT[4][16]; extern const FxU32 _gr_evenOdd_xlate_table[]; extern const FxU32 _gr_aspect_xlate_table[]; #define WIDTH_BY_ASPECT_LOD(__aspect, __lod) \ _grMipMapHostWH[G3_ASPECT_TRANSLATE(__aspect)][(__lod)][0] #define HEIGHT_BY_ASPECT_LOD(__aspect, __lod) \ _grMipMapHostWH[G3_ASPECT_TRANSLATE(__aspect)][(__lod)][1] #define WIDTH_BY_ASPECT_LOD_FXT1(__aspect, __lod) \ _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(__aspect)][(__lod)][0] #define HEIGHT_BY_ASPECT_LOD_FXT1(__aspect, __lod) \ _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(__aspect)][(__lod)][1] #define WIDTH_BY_ASPECT_LOD_DXT(__aspect, __lod) \ _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(__aspect)][(__lod)][0] #define HEIGHT_BY_ASPECT_LOD_DXT(__aspect, __lod) \ _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(__aspect)][(__lod)][1] #if 0 /* KoolSmoky - remove */ GrLOD_t _g3LodXlat(const GrLOD_t someLOD, const FxBool tBig); #endif extern void g3LodBiasPerChip(GrChipID_t tmu, FxU32 tLod); #if 0 /* KoolSmoky - remove */ extern GrChipID_t MultitextureAndTrilinear(void); #endif #define _grTexFloatLODToFixedLOD(value) \ (FxU16)((( int )(( value + .125F ) / .25F)) & 0x003F) #if 0 /* [dBorca] moved to `gtex.c' */ static GrLOD_t g3LodXlat_base[2] = { GR_LOD_LOG2_256, GR_LOD_LOG2_2048 }; #define _g3LodXlat(someLOD, tBig) \ (g3LodXlat_base[tBig] - someLOD) #endif #endif /* __FXGLIDE_H__ */ glide3x/h5/glide3/src/fxsplash.h0100700000175300010010000000444307725034667016006 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/fxsplash.h,v 1.3.4.2 2003/06/05 08:23:52 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 1 2/19/99 5:50p Peter ** type definitions for new splash screen */ #ifndef _FX_SPLASH_H_ #define _FX_SPLASH_H_ #include "3dfx.h" #define FX_DLL_DEFINITION #include "fxdll.h" #include "glide.h" typedef FxBool (FX_CALL* GrSplashInitProc)(FxU32 hWnd, FxU32 screenWidth, FxU32 screenHeight, FxU32 numColBuf, FxU32 numAuxBuf, GrColorFormat_t colorFormat); typedef void (FX_CALL* GrSplashShutdownProc)(void); typedef void (FX_CALL* GrSplashProc)(float x, float y, float w, float h, FxU32 frameNumber); typedef const void* (FX_CALL* GrSplashPlugProc)(FxU32* w, FxU32* h, FxI32* strideInBytes, GrLfbWriteMode_t* format); #endif /* _FX_SPLASH_H_ */ glide3x/h5/glide3/src/g3df.c0100700000175300010010000007105707725034667015001 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/g3df.c,v 1.3.4.7 2003/08/21 08:49:54 dborca Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 12 8/18/99 3:20p Larryw ** FXT1 refinements. ** ** 11 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 10 7/22/99 8:14p Larryw ** Texture format byte-depth improvements ** ** 9 7/14/99 6:23p Larryw ** Remove obsolete G3_LOD_TRANSLATE() macro ** Define _grMipMapOffset[][] at compile time ** Fix 2k texture address-finding ** ** 8 7/07/99 6:52p Larryw ** * 2k texture support ** * Reversed order of LOD tables ** * Added 512,1024, and 2048-sized entries in tables ** * Nullified G3_LOD_TRANSLATE() ** * Created _g3LodXlat() for where tLOD register is read/written ** * Misc cosmetic changes. ** ** 7 6/25/99 2:15p Atai ** use g3ext.h ** ** 6 6/14/99 5:16p Larryw ** Added 32-bit texture format support. ** ** 5 1/25/99 6:32p Peter ** cleaned up some translation macros and tables ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 2 1/18/98 12:03p Atai ** sync to rev 17 spec * * 1 1/16/98 4:29p Atai * create glide 3 src * * 16 1/13/98 7:48p Atai * fixed gu3dfGetInfo, grBufferClear, and GrState size * * 15 1/13/98 12:42p Atai * fixed grtexinfo, grVertexLayout, and draw triangle * * 14 1/09/98 6:48p Atai * grTexInfo, GR_LOD_* and GR_ASPECT_* * * 12 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 11 12/09/97 12:20p Peter * mac glide port * * 10 6/06/97 5:56p Peter * fixed gcc/dural compilation things * * 9 6/02/97 4:09p Peter * Compile w/ gcc for Dural * * 8 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 7 5/21/97 6:05a Peter * * 6 3/09/97 10:31a Dow * Added GR_DIENTRY for di glide functions ** */ #include #include #ifdef __GNUC__ #include #endif #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" static const FxU32 _gr_aspect_index_table[] = { 3, 2, 1, 0, 1, 2, 3, }; static FxU16 ReadDataShort(FILE *); static FxU32 ReadDataLong(FILE *); static void Read4Bit(FxU8 *dst, FILE *image, int small_lod, int large_lod, GrAspectRatio_t aspect); static void Read8Bit(FxU8 *dst, FILE *image, int small_lod, int large_lod, GrAspectRatio_t aspect); static void ReadDXT8Bit(FxU8 *dst, FILE *image, int small_lod, int large_lod, GrAspectRatio_t aspect); static void Read16Bit(FxU16 *dst, FILE *image, int small_lod, int large_lod, GrAspectRatio_t aspect); static void Read32Bit(FxU32 *dst, FILE *image, int small_lod, int large_lod, GrAspectRatio_t aspect); #if ((GLIDE_PLATFORM & (GLIDE_OS_DOS32 | GLIDE_OS_WIN32 | GLIDE_OS_MACOS)) != 0) const char *openmode = "rb"; #else const char *openmode = "r"; #endif typedef struct { const char *name; GrTextureFormat_t fmt; FxBool valid; } CfTableEntry; static FxBool _grGet3dfHeader(FILE* stream, char* const buffer, const FxU32 bufSize) { int numLines = 0; FxU32 bufPos = 0; while(numLines < 4) { /* Handle stream errors */ if (fgets(buffer + bufPos, bufSize - bufPos, stream) == NULL) break; bufPos += strlen(buffer + bufPos); /* fgets includes the '\n' in the buffer. If this is not there * then the buffer is too small so fail. */ if (*(buffer + bufPos - sizeof(char)) != '\n') break; numLines++; } return (numLines == 4); } /*--------------------------------------------------------------------------- ** gu3dfGetInfo */ GR_DIENTRY(gu3dfGetInfo, FxBool, (const char *FileName, Gu3dfInfo *Info)) { #define FN_NAME "gu3dfGetInfo" FILE *image_file; FxU32 i; FxU32 newlines = 0; char version[5]; char color_format[10]; int aspect_width, aspect_height; char buffer[100]; int small_lod, large_lod; FxBool ratio_found = FXFALSE; FxBool format_found = FXFALSE; #ifndef GLIDE3_ALPHA GrAspectRatio_t wh_aspect_table[] = { GR_ASPECT_1x1, GR_ASPECT_1x2, GR_ASPECT_1x4, GR_ASPECT_1x8 }; GrAspectRatio_t hw_aspect_table[] = { GR_ASPECT_1x1, GR_ASPECT_2x1, GR_ASPECT_4x1, GR_ASPECT_8x1 }; #else GrAspectRatio_t wh_aspect_table[] = { GR_ASPECT_LOG2_1x1, GR_ASPECT_LOG2_1x2, GR_ASPECT_LOG2_1x4, GR_ASPECT_LOG2_1x8 }; GrAspectRatio_t hw_aspect_table[] = { GR_ASPECT_LOG2_1x1, GR_ASPECT_LOG2_2x1, GR_ASPECT_LOG2_4x1, GR_ASPECT_LOG2_8x1 }; #endif CfTableEntry cftable[] = { { "I8", GR_TEXFMT_INTENSITY_8, FXTRUE }, { "A8", GR_TEXFMT_ALPHA_8, FXTRUE }, { "AI44", GR_TEXFMT_ALPHA_INTENSITY_44, FXTRUE }, { "YIQ", GR_TEXFMT_YIQ_422, FXTRUE }, { "RGB332", GR_TEXFMT_RGB_332, FXTRUE }, { "RGB565", GR_TEXFMT_RGB_565, FXTRUE }, { "ARGB8332", GR_TEXFMT_ARGB_8332, FXTRUE }, { "ARGB1555", GR_TEXFMT_ARGB_1555, FXTRUE }, { "AYIQ8422", GR_TEXFMT_AYIQ_8422, FXTRUE }, { "ARGB4444", GR_TEXFMT_ARGB_4444, FXTRUE }, { "AI88", GR_TEXFMT_ALPHA_INTENSITY_88, FXTRUE }, { "P8", GR_TEXFMT_P_8, FXTRUE }, { "AP88", GR_TEXFMT_AP_88, FXTRUE }, { "ARGB8888", GR_TEXFMT_ARGB_8888, FXTRUE }, #ifdef FX_GLIDE_NAPALM /* KoolSmoky - other texture formats. */ { "FXT1", GR_TEXFMT_ARGB_CMP_FXT1, FXTRUE }, { "FXT1_HI", GR_TEXFMT_ARGB_CMP_FXT1, FXTRUE }, { "FXT1_MIXED", GR_TEXFMT_ARGB_CMP_FXT1, FXTRUE }, { "FXT1_CHROMA", GR_TEXFMT_ARGB_CMP_FXT1, FXTRUE }, { "FXT1_ALPHA", GR_TEXFMT_ARGB_CMP_FXT1, FXTRUE }, { "P6666", GR_TEXFMT_P_8_6666, FXTRUE }, /*{ "RSVD1", GR_TEXFMT_RSVD1, FXTRUE }, { "RSVD2", GR_TEXFMT_RSVD2, FXTRUE }, { "RSVD4", GR_TEXFMT_RSVD4, FXTRUE },*/ { "YUYV422", GR_TEXFMT_YUYV_422, FXTRUE }, { "UYVY22", GR_TEXFMT_UYVY_422, FXTRUE }, { "AYUV444", GR_TEXFMT_AYUV_444, FXTRUE }, { "DXT1", GR_TEXFMT_ARGB_CMP_DXT1, FXTRUE }, { "DXT2", GR_TEXFMT_ARGB_CMP_DXT2, FXTRUE }, { "DXT3", GR_TEXFMT_ARGB_CMP_DXT3, FXTRUE }, { "DXT4", GR_TEXFMT_ARGB_CMP_DXT4, FXTRUE }, { "DXT5", GR_TEXFMT_ARGB_CMP_DXT5, FXTRUE }, #endif { 0, 0, FXFALSE } }; GDBG_INFO(81,"gu3dfGetInfo(%s,0x%x)\n",FileName,Info); /* ** open the file */ if((image_file = fopen(FileName, openmode)) == NULL) return FXFALSE; if (!_grGet3dfHeader(image_file, buffer, sizeof(buffer))) { /* ** close the file */ fclose(image_file); return FXFALSE; } /* ** grab statistics out of the header */ if(sscanf(buffer,"3df v%s %s lod range: %i %i aspect ratio: %i %i\n", version, color_format, &small_lod, &large_lod, &aspect_width, &aspect_height) == 0) { /* ** close the file */ fclose(image_file); return FXFALSE; } /* ** determine aspect ratio, height, and width */ i = 0; ratio_found = FXFALSE; while ((i < 4) && (!ratio_found)) { if ((aspect_width << i) == aspect_height) { Info->header.aspect_ratio = wh_aspect_table[i]; ratio_found = FXTRUE; } i++; } i = 0; while ((i < 4) && (!ratio_found)) { if ((aspect_height << i) == aspect_width) { Info->header.aspect_ratio = hw_aspect_table[i]; ratio_found = FXTRUE; } i++; } if (!ratio_found) { /* ** close the file */ fclose(image_file); return FXFALSE; } /* ** determine height and width of the mip map */ if (aspect_width >= aspect_height) { Info->header.width = large_lod; Info->header.height = large_lod / aspect_width; } else { Info->header.height = large_lod; Info->header.width = large_lod / aspect_height; } /* ** calculate proper LOD values */ /* ** note for glide3 lod translation: ** we should return the new defines for glide3 */ #ifndef GLIDE3_ALPHA switch (small_lod) { case 1: Info->header.small_lod = GR_LOD_1; break; case 2: Info->header.small_lod = GR_LOD_2; break; case 4: Info->header.small_lod = GR_LOD_4; break; case 8: Info->header.small_lod = GR_LOD_8; break; case 16: Info->header.small_lod = GR_LOD_16; break; case 32: Info->header.small_lod = GR_LOD_32; break; case 64: Info->header.small_lod = GR_LOD_64; break; case 128: Info->header.small_lod = GR_LOD_128; break; case 256: Info->header.small_lod = GR_LOD_256; break; case 512: Info->header.small_lod = GR_LOD_512; break; case 1024: Info->header.small_lod = GR_LOD_1024; break; case 2048: Info->header.small_lod = GR_LOD_2048; break; } switch (large_lod) { case 1: Info->header.large_lod = GR_LOD_1; break; case 2: Info->header.large_lod = GR_LOD_2; break; case 4: Info->header.large_lod = GR_LOD_4; break; case 8: Info->header.large_lod = GR_LOD_8; break; case 16: Info->header.large_lod = GR_LOD_16; break; case 32: Info->header.large_lod = GR_LOD_32; break; case 64: Info->header.large_lod = GR_LOD_64; break; case 128: Info->header.large_lod = GR_LOD_128; break; case 256: Info->header.large_lod = GR_LOD_256; break; case 512: Info->header.large_lod = GR_LOD_512; break; case 1024: Info->header.large_lod = GR_LOD_1024; break; case 2048: Info->header.large_lod = GR_LOD_2048; break; } #else /* GLIDE3_ALPHA */ switch (small_lod) { case 1: Info->header.small_lod = GR_LOD_LOG2_1; break; case 2: Info->header.small_lod = GR_LOD_LOG2_2; break; case 4: Info->header.small_lod = GR_LOD_LOG2_4; break; case 8: Info->header.small_lod = GR_LOD_LOG2_8; break; case 16: Info->header.small_lod = GR_LOD_LOG2_16; break; case 32: Info->header.small_lod = GR_LOD_LOG2_32; break; case 64: Info->header.small_lod = GR_LOD_LOG2_64; break; case 128: Info->header.small_lod = GR_LOD_LOG2_128; break; case 256: Info->header.small_lod = GR_LOD_LOG2_256; break; case 512: Info->header.small_lod = GR_LOD_LOG2_512; break; case 1024: Info->header.small_lod = GR_LOD_LOG2_1024; break; case 2048: Info->header.small_lod = GR_LOD_LOG2_2048; break; } switch (large_lod) { case 1: Info->header.large_lod = GR_LOD_LOG2_1; break; case 2: Info->header.large_lod = GR_LOD_LOG2_2; break; case 4: Info->header.large_lod = GR_LOD_LOG2_4; break; case 8: Info->header.large_lod = GR_LOD_LOG2_8; break; case 16: Info->header.large_lod = GR_LOD_LOG2_16; break; case 32: Info->header.large_lod = GR_LOD_LOG2_32; break; case 64: Info->header.large_lod = GR_LOD_LOG2_64; break; case 128: Info->header.large_lod = GR_LOD_LOG2_128; break; case 256: Info->header.large_lod = GR_LOD_LOG2_256; break; case 512: Info->header.large_lod = GR_LOD_LOG2_512; break; case 1024: Info->header.large_lod = GR_LOD_LOG2_1024; break; case 2048: Info->header.large_lod = GR_LOD_LOG2_2048; break; } #endif /* !GLIDE3_ALPHA */ /* ** determine the color format of the input image */ { char *tempStr = (char*)color_format; while (*tempStr != '\0') { *tempStr = toupper(*tempStr); tempStr++; } } i = 0; format_found = FXFALSE; while ((cftable[i].name != 0) && (!format_found)) { if (strcmp(color_format, cftable[i].name) == 0) { Info->header.format = cftable[i].fmt; format_found = FXTRUE; } i++; } /* ** close the input file */ if (image_file != NULL) fclose(image_file); if (format_found) { Info->mem_required = _grTexTextureMemRequired(Info->header.small_lod, Info->header.large_lod, Info->header.aspect_ratio, Info->header.format, GR_MIPMAPLEVELMASK_BOTH, FXFALSE, FXTRUE); } GDBG_INFO(81,"gu3dfGetInfo(%s,0x%x) -> %i tex memory required\n",FileName,Info, Info->mem_required); return format_found; #undef FN_NAME } /* gu3dfGetInfo() */ /*--------------------------------------------------------------------------- ** gu3dfLoad */ GR_DIENTRY(gu3dfLoad, FxBool, (const char *filename, Gu3dfInfo *info)) { FILE *image_file = 0; FxU32 index = 0; FxU32 newlines = 0; char buffer[100] = ""; GDBG_INFO(81,"gu3dfLoad(%s,0x%x)\n",filename,info); /* ** open the file */ if ((image_file = fopen(filename, openmode)) == NULL) return FXFALSE; if (!_grGet3dfHeader(image_file, buffer, sizeof(buffer))) { /* ** close the file */ fclose(image_file); return FXFALSE; } #if 0 /* ** If necessary, read in the YIQ decompression table */ if ((info->header.format == GR_TEXFMT_YIQ_422) || (info->header.format == GR_TEXFMT_AYIQ_8422)) { /* ** read in Y */ for (index = 0; index < 16; index++) info->table.nccTable.yRGB[index] = ((FxI16) ReadDataShort(image_file)) & 0xFF; /* ** read in I */ for (index = 0; index < 4; index++) { info->table.nccTable.iRGB[index][0] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.iRGB[index][1] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.iRGB[index][2] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; } /* ** read in Q */ for (index = 0; index < 4; index++) { info->table.nccTable.qRGB[index][0] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.qRGB[index][1] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.qRGB[index][2] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; } /* ** pack the table Y entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.yRGB[index*4+0]); packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+1]) << 8; packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+2]) << 16; packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+3]) << 24; info->table.nccTable.packed_data[index] = packedvalue; } /* ** pack the table I entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.iRGB[index][0]) << 18; packedvalue |= ((FxU32) info->table.nccTable.iRGB[index][1]) << 9; packedvalue |= ((FxU32) info->table.nccTable.iRGB[index][2]) << 0; info->table.nccTable.packed_data[index+4] = packedvalue; } /* ** pack the table Q entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.qRGB[index][0]) << 18; packedvalue |= ((FxU32) info->table.nccTable.qRGB[index][1]) << 9;; packedvalue |= ((FxU32) info->table.nccTable.qRGB[index][2]) << 0; info->table.nccTable.packed_data[index+8] = packedvalue; } } /* ** If necessary, read in the Palette */ if ((info->header.format == GR_TEXFMT_P_8) || (info->header.format == GR_TEXFMT_AP_88)) { FxU32 i; for(i = 0; i < 256; i++) info->table.palette.data[i] = ReadDataLong(image_file); } #endif /* ** Read in the image */ switch (info->header.format) { case GR_TEXFMT_YIQ_422: /* ** If necessary, read in the YIQ decompression table */ { /* ** read in Y */ for (index = 0; index < 16; index++) info->table.nccTable.yRGB[index] = ((FxI16) ReadDataShort(image_file)) & 0xFF; /* ** read in I */ for (index = 0; index < 4; index++) { info->table.nccTable.iRGB[index][0] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.iRGB[index][1] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.iRGB[index][2] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; } /* ** read in Q */ for (index = 0; index < 4; index++) { info->table.nccTable.qRGB[index][0] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.qRGB[index][1] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.qRGB[index][2] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; } /* ** pack the table Y entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.yRGB[index*4+0]); packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+1]) << 8; packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+2]) << 16; packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+3]) << 24; info->table.nccTable.packed_data[index] = packedvalue; } /* ** pack the table I entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.iRGB[index][0]) << 18; packedvalue |= ((FxU32) info->table.nccTable.iRGB[index][1]) << 9; packedvalue |= ((FxU32) info->table.nccTable.iRGB[index][2]) << 0; info->table.nccTable.packed_data[index+4] = packedvalue; } /* ** pack the table Q entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.qRGB[index][0]) << 18; packedvalue |= ((FxU32) info->table.nccTable.qRGB[index][1]) << 9;; packedvalue |= ((FxU32) info->table.nccTable.qRGB[index][2]) << 0; info->table.nccTable.packed_data[index+8] = packedvalue; } } Read8Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_AYIQ_8422: /* ** If necessary, read in the YIQ decompression table */ { /* ** read in Y */ for (index = 0; index < 16; index++) info->table.nccTable.yRGB[index] = ((FxI16) ReadDataShort(image_file)) & 0xFF; /* ** read in I */ for (index = 0; index < 4; index++) { info->table.nccTable.iRGB[index][0] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.iRGB[index][1] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.iRGB[index][2] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; } /* ** read in Q */ for (index = 0; index < 4; index++) { info->table.nccTable.qRGB[index][0] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.qRGB[index][1] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; info->table.nccTable.qRGB[index][2] = ((FxI16) ReadDataShort(image_file)) & 0x1FF; } /* ** pack the table Y entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.yRGB[index*4+0]); packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+1]) << 8; packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+2]) << 16; packedvalue |= ((FxU32) info->table.nccTable.yRGB[index*4+3]) << 24; info->table.nccTable.packed_data[index] = packedvalue; } /* ** pack the table I entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.iRGB[index][0]) << 18; packedvalue |= ((FxU32) info->table.nccTable.iRGB[index][1]) << 9; packedvalue |= ((FxU32) info->table.nccTable.iRGB[index][2]) << 0; info->table.nccTable.packed_data[index+4] = packedvalue; } /* ** pack the table Q entries */ for (index = 0; index < 4; index++) { FxU32 packedvalue; packedvalue = ((FxU32) info->table.nccTable.qRGB[index][0]) << 18; packedvalue |= ((FxU32) info->table.nccTable.qRGB[index][1]) << 9;; packedvalue |= ((FxU32) info->table.nccTable.qRGB[index][2]) << 0; info->table.nccTable.packed_data[index+8] = packedvalue; } } Read16Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_P_8: /* ** If necessary, read in the Palette */ { FxU32 i; for(i = 0; i < 256; i++) info->table.palette.data[i] = ReadDataLong(image_file); } Read8Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_AP_88: /* ** If necessary, read in the Palette */ { FxU32 i; for(i = 0; i < 256; i++) info->table.palette.data[i] = ReadDataLong(image_file); } Read16Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_ARGB_CMP_FXT1: case GR_TEXFMT_ARGB_CMP_DXT1: Read4Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: ReadDXT8Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_INTENSITY_8: case GR_TEXFMT_ALPHA_8: case GR_TEXFMT_ALPHA_INTENSITY_44: /*case GR_TEXFMT_YIQ_422:*/ case GR_TEXFMT_RGB_332: /*case GR_TEXFMT_P_8:*/ Read8Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_RGB_565: case GR_TEXFMT_ARGB_8332: case GR_TEXFMT_ARGB_1555: /*case GR_TEXFMT_AYIQ_8422:*/ case GR_TEXFMT_ARGB_4444: case GR_TEXFMT_ALPHA_INTENSITY_88: /*case GR_TEXFMT_AP_88:*/ case GR_TEXFMT_YUYV_422: case GR_TEXFMT_UYVY_422: Read16Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; case GR_TEXFMT_ARGB_8888: case GR_TEXFMT_AYUV_444: Read32Bit(info->data, image_file, info->header.small_lod, info->header.large_lod, G3_ASPECT_TRANSLATE(info->header.aspect_ratio)); break; default: /* ** close the file */ fclose(image_file); return FXFALSE; break; } /* ** close the file */ fclose(image_file); return FXTRUE; } /* ** Read4Bit ** ** Read in a 4-bit Compressed texture map. Luckily the minimum mipmap ** size is 8x4 texels so we never have to worry about where the high ** or low nibble is. ** Take advantage of the fact that the minimum size is 16 bytes ** during the fread() call. ** FXT1,DXT1 ** DXT1 has 2 side by side 4x4 microtiles thus 8x4 texels */ static void Read4Bit(FxU8 *data, FILE *image_file, int small_lod, int large_lod, GrAspectRatio_t aspect_ratio) { int lod; int width, height, thisMipMapByteCount; for (lod = small_lod; lod <= large_lod; lod++) { width = _grMipMapHostWHCmp4Bit[aspect_ratio][lod][0]; height = _grMipMapHostWHCmp4Bit[aspect_ratio][lod][1]; /* Divide the WxH by 32 (the most we can safely do) so that we can read 16 bytes at a time. */ thisMipMapByteCount = (width * height) >> 5; fread(data, 16, thisMipMapByteCount, image_file); data += thisMipMapByteCount; } } /* ** ReadDXT8Bit ** ** Read in a 8-bit Compressed texture map. the minimum mipmap ** size is 4x4 texels ** Take advantage of the fact that the minimum size is 16 bytes ** during the fread() call. ** dxt2,3,4,5 */ static void ReadDXT8Bit(FxU8 *data, FILE *image_file, int small_lod, int large_lod, GrAspectRatio_t aspect_ratio) { int lod; int width, height,thisMipMapByteCount; for (lod = small_lod; lod <= large_lod; lod++) { width = _grMipMapHostWHDXT[aspect_ratio][lod][0]; height = _grMipMapHostWHDXT[aspect_ratio][lod][1]; /* Divide the WxH by 16 (the most we can safely do) so that we can read 16 bytes at a time. */ thisMipMapByteCount = (width * height) >> 4; fread(data, 16, thisMipMapByteCount, image_file); data += thisMipMapByteCount; } } /* ** Read8Bit ** ** Read in an 8-bit texture map, unpacked. */ static void Read8Bit(FxU8 *data, FILE *image_file, int small_lod, int large_lod, GrAspectRatio_t aspect_ratio) { int lod; int width, height; for (lod = small_lod; lod <= large_lod; lod++) { width = _grMipMapHostWH[aspect_ratio][lod][0]; height = _grMipMapHostWH[aspect_ratio][lod][1]; fread(data, sizeof(char), width*height, image_file); data += width*height; } } /* ** Read16Bit ** ** Read in a 16-bit texture map, unpacked. */ static void Read16Bit(FxU16 *data, FILE *image_file, int small_lod, int large_lod, GrAspectRatio_t aspect_ratio) { int index; int lod; int width, height; for (lod = small_lod; lod <= large_lod; lod++) { width = _grMipMapHostWH[aspect_ratio][lod][0]; height = _grMipMapHostWH[aspect_ratio][lod][1]; for (index = 0; index < (width * height); index++) { *data = ReadDataShort(image_file); data++; } } } /* ** Read32Bit ** ** Read in a 32-bit texture map, unpacked. */ static void Read32Bit(FxU32 *data, FILE *image_file, int small_lod, int large_lod, GrAspectRatio_t aspect_ratio) { int index; int lod; int width, height; for (lod = small_lod; lod <= large_lod; lod++) { width = _grMipMapHostWH[aspect_ratio][lod][0]; height = _grMipMapHostWH[aspect_ratio][lod][1]; for (index = 0; index < (width * height); index++) { *data = ReadDataLong(image_file); data++; } } } /* ** FxU16 ReadDataShort */ static FxU16 ReadDataShort(FILE *fp) { FxU16 b1 = (FxU16)getc(fp); FxU16 b2 = (FxU16)getc(fp); #define kShiftB1 8 #define kShiftB2 0 return (((b1 & 0xFF) << kShiftB1) | ((b2 & 0xFF) << kShiftB2)); } /* ** ReadDataLong */ static FxU32 ReadDataLong(FILE *fp) { FxU32 data; FxU8 byte[4]; fread(byte, 4, 1, fp); data = (((FxU32) byte[0]) << 24) | (((FxU32) byte[1]) << 16) | (((FxU32) byte[2]) << 8) | ((FxU32) byte[3]); return data; } glide3x/h5/glide3/src/g3ext.h0100700000175300010010000001510307725034667015203 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED */ /* ** H3EXT.H ** ** The following #defines are relevant when using Glide: ** ** One of the following "platform constants" must be defined during ** compilation: ** ** __DOS__ Defined for 32-bit DOS applications ** __WIN32__ Defined for 32-bit Windows applications ** __sparc__ Defined for Sun Solaris/SunOS ** __linux__ Defined for Linux applications ** __FreeBSD__ Defined for FreeBSD applications ** __NetBSD__ Defined for NetBSD applications ** __OpenBSD__ Defined for OpenBSD applications ** __IRIX__ Defined for SGI Irix applications ** */ #ifndef __H3EXT_H__ #define __H3EXT_H__ #include <3dfx.h> #include #include #ifdef __cplusplus extern "C" { #endif /* ** ----------------------------------------------------------------------- ** TYPE DEFINITIONS ** ----------------------------------------------------------------------- */ /* ** ----------------------------------------------------------------------- ** CONSTANTS AND TYPES ** ----------------------------------------------------------------------- */ /* * gregk 5/3/99 * Constants defined for SSTH3_ALPHADITHERMODE registry key */ #define OPTIMAL 1 #define SHARPER 2 #define SMOOTHER 3 /* tbext */ #define GR_BUFFER_TEXTUREBUFFER_EXT 0x6 #define GR_BUFFER_TEXTUREAUXBUFFER_EXT 0x7 typedef FxU32 GrPixelFormat_t; #define GR_PIXFMT_I_8 0x0001 #define GR_PIXFMT_AI_88 0x0002 #define GR_PIXFMT_RGB_565 0x0003 #define GR_PIXFMT_ARGB_1555 0x0004 #define GR_PIXFMT_ARGB_8888 0x0005 #define GR_PIXFMT_AA_2_RGB_565 0x0006 #define GR_PIXFMT_AA_2_ARGB_1555 0x0007 #define GR_PIXFMT_AA_2_ARGB_8888 0x0008 #define GR_PIXFMT_AA_4_RGB_565 0x0009 #define GR_PIXFMT_AA_4_ARGB_1555 0x000a #define GR_PIXFMT_AA_4_ARGB_8888 0x000b #define GR_PIXFMT_AA_8_RGB_565 0x000c /* 8xaa */ #define GR_PIXFMT_AA_8_ARGB_1555 0x000d #define GR_PIXFMT_AA_8_ARGB_8888 0x000e #define GR_LFBWRITEMODE_Z32 0x0008 typedef FxU32 GrAAMode_t; #define GR_AA_NONE 0x0000 #define GR_AA_4SAMPLES 0x0001 typedef FxU8 GrStencil_t; typedef FxU32 GrStencilOp_t; #define GR_STENCILOP_KEEP 0x00 /* keep current value */ #define GR_STENCILOP_ZERO 0x01 /* set to zero */ #define GR_STENCILOP_REPLACE 0x02 /* replace with reference value */ #define GR_STENCILOP_INCR_CLAMP 0x03 /* increment - clamp */ #define GR_STENCILOP_DECR_CLAMP 0x04 /* decrement - clamp */ #define GR_STENCILOP_INVERT 0x05 /* bitwise inversion */ #define GR_STENCILOP_INCR_WRAP 0x06 /* increment - wrap */ #define GR_STENCILOP_DECR_WRAP 0x07 /* decrement - wrap */ #define GR_TEXTURE_UMA_EXT 0x06 #define GR_STENCIL_MODE_EXT 0x07 #define GR_OPENGL_MODE_EXT 0x08 typedef FxU32 GrCCUColor_t; typedef FxU32 GrACUColor_t; typedef FxU32 GrTCCUColor_t; typedef FxU32 GrTACUColor_t; #define GR_CMBX_ZERO 0x00 #define GR_CMBX_TEXTURE_ALPHA 0x01 #define GR_CMBX_ALOCAL 0x02 #define GR_CMBX_AOTHER 0x03 #define GR_CMBX_B 0x04 #define GR_CMBX_CONSTANT_ALPHA 0x05 #define GR_CMBX_CONSTANT_COLOR 0x06 #define GR_CMBX_DETAIL_FACTOR 0x07 #define GR_CMBX_ITALPHA 0x08 #define GR_CMBX_ITRGB 0x09 #define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a #define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b #define GR_CMBX_LOD_FRAC 0x0c #define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d #define GR_CMBX_OTHER_TEXTURE_RGB 0x0e #define GR_CMBX_TEXTURE_RGB 0x0f #define GR_CMBX_TMU_CALPHA 0x10 #define GR_CMBX_TMU_CCOLOR 0x11 typedef FxU32 GrCombineMode_t; #define GR_FUNC_MODE_ZERO 0x00 #define GR_FUNC_MODE_X 0x01 #define GR_FUNC_MODE_ONE_MINUS_X 0x02 #define GR_FUNC_MODE_NEGATIVE_X 0x03 #define GR_FUNC_MODE_X_MINUS_HALF 0x04 typedef FxU32 GrAlphaBlendOp_t; #define GR_BLEND_OP_ADD 0x00 #define GR_BLEND_OP_SUB 0x01 #define GR_BLEND_OP_REVSUB 0x02 #define GR_BLEND_SAME_COLOR_EXT 0x08 #define GR_BLEND_ONE_MINUS_SAME_COLOR_EXT 0x09 /* Napalm extensions to GrTextureFormat_t */ #define GR_TEXFMT_ARGB_CMP_FXT1 0x11 #define GR_TEXFMT_ARGB_8888 0x12 #define GR_TEXFMT_YUYV_422 0x13 #define GR_TEXFMT_UYVY_422 0x14 #define GR_TEXFMT_AYUV_444 0x15 #define GR_TEXFMT_ARGB_CMP_DXT1 0x16 #define GR_TEXFMT_ARGB_CMP_DXT2 0x17 #define GR_TEXFMT_ARGB_CMP_DXT3 0x18 #define GR_TEXFMT_ARGB_CMP_DXT4 0x19 #define GR_TEXFMT_ARGB_CMP_DXT5 0x1A #define GR_TEXTFMT_RGB_888 0xFF /* Napalm extensions to GrLOD_t */ #define GR_LOD_LOG2_2048 0xb #define GR_LOD_LOG2_1024 0xa #define GR_LOD_LOG2_512 0x9 /* Napalm extensions to GrTexBaseRange_t */ #define GR_TEXBASE_2048 0x7 #define GR_TEXBASE_1024 0x6 #define GR_TEXBASE_512 0x5 #define GR_TEXBASE_256_TO_1 0x4 #ifdef __cplusplus } #endif #include #endif /* __H3EXT_H__ */ glide3x/h5/glide3/src/gaa.c0100700000175300010010000014652507725034667014711 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gaa.c,v 1.3.4.2 2003/06/05 08:23:52 koolsmoky Exp $ ** $Log: ** 5 3dfx 1.2.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 4 3dfx 1.2.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 3 3dfx 1.2 11/08/99 Larry warner Changes to enable building ** with MSVC 6. ** 2 3dfx 1.1 11/02/99 Larry warner Clean up some debug code to ** make MSVC 6 happy. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 25 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 24 5/12/99 10:20a Atai ** fixed PRS 5815 ** ** 23 4/16/99 2:48p Kcd ** Hack to allow defferent SETF macro to be used. ** ** 22 2/18/99 4:38p Kcd ** Oops, broke the x86 build. That's the strangest cast I've ever seen. ** ** 21 2/18/99 3:24p Kcd ** Mac happiness. ** ** 20 12/03/98 11:26p Dow ** Code 'cleanup' heheh ** ** 19 11/04/98 5:59p Jeske ** add splash speckle mini-workaround ** ** 18 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 17 9/25/98 5:41p Atai ** fix aa point routine - saving the wrong culling flag ** ** 16 9/23/98 2:34p Atai ** fixed grDrawVertexArrayContiguous line routine in aa clip coords mode ** ** 15 9/18/98 6:43p Atai ** fix clip coords line and triangles ** ** 14 8/18/98 4:30p Atai ** fixed aa triangle in clip coords ** ** 13 7/01/98 8:40a Jdt ** removed gc arg from trisetup funcs ** ** 12 8/03/98 6:39a Jdt ** moved stats from global into gc ** ** 11 7/18/98 12:26a Jdt ** Changes to reflect new shadow register structure ** ** 10 7/16/98 8:17a Jdt ** fxcmd.h ** ** 9 6/25/98 1:19p Atai ** aaVpDrawArrayEdgeSense ** ** 8 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 7 5/29/98 2:09p Atai ** remove polygon code ** ** 6 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 4 3/21/98 11:31a Atai ** added GR_TRIANGLE_STRIP_CONTINUE and GR_TRIANGLE_FAN_CONTINUE ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 61 1/15/98 2:46p Atai * fixed grDrawPoint and grDrawLine in aa mode * * 60 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 59 12/12/97 12:43p Atai * move i and dateElem into the set up loop * * 57 12/08/97 10:40a Atai * modify draw vertex primitive routines to do grDrawVertexArrayLinear() * * 56 12/05/97 4:26p Peter * watcom warnings * * 55 11/24/97 4:40p Peter * aa prims vs packing * * 54 11/21/97 6:05p Atai * use one datalist (tsuDataList) in glide3 * * 53 11/21/97 3:20p Peter * direct writes tsu registers * * 52 11/18/97 6:11p Peter * fixed glide3 effage * * 51 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 50 11/18/97 3:26p Atai * update vData * optimize state monster * * 49 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 48 11/06/97 6:10p Atai * update GrState size * rename grDrawArray to grDrawVertexArray * update _grDrawPoint and _grDrawVertexList * * 47 11/04/97 6:35p Atai * 1. sync with data structure changes * 2. break up aa triangle routine * * 46 11/04/97 5:04p Peter * cataclysm part deux * * 45 11/04/97 4:57p Atai * use byte offset * * 44 11/03/97 3:43p Peter * h3/cvg cataclysm * * 43 11/03/97 3:19p Atai * optimization * * 42 10/29/97 2:45p Peter * C version of Taco's packing code * * 41 10/29/97 2:24p Atai * re-work aa draw routines to increase sbench number * * 40 10/21/97 8:38p Atai * added lines routine for grDrawArray * * 39 10/21/97 3:22p Peter * hand pack rgb * * 38 10/19/97 12:51p Peter * no tsu happiness * * 37 10/17/97 3:15p Peter * removed unused addr field from datalist * * 36 10/17/97 10:15a Peter * packed rgb state cleanup * * 35 10/16/97 5:33p Peter * argb != rgba * * 34 10/16/97 3:40p Peter * packed rgb * * 33 10/16/97 1:50p Atai * fix drawarray bugs * * 32 10/14/97 7:33p Atai * fix compiler error * * 31 10/14/97 5:40p Atai * added grculltest * * 30 10/14/97 4:36p Atai * added aa points, strip line and trianlges for drawarray * * 29 10/09/97 8:02p Dow * State Monster 1st Cut * * 28 10/08/97 5:19p Peter * optinally clamp only texture params * * 27 10/08/97 11:32a Peter * pre-computed packet headers for packet 3 * * 26 9/20/97 4:42p Peter * tri_setf fixup/big fifo * * 25 9/16/97 2:49p Peter * fixed watcom unhappiness w/ static initializers * * 24 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 23 9/10/97 10:13p Peter * fifo logic from GaryT, non-normalized fp first cut * * 22 8/30/97 5:58p Tarolli * cleanups * * 21 7/29/97 4:31p Atai * replace old edge sense routine * * 19 7/28/97 2:42p Peter * aa points? * * 18 7/26/97 3:04p Peter * cleanup * * 17 7/25/97 11:40a Peter * removed dHalf, change field name to match real use for cvg * * 16 6/30/97 3:21p Peter * more aa through cmd fifo * * 15 6/20/97 1:17p Peter * changes for new CVG_TRI macros ** */ #if SET_BSWAP #define SLOW_SETF 1 #endif #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if macintosh && defined(__MWERKS__) #pragma auto_inline off #endif static void aaDrawArrayEdgeSense(float *a, float *b, float *c); /* ** ----------------------------------------------------------------------- ** ** Antialiasing rendering functions ** ** ----------------------------------------------------------------------- */ typedef enum { aaEdgeSenseTop, aaEdgeSenseLeft, aaEdgeSenseBottom, aaEdgeSenseRight } aaEdgeSense; /*------------------------------------------------------------------- Function: aaVpDrawArrayEdgeSense Date: 11-Dec-97 Implementor(s): atai Description: Pass the line a, b. Use c to calculate edge sense. (clip space) Create new vertices from a, b. Arguments: Return: -------------------------------------------------------------------*/ static void aaVpDrawArrayEdgeSense(float *a, float *b, float *c, float oowa, float oowb) { #define FN_NAME "aaVpDrawArrayEdgeSense" GR_DCL_GC; #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP float dx, dy, v2x, v2y; float *fa, *fb, v1a, v2a; float fax, fay, fbx, fby; FxU32 ia; aaEdgeSense sense; if (FARRAY(a, 4) >= FARRAY(b, 4)) { fa = b; fb = a; } else { fa = a; fb = b; } dx = FARRAY(fa, 0) - FARRAY(fb, 0); dy = FARRAY(fa, 4) - FARRAY(fb, 4); if (dx == 0.f) { sense = (FARRAY(c, 0) > FARRAY(fa, 0)) ? aaEdgeSenseLeft : aaEdgeSenseRight; } else if (dy == 0.0f) { sense = (FARRAY(c, 4) > FARRAY(fa, 4)) ? aaEdgeSenseBottom : aaEdgeSenseTop; } else { float dcax, dcay, dcbx, dcby, cp; dcax = FARRAY(fa, 0) - FARRAY(c, 0); dcay = FARRAY(fa, 4) - FARRAY(c, 4); dcbx = FARRAY(fb, 0) - FARRAY(c, 0); dcby = FARRAY(fb, 4) - FARRAY(c, 4); cp = dcax * dcby - dcay * dcbx; if (dx > 0.0f) { if (dx >= -dy) /* X-major line */ sense = (cp > 0.0f) ? aaEdgeSenseTop : aaEdgeSenseBottom; else /* Y-major line */ sense = (cp > 0.0f) ? aaEdgeSenseRight : aaEdgeSenseLeft; } else { if (dx <= dy) /* X-major line */ sense = (cp < 0.0f) ? aaEdgeSenseTop : aaEdgeSenseBottom; else /* Y-major line */ sense = (cp < 0.0f) ? aaEdgeSenseLeft : aaEdgeSenseRight; } } /* v1(a), v2(b), a, b */ GR_SET_EXPECTED_SIZE(gc->state.vData.vSize << 2, 1); TRI_STRIP_BEGIN(kSetupStrip, 4, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); fax = FARRAY(a, 0)*oowa*gc->state.Viewport.hwidth+gc->state.Viewport.ox; fay = FARRAY(a, 4)*oowa*gc->state.Viewport.hheight+gc->state.Viewport.oy; fbx = FARRAY(b, 0)*oowb*gc->state.Viewport.hwidth+gc->state.Viewport.ox; fby = FARRAY(b, 4)*oowb*gc->state.Viewport.hheight+gc->state.Viewport.oy; switch (sense) { case aaEdgeSenseTop: TRI_SETF(fax); v2x = fbx; TRI_SETF(fay + _GlideRoot.pool.f1); v2y = fby + _GlideRoot.pool.f1; break; case aaEdgeSenseLeft: TRI_SETF(fax - _GlideRoot.pool.f1); v2x = fbx - _GlideRoot.pool.f1; TRI_SETF(fay); v2y = fby; break; case aaEdgeSenseBottom: TRI_SETF(fax); v2x = fbx; TRI_SETF(fay - _GlideRoot.pool.f1); v2y = fby - _GlideRoot.pool.f1; break; case aaEdgeSenseRight: TRI_SETF(fax + _GlideRoot.pool.f1); v2x = fbx + _GlideRoot.pool.f1; TRI_SETF(fay); v2y = fby; break; } if (gc->state.vData.colorType == GR_FLOAT) { ia = gc->state.vData.aInfo.offset; v1a = v2a = 0.f; } else { ia = gc->state.vData.pargbInfo.offset; *((FxU32 *)&v1a)=*((FxU32 *)((int)a + ia))&0x00ffffff; *((FxU32 *)&v2a)=*((FxU32 *)((int)b + ia))&0x00ffffff; } { AA_TRI_VP_SETFS(a,oowa); TRI_SETF(v2x); TRI_SETF(v2y); AA_TRI_VP_SETFS(b,oowb); TRI_SETF(fax); TRI_SETF(fay); TRI_VP_SETFS(a,oowa); TRI_SETF(fbx); TRI_SETF(fby); TRI_VP_SETFS(b,oowb); } gc->stats.othertrisDrawn+=2; TRI_END; GR_CHECK_SIZE(); #endif #undef FN_NAME } /*--------------------------------------------------------------------------- ** grAADrawTriangle ** ** NOTE: This doesn't quite work yet */ GR_ENTRY(grAADrawTriangle, void, (const void *a, const void *b, const void *c, FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias)) { #define FN_NAME "grAADrawTriangle" FxU32 fbzMode, /* What we write to fbzMode */ fbzModeOld; /* Squirrel away current fbzMode */ GR_BEGIN_NOFIFOCHECK(FN_NAME, 96); GDBG_INFO_MORE(gc->myLevel,"(0x%x,0x%x,0x%x,%d,%d,%d)\n", a,b,c,ab_antialias,bc_antialias,ca_antialias); GR_FLUSH_STATE(); fbzModeOld = gc->state.shadow.fbzMode; { /* ** culling */ float dxAB, dxBC, dyAB, dyBC; FxI32 j; dxAB = FARRAY(a, 0) - FARRAY(b, 0); dxBC = FARRAY(b, 0) - FARRAY(c, 0); dyAB = FARRAY(a, 4) - FARRAY(b, 4); dyBC = FARRAY(b, 4) - FARRAY(c, 4); *(float *)&j = dxAB * dyBC - dxBC * dyAB; if ((j & 0x7FFFFFFF) == 0) return; if ((gc->state.cull_mode != GR_CULL_DISABLE) && (((FxI32)(j ^ (gc->state.cull_mode << 31UL))) >= 0)) return; } #if __POWERPC__ { const void *verts[3]; verts[0] = a; verts[1] = b; verts[2] = c; (*gc->archDispatchProcs.drawTrianglesProc)(GR_VTX_PTR_ARRAY, 3, verts); } #else grDrawTriangle(a, b, c); #endif /* Disable depth buffer writes for edge triangles */ fbzMode = fbzModeOld; fbzMode &= ~(SST_ZAWRMASK); GR_SET_EXPECTED_SIZE(4 * 2, 1 * 2); /* speckle mini-workaround, another one below... - jeske */ GR_SET(BROADCAST_ID, hw, nopCMD, 0); GR_SET(BROADCAST_ID, hw, fbzMode, fbzMode); GR_CHECK_SIZE(); if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if (ab_antialias) aaDrawArrayEdgeSense((float *)a, (float *)b, (float *)c); if (bc_antialias) aaDrawArrayEdgeSense((float *)b, (float *)c, (float *)a); if (ca_antialias) aaDrawArrayEdgeSense((float *)c, (float *)a, (float *)b); } else { float oowa, oowb, oowc; if (ab_antialias) { oowa = 1.0f / FARRAY(a, gc->state.vData.wInfo.offset); oowb = 1.0f / FARRAY(b, gc->state.vData.wInfo.offset); aaVpDrawArrayEdgeSense((float *)a, (float *)b, (float *)c, oowa, oowb); } if (bc_antialias) { if (!ab_antialias) oowb = 1.0f / FARRAY(b, gc->state.vData.wInfo.offset); oowc = 1.0f / FARRAY(c, gc->state.vData.wInfo.offset); aaVpDrawArrayEdgeSense((float *)b, (float *)c, (float *)a, oowb, oowc); } if (ca_antialias) { if (!ab_antialias) oowa = 1.0f / FARRAY(a, gc->state.vData.wInfo.offset); if (!bc_antialias) oowc = 1.0f / FARRAY(c, gc->state.vData.wInfo.offset); aaVpDrawArrayEdgeSense((float *)c, (float *)a, (float *)b, oowc, oowa); } } /* Restore the old fbzMode */ GR_SET_EXPECTED_SIZE(4 * 2, 1 * 2); /* speckle mini-workaround, another one below... - jeske */ GR_SET(BROADCAST_ID, hw, nopCMD, 0); GR_SET(BROADCAST_ID, hw, fbzMode, fbzModeOld); GR_END(); #if 0 FxU32 fbzMode, /* What we write to fbzMode */ fbzModeOld; /* Squirrel away current fbzMode */ GR_BEGIN_NOFIFOCHECK(FN_NAME, 96); GDBG_INFO_MORE(gc->myLevel,"(0x%x,0x%x,0x%x,%d,%d,%d)\n", a,b,c,ab_antialias,bc_antialias,ca_antialias); GR_FLUSH_STATE(); fbzModeOld = gc->state.shadow.fbzMode; /* backfaced or zero area */ if (TRISETUP(a, b, c ) <= 0) return; /* Disable depth buffer writes for edge triangles */ fbzMode = fbzModeOld; fbzMode &= ~(SST_ZAWRMASK); GR_SET_EXPECTED_SIZE(4, 1); GR_SET(BROADCAST_ID, hw, fbzMode, fbzMode); GR_CHECK_SIZE(); if (ab_antialias) aaDrawArrayEdgeSense((float *)a, (float *)b, (float *)c); if (bc_antialias) aaDrawArrayEdgeSense((float *)b, (float *)c, (float *)a); if (ca_antialias) aaDrawArrayEdgeSense((float *)c, (float *)a, (float *)b); /* Restore the old fbzMode */ GR_SET_EXPECTED_SIZE(4, 1); GR_SET(BROADCAST_ID, hw, fbzMode, fbzModeOld); GR_END(); #endif #undef FN_NAME } /* grAADrawTriangle */ #define OK_TO_SKIP_XY #define ZEROALPHA(_ss) *((FxU32 *)&_ss)=*((FxU32 *)&_ss)&0x00ffffff /*------------------------------------------------------------------- Function: _grAADrawPoints Date: 13-Oct-97 Implementor(s): atai Description: Draw anti-alias points Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grAADrawPoints(FxI32 mode, FxI32 count, void *pointers) { #define FN_NAME "_grAADrawPoints" /* * the aa point routine is similar to grAADrawPoint routine * except the data set up is from the pointer array and * its data layout */ #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP GR_DCL_GC; float *e, ptX, ptY; FxU32 ia; FxU32 i; FxU32 vsize; FxI32 stride = mode; FxU32 tmp_cullStripHdr; GDBG_INFO(94,"_grAADrawPoints(0x%x, %d, 0x%x)\n", mode, count, pointers); GDBG_INFO_MORE(gc->myLevel, "(count = %d, pointers = 0x%x)\n", count, pointers); if (stride == 0) stride = gc->state.vData.vStride; GR_FLUSH_STATE(); if (gc->state.vData.colorType == GR_FLOAT) ia = gc->state.vData.aInfo.offset; else ia = gc->state.vData.pargbInfo.offset; vsize = gc->state.vData.vSize * 6; /* turn off culling so triangles unconditionally draw */ tmp_cullStripHdr = gc->cmdTransportInfo.cullStripHdr; gc->cmdTransportInfo.cullStripHdr &= GR_CULL_MASK; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { while (count--) { FxU32 dataElem = 0; /* We draw this as a 4 triangle fan centered around E. */ GR_SET_EXPECTED_SIZE(vsize, 1); TRI_STRIP_BEGIN(kSetupFan, 0x06UL, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); e = pointers; if (mode) e = *(float **)e; (float *)pointers += stride; ptX = FARRAY(e, gc->state.vData.vertexInfo.offset); ptY = FARRAY(e, gc->state.vData.vertexInfo.offset+4); /* Send down the original point center */ TRI_SETF(ptX); TRI_SETF(ptY); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(e, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* Send the 'surrounding' vertices w/ alpha == 0.0f. To avoid * the vertex copying from the previous version we carry around * a table of offsets that we add into the original point to get * the new points. */ { int v; static const float xAdjust[] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f }; static const float yAdjust[] = { -1.0f, -1.0f, 1.0f, 1.0f, -1.0f }; ASSERT(ArraySize(xAdjust) == ArraySize(yAdjust)); if (gc->state.vData.colorType == GR_FLOAT) { for(v = 0; v < ArraySize(xAdjust); v++) { TRI_SETF(ptX + xAdjust[v]); TRI_SETF(ptY + yAdjust[v]); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(0.0f); } else { TRI_SETF(FARRAY(e, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } } } else { for(v = 0; v < ArraySize(xAdjust); v++) { TRI_SETF(ptX + xAdjust[v]); TRI_SETF(ptY + yAdjust[v]); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { FxU32 argb; if (i == ia) { argb = *((FxU32 *)((int)e + i)) & 0x00ffffff; TRI_SETF(*((float *)&argb)); } else { TRI_SETF(FARRAY(e, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } } } } TRI_END; GR_CHECK_SIZE(); } } else { /* * first cut of clip space coordinate code. */ float oow; while (count--) { FxU32 dataElem = 0; /* We draw this as a 4 triangle fan centered around E. */ GR_SET_EXPECTED_SIZE(vsize, 1); TRI_STRIP_BEGIN(kSetupFan, 0x06UL, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); e = pointers; if (mode) e = *(float **)e; oow = 1.0f / FARRAY(e, gc->state.vData.wInfo.offset); (float *)pointers += stride; ptX = FARRAY(e, gc->state.vData.vertexInfo.offset) *oow*gc->state.Viewport.hwidth+gc->state.Viewport.ox; ptY = FARRAY(e, gc->state.vData.vertexInfo.offset+4) *oow*gc->state.Viewport.hheight+gc->state.Viewport.oy; /* Send down the original point center */ TRI_SETF(ptX); TRI_SETF(ptY); TRI_VP_SETFS(e,oow); /* Send the 'surrounding' vertices w/ alpha == 0.0f. To avoid * the vertex copying from the previous version we carry around * a table of offsets that we add into the original point to get * the new points. */ { int v; static const float xAdjust[] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f }; static const float yAdjust[] = { -1.0f, -1.0f, 1.0f, 1.0f, -1.0f }; ASSERT(ArraySize(xAdjust) == ArraySize(yAdjust)); if (gc->state.vData.colorType == GR_FLOAT) { for(v = 0; v < ArraySize(xAdjust); v++) { TRI_SETF(ptX + xAdjust[v]); TRI_SETF(ptY + yAdjust[v]); AA_TRI_VP_SETFS(e, oow); } } else { for(v = 0; v < ArraySize(xAdjust); v++) { TRI_SETF(ptX + xAdjust[v]); TRI_SETF(ptY + yAdjust[v]); AA_TRI_VP_SETFS(e, oow); } } } TRI_END; GR_CHECK_SIZE(); } } gc->cmdTransportInfo.cullStripHdr = tmp_cullStripHdr; gc->stats.pointsDrawn+=count; gc->stats.othertrisDrawn+=(count<<2); #endif #undef FN_NAME } /* _grAADrawPoints */ #if macintosh && defined(__MWERKS__) && !DEBUG #pragma optimization_level 1 #endif /*------------------------------------------------------------------- Function: _grAADrawLineStrip Date: 13-Oct-97 Implementor(s): atai Description: Draw anti-alias strip line Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grAADrawLineStrip(FxI32 mode, FxI32 ltype, FxI32 count, void *pointers) { #define FN_NAME "_grAADrawLineStrip" #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP /* * the aa line strip routine is similar to grAADrawLine routine * except the data set up is from the pointer array and * its data layout */ GR_DCL_GC; float adx, ady; /* |dX| and |dY| */ float **lPtrs = (float **) pointers; float *v1, *v2; float v1a, v2a; FxU32 ia, vNum = 0; FxU32 vsize; FxU32 sCount; FxI32 stride = mode; FxU32 tmp_cullStripHdr; GDBG_INFO(95,"_grAADrawLineStrip(count = %d, pointers = 0x%x)\n", count, pointers); if (gc->state.vData.colorType == GR_FLOAT) { ia = gc->state.vData.aInfo.offset; v1a = 0.0f; v2a = 0.0f; } else ia = gc->state.vData.pargbInfo.offset; GR_FLUSH_STATE(); if (stride == 0) stride = gc->state.vData.vStride; if (ltype == GR_LINES) sCount = count >> 1; /* line list */ else sCount = count-1; /* strip line */ vsize = 6 * gc->state.vData.vSize; tmp_cullStripHdr = gc->cmdTransportInfo.cullStripHdr; gc->cmdTransportInfo.cullStripHdr &= GR_CULL_MASK; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { while (sCount--) { v1 = (float *)pointers; v2 = (float *)pointers + stride; if (mode) { v1 = *(float **)v1; v2 = *(float **)v2; } (float *)pointers += stride; if (ltype == GR_LINES) (float *)pointers += stride; /* draw from low Y to high Y */ if (FARRAY(v2, gc->state.vData.vertexInfo.offset+4) < FARRAY(v1, gc->state.vData.vertexInfo.offset+4)) { float* tv = v1; v1 = v2; v2 = tv; } /* compute deltas and absolute deltas */ adx = FARRAY(v2, gc->state.vData.vertexInfo.offset) - FARRAY(v1, gc->state.vData.vertexInfo.offset); ady = FARRAY(v2, gc->state.vData.vertexInfo.offset+4) - FARRAY(v1, gc->state.vData.vertexInfo.offset+4); if (adx < 0) adx = -adx; if (ady < 0) ady = -ady; if (gc->state.vData.colorType != GR_FLOAT) { *((FxU32 *)&v1a)=*((FxU32 *)((int)v1 + ia))&0x00ffffff; *((FxU32 *)&v2a)=*((FxU32 *)((int)v2 + ia))&0x00ffffff; } if (adx >= ady) { /* X major line */ FxU32 i, dataElem; GR_SET_EXPECTED_SIZE(vsize, 1); TRI_STRIP_BEGIN(kSetupStrip, 6, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); /* point 1 (b) = (v2)*/ TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset+4) - _GlideRoot.pool.f1); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v2a); } else { TRI_SETF(FARRAY(v2, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } /* point 2 (a) = (v1)*/ TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset+4) - _GlideRoot.pool.f1); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v1a); } else { TRI_SETF(FARRAY(v1, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } /* point 3 (v2) = (v2)*/ TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(v2, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* point 4 (v1) = (v1)*/ TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(v1, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* point 5 (f) = (v2)*/ TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset+4) + _GlideRoot.pool.f1); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v2a); } else { TRI_SETF(FARRAY(v2, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } /* point 6 (a) = (v1)*/ TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset+4) + _GlideRoot.pool.f1); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v1a); } else { TRI_SETF(FARRAY(v1, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } TRI_END; GR_CHECK_SIZE(); } else { /* Y major line */ FxU32 i, dataElem; GR_SET_EXPECTED_SIZE(vsize, 1); TRI_STRIP_BEGIN(kSetupStrip, 6, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); /* point 1 (b) = (v2)*/ TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset) + _GlideRoot.pool.f1); TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v2a); } else { TRI_SETF(FARRAY(v2, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } /* point 2 (a) = (v1)*/ TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset) + _GlideRoot.pool.f1); TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v1a); } else { TRI_SETF(FARRAY(v1, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } /* point 3 (v2) = (v2)*/ TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(v2, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* point 4 (v1) = (v1)*/ TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(v1, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* point 5 (f) = (v2)*/ TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset) - _GlideRoot.pool.f1); TRI_SETF(FARRAY(v2, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v2a); } else { TRI_SETF(FARRAY(v2, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } /* point 6 (a) = (v1)*/ TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset) - _GlideRoot.pool.f1); TRI_SETF(FARRAY(v1, gc->state.vData.vertexInfo.offset+4)); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v1a); } else { TRI_SETF(FARRAY(v1, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } TRI_END; GR_CHECK_SIZE(); } gc->stats.linesDrawn++; gc->stats.othertrisDrawn+=4; } } else { float oowa, oowb, owa, owb, tmp1, tmp2, fax, fay, fbx, fby; if (ltype == GR_LINE_STRIP) { v1 = (float *)pointers; if (mode) { v1 = *(float **)v1; } oowb = 1.0f / FARRAY(v1, gc->state.vData.wInfo.offset); } while (sCount--) { if (ltype == GR_LINES) { v1 = (float *)pointers; v2 = (float *)pointers + stride; if (mode) { v1 = *(float **)v1; v2 = *(float **)v2; } (float *)pointers += stride; if (ltype == GR_LINES) (float *)pointers += stride; owa = oowa = 1.0f / FARRAY(v1, gc->state.vData.wInfo.offset); owb = oowb = 1.0f / FARRAY(v2, gc->state.vData.wInfo.offset); } else { owa = oowa = oowb; v1 = (float *)pointers; v2 = (float *)pointers + stride; if (mode) { v1 = *(float **)v1; v2 = *(float **)v2; } (float *)pointers += stride; owb = oowb = 1.0f / FARRAY(v2, gc->state.vData.wInfo.offset); } fay = tmp1 = FARRAY(v1, gc->state.vData.vertexInfo.offset+4) *oowa*gc->state.Viewport.hheight+gc->state.Viewport.oy; fby = tmp2 = FARRAY(v2, gc->state.vData.vertexInfo.offset+4) *oowb*gc->state.Viewport.hheight+gc->state.Viewport.oy; /* draw from low Y to high Y */ if (tmp2 < tmp1) { float* tv = v1; v1 = v2; v2 = tv; owa = oowb; owb = oowa; fay = tmp2; fby = tmp1; } fax = FARRAY(v1, gc->state.vData.vertexInfo.offset) *owa*gc->state.Viewport.hwidth+gc->state.Viewport.ox; fbx = FARRAY(v2, gc->state.vData.vertexInfo.offset) *owb*gc->state.Viewport.hwidth+gc->state.Viewport.ox; /* compute deltas and absolute deltas */ adx = fbx - fax; ady = fby - fay; if (adx < 0) adx = -adx; if (ady < 0) ady = -ady; /* if (gc->state.vData.colorType != GR_FLOAT) { *((FxU32 *)&v1a)=*((FxU32 *)((int)v1 + ia))&0x00ffffff; *((FxU32 *)&v2a)=*((FxU32 *)((int)v2 + ia))&0x00ffffff; } */ if (adx >= ady) { /* X major line */ GR_SET_EXPECTED_SIZE(vsize, 1); TRI_STRIP_BEGIN(kSetupStrip, 6, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); /* point 1 (b) = (v2)*/ TRI_SETF(fbx); TRI_SETF(fby - _GlideRoot.pool.f1); AA_TRI_VP_SETFS(v2, owb); /* point 2 (a) = (v1)*/ TRI_SETF(fax); TRI_SETF(fay - _GlideRoot.pool.f1); AA_TRI_VP_SETFS(v1, owa); /* point 3 (v2) = (v2)*/ TRI_SETF(fbx); TRI_SETF(fby); TRI_VP_SETFS(v2, owb); /* point 4 (v1) = (v1)*/ TRI_SETF(fax); TRI_SETF(fay); TRI_VP_SETFS(v1, owa); /* point 5 (f) = (v2)*/ TRI_SETF(fbx); TRI_SETF(fby + _GlideRoot.pool.f1); AA_TRI_VP_SETFS(v2, owb); /* point 6 (a) = (v1)*/ TRI_SETF(fax); TRI_SETF(fay + _GlideRoot.pool.f1); AA_TRI_VP_SETFS(v1, owa); TRI_END; GR_CHECK_SIZE(); } else { /* Y major line */ GR_SET_EXPECTED_SIZE(vsize, 1); TRI_STRIP_BEGIN(kSetupStrip, 6, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); /* point 1 (b) = (v2)*/ TRI_SETF(fbx + _GlideRoot.pool.f1); TRI_SETF(fby); AA_TRI_VP_SETFS(v2, owb); /* point 2 (a) = (v1)*/ TRI_SETF(fax + _GlideRoot.pool.f1); TRI_SETF(fay); AA_TRI_VP_SETFS(v1, owa); /* point 3 (v2) = (v2)*/ TRI_SETF(fbx); TRI_SETF(fby); TRI_VP_SETFS(v2, owb); /* point 4 (v1) = (v1)*/ TRI_SETF(fax); TRI_SETF(fay); TRI_VP_SETFS(v1, owa); /* point 5 (f) = (v2)*/ TRI_SETF(fbx - _GlideRoot.pool.f1); TRI_SETF(fby); AA_TRI_VP_SETFS(v2, owb); /* point 6 (a) = (v1)*/ TRI_SETF(fax - _GlideRoot.pool.f1); TRI_SETF(fay); AA_TRI_VP_SETFS(v1, owa); TRI_END; GR_CHECK_SIZE(); } gc->stats.linesDrawn++; gc->stats.othertrisDrawn+=4; } } gc->cmdTransportInfo.cullStripHdr = tmp_cullStripHdr; #endif #undef FN_NAME } /* _grAADrawLineStrip */ #if macintosh && defined(__MWERKS__) && !DEBUG #pragma optimization_level 4 #endif /*------------------------------------------------------------------- Function: aaDrawArrayEdgeSense Date: 13-Oct-97 Implementor(s): atai Description: Pass the line a, b. Use c to calculate edge sense. Create new vertices from a, b. Arguments: Return: -------------------------------------------------------------------*/ static void aaDrawArrayEdgeSense(float *a, float *b, float *c) { #define FN_NAME "aaDrawArrayEdgeSense" GR_DCL_GC; #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP float dx, dy, v2x, v2y; float *fa, *fb, v1a, v2a; FxU32 ia; aaEdgeSense sense; if (FARRAY(a, gc->state.vData.vertexInfo.offset+4) >= FARRAY(b, gc->state.vData.vertexInfo.offset+4)) { fa = b; fb = a; } else { fa = a; fb = b; } dx = FARRAY(fa, gc->state.vData.vertexInfo.offset) - FARRAY(fb, gc->state.vData.vertexInfo.offset); dy = FARRAY(fa, gc->state.vData.vertexInfo.offset+4) - FARRAY(fb, gc->state.vData.vertexInfo.offset+4); if (dx == 0.f) { sense = (FARRAY(c, gc->state.vData.vertexInfo.offset) > FARRAY(fa, gc->state.vData.vertexInfo.offset)) ? aaEdgeSenseLeft : aaEdgeSenseRight; } else if (dy == 0.0f) { sense = (FARRAY(c, gc->state.vData.vertexInfo.offset+4) > FARRAY(fa, gc->state.vData.vertexInfo.offset+4)) ? aaEdgeSenseBottom : aaEdgeSenseTop; } else { float dcax, dcay, dcbx, dcby, cp; dcax = FARRAY(fa, gc->state.vData.vertexInfo.offset) - FARRAY(c, gc->state.vData.vertexInfo.offset); dcay = FARRAY(fa, gc->state.vData.vertexInfo.offset+4) - FARRAY(c, gc->state.vData.vertexInfo.offset+4); dcbx = FARRAY(fb, gc->state.vData.vertexInfo.offset) - FARRAY(c, gc->state.vData.vertexInfo.offset); dcby = FARRAY(fb, gc->state.vData.vertexInfo.offset+4) - FARRAY(c, gc->state.vData.vertexInfo.offset+4); cp = dcax * dcby - dcay * dcbx; if (dx > 0.0f) { if (dx >= -dy) /* X-major line */ sense = (cp > 0.0f) ? aaEdgeSenseTop : aaEdgeSenseBottom; else /* Y-major line */ sense = (cp > 0.0f) ? aaEdgeSenseRight : aaEdgeSenseLeft; } else { if (dx <= dy) /* X-major line */ sense = (cp < 0.0f) ? aaEdgeSenseTop : aaEdgeSenseBottom; else /* Y-major line */ sense = (cp < 0.0f) ? aaEdgeSenseLeft : aaEdgeSenseRight; } } /* v1(a), v2(b), a, b */ GR_SET_EXPECTED_SIZE(gc->state.vData.vSize << 2, 1); TRI_STRIP_BEGIN(kSetupStrip, 4, gc->state.vData.vSize, SSTCP_PKT3_BDDDDD); switch (sense) { case aaEdgeSenseTop: TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset)); v2x = FARRAY(b, gc->state.vData.vertexInfo.offset); TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4) + _GlideRoot.pool.f1); v2y = FARRAY(b, gc->state.vData.vertexInfo.offset+4) + _GlideRoot.pool.f1; break; case aaEdgeSenseLeft: TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset) - _GlideRoot.pool.f1); v2x = FARRAY(b, gc->state.vData.vertexInfo.offset) - _GlideRoot.pool.f1; TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4)); v2y = FARRAY(b, gc->state.vData.vertexInfo.offset+4); break; case aaEdgeSenseBottom: TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset)); v2x = FARRAY(b, gc->state.vData.vertexInfo.offset); TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4) - _GlideRoot.pool.f1); v2y = FARRAY(b, gc->state.vData.vertexInfo.offset+4) - _GlideRoot.pool.f1; break; case aaEdgeSenseRight: TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset) + _GlideRoot.pool.f1); v2x = FARRAY(b, gc->state.vData.vertexInfo.offset) + _GlideRoot.pool.f1; TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4)); v2y = FARRAY(b, gc->state.vData.vertexInfo.offset+4); break; } if (gc->state.vData.colorType == GR_FLOAT) { ia = gc->state.vData.aInfo.offset; v1a = v2a = 0.f; } else { ia = gc->state.vData.pargbInfo.offset; *((FxU32 *)&v1a)=*((FxU32 *)((int)a + ia))&0x00ffffff; *((FxU32 *)&v2a)=*((FxU32 *)((int)b + ia))&0x00ffffff; } { FxU32 i, dataElem; dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v1a); } else { TRI_SETF(FARRAY(a, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } TRI_SETF(v2x); dataElem = 0; TRI_SETF(v2y); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { if (i == ia) { TRI_SETF(v2a); } else { TRI_SETF(FARRAY(b, i)); } dataElem++; i = gc->tsuDataList[dataElem]; } dataElem = 0; TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } dataElem = 0; TRI_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset)); TRI_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset+4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(b, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } gc->stats.othertrisDrawn+=2; TRI_END; GR_CHECK_SIZE(); #endif #undef FN_NAME } /* aaCalcEdgeSense */ /*------------------------------------------------------------------- Function: _grAADrawTriangles Date: 13-Oct-97 Implementor(s): atai Description: Draw anti-alias triangles Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grAADrawTriangles(FxI32 mode, FxI32 ttype, FxI32 count, void *pointers) { #define FN_NAME "_grAADrawTriangles" GR_DCL_GC; float **lPtr = (float **)pointers; FxI32 tCount = 3; FxU32 fbzModeOld; /* Squirrel away current fbzMode */ FxI32 stride = mode; FxI32 xindex = (gc->state.vData.vertexInfo.offset >> 2); FxI32 yindex = xindex + 1; GDBG_INFO(96, "_grAADrawTriangles (count = %d, pointers = 0x%x)\n", count, pointers); GR_FLUSH_STATE(); if (ttype == GR_TRIANGLES) (*gc->archDispatchProcs.drawTrianglesProc)(mode, count, pointers); fbzModeOld = gc->state.shadow.fbzMode; gc->state.shadow.fbzMode &= ~(SST_ZAWRMASK); /* gc->state.invalid |= fbzModeBIT; */ GR_FLUSH_STATE(); if (stride == 0) stride = gc->state.vData.vStride; /* backfaced or zero area */ while (tCount <= count) { float *a, *b, *c; GR_BEGIN_NOFIFOCHECK("_grAADrawTri",96); a = pointers; b = (float *)pointers + stride; c = b + stride; if (mode) { a = *(float **)a; b = *(float **)b; c = *(float **)c; } (float *)pointers += stride*3; /* move culling test to here */ { float *fa = a; float *fb = b; float *fc = c; float dxAB, dxBC, dyAB, dyBC; /* ** Sort the vertices. ** Whenever the radial order is reversed (from counter-clockwise to ** clockwise), we need to change the area of the triangle. Note ** that we know the first two elements are X & Y by looking at the ** grVertex structure. */ { int ay = *(int *)&a[(gc->state.vData.vertexInfo.offset>>2)+1]; int by = *(int *)&b[(gc->state.vData.vertexInfo.offset>>2)+1]; int cy = *(int *)&c[(gc->state.vData.vertexInfo.offset>>2)+1]; int culltest = gc->state.cull_mode; if (ay < 0) ay ^= 0x7FFFFFFF; if (by < 0) by ^= 0x7FFFFFFF; if (cy < 0) cy ^= 0x7FFFFFFF; if (ay < by) { if (by > cy) { /* acb */ if (ay < cy) { fa = a; fb = c; fc = b; culltest ^= 1; } else { /* cab */ fa = c; fb = a; fc = b; } /* else it's already sorted */ } } else { if (by < cy) { /* bac */ if (ay < cy) { fa = b; fb = a; fc = c; culltest ^= 1; } else { /* bca */ fa = b; fb = c; fc = a; } } else { /* cba */ fa = c; fb = b; fc = a; culltest ^= 1; } } /* Compute Area */ dxAB = fa[xindex] - fb[xindex]; dxBC = fb[xindex] - fc[xindex]; dyAB = fa[yindex] - fb[yindex]; dyBC = fb[yindex] - fc[yindex]; /* Stash the area in the float pool for easy access */ gc->pool.ftemp1 = dxAB * dyBC - dxBC * dyAB; #define FloatVal(__f) (((__f) < 786432.875) ? (__f) : ((__f) - 786432.875)) { const FxI32 j = *(FxI32*)&gc->pool.ftemp1; /* Zero-area triangles are BAD!! */ if ((j & 0x7FFFFFFF) == 0) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", FloatVal(fa[xindex]), FloatVal(fa[yindex]), FloatVal(fb[xindex]), FloatVal(fb[yindex]), FloatVal(fc[xindex]), FloatVal(fc[yindex]), gc->pool.ftemp1, gc->state.cull_mode, culltest); goto done; } /* Backface culling, use sign bit as test */ if ((gc->state.cull_mode != GR_CULL_DISABLE) && ((j ^ (culltest << 31)) >= 0)) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", FloatVal(fa[xindex]), FloatVal(fa[yindex]), FloatVal(fb[xindex]), FloatVal(fb[yindex]), FloatVal(fc[xindex]), FloatVal(fc[yindex]), gc->pool.ftemp1, gc->state.cull_mode, culltest); goto done; } } } } /* end culling test */ aaDrawArrayEdgeSense(a, b, c); aaDrawArrayEdgeSense(b, c, a); aaDrawArrayEdgeSense(c, a, b); done: lPtr += 3; tCount+=3; gc->stats.trisProcessed++; } gc->state.shadow.fbzMode = fbzModeOld; gc->state.invalid |= fbzModeBIT; GR_FLUSH_STATE(); #undef FN_NAME } /* _grAADrawTriangles */ /*------------------------------------------------------------------- Function: _grAAVpDrawTriangles Date: 11-Dec-97 Implementor(s): atai Description: Draw anti-alias triangles (clip coords) Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grAAVpDrawTriangles(FxI32 mode, FxI32 ttype, FxI32 count, void *pointers) { #define FN_NAME "_grAAVpDrawTriangles" GR_DCL_GC; float **lPtr = (float **)pointers; FxI32 tCount = 3; FxU32 fbzModeOld; /* Squirrel away current fbzMode */ FxI32 stride = mode; FxI32 xindex = (gc->state.vData.vertexInfo.offset >> 2); FxI32 yindex = xindex + 1; GDBG_INFO(96, "_grAADrawTriangles (count = %d, pointers = 0x%x)\n", count, pointers); GR_FLUSH_STATE(); if (ttype == GR_TRIANGLES) (*gc->archDispatchProcs.drawTrianglesProc)(mode, count, pointers); fbzModeOld = gc->state.shadow.fbzMode; gc->state.shadow.fbzMode &= ~(SST_ZAWRMASK); /* gc->state.invalid |= fbzModeBIT; */ GR_FLUSH_STATE(); if (stride == 0) stride = gc->state.vData.vStride; /* backfaced or zero area */ while (tCount <= count) { float *a, *b, *c; float oowa, oowb, oowc; GR_BEGIN_NOFIFOCHECK("_grAADrawTri",96); a = pointers; b = (float *)pointers + 1; c = (float *)pointers + 2; if (mode) { a = *(float **)a; b = *(float **)b; c = *(float **)c; } (float *)pointers += stride*3; oowa = 1.0f / FARRAY(a, gc->state.vData.wInfo.offset); oowb = 1.0f / FARRAY(b, gc->state.vData.wInfo.offset); oowc = 1.0f / FARRAY(c, gc->state.vData.wInfo.offset); /* move culling test to here */ { float *fa = a; float *fb = b; float *fc = c; float dxAB, dxBC, dyAB, dyBC; /* ** Sort the vertices. ** Whenever the radial order is reversed (from counter-clockwise to ** clockwise), we need to change the area of the triangle. Note ** that we know the first two elements are X & Y by looking at the ** grVertex structure. */ { float fay = a[yindex]*oowa*gc->state.Viewport.hheight*gc->state.Viewport.oy; float fby = b[yindex]*oowb*gc->state.Viewport.hheight*gc->state.Viewport.oy; float fcy = c[yindex]*oowc*gc->state.Viewport.hheight*gc->state.Viewport.oy; int ay = *(int *)&fay; int by = *(int *)&fby; int cy = *(int *)ф int culltest = gc->state.cull_mode; if (ay < 0) ay ^= 0x7FFFFFFF; if (by < 0) by ^= 0x7FFFFFFF; if (cy < 0) cy ^= 0x7FFFFFFF; if (ay < by) { if (by > cy) { /* acb */ if (ay < cy) { fa = a; fb = c; fc = b; culltest ^= 1; } else { /* cab */ fa = c; fb = a; fc = b; } /* else it's already sorted */ } } else { if (by < cy) { /* bac */ if (ay < cy) { fa = b; fb = a; fc = c; culltest ^= 1; } else { /* bca */ fa = b; fb = c; fc = a; } } else { /* cba */ fa = c; fb = b; fc = a; culltest ^= 1; } } /* Compute Area */ dxAB = fa[xindex] - fb[xindex]; dxBC = fb[xindex] - fc[xindex]; dyAB = fa[yindex] - fb[yindex]; dyBC = fb[yindex] - fc[yindex]; /* Stash the area in the float pool for easy access */ gc->pool.ftemp1 = dxAB * dyBC - dxBC * dyAB; #define FloatVal(__f) (((__f) < 786432.875) ? (__f) : ((__f) - 786432.875)) { const FxI32 j = *(FxI32*)&gc->pool.ftemp1; /* Zero-area triangles are BAD!! */ if ((j & 0x7FFFFFFF) == 0) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", FloatVal(fa[xindex]), FloatVal(fa[yindex]), FloatVal(fb[xindex]), FloatVal(fb[yindex]), FloatVal(fc[xindex]), FloatVal(fc[yindex]), gc->pool.ftemp1, gc->state.cull_mode, culltest); goto done; } /* Backface culling, use sign bit as test */ if ((gc->state.cull_mode != GR_CULL_DISABLE) && ((j ^ (culltest << 31)) >= 0)) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", FloatVal(fa[xindex]), FloatVal(fa[yindex]), FloatVal(fb[xindex]), FloatVal(fb[yindex]), FloatVal(fc[xindex]), FloatVal(fc[yindex]), gc->pool.ftemp1, gc->state.cull_mode, culltest); goto done; } } } } /* end culling test */ aaVpDrawArrayEdgeSense(a, b, c, oowa, oowb); aaVpDrawArrayEdgeSense(b, c, a, oowb, oowc); aaVpDrawArrayEdgeSense(c, a, b, oowc, oowa); done: lPtr += 3; tCount+=3; gc->stats.trisProcessed++; } gc->state.shadow.fbzMode = fbzModeOld; gc->state.invalid |= fbzModeBIT; GR_FLUSH_STATE(); #undef FN_NAME } /* _grAAVpDrawTriangles */ /*------------------------------------------------------------------- Function: _grAADrawVertexList Date: 14-Oct-97 Implementor(s): atai Description: Sends an aa triangle strip/fan to CVG. Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grAADrawVertexList(FxU32 type, FxI32 mode, FxI32 count, void *pointers) { #define FN_NAME "_grAADrawVertexList" GR_DCL_GC; FxU32 sCount = count; float *v[3]; FxBool flip = FXFALSE; FxU32 fbzModeOld; /* Squirrel away current fbzMode */ FxI32 stride = mode; if (sCount <= 2) return; GR_FLUSH_STATE(); (*gc->archDispatchProcs.drawVertexList)(SSTCP_PKT3_BDDDDD, type, mode, count, pointers); fbzModeOld = gc->state.shadow.fbzMode; gc->state.shadow.fbzMode &= ~(SST_ZAWRMASK); /* gc->state.invalid |= fbzModeBIT; */ GR_FLUSH_STATE(); if (stride == 0) stride = gc->state.vData.vStride; sCount-=2; if (type == kSetupFan) { v[0] = (mode == 0) ? pointers : *(float **)pointers; while (sCount--) { (float *)pointers += stride; if (mode) { v[1] = *(float **)pointers; v[2] = *((float **)pointers+1); } else { v[1] = pointers; v[2] = (float *)pointers+stride; } if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) _grAADrawTriangles(1, type, 3, v); else _grAAVpDrawTriangles(1, type, 3, v); } } else if (type == kSetupStrip){ while (sCount--) { if (flip) { if (mode) { v[0] = *((float **)pointers+1); v[1] = *(float **)pointers; v[2] = *((float **)pointers+2); } else { v[0] = (float *)pointers+stride; v[1] = pointers; v[2] = (float *)pointers+(stride<<1); } } else { if (mode) { v[0] = *(float **)pointers; v[1] = *((float **)pointers+1); v[2] = *((float **)pointers+2); } else { v[0] = pointers; v[1] = (float *)pointers+stride; v[2] = (float *)pointers+(stride<<1); } } if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) _grAADrawTriangles(1, type, 3, v); else _grAAVpDrawTriangles(1, type, 3, v); (float *)pointers += stride; flip = ~flip; } flip = ~flip; } gc->state.shadow.fbzMode = fbzModeOld; gc->state.invalid |= fbzModeBIT; GR_FLUSH_STATE(); #undef FN_NAME } /* _grAADrawVertexList */ glide3x/h5/glide3/src/gbanner.c0100700000175300010010000003071707725034667015570 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gbanner.c,v 1.3.4.6 2003/07/29 10:04:32 dborca Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 8 2/19/99 8:03p Peter ** new splash ** ** 7 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 6 7/16/98 8:17a Jdt ** fxcmd.h ** ** 5 5/29/98 11:45a Atai ** 1.added _EXT for extension #defines. ** 2. change GR_TEXBASE_* values ** 3. Remove GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB ** ** 3 2/05/98 2:30p Atai ** fixed bug#1222. ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 17 1/05/98 6:06p Atai * glide extension stuff * * 16 12/15/97 5:52p Atai * disable obsolete glide2 api for glide3 * * 15 11/18/97 4:36p Peter * make thing more translucent * * 14 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 13 7/26/97 3:04p Peter * gratuitous plug is translucent * * 12 7/08/97 2:48p Peter * shameless plug just uses lfb routines * * 11 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 10 5/21/97 6:05a Peter * * 9 5/02/97 2:08p Pgj * screen_width/height now FxU32 * * 8 3/16/97 2:24a Jdt * Fixed bug. Didn't initialize info. * * 7 3/12/97 11:51p Jdt * Watcom warning. * * 6 3/12/97 4:20p Jdt * Fixed for VG96 and optimized SST-1 * * 5 2/26/97 11:55a Jdt * Updated banner for new lfb api * * 4 12/23/96 1:37p Dow * chagnes for multiplatform glide ** */ #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" void _grShamelessPlug(void) { GR_BEGIN_NOFIFOCHECK("_grShamelessPlug", 80); GDBG_INFO_MORE(gc->myLevel, "()\n"); if (gc->pluginInfo.plugProc != NULL) { FxU32 plugWidth, plugHeight, plugStride; GrLfbWriteMode_t plugFormat; const void* plugData = (*gc->pluginInfo.plugProc)(&plugWidth, &plugHeight, &plugStride, &plugFormat); if (plugData != NULL) { #ifdef GLIDE_PLUG GrState state; grGlideGetState(&state); grDisableAllEffects(); grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE, FXFALSE); grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE); grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ZERO, GR_BLEND_ZERO); grClipWindow(0, 0, gc->state.screen_width - 1, gc->state.screen_height - 1); grDepthMask(FXFALSE); grDepthBufferFunction(GR_CMP_ALWAYS); grDepthBufferMode(GR_DEPTHBUFFER_DISABLE); grChromakeyValue(0x0000); grChromakeyMode(GR_CHROMAKEY_ENABLE); grLfbConstantAlpha((FxU8) 0x40); grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); _grLfbWriteRegion(FXTRUE, GR_BUFFER_BACKBUFFER, gc->state.screen_width - (plugWidth + 1), gc->state.screen_height - (plugHeight + 1), GR_LFBWRITEMODE_565, plugWidth, plugHeight, plugStride, plugData); grGlideSetState(&state); #endif /* GLIDE_PLUG */ } } GR_END(); } /* _grShamelessPlug */ #if !(GLIDE_PLATFORM & GLIDE_OS_WIN32) #if GLIDE_PLUG #if GLIDE_PLUG_EXT static FxU32 fxPlugWidth; static FxU32 fxPlugHeight; static FxU32 fxPlugStride; #else #include "banner.inc" #endif static GrLfbWriteMode_t fxPlugFormat = GR_LFBWRITEMODE_565; static FxU16 *fxPlugData; #endif /* GLIDE_PLUG */ void fxSplashShutdown (void) { #if GLIDE_PLUG if (fxPlugData != NULL) { free(fxPlugData); fxPlugData = NULL; } #endif } FxBool fxSplashInit (FxU32 hWnd, FxU32 screenWidth, FxU32 screenHeight, FxU32 numColBuf, FxU32 numAuxBuf, GrColorFormat_t colorFormat) { #if GLIDE_PLUG if (fxPlugData == NULL) { #if GLIDE_PLUG_EXT /* [dBorca] * we should try to extract TGA resource from 3dfxspl3.dll */ FILE *f; if ((f = fopen("3dfxplug.tga", "rb")) != NULL) { int bpp, skip; int i, j, decoded; unsigned char header[18], b1[4], b0; /* read TGA header */ if (!fread(header, 18, 1, f)) { fclose(f); return FXFALSE; } /* fill in values */ fxPlugWidth = ((unsigned short *)header)[6]; fxPlugHeight = ((unsigned short *)header)[7]; fxPlugStride = fxPlugWidth * 2; /* compute bits/pixel, then bytes/pixel; also check TGA type */ bpp = header[16]; if (((bpp != 16) && (bpp != 24) && (bpp != 32)) || ((header[2] & ~0x8) != 2)) { fclose(f); return FXFALSE; } bpp >>= 3; /* skip colormap + junk */ skip = header[0]; if (header[1]) { skip += *(unsigned short *)&header[5] * header[7] >> 3; } fseek(f, skip, SEEK_CUR); /* allocate datablock */ if ((fxPlugData = malloc(fxPlugStride * fxPlugHeight)) == NULL) { fclose(f); return FXFALSE; } if (header[2] == 10) { /* RLE */ j = 0; while (j < (fxPlugWidth * fxPlugHeight)) { /* packet header */ if (!fread(&b0, 1, 1, f)) { fxSplashShutdown(); fclose(f); return FXFALSE; } if (b0 & 0x80) { /* replicate pixels */ b0 &= 0x7f; if (!fread(b1, bpp, 1, f)) { fxSplashShutdown(); fclose(f); return FXFALSE; } switch (bpp) { case 2: decoded = *(unsigned short *)&b1[0]; decoded = ((decoded & 0x7fe0) << 1) | ((decoded & 0x0200) >> 4) | (decoded & 0x001f); break; case 3: case 4: decoded = (b1[0]>>3) + ((b1[1]>>2)<<5) + ((b1[2]>>3)<<11); break; } for (i = 0; i <= b0; i++) { fxPlugData[j++] = decoded; } } else { /* read pixels */ for (i = 0; i <= b0; i++) { if (!fread(b1, bpp, 1, f)) { fxSplashShutdown(); fclose(f); return FXFALSE; } switch (bpp) { case 2: decoded = *(unsigned short *)&b1[0]; decoded = ((decoded & 0x7fe0) << 1) | ((decoded & 0x0200) >> 4) | (decoded & 0x001f); break; case 3: case 4: decoded = (b1[0]>>3) + ((b1[1]>>2)<<5) + ((b1[2]>>3)<<11); break; } fxPlugData[j++] = decoded; } } } /* flip (RLE can cross scanlines, thus we can't use tricks) */ if (!(header[17] & 0x20)) { for (i = 0; i < fxPlugHeight / 2; i++) { unsigned short *src = &fxPlugData[fxPlugWidth * i]; unsigned short *dst = &fxPlugData[fxPlugWidth * (fxPlugHeight - i - 1)]; for (j = 0; j < fxPlugWidth; j++) { decoded = dst[j]; dst[j] = src[j]; src[j] = decoded; } } } } else if (header[2] == 2) { /* normal (flip on-the-fly) */ for (i = 0; i < fxPlugHeight; i++) { int l = (header[17] & 0x20) ? i : (fxPlugHeight-i-1); unsigned short *line = &fxPlugData[fxPlugWidth * l]; for (j = 0; j < fxPlugWidth; j++) { if (!fread(b1, bpp, 1, f)) { fxSplashShutdown(); fclose(f); return FXFALSE; } switch (bpp) { case 2: decoded = *(unsigned short *)&b1[0]; decoded = ((decoded & 0x7fe0) << 1) | ((decoded & 0x0200) >> 4) | (decoded & 0x001f); break; case 3: case 4: decoded = (b1[0]>>3) + ((b1[1]>>2)<<5) + ((b1[2]>>3)<<11); break; } line[j] = decoded; } } } fclose(f); } #else /* GLIDE_PLUG_EXT */ /* [dBorca] * embedded image is always 16bit RLE and does not need to be flipped */ int k = 0; int i, j, decoded; unsigned char b0; /* allocate datablock */ if ((fxPlugData = malloc(fxPlugStride * fxPlugHeight)) == NULL) { return FXFALSE; } /* RLE */ j = 0; while (j < (fxPlugWidth * fxPlugHeight)) { /* packet header */ b0 = tga_16rle[k++]; if (b0 & 0x80) { /* replicate pixels */ b0 &= 0x7f; decoded = *(unsigned short *)&tga_16rle[k]; k += 2; for (i = 0; i <= b0; i++) { fxPlugData[j++] = decoded; } } else { /* read pixels */ for (i = 0; i <= b0; i++) { decoded = *(unsigned short *)&tga_16rle[k]; k += 2; fxPlugData[j++] = decoded; } } } #endif /* GLIDE_PLUG_EXT */ } return FXTRUE; #else /* GLIDE_PLUG */ return FXFALSE; #endif /* GLIDE_PLUG */ } const void *fxSplashPlug (FxU32* w, FxU32* h, FxI32* strideInBytes, GrLfbWriteMode_t* format) { #if GLIDE_PLUG *w = fxPlugWidth; *h = fxPlugHeight; *strideInBytes = fxPlugStride; *format = fxPlugFormat; return fxPlugData; #else return NULL; #endif } void fxSplash (float x, float y, float w, float h, FxU32 frameNumber) { } #endif /* (GLIDE_PLATFORM & GLIDE_OS_WIN32) */ glide3x/h5/glide3/src/gdraw.c0100700000175300010010000010744307725034667015261 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gdraw.c,v 1.3.4.6 2003/08/04 12:45:47 dborca Exp $ ** $Log: ** 11 3dfx 1.5.1.2.1.1 10/11/00 Brent Forced check in to enforce ** branching. ** 10 3dfx 1.5.1.2.1.0 07/10/00 troy thornton changed grDrawPoints to ** draw points in FSAA ** 9 3dfx 1.5.1.2 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 8 3dfx 1.5.1.1 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 7 3dfx 1.5.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 6 3dfx 1.5 03/26/00 Don Mullis Non-floating point data ** loaded to the floating point unit may upon re-emerging appear somewhat the ** worse for the experience. ** ** 5 3dfx 1.4 11/08/99 Larry warner Changes to enable building ** with MSVC 6. ** 4 3dfx 1.3 11/02/99 Larry warner Clean up some debug code to ** make MSVC 6 happy. ** 3 3dfx 1.2 10/08/99 Anthony tai fixed grdrawpoint for ** napalm csim ** 2 3dfx 1.1 09/14/99 Anthony tai workaround csim bias ** snapping for points ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 36 9/10/99 2:16p Atai ** workaround csim bias snapping for points ** ** 35 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 34 6/03/99 12:15p Kcd ** Inline assembly with CodeWarrior isn't working out, so grDrawTriangle is don ** totally in assembly in another file. ** ** 33 5/26/99 4:17p Kcd ** Fix portability problem for PPC systems. ** ** 32 4/24/99 11:19a Atai ** check if we have valid gc and lostcontext pointer ** ** 31 4/22/99 3:53p Dow ** Alt-Tab on NT ** ** 30 4/16/99 2:48p Kcd ** Hack to allow different SETF macro, SETF_FIFO fixes. ** ** 29 1/06/99 11:30a Peter ** cleanup trinalge dispatch code ** ** 28 1/05/99 4:27p Peter ** first pass at fixing inline asssembly for triangle dispatch. ** ** 27 10/16/98 1:24p Peter ** c trisetup fixes ** ** 26 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 25 9/24/98 11:17a Dow ** AMD 3DNow! (tm) mods ** ** 24 9/08/98 6:05p Atai ** fixed clip coords line routine ** ** 23 8/31/98 10:33a Peter ** asm w/ debugging ** ** 22 8/30/98 1:34p Dow ** State & other optimizations ** ** 21 7/01/98 8:40a Jdt ** removed gc arg from trisetup funcs ** ** 20 8/03/98 6:40a Jdt ** We now pass GC on the stack to trisetup functions, moved ftemp, stats ** into gc from old global location. ** ** 19 7/18/98 12:26a Jdt ** Removed ColorCombineDelta0 Mode. ** ** 18 7/16/98 8:17a Jdt ** fxcmd.h ** ** 17 6/19/98 1:00p Atai ** fixed tri stats ** ** 16 6/18/98 6:38p Atai ** fixed line routine for grDrawVertexArrayContiguous ** ** 15 6/11/98 6:04p Atai ** added aa case for OGL ** ** 14 6/09/98 2:34p Peter ** point happiness ** ** 13 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 12 5/29/98 2:09p Atai ** remove polygon code ** ** 11 5/19/98 1:04p Peter ** point fun ** ** 9 2/24/98 6:00p Atai ** use 0 offset for vertex data ** ** 8 2/11/98 7:04p Atai ** added grDrawTriangle setup code ** ** 7 2/09/98 6:19p Atai ** fix clip space poiint debug assertion ** ** 6 1/30/98 10:08a Atai ** fixed clip space drawtriangle routine ** ** 5 1/26/98 11:30a Atai ** update to new glide.h ** ** 4 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 3 1/19/98 1:38p Atai ** fixed _grDrawLineStrip zero length lline ** ** 2 1/18/98 12:03p Atai ** sync to rev 17 spec * * 1 1/16/98 4:29p Atai * create glide 3 src * * 92 1/15/98 2:46p Atai * fixed grDrawPoint and grDrawLine in aa mode * * 90 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 89 12/15/97 5:52p Atai * disable obsolete glide2 api for glide3 * * 85 12/08/97 12:06p Atai * change prototype for grDrawPoint, grDrawLine, grDrawTriangel * * 83 11/21/97 6:05p Atai * use one datalist (tsuDataList) in glide3 * * 82 11/21/97 3:20p Peter * direct writes tsu registers * * 81 11/19/97 4:33p Atai * make vSize debug variable * * 80 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 79 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 78 11/16/97 2:20p Peter * cleanup * * 77 11/15/97 7:43p Peter * more comdex silliness * ** */ #if SET_BSWAP #define SLOW_SETF 1 #endif #include #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #include "fxinline.h" #ifdef GLIDE_DEBUG #include #endif /* GLIDE_DEBUG */ #define SST_XY_HALF (1 << (SST_XY_FRACBITS - 1)) #define SST_XY_ONE (1 << SST_XY_FRACBITS) #define OUTBOUNDSX(a) ((a->x < 0.f ? 1 : 0) || (a->x > gc->state.screen_width ? 1 : 0)) #define OUTBOUNDSY(a) ((a->y < 0.f ? 1 : 0) || (a->y > gc->state.screen_height ? 1 : 0)) #define OUTBOUNDS(a) (OUTBOUNDSX(a) || OUTBOUNDSY(a)) /* access an array of four-byte opaque datums with a byte index */ #define ARRAY(p,i) (*(int *)((i)+(int)(p))) /*--------------------------------------------------------------------------- ** grDrawPoint */ GR_ENTRY(grDrawPoint, void, (const void *p)) { #define FN_NAME "grDrawPoint" GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(p = 0x%x)\n", p); #ifdef __GNUC__ if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_POINTS_MASK) _grAADrawPoints(GR_VTX_PTR_ARRAY, 1, (void *)&p); else _grDrawPoints(GR_VTX_PTR_ARRAY, 1, (void *)&p); #else if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_POINTS_MASK) _grAADrawPoints(GR_VTX_PTR_ARRAY, 1, &(void *)p); else _grDrawPoints(GR_VTX_PTR_ARRAY, 1, &(void *)p); #endif #undef FN_NAME } /* grDrawPoint */ /*--------------------------------------------------------------------------- ** grDrawLine ** ** NOTE: 1. this will not fill the last pixel in line because ** B2 or C is on the right edge and the right edge is not ** drawn. ** (0,0) ** ** A(x1,y1-0.5)+ ** | \ ** | \ \ ** (x1,y1)* \ ** | * \ ** | *\ \ ** B1(x1,y1+0.5)+ * \ ** \ \ * +B2(x2,y2-0.5) ** \ * | ** \ \ * | ** \ \ + (x2,y2) ** \ | ** \ | ** +C(x2,y2+0.5) */ GR_ENTRY(grDrawLine, void, (const void *a, const void *b)) { #define FN_NAME "grDrawLine" GR_BEGIN_NOFIFOCHECK(FN_NAME, 91); GDBG_INFO_MORE(gc->myLevel, "(a = 0x%x, b = 0x%x)\n", a, b); #if __POWERPC__ { const void *verts[2]; verts[0] = a; verts[1] = b; if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, 2, verts); else _grDrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, 2, verts); } #else #ifdef __GNUC__ if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, 2, (void *)&a); else _grDrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, 2, (void *)&a); #else /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) */ if (gc->state.grEnableArgs.primitive_smooth_mode & GR_AA_ORDERED_LINES_MASK) _grAADrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, 2, &(void *)a); else _grDrawLineStrip(GR_VTX_PTR_ARRAY, GR_LINES, 2, &(void *)a); #endif /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) */ #endif #undef FN_NAME } /* grDrawLine */ /*--------------------------------------------------------------------------- ** grDrawTriangle */ #if !defined(__POWERPC__) || GLIDE_USE_C_TRISETUP #if !defined(GLIDE_DEBUG) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) #if !(GLIDE_USE_C_TRISETUP) __declspec( naked ) #endif #endif /* !defined(GLIDE_DEBUG) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) */ GR_ENTRY(grDrawTriangle, void, (const void *a, const void *b, const void *c)) { #define FN_NAME "grDrawTriangle" GR_CHECK_F(FN_NAME, !a || !b || !c, "NULL pointer passed"); #if GLIDE_USE_C_TRISETUP || GLIDE_DEBUG { #if GLIDE_DEBUG GR_DCL_GC; GR_DCL_HW; #else /* GLIDE_DEBUG */ //GR_BEGIN_NOFIFOCHECK("grDrawTriangle",92); GR_BEGIN_NOFIFOCHECK_NORET("grDrawTriangle",92); #endif /* GLIDE_DEBUG */ GDBG_INFO_MORE(gc->myLevel,"(0x%x,0x%x,0x%x)\n",a,b,c); TRISETUP(a, b, c ); #if GLIDE_DEBUG /* HackAlert: Nuke the fifo ptr checking stuff here if we're just * debugging the asm tri code. */ gc->checkPtr = (FxU32)gc->cmdTransportInfo.fifoPtr; gc->checkCounter = 0; #else /* GLIDE_DEBUG */ GR_END(); #endif /* GLIDE_DEBUG */ } #elif defined(__MSC__) { __asm { mov eax, DWORD PTR fs:[WNT_TEB_PTR] ; add eax, DWORD PTR _GlideRoot.tlsOffset; mov edx, [eax]; test edx, edx; je lostContext; mov eax, [edx + kLostContextOffset]; test eax, eax je lostContext; mov eax, [eax]; test eax, 1; jnz lostContext; mov eax, [edx + kTriProcOffset]; jmp eax; } lostContext: ; /* <-- my, that's odd, but MSVC was insistent */ } #elif (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) { GR_BEGIN_NOFIFOCHECK("grDrawTriangle",92); TRISETUP(a, b, c); GR_END(); } #else /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) */ #error "Write triangle proc dispatch for this compiler" #endif /* Triangle proc dispatch routine */ #undef FN_NAME } /* grDrawTriangle */ #endif #define DA_BEGIN \ { \ FxU32* packetPtr = gc->cmdTransportInfo.fifoPtr; \ FxU32 packetVal; #define DA_CONT(__setupMode, __params, __nVertex, __vertexSize, __cmd) \ packetVal = (((__setupMode) << SSTCP_PKT3_SMODE_SHIFT) | /* [27:22] */ \ (__params) | /* pack[28] params[21:10] */ \ ((__nVertex) << SSTCP_PKT3_NUMVERTEX_SHIFT) | /* [9:6] */ \ (__cmd) | /* command [5:3] */ \ SSTCP_PKT3); /* type [2:0] */ \ SET_FIFO(*packetPtr++, packetVal); #define DA_SETF(__val) \ SETF_FIFO(*packetPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxFloat)) #define DA_SET(__val) \ SET_FIFO(*packetPtr++, (__val)); \ GR_INC_SIZE(sizeof(FxU32)) #define DA_END \ gc->cmdTransportInfo.fifoRoom -= ((FxU32)packetPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); \ gc->cmdTransportInfo.fifoPtr = packetPtr; \ FIFO_ASSERT(); \ } /*------------------------------------------------------------------- Function: _grDrawPoints Date: 13-Oct-97 Implementor(s): atai Description: Draw array points Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grDrawPoints(FxI32 mode, FxI32 count, void *pointers) { #define FN_NAME "_grDrawPoints" #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP /* * the point routine is similar to grDrawPoint routine * except the data set up is from the pointer array and * its data layout */ FxI32 stride = mode; /* we snap to an integer by adding a large enough number that it * shoves all fraction bits off the right side of the mantissa. * * NB: IEEE rounds to nearest integer by default, but applications * can change the rounding mode so that it is difficult to get the * correct truncation/ceiling operation w/ a simple adjustment to * the bias so we do it all by hand treating the fp # as a * bucket-o-bits. * * NB: The constant kNumMantissaBits defines how many bits of * integer precision a coordinate can have. This needs to be atleast * as large as the maximum hw screen resolution. We later use this * to compute a logical 1 value to fill an entire pixel. */ #define kNumMantissaBits 12UL const float bias = (const float)(3UL << kNumMantissaBits); GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(count = %d, pointers = 0x%x)\n", count, pointers); GR_FLUSH_STATE(); /* * In the sbench example, we observe larger buffer, less fifo * size updating and less checking make the routine run faster. * Here we use a point buffer of size 100. We also remove the size * check outside the buffer loop */ #define POINTS_BUFFER 100 if (stride == 0) stride = gc->state.vData.vStride; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { #ifndef FX_GLIDE_H5_CSIM while (count > 0) { float *vPtr; FxI32 k, i; FxI32 vcount = count >= POINTS_BUFFER ? POINTS_BUFFER : count; GR_SET_EXPECTED_SIZE(((sizeof(FxU32) << 2) + gc->state.vData.vSize) * vcount, vcount << 1); /* begin points routine */ DA_BEGIN; for (k = 0; k < vcount; k++) { vPtr = pointers; if (mode) vPtr = *(float **)vPtr; (float *)pointers += stride; GDBG_INFO_MORE(gc->myLevel, "(%f %f)\n", FARRAY(vPtr,gc->state.vData.vertexInfo.offset), FARRAY(vPtr,gc->state.vData.vertexInfo.offset + 4)); { FxU32 x, y; FxU32 dataElem; DA_CONT(kSetupStrip | kSetupCullDisable, 0x00, 0x02, sizeof(FxU32) << 1, SSTCP_PKT3_BDDDDD); /* Convert to 32-bit representation */ gc->pool.ftemp1 = FARRAY(vPtr, gc->state.vData.vertexInfo.offset) + bias; gc->pool.ftemp2 = FARRAY(vPtr, gc->state.vData.vertexInfo.offset + 4) + bias; /* draw a little triangle, with the lower left corner at pixel center. */ /* The approach here is to split the triangle into two packets, one * that sends just the coordinates of the last two points of the * triangle w/ no other parameter information, and then the * centered point w/ all of the parameter information. The first * packet is has a BDD command, but is incomplete, so nothing * draws, the next packet has a DDD command so will complete the * triangle from the first packet sent. */ /* Mask off the real fractional bits from the mantissa */ x = ((*(FxU32*)&gc->pool.ftemp1 & (0xFFFFFFFFUL << (22UL - kNumMantissaBits))) + (0x01UL << (22UL - kNumMantissaBits))); y = ((*(FxU32*)&gc->pool.ftemp2 & (0xFFFFFFFFUL << (22UL - kNumMantissaBits))) + (0x01UL << (22UL - kNumMantissaBits))); /* Lower right corner */ DA_SET(x); DA_SET(y); /* Upper right corner */ y -= (0x01UL << (21UL - kNumMantissaBits)); DA_SET(x); dataElem = 0; DA_SET(y); /* Upper Left corner */ x -= (0x01UL << (21UL - kNumMantissaBits)); /* Packet w/ actual point coordinate and parameter data */ DA_CONT(kSetupStrip | kSetupCullDisable, gc->cmdTransportInfo.paramMask, 1, gc->state.vData.vSize, SSTCP_PKT3_DDDDDD); i = gc->tsuDataList[dataElem]; DA_SET(x); DA_SET(y); while (i != GR_DLIST_END) { DA_SET(ARRAY(vPtr, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } } DA_END; GR_CHECK_SIZE(); /* end points routine */ count -= POINTS_BUFFER; } #else while (count > 0) { float lbias = (float)( 3 << 22); float *vPtr; FxI32 k, i; FxI32 vcount = count >= POINTS_BUFFER ? POINTS_BUFFER : count; GR_SET_EXPECTED_SIZE((gc->state.vData.vSize << 2) * vcount, vcount); /* begin points routine */ DA_BEGIN; for (k = 0; k < vcount; k++) { vPtr = pointers; if (mode) vPtr = *(float **)vPtr; (float *)pointers += stride; GDBG_INFO_MORE(gc->myLevel, "(%f %f)\n", FARRAY(vPtr,gc->state.vData.vertexInfo.offset), FARRAY(vPtr,gc->state.vData.vertexInfo.offset + 4)); { volatile float x, y; FxU32 dataElem; DA_CONT(kSetupStrip | kSetupCullDisable, gc->cmdTransportInfo.paramMask, 4, -1/*NOT USED*//*gc->state.vData.vSize * 3*/, SSTCP_PKT3_BDDDDD); x = FARRAY(vPtr, gc->state.vData.vertexInfo.offset) + 0.5f; y = FARRAY(vPtr, gc->state.vData.vertexInfo.offset + 4) + 0.5f; x += lbias; y += lbias; /* Convert to 32-bit representation */ gc->pool.ftemp1 = (const float)x; gc->pool.ftemp2 = (const float)y; /* Correct the bias to get rid of the fractional bits */ x = /*(volatile float)*/gc->pool.ftemp1 - lbias; y = /*(volatile float)*/gc->pool.ftemp2 - lbias; /* Lower right corner */ DA_SETF(x); DA_SETF(y); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(vPtr, i)); GDBG_INFO_MORE( gc->myLevel, "value = %x\n", *(packetPtr-1)); // if color, format is BGRA if ((*(packetPtr-1)&0x00ff0000) >= 0x00800000) i&=0xfffff; dataElem++; i = gc->tsuDataList[dataElem]; } /* Upper right corner */ y -= 1.0f; DA_SETF(x); DA_SETF(y); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(vPtr, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* Lower left corner */ y += 1.0f; x -= 1.0f; DA_SETF(x); DA_SETF(y); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(vPtr, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* Upper leftcorner */ y += 1.0f; DA_SETF(x); DA_SETF(y); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(vPtr, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } } DA_END; GR_CHECK_SIZE(); /* end points routine */ count -= POINTS_BUFFER; } #endif } else { /* * first cut of clip space coordinate code. */ float oow; while (count > 0) { float lbias = (float)( 3 << 22); float *vPtr; FxI32 k; FxI32 vcount = count >= POINTS_BUFFER ? POINTS_BUFFER : count; GR_SET_EXPECTED_SIZE((gc->state.vData.vSize << 2) * vcount, vcount << 1); /* begin points routine */ DA_BEGIN; for (k = 0; k < vcount; k++) { vPtr = pointers; if (mode) vPtr = *(float **)vPtr; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset); (float *)pointers += stride; { float fx, fy; DA_CONT(kSetupStrip | kSetupCullDisable, 0x00, 0x03, sizeof(FxU32) << 1, SSTCP_PKT3_BDDDDD); /* Convert to 32-bit representation */ gc->pool.ftemp1 = (FARRAY(vPtr, gc->state.vData.vertexInfo.offset) * oow * gc->state.Viewport.hwidth + gc->state.Viewport.ox + 0.5f); gc->pool.ftemp2 = (FARRAY(vPtr, gc->state.vData.vertexInfo.offset + 4) * oow * gc->state.Viewport.hheight + gc->state.Viewport.oy + 0.5f); fx = gc->pool.ftemp1; fy = gc->pool.ftemp2; gc->pool.ftemp1 += lbias; gc->pool.ftemp2 += lbias; fx = gc->pool.ftemp1 - lbias; fy = gc->pool.ftemp2 - lbias; /* Lower right corner */ DA_SETF(fx); DA_SETF(fy); /* Upper right corner. */ fy -= 1.0f; DA_SETF(fx); DA_SETF(fy); /* Lower left corner */ fy += 1.0f; fx -= 1.0f; DA_SETF(fx); DA_SETF(fy); /* Packet w/ actual point coordinate and parameter data */ DA_CONT(kSetupStrip | kSetupCullDisable, gc->cmdTransportInfo.paramMask, 1, gc->state.vData.vSize, SSTCP_PKT3_DDDDDD); /*Upper left corner */ fy -= 1.0f; DA_SETF(fx); DA_SETF(fy); DA_VP_SETFS(vPtr, oow); } } DA_END; GR_CHECK_SIZE(); /* end points routine */ count -= POINTS_BUFFER; } } gc->stats.pointsDrawn+=count; gc->stats.othertrisDrawn+=(count<<1); #endif #undef FN_NAME } /* _grDrawPoints */ /*------------------------------------------------------------------- Function: _grDrawLineStrip Date: 13-Oct-97 Implementor(s): atai Description: Draw strip line Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grDrawLineStrip(FxI32 mode, FxI32 ltype, FxI32 count, void *pointers) { #define FN_NAME "_grDrawLineStrip" #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP /* * the line routine is similar to grDrawLine routine * except the data set up is from the pointer array and * its data layout */ int j; FxI32 sCount; FxU32 vertexParamOffset; FxI32 stride = mode; #define DX gc->pool.ftemp1 #define ADY gc->pool.ftemp2 GR_BEGIN_NOFIFOCHECK("_grDrawLineStrip", 91); GDBG_INFO_MORE(gc->myLevel, "(count = %d, pointers = 0x%x)\n", count, pointers); vertexParamOffset = gc->state.vData.vSize; GR_FLUSH_STATE(); #define LINES_BUFFER 100 if (stride == 0) stride = gc->state.vData.vStride; if (ltype == GR_LINES) sCount = count >> 1; /* line list */ else sCount = count-1; /* strip line */ if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { while (sCount > 0) { FxI32 k, i; FxI32 vcount = sCount >= LINES_BUFFER ? LINES_BUFFER : sCount; GR_SET_EXPECTED_SIZE((gc->state.vData.vSize << 2) * vcount, vcount); DA_BEGIN; for (k = 0; k < vcount; k++) { float *a = (float *)pointers; float *b = (float *)pointers + stride; if (mode) { a = *(float **)a; b = *(float **)b; } (float *)pointers += stride; if (ltype == GR_LINES) (float *)pointers += stride; /* ** compute absolute deltas and draw from low Y to high Y */ ADY = FARRAY(b, gc->state.vData.vertexInfo.offset+4) - FARRAY(a, gc->state.vData.vertexInfo.offset+4); i = *(long *)&ADY; if (i < 0) { float *tv; tv = a; a = b; b = tv; i ^= 0x80000000; /* ady = -ady; */ (*(long *)&ADY) = i; } DX = FARRAY(b, gc->state.vData.vertexInfo.offset) - FARRAY(a, gc->state.vData.vertexInfo.offset); j = *(long *)&DX; if (j < 0) { j ^= 0x80000000; /* adx = -adx; */ } /* check for zero-length lines */ if ((j >= i) && (j == 0)) { #ifdef GLIDE_DEBUG gc->expected_counter -= (gc->state.vData.vSize << 2 ); gc->checkCounter -= ((gc->state.vData.vSize+1) << 2 ); #endif goto all_done; } /* Draw the triangle pair as a strip of 4 vertices. * We can skip all of the gradient calculation stuff. * * NB: There are two cases, x/y major lines, and each of these * loops are unrolled to send one set of endpoints of the 'line' * per iteration since we can use the same bias per iteration. */ DA_CONT(kSetupCullDisable | kSetupStrip, gc->cmdTransportInfo.paramMask, 0x04UL, vertexParamOffset, SSTCP_PKT3_BDDDDD); { FxU32 dataElem; /* x major */ if (j >= i) { DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset)); dataElem = 0; DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset+4) - _GlideRoot.pool.fHalf); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(b, i)); dataElem++; i = gc->tsuDataList[dataElem]; } DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset)); dataElem = 0; DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4) - _GlideRoot.pool.fHalf); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset)); dataElem = 0; DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset+4) + _GlideRoot.pool.fHalf); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(b, i)); dataElem++; i = gc->tsuDataList[dataElem]; } DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset)); dataElem = 0; DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4) + _GlideRoot.pool.fHalf); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } else { /* y major */ DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset) - _GlideRoot.pool.fHalf); dataElem = 0; DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset+4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(b, i)); dataElem++; i = gc->tsuDataList[dataElem]; } DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset) - _GlideRoot.pool.fHalf); dataElem = 0; DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset) + _GlideRoot.pool.fHalf); dataElem = 0; DA_SETF(FARRAY(b, gc->state.vData.vertexInfo.offset+4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(b, i)); dataElem++; i = gc->tsuDataList[dataElem]; } DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset) + _GlideRoot.pool.fHalf); dataElem = 0; DA_SETF(FARRAY(a, gc->state.vData.vertexInfo.offset+4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { DA_SET(ARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } } gc->stats.linesDrawn++; gc->stats.othertrisDrawn+=2; all_done: ; } DA_END; GR_CHECK_SIZE(); sCount -= LINES_BUFFER; } } else { float oowa, oowb, owa, owb, tmp1, tmp2, fax, fay, fbx, fby; while (sCount > 0) { FxI32 k, i; FxI32 vcount = sCount >= LINES_BUFFER ? LINES_BUFFER : sCount; float *a,*b; GR_SET_EXPECTED_SIZE((gc->state.vData.vSize << 2) * vcount, vcount); DA_BEGIN; if (ltype == GR_LINE_STRIP) { a = (float *)pointers; if (mode) { a = *(float **)a; } oowb = 1.0f / FARRAY(a, gc->state.vData.wInfo.offset); } for (k = 0; k < vcount; k++) { if (ltype == GR_LINES) { a = (float *)pointers; b = (float *)pointers + stride; if (mode) { a = *(float **)a; b = *(float **)b; } (float *)pointers += stride; owa = oowa = 1.0f / FARRAY(a, gc->state.vData.wInfo.offset); owb = oowb = 1.0f / FARRAY(b, gc->state.vData.wInfo.offset); (float *)pointers += stride; } else { owa = oowa = oowb; a = (float *)pointers; b = (float *)pointers + stride; if (mode) { a = *(float **)a; b = *(float **)b; } (float *)pointers += stride; owb = oowb = 1.0f / FARRAY(b, gc->state.vData.wInfo.offset); } fay = tmp1 = FARRAY(a, gc->state.vData.vertexInfo.offset+4) *oowa*gc->state.Viewport.hheight+gc->state.Viewport.oy; fby = tmp2 = FARRAY(b, gc->state.vData.vertexInfo.offset+4) *oowb*gc->state.Viewport.hheight+gc->state.Viewport.oy; /* ** compute absolute deltas and draw from low Y to high Y */ ADY = tmp2 - tmp1; i = *(long *)&ADY; if (i < 0) { float *tv; owa = oowb; owb = oowa; fay = tmp2; fby = tmp1; tv = a; a = b; b = tv; i ^= 0x80000000; /* ady = -ady; */ (*(long *)&ADY) = i; } fax = FARRAY(a, gc->state.vData.vertexInfo.offset) *owa*gc->state.Viewport.hwidth+gc->state.Viewport.ox; fbx = FARRAY(b, gc->state.vData.vertexInfo.offset) *owb*gc->state.Viewport.hwidth+gc->state.Viewport.ox; DX = fbx - fax; j = *(long *)&DX; if (j < 0) { j ^= 0x80000000; /* adx = -adx; */ } /* check for zero-length lines */ if ((j >= i) && (j == 0)) goto all_done_vp; DA_CONT(kSetupCullDisable | kSetupStrip, gc->cmdTransportInfo.paramMask, 0x04UL, vertexParamOffset, SSTCP_PKT3_BDDDDD); { /* x major */ if (j >= i) { DA_SETF(fbx); DA_SETF(fby - _GlideRoot.pool.fHalf); DA_VP_SETFS(b,oowb); DA_SETF(fax); DA_SETF(fay - _GlideRoot.pool.fHalf); DA_VP_SETFS(a,oowa); DA_SETF(fbx); DA_SETF(fby + _GlideRoot.pool.fHalf); DA_VP_SETFS(b,oowb); DA_SETF(fax); DA_SETF(fay + _GlideRoot.pool.fHalf); DA_VP_SETFS(a,oowa); } else { /* y major */ DA_SETF(fbx - _GlideRoot.pool.fHalf); DA_SETF(fby); DA_VP_SETFS(b,oowb); DA_SETF(fax - _GlideRoot.pool.fHalf); DA_SETF(fay); DA_VP_SETFS(a,oowa); DA_SETF(fbx + _GlideRoot.pool.fHalf); DA_SETF(fby); DA_VP_SETFS(b,oowb); DA_SETF(fax + _GlideRoot.pool.fHalf); DA_SETF(fay); DA_VP_SETFS(a,oowa); } } gc->stats.linesDrawn++; gc->stats.othertrisDrawn+=2; all_done_vp: ; } DA_END; GR_CHECK_SIZE(); sCount -= LINES_BUFFER; } } #endif #undef FN_NAME } /* _grDrawLineStrip */ /*------------------------------------------------------------------- Function: _grDrawTriangles Date: 13-Oct-97 Implementor(s): atai Description: Draw triangles Arguments: mode - 0 if grDrawVertexArrayLinear 1 if grDrawVertexArray count - number of triangles. pointer - pointer to vertex data (mode = 0) or vertex array (mode = 1) Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grDrawTriangles_Default(FxI32 mode, FxI32 count, void *pointers) { #define FN_NAME "_grDrawTriangles_Default" #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP FxI32 k; FxI32 stride = mode; float *vPtr; GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(count = %d, pointers = 0x%x)\n", count, pointers); GR_FLUSH_STATE(); #ifdef GLIDE_DEBUG GDBG_INFO(110, "%s: paramMask = 0x%x\n", FN_NAME, gc->cmdTransportInfo.paramMask); #endif if (stride == 0) stride = gc->state.vData.vStride; gc->stats.trisProcessed+=(count/3); if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { while (count > 0) { FxI32 vcount = count >=15 ? 15 : count; GR_SET_EXPECTED_SIZE(vcount * gc->state.vData.vSize, 1); TRI_STRIP_BEGIN(kSetupStrip, vcount, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD); for (k = 0; k < vcount; k++) { FxI32 i; FxU32 dataElem = 0; vPtr = pointers; if (mode) vPtr = *(float **)vPtr; (float *)pointers += stride; i = gc->tsuDataList[dataElem]; TRI_SETF(FARRAY(vPtr, 0)); TRI_SETF(FARRAY(vPtr, 4)); while (i != GR_DLIST_END) { TRI_SET(ARRAY(vPtr, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } TRI_END; GR_CHECK_SIZE(); count -= 15; } } else { /* * first cut of clip space coordinate code, no optimization. */ float oow; while (count > 0) { FxI32 vcount = count >= 15 ? 15 : count; GR_SET_EXPECTED_SIZE(vcount * gc->state.vData.vSize, 1); TRI_STRIP_BEGIN(kSetupStrip, vcount, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD); for (k = 0; k < vcount; k++) { vPtr = pointers; if (mode) vPtr = *(float **)pointers; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset); /* x, y */ TRI_SETF(FARRAY(vPtr, 0) *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox); TRI_SETF(FARRAY(vPtr, 4) *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy); (float *)pointers += stride; TRI_VP_SETFS(vPtr,oow); } TRI_END; GR_CHECK_SIZE(); count -= 15; } } #endif #undef FN_NAME } /* _grDrawTriangles */ glide3x/h5/glide3/src/gerror.c0100700000175300010010000002041207725034670015435 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gerror.c,v 1.3.4.5 2003/07/25 07:13:41 dborca Exp $ ** $Log: ** 6 3dfx 1.1.1.2.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 5 3dfx 1.1.1.2 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 4 3dfx 1.1.1.1 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 3 3dfx 1.1.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 2 3dfx 1.1 11/23/99 Kenneth Dyke Improved Mac error ** handling. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 15 4/16/99 2:49p Kcd ** PowerPC fix. ** ** 14 4/15/99 5:33p Dow ** Fixed assert ** ** 13 4/05/99 8:25p Dow ** Alt tab mostly happy ** ** 12 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 11 3/19/99 11:26a Peter ** expose direct fifo for gl ** ** 10 3/02/99 2:04p Peter ** made error tracing output use consistent address bases for the fifo ** output ** ** 9 10/22/98 11:45a Atai ** be consistent with fatal error ** ** 8 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 7 7/16/98 8:17a Jdt ** fxcmd.h ** ** protected some direct hardware reads from TACO_MEMORY_FIFO_HACK ** ** 6 7/01/98 12:40p Jdt ** Changed grErrorWindowsCallback to grErrorDefault Callback, ** this removes some conditional compilation from grSstWinOpen ** ** 5 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 3 4/22/98 4:57p Peter ** glide2x merge ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 26 12/18/97 2:13p Peter * cleaned up the error code * * 25 12/09/97 12:20p Peter * mac glide port * * 24 12/05/97 4:38p Peter * sli vs assertions * * 23 12/03/97 11:34a Peter * dos debugging * * 22 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 21 11/15/97 8:55p Peter * Removed OutputDebugString * * 20 11/15/97 7:43p Peter * more comdex silliness * * 19 11/12/97 2:27p Peter * simulator happiness w/o fifo * * 18 11/12/97 11:16a Peter * cleaned up assertions * * 17 11/04/97 5:04p Peter * cataclysm part deux * * 16 11/03/97 4:02p Peter * cataclysm fix * * 15 11/03/97 3:43p Peter * h3/cvg cataclysm * * 14 10/23/97 5:28p Peter * sli fifo thing * * 13 9/24/97 1:29p Peter * more assertion spewage * * 12 9/05/97 5:29p Peter * changes for direct hw * * 11 5/30/97 5:44p Peter * Version that does basic triangles/registers w/ command fifo. Does not * currently download textures correctly. * * 10 5/28/97 9:05a Peter * Merge w/ latest glide changes * * 9 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 8 5/21/97 6:05a Peter * * 7 5/20/97 9:47a Pgj * Use OutputDebugString for non-fatal errors under windows * * 6 5/19/97 7:35p Pgj * Print cogent error message if h/w not found * * 5 3/09/97 10:31a Dow * Added GR_DIENTRY for di glide functions * * 4 12/23/96 1:37p Dow * chagnes for multiplatform glide ** */ #include #ifdef __DOS__ # include #endif #ifdef __WIN32__ # include #endif #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" void (*GrErrorCallback)( const char *string, FxBool fatal ); void _doGrErrorCallback( const char *name, const char *msg, FxBool fatal ) { char buf[1024]; #if GDBG_INFO_ON /* Stop any fifo checking from the failin * call. Otherwise entries into the shutdown * calls cause spurious crap. */ if (fatal) { GR_DCL_GC; gc->checkCounter = gc->expected_counter = 0; gc->checkCounter = gc->checkPtr = 0UL; } #endif /* GDBG_INFO_ON */ GDBG_PRINTF("%s: %s.\n", name, msg); sprintf(buf,"%s: %s.\n", name, msg); GrErrorCallback(buf, fatal); if (fatal) exit(1); } GR_DIENTRY(grErrorSetCallback, void, ( void (*function) ( const char *string, FxBool fatal ) )) { GDBG_INFO(80,"grErrorSetCallback(0x%x)\n",function); GrErrorCallback = function; } #ifdef __WIN32__ void _grErrorDefaultCallback( const char *s, FxBool fatal ) { if ( fatal ) { GDBG_ERROR("glide", s); grGlideShutdown(); MessageBox(NULL, s, NULL, MB_OK); exit(1); } } #else void _grErrorDefaultCallback( const char *s, FxBool fatal ) { if ( fatal ) { GDBG_ERROR("glide",s); grGlideShutdown(); #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) { //Str255 errBuf; //errBuf[0] = sprintf((char*)(errBuf + 1), "%s", s); //DebugStr(errBuf); ErrorMacCallback(s); ExitToShell(); } #endif /* (GLIDE_PLATFORM * GLIDE_OS_MACOS) */ } } #endif void _grAssert(char *exp, char *fileName, int lineNo) { static int depth; if (depth) return; depth++; #if GLIDE_INIT_HAL #else /* !GLIDE_INIT_HAL */ /* initRestoreVideo(); */ #endif /* !GLIDE_INIT_HAL */ GDBG_PRINTF("ASSERTION FAILED:\n"); GDBG_PRINTF("\tExpression: %s\n", exp); GDBG_PRINTF("\tFile: %s\n", fileName); GDBG_PRINTF("\tLine: %d\n", lineNo); #if USE_PACKET_FIFO /* Spew about the state of the fifo since that's what most of the * assertions are about anyway. */ { GR_DCL_GC; GR_DCL_HW; GDBG_PRINTF("Command Fifo:\n"); GDBG_PRINTF("\tSoftware:\n"); GDBG_PRINTF("\t\tfifoPtr: 0x%X\n", (FxU32)gc->cmdTransportInfo.fifoPtr - (FxU32) gc->rawLfb); GDBG_PRINTF("\t\tfifoOffset: 0x%X\n", gc->cmdTransportInfo.fifoOffset); GDBG_PRINTF("\t\tfifoEnd: 0x%X\n", gc->cmdTransportInfo.fifoEnd - gc->rawLfb); GDBG_PRINTF("\t\tfifoSize: 0x%X\n", gc->cmdTransportInfo.fifoSize); GDBG_PRINTF("\t\tfifoRoom: 0x%X\n", gc->cmdTransportInfo.fifoRoom); GDBG_PRINTF("\t\troomToReadPtr: 0x%X\n", gc->cmdTransportInfo.roomToReadPtr); GDBG_PRINTF("\t\troomToEnd: 0x%X\n", gc->cmdTransportInfo.roomToEnd); if ( !gc->windowed ) { GDBG_PRINTF("\tHardware:\n"); GDBG_PRINTF("\t\treadPtrL: 0x%X\n", HW_FIFO_PTR(FXTRUE) - (FxU32)gc->rawLfb); GDBG_PRINTF("\t\tdepth: 0x%X\n", GR_CAGP_GET(depth)); GDBG_PRINTF("\t\tholeCount: 0x%X\n", GR_CAGP_GET(holeCount)); GDBG_PRINTF("\t\tbaseAddrL: 0x%X\n", GR_CAGP_GET(baseAddrL)); GDBG_PRINTF("\t\taMin: 0x%X\n", GR_CAGP_GET(aMin)); GDBG_PRINTF("\t\taMax: 0x%X\n", GR_CAGP_GET(aMax)); gdbg_printf("\t\tStatus: 0x%X\n", GR_GET(hw->status)); } } #endif /* (GLIDE_PLATFORM & GLIDE_HW_CVG) && USE_PACKET_FIFO */ GDBG_PRINTF("ABNORMAL TERMINATION\n"); grGlideShutdown(); depth--; exit(-1); } /* _grAssert */ glide3x/h5/glide3/src/gglide.c0100700000175300010010000063210607725034670015401 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gglide.c,v 1.7.4.11 2003/08/26 18:03:41 koolsmoky Exp $ ** $Log: ** 51 3dfx 1.41.1.6.1.110/11/00 Brent Forced check in to enforce ** branching. ** 50 3dfx 1.41.1.6.1.008/29/00 Jonny Cochrane Some 8x FSAA code ** 49 3dfx 1.41.1.6 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 48 3dfx 1.41.1.5 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 47 3dfx 1.41.1.4 06/18/00 Stephane Huaulme fixed toggle and screen ** shot key for the Macintosh ** 46 3dfx 1.41.1.3 06/15/00 Bill White Merged changes to support ** Linux. ** ** 45 3dfx 1.41.1.2 05/25/00 Kenneth Dyke Fixed bogus file time ** stamp. ** 44 3dfx 1.41.1.1 05/24/00 Kenneth Dyke Added MacOS support for ** screenshots and AA toggling. ** 43 3dfx 1.41.1.0 05/09/00 Kenneth Dyke Paranoia fix to make sure ** fogMode is updated properly after grGlideSetState(). ** 42 3dfx 1.41 04/21/00 Kenneth Dyke Fix for ITRGBA parameter ** setup. Added 2D nop after a WAX clear. ** 41 3dfx 1.40 04/13/00 Kenneth Dyke Added support for new style ** 2-sample AA mode. ** 40 3dfx 1.39 04/10/00 Kenneth Dyke Added magical screenshot ** hotkey. ** 39 3dfx 1.38 04/06/00 Kenneth Dyke More paranoia to make ** buffer clears safer in windowed mode. ** 38 3dfx 1.37 04/05/00 Adam Briggs I can't believe the guy who ** wrote the 2D buffer clear didn't implement code for the swapped y-origin ** case! Anyway, it's fixed now. ** 37 3dfx 1.36 04/03/00 Adam Briggs Added a nop after a ** bufferswap ** 36 3dfx 1.35 03/24/00 Chris Dow If I cut off your pinky ** with my bolt cutters, then you can't make the // comment. ** 35 3dfx 1.34 03/24/00 Kenneth Dyke Removed stencil clear ** optimization since it's non-corformant. :-\ ** 34 3dfx 1.33 03/23/00 Kenneth Dyke Buffer clear optimizations ** and fixes for tbuffering. ** 33 3dfx 1.32 03/21/00 Don Mullis Fixes stencil-related ** failures reported in PRS #13274-13277. ** 32 3dfx 1.31 03/19/00 Kenneth Dyke Mode 2ppc mode state a bit ** more robust. ** 31 3dfx 1.30 03/13/00 Kenneth Dyke Remove A0 AA swap ** workaround. ** 30 3dfx 1.29 03/11/00 Kenneth Dyke Make sure two pixel per ** clock mode is disabled when restoring glide state. ** 29 3dfx 1.28 03/06/00 Kenneth Dyke Added backdoor hack to ** toggle AA on and off on the fly. ** 28 3dfx 1.27 03/01/00 Kenneth Dyke Fix for random aux buffer ** clears. ** 27 3dfx 1.26 02/28/00 Kenneth Dyke Fixed dither rotation stuff ** for 4-sample AA. We also no longer clobber the fog mode setting. ** ** 26 3dfx 1.25 02/22/00 Kenneth Dyke Work around compiler ** optimization bug. ** Fix alpha blend modes during triangle clear. ** Safer combineMode settings for TMUs during triangle clear. ** 25 3dfx 1.24 02/18/00 Adam Briggs added FX_GLIDE_WAX_ON var ** which must be set to 1 to enable the newly uncommented SLI WAX buffer ** clears ** 24 3dfx 1.23 02/07/00 Kenneth Dyke Removed slave chip stuff ** for pending swap count. ** 23 3dfx 1.22 02/03/00 Kenneth Dyke Allow grTBufferWriteMaskExt ** to work with two sample AA. ** 22 3dfx 1.21 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 21 3dfx 1.20 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 20 3dfx 1.19 01/30/00 Adam Briggs get napalm status correctly ** 19 3dfx 1.18 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 18 3dfx 1.17 01/18/00 Kenneth Dyke Get AA jitter values from ** the right place. ** 17 3dfx 1.16 01/16/00 Kenneth Dyke More minor AA swap fixes. ** 16 3dfx 1.15 01/16/00 Kenneth Dyke Fixes for windowed 32-bit ** buffer clears using WAX. ** Force swap interval >0 for AA modes. ** AA dither rotation matrix stuff. ** 15 3dfx 1.14 01/07/00 Adam Briggs Moved freeThreadStorage ** from grShutdown to the DllMain process detach code. This fixes PRS#12190, ** 12192 and 12196. ** 14 3dfx 1.13 12/04/99 Adam Briggs Made aux buffer get cleared ** correctly while in AA modes & incorporated dwm's recommendation about aux ** buffer addressing (avoids an if). ** 13 3dfx 1.12 11/29/99 Adam Briggs Oops: color buffer stride ** was being used to clear aux buffer. ** 12 3dfx 1.11 11/10/99 Adam Briggs Made grBufferClear(Ext) ** cooperate with linear surfaces & texture buffers ** 11 3dfx 1.10 11/08/99 Adam Briggs Initialized doStencil & ** ifdef'd it out on non-Napalm builds. ** 10 3dfx 1.9 11/05/99 Adam Briggs Fixed a bug or so with ** grBufferClear(Ext) and doubtless added several more. Also added commented ** out code for better buffer clears on Napalm SLI. ** 9 3dfx 1.8 11/05/99 Anthony tai added ** FX_GLIDE_SWAPPENDINGCOUNT. Default=1. Range 0-3 ** 8 3dfx 1.7 10/21/99 Anthony tai fixed iterated rgb checking ** 7 3dfx 1.6 10/07/99 Adam Briggs Implemented stencil clears ** for grBufferClearExt ** 6 3dfx 1.5 09/28/99 Adam Briggs 'nother fix for 24bit depth ** clears.. In theory they should now work when doing depth-only clears. ** 5 3dfx 1.4 09/24/99 Adam Briggs In theory, fixed 24bit ** BufferClear & BufferClearExt for windowed glide. ** 4 3dfx 1.3 09/23/99 Adam Briggs changed grBufferClear so ** the 16->24 depth conversion doesn't happen in 32bpp mode. ** 3 3dfx 1.2 09/20/99 Adam Briggs put IFDEF NAPALM around a ** change so I no longer hose other people... for now! ** 2 3dfx 1.1 09/17/99 Adam Briggs Supported TEXTUREBUFFEREXT ** for Napalm 32bpp and AA modes. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 122 9/01/99 2:22p Atai ** fixed h3 build ** ** 121 8/31/99 5:49p Atai ** fixed 2nd colbuffer mask ** ** 120 8/16/99 11:18a Adamb ** Merged in V3_OEM_100 fixes ** ** 119 7/23/99 2:01p Atai ** change tbuffer interface to grTBufferWriteMaskExt ** ** 118 7/22/99 1:18p Atai ** added grTBufferMaskExt ** ** 117 7/19/99 6:01p Sbrooks ** Defined freeThreadStorage() ** ** 116 7/19/99 4:30p Kcd ** Fixed portability problem with freeing up thread local storage. ** ** 115 7/18/99 1:59p Atai ** added grAlphaBlendFunctionExt ** ** 113 7/16/99 5:10p Sbrooks ** Fixes PRS 6869 ** ** 112 7/16/99 10:59a Atai ** remove un-supported mode ** fixed tcc, tac problem ** ** 111 7/14/99 5:07p Atai ** fixed stencil interface and some cc/ac stuff ** ** 110 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 109 7/06/99 2:44p Atai ** added gbc ** ** 108 6/29/99 7:19p Atai ** remove argument for enabling SST_CM_USE_COMBINE_MODE ** ** 107 6/29/99 2:55p Atai ** added invert mode for COMBINE ext c and d term ** ** 106 6/27/99 12:44p Atai ** fixed CC and TCC ** ** 105 6/25/99 2:11p Atai ** more 2 buffers stuff ** ** 104 6/24/99 7:17p Atai ** added STENCIL and COMBINE extension, 2 buffers per chip, and more ** register state recovery ** ** 103 6/19/99 11:36p Atai ** restore renderMode ** ** 102 6/14/99 10:41a Stb_gkincade ** Improved comments for image quality code in grDitherMode() ** ** 101 6/13/99 4:55p Atai ** fixed register mask ** ** 100 6/10/99 5:12p Atai ** fist pass CC and AC ext ** ** 99 6/04/99 3:18p Atai ** stencilMode and stencilOp ** ** 98 6/04/99 1:47p Atai ** fixed my Fed code ** ** 97 6/04/99 11:00a Atai ** added stencil functions ** ** 96 5/28/99 1:11p Atai ** again ** ** 94 5/19/99 3:55p Denis ** ** 93 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a tbext comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 92 5/13/99 2:42p Stb_gkincade ** Force dither matrix to 2x2 and Added user support for turning on/off ** dither substraction ** ** 91 4/28/99 3:48p Atai ** disable dither subtraction if GR_DITHER_DISABLE ** ** 90 4/14/99 5:05p Dow ** Fixed compiler error. ** ** 89 4/14/99 4:22p Dow ** Snarl ** ** 88 4/10/99 1:23p Atai ** fixed code to compile in packet fifo mode ** ** 87 3/24/99 6:17p Peter ** streamlined (made more dangerouse) state validation ** ** 86 3/10/99 10:42a Peter ** bump-n-grind workaround for katmai until the bug is better ** characterized ** ** 85 3/05/99 10:31p Peter ** coalesced texture state change nop into validate state ** ** 84 3/02/99 2:03p Peter ** removed no_check variant that led me astray ** ** 83 2/18/99 3:27p Kcd ** Fixed direct register access, removed surface extension call for ** non-Win32. ** ** 82 2/11/99 1:38p Atai ** sync buffer swap pending code, the right way. ** ** 81 2/09/99 5:08p Atai ** fixed fog ext win coords that I broke in my previous check-in ** ** 80 2/02/99 4:39p Peter ** cleaned up wax commands ** ** 79 1/28/99 3:04p Atai ** fixed clip coord fog extension (c and asm version) ** ** 78 1/25/99 6:34p Peter ** _grDepthBufferFunction should not write to hw as an intermediary step ** ** 77 1/15/99 10:52a Peter ** cleanup lazy evaluation of fbzMode for grDepthMask and grColorMask ** ** 76 12/21/98 3:01p Peter ** cleaned up shutdow semantics ** ** 75 12/09/98 6:25p Atai ** grTexCombine did the right thing for the un-used TMU. Initialize the ** 2nd TMU value to take care of "set FX_GLIDE_NUM_TMU=1" ** ** 74 12/09/98 5:10p Atai ** set MAXLOD = MINLOD = 8 in _grUpdateParamIndex if ST1 is not used ** ** 73 12/09/98 3:59p Peter ** test20 state validation bug ** ** 72 12/07/98 4:42p Atai ** enable w is good enough for qx/q ** ** 71 12/05/98 2:51p Dow ** Fixed swapinterval ** ** 70 12/03/98 11:26p Dow ** ** 69 12/02/98 11:30a Dow ** Fixed effed-up size checking in gglide.c ** ** 68 11/30/98 6:57p Peter ** windowed texture f*ckage ** ** 67 11/18/98 6:34p Dow ** Fixed clear problem on v3/banshee ** ** 66 11/17/98 4:27p Atai ** fixed gc->triSetupProc for clip coords grDrawTriangle ** ** 65 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 64 11/02/98 5:34p Peter ** tls per thread for fullscreen contexts ** ** 63 10/30/98 3:45p Dow ** Fixed Tiled/Linear color/aux bug ** ** 62 10/08/98 10:29a Dow ** Fixes triple buffering ** ** 61 9/30/98 12:59p Atai ** use texchromakey and texchromarange shadow state ** ** 60 9/08/98 7:19p Atai ** fix debug info. added underline for internal routines and some \n ** ** 59 9/02/98 3:34p Atai ** fixed texturing transition bug ** ** 58 8/31/98 7:11p Atai ** fix clip coord tmu q param bug. send 1/w or Qn/w ** ** 57 8/30/98 1:34p Dow ** State & other optimizations ** ** 56 8/29/98 10:04p Peter ** sdram clear fixes ** ** 55 8/29/98 8:12p Dow ** Clip optimization ** ** 54 8/29/98 2:29p Peter ** call grSstWinClose w/ correct context parameter ** ** 53 8/27/98 9:54p Peter ** clear aux buffer w/ rgb not rbg ** ** 52 8/27/98 5:52p Jdt ** removed maxx maxy check from grClipwindow ** ** 51 8/27/98 1:55p Peter ** use converted color on sdram boards ** ** 50 8/26/98 3:01p Jdt ** tsuIndices may not be used to index p_str < debugging bug only > ** ** 49 8/18/98 1:44p Atai ** fixed "w param is turned off in clip space" ** ** 48 8/14/98 1:56p Atai ** fix fog coord bug ** ** 47 8/14/98 10:21a Dow ** Fixed fog for B silicon ** ** 46 8/06/98 8:04p Dow ** Fixed SDRAM for full-screen ** ** 45 8/06/98 7:50p Dow ** Fixed SDRAM stuff ** ** 43 8/05/98 11:46p Atai ** 1. grBufferSwap argument FxU32 ** 2. grGet return FxU32 ** ** 42 8/03/98 6:40a Jdt ** moved stats, curvertexsize, curtrisize into gc from global ** ** 41 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 40 7/18/98 12:27a Jdt ** Added shadowing of fog tables. Chagnes to reflect new shadow register ** structure. ** ** 39 7/17/98 2:04p Jdt ** Remove pointless SST_DRAWBUFFER bits. ** ** 38 7/16/98 8:18a Jdt ** Removed conditional screen clear for A1 ** ** fxcmd.h ** ** 37 7/02/98 1:55p Atai ** grDepthBiasLevel argument is FxI32 ** ** 36 7/01/98 12:40p Jdt ** Protected hacks for Glide/Win ( FX_TACO_MEMORY_FIFO_HACK ) ** ** 35 6/21/98 11:56a Atai ** fixed fogcoord paramindex ** ** 34 6/10/98 12:53p Atai ** replace grSstControl with grEnable/grDisable(GR_PASSTHRU) ** ** 33 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 32 5/29/98 6:39p Atai ** fix chromarange ** ** 31 5/29/98 11:45a Atai ** 1.added _EXT for extension #defines. ** 2. change GR_TEXBASE_* values ** 3. Remove GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB ** ** 30 5/28/98 2:07p Peter ** banshee merge ** ** 29 5/27/98 9:52a Peter ** grBufferClear is constrained by clipping ** ** 28 5/21/98 7:15p Atai ** fix q0 and q1 for clip coords ** ** 27 5/19/98 2:00p Atai ** use GR_PARAM_Q for fbi w ** ** 26 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 25 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 23 4/22/98 4:57p Peter ** glide2x merge ** ** 22 4/21/98 1:34p Atai ** make 32 bit clean ** ** 21 3/23/98 6:34p Atai ** Fixed texture state validation bug in grColorCombine ** ** 20 3/21/98 11:31a Atai ** added GR_TRIANGLE_STRIP_CONTINUE and GR_TRIANGLE_FAN_CONTINUE ** ** 19 2/20/98 2:17p Peter ** shutting down hw should clear hwInit and open ** ** 18 2/17/98 5:07p Atai ** fixed packed a ** ** 17 2/17/98 12:40p Peter ** fog table fix ** ** 16 2/12/98 4:08p Atai ** casting value ** ** 15 2/12/98 3:40p Peter ** single buffering for opengl ** ** 14 2/12/98 3:05p Peter ** fixed naming change for glid3 ** ** 13 2/11/98 7:31p Peter ** blit clear vs grRenderBuffer ** ** 12 2/05/98 6:52p Atai ** fixed pargb vertex size ** ** 11 2/05/98 6:19p Atai ** lazy evaluate for grVertexLayout ** ** 10 1/30/98 4:21p Peter ** fixed old glide-ism ** ** 9 1/30/98 4:18p Peter ** sli/y-origin blit clear ** ** 8 1/30/98 1:19p Atai ** fixed chromarange ** ** 7 1/28/98 2:20p Atai ** fixed lfb state validation ** ** 6 1/23/98 3:07p Peter ** uswc nightmare ** ** 5 1/19/98 1:38p Atai ** fixed _grDrawLineStrip zero length lline ** ** 4 1/19/98 11:03a Atai ** remove assignment before validate the state ** ** 3 1/18/98 12:03p Atai ** sync to rev 17 spec * * 2 1/16/98 6:44p Atai * fixed for glide 3 build * * 1 1/16/98 4:29p Atai * create glide 3 src * * 137 1/15/98 1:12p Peter * only one culler please * * 136 1/13/98 7:48p Atai * fixed gu3dfGetInfo, grBufferClear, and GrState size * * 135 1/13/98 12:42p Atai * fixed grtexinfo, grVertexLayout, and draw triangle * * 134 1/09/98 7:29p Atai * fixed grBufferSwap for glide3 * * 133 1/08/98 9:25p Peter * infinite recurrsion in debugging assert * * 132 1/08/98 9:23p Peter * fixed macro effage * * 131 1/08/98 7:09p Peter * real hw stuff modulo makefile change * * 130 1/08/98 4:58p Atai * tex table broadcast, grVertexLayout enable/disable, stq, and some * defines * * 129 1/07/98 5:22p Atai * fixed grGet compiler error * * 128 1/07/98 10:22a Peter * merged John's ooz fix * * 127 1/06/98 3:53p Atai * remove grHint, modify grLfbWriteRegion and grGet * * 126 1/05/98 6:06p Atai * glide extension stuff * * 125 12/22/97 12:40p Peter * added new grColorCombine factor for OpenGL * * 124 12/18/97 2:13p Peter * fogTable cataclysm * * 123 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 122 12/17/97 4:06p Atai * added grChromaRange(), grGammaCorrecionRGB(), grRest(), and grGet() * functions * * 120 12/16/97 11:38a Atai * added grChromaRange() * * 118 12/08/97 10:49a Atai * rename some state variables * * 117 12/03/97 11:35a Peter * reset for swapping * * 116 11/21/97 6:05p Atai * use one datalist (tsuDataList) in glide3 * * 115 11/21/97 3:20p Peter * direct writes tsu registers * * 114 11/18/97 6:11p Peter * fixed glide3 effage * * 113 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 112 11/18/97 3:27p Atai * update vData * optimize state monster * * 111 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 110 11/16/97 2:20p Peter * cleanup * * 109 11/15/97 7:43p Peter * more comdex silliness * * 108 11/14/97 5:02p Peter * more comdex stuff * * 107 11/14/97 12:09a Peter * comdex thing and some other stuff * * 106 11/13/97 4:39p Atai * enable _grUpdateParamIndex for grGlideSetState * * 105 11/12/97 9:54p Peter * fixed all the effage from new config * * 104 11/12/97 2:27p Peter * simulator happiness w/o fifo * * 103 11/12/97 11:16a Peter * cleaned up assertions * * 102 11/06/97 3:38p Dow * More banshee stuff * * 101 11/04/97 5:59p Peter * more of the same * * 100 11/03/97 3:43p Peter * h3/cvg cataclysm * * 99 11/01/97 10:01a Peter * tri dispatch stuff * ** */ #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #include "fxinline.h" #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #if HAL_CSIM #include #else /* !HAL_CSIM */ #include #endif /* !HAL_CSIM */ #endif /* (GLIDE_PLATFORM & GLIDE_SST_SIM) */ #ifdef DRI_BUILD #include #endif #include "rcver.h" static char glideIdent[] = "@#%" VERSIONSTR ; #if GLIDE_HW_TRI_SETUP static void _grUpdateTriPacketHdr(FxU32 paramMask, const GrCullMode_t mode); #endif /* GLIDE_HW_TRI_SETUP */ /*--------------------------------------------------------------------------- ** grAlphaBlendFunction ** ** GMT: BUG if grColorMask() turns off alphaplanes then destination alpha ** blending wont work! */ GR_STATE_ENTRY(grAlphaBlendFunction, void, (GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df)) { #define FN_NAME "_grAlphaBlendFunction" FxU32 alphamode; GR_BEGIN_NOFIFOCHECK("_grAlphaBlendFunction", 85); GDBG_INFO_MORE(gc->myLevel, "(%d,%d,%d,%d)\n", rgb_sf, rgb_df, alpha_sf, alpha_df); /* Watcom warning suppressor */ glideIdent[0] = glideIdent[0]; alphamode = gc->state.shadow.alphaMode; if (gc->grPixelSize == 4) { switch (alpha_sf) { case GR_BLEND_ZERO: case GR_BLEND_SRC_ALPHA: case GR_BLEND_DST_ALPHA: case GR_BLEND_ONE: case GR_BLEND_ONE_MINUS_SRC_ALPHA: case GR_BLEND_ONE_MINUS_DST_ALPHA: break; default: /* GR_CHECK_W(myName, 1, "unsupported alpha source blend function"); */ alpha_sf = GR_BLEND_ONE; break; } switch (alpha_df) { case GR_BLEND_ZERO: case GR_BLEND_SRC_ALPHA: case GR_BLEND_DST_ALPHA: case GR_BLEND_ONE: case GR_BLEND_ONE_MINUS_SRC_ALPHA: case GR_BLEND_ONE_MINUS_DST_ALPHA: break; default: /* GR_CHECK_W(myName, 1, "unsupported alpha destination blend function"); */ alpha_df = GR_BLEND_ZERO; break; } } else { if (alpha_sf != GR_BLEND_ONE && alpha_sf != GR_BLEND_ZERO) { /* GR_CHECK_W(myName, 1, "unsupported alpha source blend function"); */ alpha_sf = GR_BLEND_ONE; } if (alpha_df != GR_BLEND_ONE && alpha_df != GR_BLEND_ZERO) { /* GR_CHECK_W(myName, 1, "unsupported alpha destination blend function"); */ alpha_df = GR_BLEND_ZERO; } } if (rgb_sf == GR_BLEND_ONE && rgb_df == GR_BLEND_ZERO && alpha_sf == GR_BLEND_ONE && alpha_df == GR_BLEND_ZERO) alphamode &= ~SST_ENALPHABLEND; else alphamode |= SST_ENALPHABLEND; alphamode &= ~(SST_RGBSRCFACT | SST_RGBDSTFACT | SST_ASRCFACT | SST_ADSTFACT); alphamode |= ((((FxU32) rgb_sf) << SST_RGBSRCFACT_SHIFT) | (((FxU32) rgb_df) << SST_RGBDSTFACT_SHIFT) | (((FxU32) alpha_sf) << SST_ASRCFACT_SHIFT) | (((FxU32) alpha_df) << SST_ADSTFACT_SHIFT)); gc->state.shadow.alphaMode = alphamode; #undef FN_NAME } /* grAlphaBlendFunction */ /*--------------------------------------------------------------------------- ** grAlphaCombine */ GR_STATE_ENTRY(grAlphaCombine, void, (GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert)) { #define FN_NAME "_grAlphaCombine" FxU32 fbzColorPath; GR_BEGIN_NOFIFOCHECK("_grAlphaCombine",85); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d,%d,%d)\n",function,factor,local,other,invert); GR_CHECK_W(myName, function < GR_COMBINE_FUNCTION_ZERO || function > GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA, "unsupported alpha combine function"); GR_CHECK_W(myName, (factor & 0x7) < GR_COMBINE_FACTOR_ZERO || (factor & 0x7) > GR_COMBINE_FACTOR_TEXTURE_ALPHA || factor > GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA, "unsupported alpha combine scale factor"); GR_CHECK_W(myName, local < GR_COMBINE_LOCAL_ITERATED || local > GR_COMBINE_LOCAL_DEPTH, "unsupported alpha combine local color"); GR_CHECK_W(myName, other < GR_COMBINE_OTHER_ITERATED || other > GR_COMBINE_OTHER_CONSTANT, "unsupported alpha combine other color"); fbzColorPath = gc->state.shadow.fbzColorPath; fbzColorPath &= ~(SST_ENTEXTUREMAP | SST_ASELECT | SST_ALOCALSELECT | SST_CCA_ZERO_OTHER | SST_CCA_SUB_CLOCAL | SST_CCA_MSELECT | SST_CCA_REVERSE_BLEND | SST_CCA_ADD_CLOCAL | SST_CCA_ADD_ALOCAL | SST_CCA_INVERT_OUTPUT); /* setup reverse blending first, then strip off the the high bit */ if ((factor & 0x8) == 0) fbzColorPath |= SST_CCA_REVERSE_BLEND; factor &= 0x7; /* NOTE: we use boolean OR instead of logical to avoid branches */ gc->state.ac_requires_texture = ((factor == GR_COMBINE_FACTOR_TEXTURE_ALPHA) | (other == GR_COMBINE_OTHER_TEXTURE)); gc->state.ac_requires_it_alpha = ((local == GR_COMBINE_LOCAL_ITERATED) | (other == GR_COMBINE_OTHER_ITERATED)); gc->state.tcc_requires_it_alpha[GR_TMU0] = FXFALSE; gc->state.tcc_requires_it_alpha[GR_TMU1] = FXFALSE; gc->state.tac_requires_it_alpha[GR_TMU0] = FXFALSE; gc->state.tac_requires_it_alpha[GR_TMU1] = FXFALSE; /* setup scale factor bits */ fbzColorPath |= factor << SST_CCA_MSELECT_SHIFT; /* setup local color bits */ fbzColorPath |= local << SST_ALOCALSELECT_SHIFT; /* setup other color bits */ fbzColorPath |= other << SST_ASELECT_SHIFT; /* setup invert output bits */ if (invert) fbzColorPath |= SST_CCA_INVERT_OUTPUT; /* setup core color combine unit bits */ switch (function) { case GR_COMBINE_FUNCTION_ZERO: fbzColorPath |= SST_CCA_ZERO_OTHER; break; case GR_COMBINE_FUNCTION_LOCAL: case GR_COMBINE_FUNCTION_LOCAL_ALPHA: fbzColorPath |= SST_CCA_ZERO_OTHER | SST_CCA_ADD_ALOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: fbzColorPath |= SST_CCA_ADD_ALOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: fbzColorPath |= SST_CCA_SUB_CLOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: fbzColorPath |= SST_CCA_SUB_CLOCAL | SST_CCA_ADD_ALOCAL; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: fbzColorPath |= SST_CCA_ZERO_OTHER | SST_CCA_SUB_CLOCAL | SST_CCA_ADD_ALOCAL; break; } /* if either color or alpha combine requires texture then enable it */ if (gc->state.cc_requires_texture || gc->state.ac_requires_texture) fbzColorPath |= SST_ENTEXTUREMAP; gc->state.shadow.fbzColorPath = fbzColorPath; GR_END(); #undef FN_NAME } /* grAlphaCombine */ /*--------------------------------------------------------------------------- ** grAlphaControlsITRGBLighting ** ** Determines whether the LSB of alpha controls what lighting is used-- ** Specifically whether grConstantColorValu or the interated RGB values are used ** during TEXTURE_TIMES_itrgb & TEXTURE_TIMES_ITRGB_DELTA0 color combine modes. ** */ GR_STATE_ENTRY(grAlphaControlsITRGBLighting, void, (FxBool enable)) { #define FN_NAME "_grAlphaControlsITRGBLighting" FxU32 fbzColorPath; GR_BEGIN_NOFIFOCHECK("_grAlphaControlsITRGBLighting", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", enable); fbzColorPath = gc->state.shadow.fbzColorPath; if (enable) { fbzColorPath |= SST_LOCALSELECT_OVERRIDE_WITH_ATEX; } else { fbzColorPath &= ~SST_LOCALSELECT_OVERRIDE_WITH_ATEX; } gc->state.shadow.fbzColorPath = fbzColorPath; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, fbzColorPath, fbzColorPath); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grAlphaControlsITRGBLighting() */ /*--------------------------------------------------------------------------- ** grAlphaTestFunction */ GR_STATE_ENTRY(grAlphaTestFunction, void, (GrCmpFnc_t fnc)) { #define FN_NAME "_grAlphaTestFunction" FxU32 alphamode; GR_BEGIN_NOFIFOCHECK("_grAlphaTestFunction", 85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",fnc); alphamode = gc->state.shadow.alphaMode; alphamode &= ~(SST_ALPHAFUNC | SST_ENALPHAFUNC); if (fnc != GR_CMP_ALWAYS) alphamode |= ((fnc << SST_ALPHAFUNC_SHIFT) | SST_ENALPHAFUNC); gc->state.shadow.alphaMode = alphamode; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, alphaMode, alphamode); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grAlphaTestFunction */ /*--------------------------------------------------------------------------- ** grAlphaTestReferenceValue */ GR_STATE_ENTRY(grAlphaTestReferenceValue, void, (GrAlpha_t value)) { #define FN_NAME "_grAlphaTestReferenceValue" FxU32 alphamode; GR_BEGIN_NOFIFOCHECK("_grAlphaTestReferenceValue", 85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",value); alphamode = gc->state.shadow.alphaMode; alphamode &= ~SST_ALPHAREF; alphamode |= (((FxU32) value) << SST_ALPHAREF_SHIFT); gc->state.shadow.alphaMode = alphamode; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, alphaMode, alphamode); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grAlphaTestReferenceValue */ /* */ /* GASP: The dreaded WAX buffer clear. */ /* */ #ifndef HAL_CSIM static void _grBufferClear2D(/*const*/ FxU32 buffOffset, const FxU32 clipLeft, const FxU32 clipTop, const FxU32 clipRight, const FxU32 clipBottom, const FxU32 color, const FxU32 mask, const FxBool tiled, const FxU32 stride) { #define FN_NAME "_grBufferClear2D" FxU32 /* Registers we use */ clip0min, clip0max, dstBaseAddr, dstFormat, colorFore, command; FxU32 regMask = 0L; FxU32 rop = SSTG_ROP_SRCCOPY ; /* Default to SRCCOPY ROP */ FxU32 commandEx = 0x00000000; FxU32 width, height; GR_BEGIN_NOFIFOCHECK("_grBufferClear2D", 86); if (mask == 0) /* This one is easy! */ return ; GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0x0); GR_CHECK_SIZE(); /* */ /* In 3D land we can only apply a write mask in 32bpp modes */ /* so we can be lame and do the same thing here. */ /* */ if ((gc->grPixelSize == 4) && (mask != 0xffffffff)) { int i ; rop = 0xCA000000 ; /* Dst = (Pat & Src) | Dst */ commandEx = SSTG_PAT_FORCE_ROW0 ; /* use only row 0 of pat */ /* Set only row 0 of pat */ REG_GROUP_BEGIN_WAX(colorPattern[0], 8, 0xFF) ; for (i = 0 ; i < 8 ; i++) REG_GROUP_SET_WAX(gc->gRegs, colorPattern[i], mask) ; REG_GROUP_END() ; } #define ADDWAXMASK(mask, reg, base) mask |= (1 << ((offsetof(SstGRegs, reg) - offsetof(SstGRegs, base)) >> 2)) ADDWAXMASK(regMask, clip0min, clip0min); ADDWAXMASK(regMask, clip0max, clip0min); ADDWAXMASK(regMask, dstBaseAddr, clip0min); ADDWAXMASK(regMask, dstFormat, clip0min); ADDWAXMASK(regMask, commandEx, clip0min); REG_GROUP_BEGIN_WAX(clip0min, 5, regMask); width = clipRight - clipLeft; height = clipBottom - clipTop; /* Setup clipping rectangle based on top left origin */ if (gc->state.shadow.fbzMode & SST_YORIGIN) { FxU32 flippedTop ; FxU32 flippedBottom ; #if 1 FxU32 maxY; /* [dBorca] Hack alert: * textureAuxBuffer is not correctly handled! */ if (gc->textureBuffer.on) { maxY = gc->textureBuffer.height; } else { maxY = gc->state.screen_height >> (gc->sliCount >> 1); } flippedTop = maxY - clipBottom ; flippedBottom = maxY - clipTop ; /* [dBorca] Hack alert: * textureAuxBuffer is not correctly handled! * Compensate for grTextureBuffer subtraction in `gtex.c'. Why? Oh, why? * Could be a bug in hardware logic? * It seems the non-tiled path is not correctly understood by WAX! * I'm not sure about the next condition... should we use (!tiled) instead? */ if (gc->textureBuffer.on) { buffOffset += ( gc->state.screen_height - height ) * gc->textureBuffer.width * gc->grPixelSize; } #else flippedTop = (gc->state.screen_height >> (gc->sliCount >> 1)) - height - clipTop ; flippedBottom = flippedTop + height ; #endif clip0min = ((flippedTop << 16) | clipLeft); clip0max = ((clipRight) | ((flippedBottom) << 16)); } else { clip0min = ((clipTop << 16) | clipLeft); clip0max = ((clipRight) | ((clipBottom) << 16)); } REG_GROUP_SET_WAX(gc->gRegs, clip0min, clip0min); REG_GROUP_SET_WAX(gc->gRegs, clip0max, clip0max); /* Set buffer address and or in the tiled bit */ #if 0 /* [dBorca] dumb assumption */ dstBaseAddr = buffOffset | ((stride & SST_BUFFER_MEMORY_TILED) ? SSTG_IS_TILED : 0) ; #else dstBaseAddr = buffOffset | (tiled ? SSTG_IS_TILED : 0) ; #endif REG_GROUP_SET_WAX(gc->gRegs, dstBaseAddr, dstBaseAddr); /* Build up dstFormat (Should this be done globally?) */ dstFormat = stride & SST_BUFFER_LINEAR_STRIDE ; if (gc->grPixelSize == 2) dstFormat |= SSTG_PIXFMT_16BPP ; /* 16bpp */ else dstFormat |= SSTG_PIXFMT_32BPP ; /* 32bpp */ REG_GROUP_SET_WAX(gc->gRegs, dstFormat, dstFormat); /* Setup Command extra */ REG_GROUP_SET_WAX(gc->gRegs, commandEx, commandEx); REG_GROUP_END(); regMask = 0L; ADDWAXMASK(regMask, colorFore, colorFore); ADDWAXMASK(regMask, dstSize, colorFore); ADDWAXMASK(regMask, dstXY, colorFore); ADDWAXMASK(regMask, command, colorFore); REG_GROUP_BEGIN_WAX(colorFore, 4, regMask); /* Setup colorFore */ colorFore = color; REG_GROUP_SET_WAX(gc->gRegs, colorFore, colorFore); /* Setup dstSize - height/width */ REG_GROUP_SET_WAX(gc->gRegs, dstSize, (height << 16) | width); /* Setup dstXY - starting coordinate */ REG_GROUP_SET_WAX(gc->gRegs, dstXY, clip0min); /* Setup command */ command = SSTG_RECTFILL; /* rectangle fill */ command |= SSTG_GO; /* Initiate immediately */ command |= rop ; /* ROP */ REG_GROUP_SET_WAX(gc->gRegs, command, command); REG_GROUP_END(); /* Force 2D idle */ REG_GROUP_BEGIN_WAX(command, 1, command); command = SSTG_GO | SSTG_NOP; /* 2D NOP */ REG_GROUP_SET_WAX(gc->gRegs, command, command); REG_GROUP_END(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0x0); GR_CHECK_SIZE(); #undef FN_NAME } /* _grBufferClear2D */ #endif /* */ /* AJB: Stole all this noise from SST2 Glide, but the Non-Reference TRI fill */ /* has gotten LOTS of re-write... Also a 2-Tri fill might be better on */ /* Napalm, but some experimenting will be required. */ /* */ /* The triangle will look like this: */ /* */ /* A---B */ /* \| | */ /* \-| */ /* \| */ /* C */ /* */ /* A = (-width,0) */ /* B = (width+1, 0) */ /* C = (width+1, height*2) */ /* */ #define REFERENCE_TRI_FILL 0 #ifdef FX_GLIDE_NAPALM /* KoolSmoky - testing 2-tri fill with napalm */ #define TWO_TRI_FILL 1 #else #define TWO_TRI_FILL 0 #endif void _grTriFill(GrColor_t color, FxU32 depth, GrStencil_t stencil) { #define FN_NAME "_grTriFill" #if REFERENCE_TRI_FILL GrState oldState ; GrDepthBufferMode_t bufferMode ; #endif #if TWO_TRI_FILL struct { float x, y, depth ; } vertex[6] ; #else struct { float x, y, depth ; } vertex[3] ; #endif GR_BEGIN_NOFIFOCHECK("_grTriFill", 86); #if REFERENCE_TRI_FILL /* */ /*warning Reference triangle fill code is not fixing chromakey mode. */ /* */ /* Note: The following is a "reference" implementation of triangle buffer * clearing based 'mostly' on Glide API calls. */ grGlideGetState(&oldState); bufferMode = gc->state.stateArgs.grDepthBufferModeArgs.mode ; /* AJB - Flat shaded Tri. */ grColorCombine(GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE) ; /* This takes care of color and alpha */ grConstantColorValue(color); /* Set up to force depth buffer comparison to succeed */ grDepthBufferFunction(GR_CMP_ALWAYS); /* Figure out which way to set up vertex */ /* Doing it this way means that we don't cause a PE cache */ /* flush due to changing depth buffer modes */ if (bufferMode == GR_DEPTHBUFFER_WBUFFER || bufferMode == GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS) { grVertexLayout(GR_PARAM_Z, 0, GR_PARAM_DISABLE) ; grVertexLayout(GR_PARAM_Q, 8, GR_PARAM_ENABLE) ; } else if (bufferMode == GR_DEPTHBUFFER_ZBUFFER || bufferMode == GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS) { grVertexLayout(GR_PARAM_Z, 8, GR_PARAM_ENABLE) ; grVertexLayout(GR_PARAM_Q, 0, GR_PARAM_DISABLE) ; } #ifdef FX_GLIDE_NAPALM /* AJB - 2ppc rendering */ _grTex2ppc(GR_TMU0, FXTRUE) ; /* Set up stencil stuff */ grStencilFunc(GR_CMP_ALWAYS,stencil,0xFF); grStencilOp(GR_STENCILOP_REPLACE,GR_STENCILOP_REPLACE,GR_STENCILOP_REPLACE); #endif /* Make sure we're doing window coords */ grCoordinateSpace(GR_WINDOW_COORDS); /* Finally draw the triangle! */ #if TWO_TRI_FILL vertex[0].x = gc->state.clipwindowf_xmin ; vertex[0].y = gc->state.clipwindowf_ymin ; vertex[0].depth = (float)depth ; vertex[1].x = gc->state.clipwindowf_xmax ; vertex[1].y = gc->state.clipwindowf_ymin ; vertex[1].depth = (float)depth ; vertex[2].x = gc->state.clipwindowf_xmax ; vertex[2].y = gc->state.clipwindowf_ymax ; vertex[2].depth = (float)depth ; vertex[3].x = gc->state.clipwindowf_xmin ; vertex[3].y = gc->state.clipwindowf_ymin ; vertex[3].depth = (float)depth ; vertex[4].x = gc->state.clipwindowf_xmax ; vertex[4].y = gc->state.clipwindowf_ymax ; vertex[4].depth = (float)depth; vertex[5].x = gc->state.clipwindowf_xmin ; vertex[5].y = gc->state.clipwindowf_ymax ; vertex[5].depth = (float)depth ; grDrawTriangle(&vertex[0],&vertex[1],&vertex[2]) ; grDrawTriangle(&vertex[3],&vertex[4],&vertex[5]) ; #else vertex[0].x = 0.0f -(float)gc->state.screen_width ; vertex[0].y = 0.0f; vertex[0].depth = (float)depth; vertex[1].x = (float)gc->state.screen_width + 1; vertex[1].y = 0.0f; vertex[1].depth = (float)depth; vertex[2].x = (float)gc->state.screen_width + 1; vertex[2].y = (float)gc->state.screen_height * 2; vertex[2].depth = (float)depth; grDrawTriangle(&vertex[0],&vertex[1],&vertex[2]); #endif /* Restore all touched state */ grGlideSetState(&oldState); #else /* */ /* Here is the 'real' implementation */ /* */ { /* Save off regs that this function will trash */ GrDepthBufferMode_t bufferMode ; FxU32 fbzMode = gc->state.shadow.fbzMode ; FxU32 color0 = gc->state.shadow.color0 ; FxU32 color1 = gc->state.shadow.color1 ; FxU32 fbzColorPath = gc->state.shadow.fbzColorPath ; FxU32 alphaMode = gc->state.shadow.alphaMode; #ifdef FX_GLIDE_NAPALM FxU32 combineMode; FxU32 stencilMode; FxU32 stencilOp; #endif bufferMode = gc->state.stateArgs.grDepthBufferModeArgs.mode ; GR_CHECK_FOR_ROOM(256, 0); /* Probably a little overkill */ /* */ /* Set up rendering for flat shading */ /* */ fbzMode &= ~(SST_WBUFFER | SST_ZFUNC | SST_ENCHROMAKEY | SST_ENZBIAS | SST_DEPTH_FLOAT_SEL); fbzMode |= (GR_CMP_ALWAYS << SST_ZFUNC_SHIFT); REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 1, 0x1) ; { REG_GROUP_SET(hw, fbzMode, fbzMode ) ; } REG_GROUP_END(); /* Set the constant color to the given color */ REG_GROUP_BEGIN(BROADCAST_ID, c0, 2, 0x03) ; { REG_GROUP_SET(hw, c0, color) ; REG_GROUP_SET(hw, c1, color) ; } REG_GROUP_END() ; /* Set the blend mode to only use the constant color */ REG_GROUP_BEGIN(BROADCAST_ID, fbzColorPath, 1, 0x1) ; { REG_GROUP_SET(hw, fbzColorPath, (GR_COMBINE_FACTOR_NONE << SST_CC_MSELECT_SHIFT) | (GR_COMBINE_LOCAL_CONSTANT << SST_LOCALSELECT_SHIFT) | (GR_COMBINE_OTHER_NONE << SST_RGBSELECT_SHIFT) | SST_CC_ZERO_OTHER | SST_CC_ADD_CLOCAL) ; } REG_GROUP_END() ; /* Make sure alpha blending is disabled */ REG_GROUP_BEGIN(BROADCAST_ID, alphaMode, 1, 0x01) ; { REG_GROUP_SET(hw, alphaMode, 0); } REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM #if 0 /* if we haven't already, enable 2 pixel/clock rendering */ if (!gc->mode2ppc) _grTex2ppc(GR_TMU0, FXTRUE) ; #endif combineMode = gc->state.shadow.combineMode ; stencilMode = gc->state.shadow.stencilMode ; stencilOp = gc->state.shadow.stencilOp ; /* if we're in 32bpp mode, setup to clear the stencil BUT DON'T CHANGE THE STENCIL MASK! */ if (gc->grPixelSize == 4) { REG_GROUP_BEGIN(BROADCAST_ID, stencilMode, 2, 0x3) ; { REG_GROUP_SET(hw, stencilMode, (GR_CMP_ALWAYS << SST_STENCIL_FUNC_SHIFT) | (stencil << SST_STENCIL_REF_SHIFT) | stencilMode & (SST_STENCIL_WMASK | SST_STENCIL_MASK) | SST_STENCIL_ENABLE) ; REG_GROUP_SET(hw, stencilOp, (GR_STENCILOP_REPLACE << SST_STENCIL_SFAIL_OP_SHIFT) | (GR_STENCILOP_REPLACE << SST_STENCIL_ZFAIL_OP_SHIFT) | (GR_STENCILOP_REPLACE << SST_STENCIL_ZPASS_OP_SHIFT)) ; } REG_GROUP_END() ; } /* turn off whatever fancy Napalm combine mode was set & just use the old fashioned fbzColorPath */ REG_GROUP_BEGIN(eChipFBI, combineMode, 1, 0x01) ; { REG_GROUP_SET(hw, combineMode, combineMode & ~(SST_CM_USE_COMBINE_MODE)) ; } REG_GROUP_END() ; { int tmu; for (tmu = 0 ; tmu < gc->num_tmu ; tmu++) { SstRegs* tmuregs = SST_TMU(hw, tmu); const FifoChipField chipField = (FifoChipField)(0x02UL << tmu); REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuregs, combineMode, gc->state.shadow.tmuState[tmu].combineMode & ~(SST_CM_USE_COMBINE_MODE)); } REG_GROUP_END(); } } #endif /* */ /* Draw the triangle already! */ /* */ #if TWO_TRI_FILL vertex[0].x = (float)gc->state.clipwindowf_xmin ; vertex[0].y = (float)gc->state.clipwindowf_ymin ; vertex[1].x = (float)gc->state.clipwindowf_xmax ; vertex[1].y = (float)gc->state.clipwindowf_ymin ; vertex[2].x = (float)gc->state.clipwindowf_xmax ; vertex[2].y = (float)gc->state.clipwindowf_ymax ; vertex[3].x = (float)gc->state.clipwindowf_xmin ; vertex[3].y = (float)gc->state.clipwindowf_ymin ; vertex[4].x = (float)gc->state.clipwindowf_xmax ; vertex[4].y = (float)gc->state.clipwindowf_ymax ; vertex[5].x = (float)gc->state.clipwindowf_xmin ; vertex[5].y = (float)gc->state.clipwindowf_ymax ; #else vertex[0].x = 0.0f -(float)gc->state.screen_width ; vertex[0].y = 0.0f ; vertex[1].x = (float)gc->state.screen_width + 1 ; vertex[1].y = 0.0f ; vertex[2].x = (float)gc->state.screen_width + 1 ; vertex[2].y = (float)gc->state.screen_height * 2 ; #endif /* Here I have assumed that bufferMode will be 0 when there is no */ /* depth buffering and odd when z buffering. */ if (bufferMode) { vertex[0].depth = (float)depth ; #if TWO_TRI_FILL vertex[3].depth = (float)depth ; GR_SET_EXPECTED_SIZE(sizeof(float) * 3 * 3 * 2, 1) ; TRI_PACKET_BEGIN(kSetupStrip, SST_SETUP_Z << SSTCP_PKT3_PMASK_SHIFT, 6, sizeof(float) * 3, SSTCP_PKT3_BDDBDD); #else GR_SET_EXPECTED_SIZE(sizeof(float) * 3 * 3, 1) ; TRI_PACKET_BEGIN(kSetupStrip, SST_SETUP_Z << SSTCP_PKT3_PMASK_SHIFT, 3, sizeof(float) * 3, SSTCP_PKT3_BDDBDD); #endif { TRI_SETF(vertex[0].x); TRI_SETF(vertex[0].y); TRI_SETF(vertex[0].depth); TRI_SETF(vertex[1].x); TRI_SETF(vertex[1].y); TRI_SETF(vertex[0].depth); TRI_SETF(vertex[2].x); TRI_SETF(vertex[2].y); TRI_SETF(vertex[0].depth); #if TWO_TRI_FILL TRI_SETF(vertex[3].x); TRI_SETF(vertex[3].y); TRI_SETF(vertex[3].depth); TRI_SETF(vertex[4].x); TRI_SETF(vertex[4].y); TRI_SETF(vertex[3].depth); TRI_SETF(vertex[5].x); TRI_SETF(vertex[5].y); TRI_SETF(vertex[3].depth); #endif } TRI_END ; GR_CHECK_SIZE() ; } else { /* When depth buffering is disabled, don't send a depth component */ #if TWO_TRI_FILL GR_SET_EXPECTED_SIZE(sizeof(float) * 2 * 3 * 2, 1) ; TRI_PACKET_BEGIN(kSetupStrip, 0, 6, sizeof(float) * 2, SSTCP_PKT3_BDDBDD) ; #else GR_SET_EXPECTED_SIZE(sizeof(float) * 2 * 3, 1) ; TRI_PACKET_BEGIN(kSetupStrip, 0, 3, sizeof(float) * 2, SSTCP_PKT3_BDDBDD) ; #endif { TRI_SETF(vertex[0].x); TRI_SETF(vertex[0].y); TRI_SETF(vertex[1].x); TRI_SETF(vertex[1].y); TRI_SETF(vertex[2].x); TRI_SETF(vertex[2].y); #if TWO_TRI_FILL TRI_SETF(vertex[3].x); TRI_SETF(vertex[3].y); TRI_SETF(vertex[4].x); TRI_SETF(vertex[4].y); TRI_SETF(vertex[5].x); TRI_SETF(vertex[5].y); #endif } TRI_END ; GR_CHECK_SIZE() ; } /* */ /* Restore all the regs we trashed */ /* */ REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 1, 0x1) ; { REG_GROUP_SET(hw, fbzMode, gc->state.shadow.fbzMode) ; } REG_GROUP_END() ; REG_GROUP_BEGIN(BROADCAST_ID, c0, 2, 0x03) ; { REG_GROUP_SET(hw, c0, color0) ; REG_GROUP_SET(hw, c1, color1) ; } REG_GROUP_END() ; REG_GROUP_BEGIN(BROADCAST_ID, alphaMode, 1, 0x01) ; { REG_GROUP_SET(hw, alphaMode, alphaMode); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, fbzColorPath, 1, 0x1) ; { REG_GROUP_SET(hw, fbzColorPath, fbzColorPath) ; } REG_GROUP_END() ; #ifdef FX_GLIDE_NAPALM #if 0 if (!gc->mode2ppc) _grTex2ppc(GR_TMU0, FXFALSE) ; #endif if (gc->grPixelSize == 4) { REG_GROUP_BEGIN(BROADCAST_ID, stencilMode, 2, 0x3) ; { REG_GROUP_SET(hw, stencilMode, stencilMode) ; REG_GROUP_SET(hw, stencilOp, stencilOp) ; } REG_GROUP_END() ; } REG_GROUP_BEGIN(eChipFBI, combineMode, 1, 0x01) ; { REG_GROUP_SET(hw, combineMode, combineMode) ; } REG_GROUP_END() ; { int tmu; for (tmu = 0 ; tmu < gc->num_tmu ; tmu++) { SstRegs* tmuregs = SST_TMU(hw, tmu); const FifoChipField chipField = (FifoChipField)(0x02UL << tmu); REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuregs, combineMode, gc->state.shadow.tmuState[tmu].combineMode); } REG_GROUP_END(); } } #endif } #endif #undef FN_NAME } /* _grTriFill */ /*--------------------------------------------------------------------------- ** grBufferClear */ GR_ENTRY(grBufferClear, void, (GrColor_t color, GrAlpha_t alpha, FxU32 depth)) { #define FN_NAME "grBufferClear" GR_BEGIN_NOFIFOCHECK("grBufferClear", 86); GDBG_INFO_MORE(gc->myLevel, "(0x%x,0x%x,0x%x)\n", color, alpha, depth); /* validate the state */ if (gc->state.invalid) _grValidateState(); { const GrColor_t oldc1 = gc->state.shadow.color1; const FxU32 oldzacolor = gc->state.shadow.zaColor; const FxU32 fbzMode = gc->state.shadow.fbzMode; FxU32 zacolor = oldzacolor; #if FX_GLIDE_NAPALM FxBool restoreRenderMode = FXFALSE; #endif FxBool doneP = FXFALSE; FxBool doColorP, doAuxP = FXFALSE; /* validate the state */ /* Setup source registers */ doColorP = ((fbzMode & SST_RGBWRMASK) != 0); if (doColorP) { _grSwizzleColor(&color) ; #ifdef FX_GLIDE_NAPALM /* OR in Alpha component */ if (gc->grPixelSize == 4) color |= alpha << 24 ; #endif } if ((fbzMode & SST_ZAWRMASK) != 0) { if ((fbzMode & SST_ENALPHABUFFER) != 0) { doAuxP = FXTRUE; zacolor &= ~SST_ZACOLOR_ALPHA; zacolor |= (((FxU32) alpha) << SST_ZACOLOR_ALPHA_SHIFT); depth = alpha ; } else if ((fbzMode & SST_ENDEPTHBUFFER) != 0) { doAuxP = FXTRUE; if ((fbzMode & SST_WBUFFER) && (gc->grPixelSize == 4)) depth = depth << 8 | 0xff ; zacolor &= ~SST_ZACOLOR_DEPTH; zacolor |= (((FxU32) depth) << SST_ZACOLOR_DEPTH_SHIFT); } } /* Why were we called? */ if (!doColorP && !doAuxP) return; /* HACK! FIXME! This routine (or any of the ones it calls) is currently not updating * the register shadows properly. This could cause things to screw up in * the windowed case, so we make sure that we have enough room in the fifo * to write everything out into one buffer. %%KCD */ GR_CHECK_FOR_ROOM(512, 0); if (!doneP) { #ifdef GLIDE_INIT_HWC #ifdef FX_GLIDE_NAPALM #ifndef HAL_CSIM /* old school CSIM uses Nair instead of Wax */ /* */ /* do a hot WAX job on the buffer(s) */ /* to get all of their little hairs off */ /* */ if (gc->sliCount > 1) /* This code can only possibly help in Sli */ { /* We don't do bikini lines yet */ /* ie, clip window must be on an even chip boundary */ /* If we start doing bikini lines, we will need to either send diff't size */ /* blts to each chip, or send extra single line blts to certain chips */ /* in addition to a blt for the common area of the fill. */ /* [dBorca] * the `clipBottomTop' and `clipLeftRight' are defined wrong if we * want texturebuffer clears. Also failing the test below will get * us into `_grTriFill', which is not fixed for textureBuffer yet! */ if ((!(gc->state.shadow.clipBottomTop & (((gc->sliCount << gc->sliBandHeight) - 1) << SST_CLIPTOP_SHIFT)) && !(gc->state.shadow.clipBottomTop & (((gc->sliCount << gc->sliBandHeight) - 1) << SST_CLIPBOTTOM_SHIFT))) && _GlideRoot.environment.waxon && ((gc->state.tbufferMask & 0xf) == 0xf)) /* KoolSmoky - come back to this! tbufferMask incorrect! */ { FxU32 clipLeft, clipRight, clipTop, clipBottom ; FxU32 mask = 0xFFFFFFFF ; clipLeft = gc->state.shadow.clipLeftRight ; clipRight = clipLeft & SST_CLIPRIGHT ; clipLeft >>= SST_CLIPLEFT_SHIFT ; /* All of this wackiness here divides the the height of the blt by the */ /* bandheight * number of chips blting (since WAX doesn't speak Sli, we have to */ /* explicitly tell it to do less work). */ clipBottom = gc->state.shadow.clipBottomTop ; clipTop = (clipBottom & SST_CLIPTOP) ; clipTop >>= (gc->sliCount >> 1) ; clipBottom >>= (SST_CLIPBOTTOM_SHIFT + (gc->sliCount >> 1)) ; if (doColorP) { /* Color has already been swizzled to ARGB */ /* now we get to squish it to the proper size */ if (gc->grPixelSize == 2) color = ((color & 0xf8) >> 3) | /* blue */ ((color & 0xfc00) >> 5) | /* green */ ((color & 0xf80000) >> 8) ; /* red */ else { /* Apply color write mask for 32bpp mode */ mask = ((gc->state.shadow.renderMode & SST_RM_ALPHA_WMASK) ? 0xFF000000 : 0) | ((gc->state.shadow.renderMode & SST_RM_RED_WMASK) ? 0x00FF0000 : 0) | ((gc->state.shadow.renderMode & SST_RM_GREEN_WMASK) ? 0x0000FF00 : 0) | ((gc->state.shadow.renderMode & SST_RM_BLUE_WMASK) ? 0x000000FF : 0) ; } /* call 2D buffer clear */ if (gc->textureBuffer.on) { #if 0 /* [dBorca] don't use colBuffer addr/stride */ _grBufferClear2D(gc->state.shadow.colBufferAddr, clipLeft, clipBottom, clipRight, clipTop, color, mask, FXFALSE, gc->state.shadow.colBufferStride) ; #else /* [dBorca] right now we are discarding any clipping into texturebuffers. Fix me! */ _grBufferClear2D(gc->textureBuffer.addr, 0, 0, gc->textureBuffer.width, gc->textureBuffer.height, color, mask, FXFALSE, gc->textureBuffer.stride) ; #endif } else { _grBufferClear2D(gc->buffers0[gc->windowed ? 0 : gc->curBuffer], clipLeft, clipBottom, clipRight, clipTop, color, mask, gc->colTiled, gc->state.shadow.colBufferStride) ; /* If there is an AA buffer, clear that too. */ if (gc->enableSecondaryBuffer) _grBufferClear2D(gc->buffers1[gc->windowed ? 0 : gc->curBuffer], clipLeft, clipBottom, clipRight, clipTop, color, mask, gc->colTiled, gc->state.shadow.colBufferStride) ; } } if (doAuxP) { /* How nice. Depth is already in the format we want. */ /* Load up the slingshot, let one fly. */ /* THIS COULD BE FASTER: If the last 2D blt we did was to the same */ /* the clip window, src and dst offsets need not be re-asserted. */ if (gc->textureAuxBuffer.on) { #if 0 /* [dBorca] don't use auxBuffer addr/stride */ _grBufferClear2D(gc->state.shadow.auxBufferAddr, clipLeft, clipBottom, clipRight, clipTop, depth, mask, FXFALSE, gc->state.shadow.auxBufferStride) ; #else /* [dBorca] right now we are discarding any clipping into texturebuffers. Fix me! */ _grBufferClear2D(gc->textureAuxBuffer.addr, 0, 0, gc->textureAuxBuffer.width, gc->textureAuxBuffer.height, color, mask, FXFALSE, gc->textureAuxBuffer.stride) ; #endif } else { _grBufferClear2D(gc->buffers0[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, depth, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; /* ?Is this wrong? */ if (gc->enableSecondaryBuffer) _grBufferClear2D(gc->buffers1[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, depth, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; } } } else { /* */ /* Not on an even sli bandheight boundary or range... */ /* so use a triangle fill (yuck!) */ /* */ _grTriFill(color, depth, 0) ; } } else #endif #endif /* end of hot wax session */ { if (!gc->bInfo->sdRAM && !gc->windowed) { REG_GROUP_BEGIN(BROADCAST_ID, zaColor, 2, 0x41); { REG_GROUP_SET(hw, zaColor, zacolor); REG_GROUP_SET(hw, c1, color); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 3, 0x209); { /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1); /* Restore C1 and ZACOLOR */ REG_GROUP_SET(hw, zaColor, oldzacolor); REG_GROUP_SET(hw, c1, oldc1); } REG_GROUP_END(); } else { /* Windowed or SDRAM clears */ const FxU32 colorBufMode = ((fbzMode & ~(SST_ZAWRMASK | SST_ENDEPTHBUFFER)) | SST_RGBWRMASK | SST_ENRECTCLIP); /* Turn off writes to the aux buffer */ REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 1, 1); REG_GROUP_SET(hw, fbzMode, colorBufMode); REG_GROUP_END(); if (doColorP) { /* Clear Color Buffer */ REG_GROUP_BEGIN(BROADCAST_ID, c1, 1, 0x1); REG_GROUP_SET(hw, c1, color); REG_GROUP_END(); /* Execute the FASTFILL command */ REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 1, 1); REG_GROUP_SET(hw, fastfillCMD, 1); REG_GROUP_END(); } if (doAuxP) { FxU32 red, green, blue, convertedDepth; #define GETRED(a) ((a >> 11) & 0x1f) #define GETGREEN(a) ((a >> 5) & 0x3f) #define GETBLUE(a) (a & 0x1f) #ifdef FX_GLIDE_NAPALM if (gc->grPixelSize == 2) { #endif /* Convert 16-bit depth to 24-bit, ready for truncation: 20 10 0 321098765432109876543210 RRRRR000GGGGGG00BBBBB000 So, we get the 565 out of 16-bit depth, then operate like this: RED' = red << 3 GREEN' = green << 2 BLUE' = blue << 3 This way, when the fastFill hardware truncates, we still have all the bits we were given. We then simply recombin RED', BLUE', and GREEN' to make a 24-bit color value. capisce? */ red = GETRED(depth) << 3; green = GETGREEN(depth) << 2; blue = GETBLUE(depth) << 3; convertedDepth = ((red << 16) | (green << 8) | blue); #if FX_GLIDE_NAPALM /* If we are in 15bpp mode, then turn it off so that clears work as expected and we can clear all 16 bits. */ if((gc->state.shadow.renderMode & SST_RM_3D_MODE) == SST_RM_15BPP) { FxU32 renderMode = gc->state.shadow.renderMode; renderMode &= ~SST_RM_15BPP; REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 1, 0x01); REG_GROUP_SET(hw, renderMode, renderMode); REG_GROUP_END(); restoreRenderMode = FXTRUE; } #endif #ifdef FX_GLIDE_NAPALM } else { FxU32 renderMode = gc->state.shadow.renderMode ; /* All of that hoopla is no help at all in 32bpp mode */ /* since the depth buffer is 24bpp */ convertedDepth = depth ; /* Since we are treating the depth buffer as a color buffer, */ /* We had best enable color writes. */ renderMode |= SST_RM_RED_WMASK | SST_RM_GREEN_WMASK | SST_RM_BLUE_WMASK | SST_RM_ALPHA_WMASK ; REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 1, 0x01); REG_GROUP_SET(hw, renderMode, renderMode); REG_GROUP_END(); restoreRenderMode = FXTRUE; } #endif /* Clear Aux Buffer */ REG_GROUP_BEGIN(BROADCAST_ID, c1, 1, 0x1); REG_GROUP_SET(hw, c1, convertedDepth); REG_GROUP_END(); /* tbext */ REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.auxBufferAddr ); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer)? driInfo.stride : gc->state.shadow.auxBufferStride); #else /* defined(DRI_BUILD) */ REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.auxBufferStride ); #endif /* defined(DRI_BUILD) */ REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->grColBuf] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 2, 0x21); { /* Write the depth buffer as if it were a color buffer, * but w/ actual color buffer features * (dithering/chroma/stipple) cleared so that the * converted depth value does not get dorked along the * way down the eerie pathways of banshee. */ REG_GROUP_SET(hw, fbzMode, colorBufMode & ~(SST_ENCHROMAKEY | SST_ENSTIPPLE | SST_ENDITHER)); /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1); } REG_GROUP_END(); } /* Restore trashed things */ REG_GROUP_BEGIN(BROADCAST_ID, c1, 1, 0x1); REG_GROUP_SET(hw, c1, oldc1); REG_GROUP_END(); /* tbext */ if ( gc->textureBuffer.on ) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->textureBuffer.addr ); REG_GROUP_SET(hw, colBufferStride, gc->textureBuffer.stride ); REG_GROUP_END(); } else { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->buffers0[gc->windowed ? 0 : gc->curBuffer]); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif } /* endif gc->texRender.on */ #ifdef FX_GLIDE_NAPALM /* If we did a 32bpp depth clear, restore the color write masks */ if (restoreRenderMode) { REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 1, 0x01); REG_GROUP_SET(hw, renderMode, gc->state.shadow.renderMode); REG_GROUP_END(); } #endif REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 1, 1); REG_GROUP_SET(hw, fbzMode, fbzMode); REG_GROUP_END(); } } #else /* !GLIDE_INIT_HWC */ /* */ /* Life was simple in the days of DOS Glide */ /* */ REG_GROUP_BEGIN(BROADCAST_ID, zaColor, 2, 0x41); { REG_GROUP_SET(hw, zaColor, zacolor); REG_GROUP_SET(hw, c1, color); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 3, 0x209); { /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1); /* Restore C1 and ZACOLOR */ REG_GROUP_SET(hw, zaColor, oldzacolor); REG_GROUP_SET(hw, c1, oldc1); } REG_GROUP_END(); #endif /* !GLIDE_INIT_HWC */ } } #undef FN_NAME } /* grBufferClear */ /*--------------------------------------------------------------------------- ** grBufferClearExt */ GR_EXT_ENTRY(grBufferClearExt, void, (GrColor_t color, GrAlpha_t alpha, FxU32 depth, GrStencil_t stencil)) { #define FN_NAME "grBufferClearExt" GR_BEGIN_NOFIFOCHECK("grBufferClearExt", 86); GDBG_INFO_MORE(gc->myLevel, "(0x%x,0x%x,0x%x)\n", color, depth); /* validate the state so we can diddle the regs & restore them */ if (gc->state.invalid) _grValidateState() ; { GrColor_t oldc1 = gc->state.shadow.color1 ; FxU32 oldzacolor = gc->state.shadow.zaColor ; FxU32 zacolor = oldzacolor ; FxU32 fbzMode = gc->state.shadow.fbzMode ; #ifdef FX_GLIDE_NAPALM FxU32 oldstencilMode = gc->state.shadow.stencilMode ; FxU32 renderMode = gc->state.shadow.renderMode & ~SST_RM_DITHER_ROTATION ; FxBool doStencil = FXFALSE ; #endif FxBool doColorP, doAuxP = FXFALSE, restoreRenderStencil = FXFALSE; #ifdef FX_GLIDE_NAPALM if (gc->grPixelSize == 4) { doColorP = (gc->state.shadow.renderMode & SST_RM_RGBA_WMASK) ; /* OpenGL will always enable stencil mode before a clear if the client really wanted * to clear the stencil buffer. So, we won't mess with it if we don't have stenciling * enabled to save time. */ doStencil = (oldstencilMode & SST_STENCIL_WMASK) && (oldstencilMode & SST_STENCIL_ENABLE); if(doStencil) { /* Note that we cleared the stencil buffer at least once, so from * now on we have to preserve it's contents when we do a buffer clear. */ gc->stencilCleared = FXTRUE; } } else #endif doColorP = ((fbzMode & SST_RGBWRMASK) != 0) ; if ((fbzMode & SST_ZAWRMASK) != 0) { if ((fbzMode & SST_ENALPHABUFFER) != 0) { doAuxP = FXTRUE ; zacolor &= ~SST_ZACOLOR_ALPHA ; zacolor |= (((FxU32) alpha) << SST_ZACOLOR_ALPHA_SHIFT) ; depth = alpha ; } else if ((fbzMode & SST_ENDEPTHBUFFER) != 0) { doAuxP = FXTRUE; zacolor &= ~SST_ZACOLOR_DEPTH ; zacolor |= (((FxU32) depth) << SST_ZACOLOR_DEPTH_SHIFT) ; } } /* Why were we called? */ #ifdef FX_GLIDE_NAPALM if ((!doColorP && !doAuxP) && !doStencil) return; #else if (!doColorP && !doAuxP) return ; #endif /* FX_GLIDE_NAPALM */ if (doColorP) { _grSwizzleColor(&color); #ifdef FX_GLIDE_NAPALM /* OR in Alpha component */ if (gc->grPixelSize == 4) color |= alpha << 24 ; #endif } /* HACK! FIXME! This routine (or any of the ones it calls) is currently not updating * the register shadows properly. This could cause things to screw up in * the windowed case, so we make sure that we have enough room in the fifo * to write everything out into one buffer. %%KCD */ GR_CHECK_FOR_ROOM(512, 0); #ifdef GLIDE_INIT_HWC #ifdef FX_GLIDE_NAPALM #ifndef HAL_CSIM /* old school CSIM uses Nair instead of Wax */ /* */ /* do a hot WAX job on the buffer(s) */ /* to get all of their little hairs off */ /* */ if (gc->sliCount > 1) { /* This code can only possibly help in Sli */ /* [dBorca] * texturebuffer clears will fail badly! See `grClearBuffer' for needed * modifications. As soon as the required changes will be made, this comment * will become futile and shall be scheduled for deletion! :) */ /* We don't do bikini lines yet */ /* ie, clip window must be on an even chip boundary */ /* If we start doing bikini lines, we will need to either send diff't size */ /* blts to each chip, or send extra single line blts to certain chips */ /* in addition to a blt for the common area of the fill. */ if ((!(gc->state.shadow.clipBottomTop & (((gc->sliCount << gc->sliBandHeight) - 1) << SST_CLIPTOP_SHIFT)) && !(gc->state.shadow.clipBottomTop & (((gc->sliCount << gc->sliBandHeight) - 1) << SST_CLIPBOTTOM_SHIFT))) && _GlideRoot.environment.waxon && ((gc->state.tbufferMask & 0xf) == 0xf)) /* KoolSmoky - come back to this! tbufferMask incorrect! */ { FxU32 clipLeft, clipRight, clipTop, clipBottom ; FxU32 mask = 0xFFFFFFFF ; clipLeft = gc->state.shadow.clipLeftRight ; clipRight = clipLeft & SST_CLIPRIGHT ; clipLeft >>= SST_CLIPLEFT_SHIFT ; /* All of this wackiness here divides the the height of the blt by the */ /* bandheight * number of chips blting (since WAX doesn't speak Sli, we have to */ /* explicitly tell it to do less work). */ clipBottom = gc->state.shadow.clipBottomTop ; clipTop = (clipBottom & SST_CLIPTOP) ; clipTop >>= (gc->sliCount >> 1) ; clipBottom >>= (SST_CLIPBOTTOM_SHIFT + (gc->sliCount >> 1)) ; if (doColorP) { /* Color has already been swizzled to RGB */ /* now we get to squish it to the proper size */ if (gc->grPixelSize == 2) { color = ((color & 0xf8) >> 3) | /* blue */ ((color & 0xfc00) >> 5) | /* green */ ((color & 0xf80000) >> 8) ; /* red */ } else { /* Apply color write mask for 32bpp mode */ mask = ((gc->state.shadow.renderMode & SST_RM_ALPHA_WMASK) ? 0xFF000000 : 0) | ((gc->state.shadow.renderMode & SST_RM_RED_WMASK) ? 0x00FF0000 : 0) | ((gc->state.shadow.renderMode & SST_RM_GREEN_WMASK) ? 0x0000FF00 : 0) | ((gc->state.shadow.renderMode & SST_RM_BLUE_WMASK) ? 0x000000FF : 0) ; } /* call 2D buffer clear */ if (gc->textureBuffer.on) { _grBufferClear2D(gc->state.shadow.colBufferAddr, clipLeft, clipBottom, clipRight, clipTop, depth, mask, FXFALSE, gc->state.shadow.colBufferStride) ; } else { _grBufferClear2D(gc->buffers0[gc->windowed ? 0 : gc->curBuffer], clipLeft, clipBottom, clipRight, clipTop, color, mask, gc->colTiled, gc->state.shadow.colBufferStride) ; /* If there is an AA buffer, clear that too. */ if (gc->enableSecondaryBuffer) { _grBufferClear2D(gc->buffers1[gc->windowed ? 0 : gc->curBuffer], clipLeft, clipBottom, clipRight, clipTop, color, mask, gc->colTiled, gc->state.shadow.colBufferStride) ; } } } if (doAuxP) { /* How nice. Depth is already in the format we want. */ /* Load up the slingshot, let one fly. */ /* THIS COULD BE FASTER: If the last 2D blt we did was to the same */ /* the clip window, src and dst offsets need not be re-asserted. */ if (gc->grPixelSize == 4) { if (doStencil) { mask = ((gc->state.shadow.stencilMode & SST_STENCIL_WMASK) << (24 - SST_STENCIL_WMASK_SHIFT)) | 0x00FFFFFF ; depth = ((FxU32)stencil << 24) | (depth & 0x00FFFFFF) ; } /* If the stencil buffer has been cleared, then we have to leave it alone...*/ else if(gc->stencilCleared || 1) { mask = 0x00FFFFFF ; } else { /* Otherwise we can just blow it away... */ mask = 0xFFFFFFFF ; } } if (gc->textureAuxBuffer.on) { _grBufferClear2D(gc->state.shadow.auxBufferAddr, clipLeft, clipBottom, clipRight, clipTop, depth, mask, FXFALSE, gc->state.shadow.auxBufferStride) ; } else { _grBufferClear2D(gc->buffers0[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, depth, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; if (gc->enableSecondaryBuffer) _grBufferClear2D(gc->buffers1[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, depth, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; } } else if (doStencil) { mask = ((gc->state.shadow.stencilMode & SST_STENCIL_WMASK) << (24 - SST_STENCIL_WMASK_SHIFT)) ; depth = ((FxU32)stencil << 24); if (gc->textureAuxBuffer.on) { _grBufferClear2D(gc->state.shadow.auxBufferAddr, clipLeft, clipBottom, clipRight, clipTop, depth, mask, FXFALSE, gc->state.shadow.auxBufferStride) ; } else { _grBufferClear2D(gc->buffers0[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, stencil << 24, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; /* ?Is this wrong? */ if (gc->enableSecondaryBuffer) { _grBufferClear2D(gc->buffers1[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, stencil << 24, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; } } } } else { /* */ /* Not on an even sli bandheight boundary or range, or tbuffer mask isn't set to all buffers... */ /* so use a triangle fill (yuck!) */ /* */ _grTriFill(color, depth, stencil) ; } /* KoolSmoky - there is nothing else to do so return */ return; } else #endif #endif /* end of hot wax session */ if (!gc->bInfo->sdRAM && !gc->windowed) { /* */ /* Fullscreen Non-SLI SGRAM clear */ /* */ REG_GROUP_BEGIN(BROADCAST_ID, zaColor, 2, 0x41) ; { REG_GROUP_SET(hw, zaColor, zacolor) ; REG_GROUP_SET(hw, c1, color) ; } REG_GROUP_END() ; #ifdef FX_GLIDE_NAPALM REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 2, 0x3) ; { REG_GROUP_SET(hw, renderMode, renderMode) ; REG_GROUP_SET(hw, stencilMode, (doStencil ? (stencil | SST_STENCIL_ENABLE | oldstencilMode) : 0)) ; } REG_GROUP_END() ; #endif REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 3, 0x209); { /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1); /* Restore C1 and ZACOLOR */ REG_GROUP_SET(hw, zaColor, oldzacolor); REG_GROUP_SET(hw, c1, oldc1); } REG_GROUP_END(); /* */ /* Restore whatever else we trashed */ /* */ #ifdef FX_GLIDE_NAPALM REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 2, 0x3); { REG_GROUP_SET(hw, renderMode, gc->state.shadow.renderMode) ; REG_GROUP_SET(hw, stencilMode, oldstencilMode) ; } REG_GROUP_END() ; #endif /* KoolSmoky - there is nothing else to do so return */ return; } else { /* */ /* Windowed / SDRAM clear */ /* (it's possible this surface could be linear) */ /* */ /* If we are in 16-bit mode then we can handle all tbuffer clears */ /* properly with this code path. Otherwise if we're in 32-bit mode */ /* and the tbuffer mask isn't set to all four samples, we have to fall back */ /* to triangle clears to do the right thing. -- KCD */ /* */ /* Actually, that's not entirely true. The main reason to fall back to */ /* triangle clears for tbuffer clears is because we can't use WAX to do */ /* tbuffer clears since the 2D engine doesn't pay attention to the chip */ /* mask (D'oh). So, in theory we can still do fastfill based tbuffer */ /* clears as long as we know we don't need to use WAX. Yikes. -- KCD */ /* */ if((gc->grPixelSize == 2) || ((gc->state.tbufferMask & 0xf) == 0xf) || /* KoolSmoky - come back to this! tbufferMask incorrect! */ (!doStencil) || (doStencil && ((gc->state.shadow.stencilMode & SST_STENCIL_WMASK) == SST_STENCIL_WMASK))) { FxU32 colorBufMode ; colorBufMode = ((fbzMode & ~(SST_ZAWRMASK | SST_ENDEPTHBUFFER)) | SST_RGBWRMASK | SST_ENRECTCLIP) ; /* Turn off writes to the aux buffer */ REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 1, 1) ; REG_GROUP_SET(hw, fbzMode, colorBufMode) ; REG_GROUP_END() ; if (doColorP) { /* Clear Color Buffer to color */ REG_GROUP_BEGIN(BROADCAST_ID, c1, 1, 0x1) ; REG_GROUP_SET(hw, c1, color) ; REG_GROUP_END() ; /* Execute the FASTFILL command */ REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 1, 1) ; REG_GROUP_SET(hw, fastfillCMD, 1) ; REG_GROUP_END() ; } #ifdef FX_GLIDE_NAPALM if (doStencil && ((gc->state.shadow.stencilMode & SST_STENCIL_WMASK) != SST_STENCIL_WMASK)) { /* */ /* Windowed & SDRAM stencil clears have to be done with hot WAX */ /* since OpenGL wants to apply the 8bit stencil write mask */ /* and the color fastfill can only mask entire channels */ /* */ FxU32 clipLeft, clipRight, clipTop, clipBottom ; FxU32 mask ; FxU32 BC2D_color; clipLeft = gc->state.shadow.clipLeftRight ; clipRight = clipLeft & SST_CLIPRIGHT ; clipLeft >>= SST_CLIPLEFT_SHIFT ; clipBottom = gc->state.shadow.clipBottomTop ; clipTop = clipBottom & SST_CLIPTOP ; clipBottom >>= SST_CLIPBOTTOM_SHIFT ; if (doAuxP) { /* If we get to clear depth at the same time, so much the better */ mask = ((gc->state.shadow.stencilMode & SST_STENCIL_WMASK) << (24 - SST_STENCIL_WMASK_SHIFT)) | 0x00FFFFFF ; BC2D_color = ((FxU32)stencil << 24) | (depth & 0x00FFFFFF) ; } else { mask = ((gc->state.shadow.stencilMode & SST_STENCIL_WMASK) << (24 - SST_STENCIL_WMASK_SHIFT)) ; BC2D_color = ((FxU32)stencil << 24); } if (gc->textureAuxBuffer.on) { _grBufferClear2D(gc->state.shadow.auxBufferAddr, clipLeft, clipBottom, clipRight, clipTop, BC2D_color, mask, FXFALSE, gc->state.shadow.auxBufferStride) ; } else { _grBufferClear2D(gc->buffers0[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, BC2D_color, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; /* ?Is this wrong? */ if (gc->enableSecondaryBuffer) { _grBufferClear2D(gc->buffers1[gc->grColBuf], clipLeft, clipBottom, clipRight, clipTop, BC2D_color, mask, gc->auxTiled, gc->state.shadow.auxBufferStride) ; } } } else #endif /* FX_GLIDE_NAPALM */ if (doAuxP || ((gc->grPixelSize == 4) && doStencil)) { FxU32 red, green, blue, convertedDepth ; #define GETRED(a) ((a >> 11) & 0x1f) #define GETGREEN(a) ((a >> 5) & 0x3f) #define GETBLUE(a) (a & 0x1f) #ifdef FX_GLIDE_NAPALM if (gc->grPixelSize == 2) { #endif /* Convert 16-bit depth to 24-bit, ready for truncation: 20 10 0 321098765432109876543210 RRRRR000GGGGGG00BBBBB000 So, we get the 565 out of 16-bit depth, then operate like this: RED' = red << 3 GREEN' = green << 2 BLUE' = blue << 3 This way, when the fastFill hardware truncates, we still have all the bits we were given. We then simply recombin RED', BLUE', and GREEN' to make a 24-bit color value. capisce? */ red = GETRED(depth) << 3 ; green = GETGREEN(depth) << 2 ; blue = GETBLUE(depth) << 3 ; convertedDepth = ((red << 16) | (green << 8) | blue) ; #ifdef FX_GLIDE_NAPALM } else { /* All of that hoopla is no help at all in 32bpp mode */ /* since the depth buffer is 24bpp */ /* */ /* enable RGB writes if clearing the depth components. */ /* enable A writes if we want to clear the stencil buffer too. */ convertedDepth = depth ; renderMode &= ~(SST_RM_ALPHA_WMASK | SST_RM_RGBA_WMASK) ; if(doAuxP) { renderMode |= SST_RM_RED_WMASK | SST_RM_GREEN_WMASK | SST_RM_BLUE_WMASK ; } if(doStencil) { renderMode |= SST_RM_ALPHA_WMASK; convertedDepth = (depth & 0xffffff) | (stencil << 24); } REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 2, 0x03) ; REG_GROUP_SET(hw, renderMode, renderMode) ; REG_GROUP_SET(hw, stencilMode, oldstencilMode & ~(SST_STENCIL_WMASK | SST_STENCIL_ENABLE)); REG_GROUP_END() ; restoreRenderStencil = FXTRUE; } #endif /* Clear Aux Buffer */ REG_GROUP_BEGIN(BROADCAST_ID, c1, 1, 0x1) ; REG_GROUP_SET(hw, c1, convertedDepth) ; REG_GROUP_END() ; /* tbext */ REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3) ; REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.auxBufferAddr) ; #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.auxBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.auxBufferStride ); #endif REG_GROUP_END() ; #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->grColBuf] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 2, 0x21) ; { /* Write the depth buffer as if it were a color buffer, * but w/ actual color buffer features * (dithering/chroma/stipple) cleared so that the * converted depth value does not get dorked along the * way down the eerie pathways of banshee. */ REG_GROUP_SET(hw, fbzMode, colorBufMode & ~(SST_ENCHROMAKEY | SST_ENSTIPPLE | SST_ENDITHER)) ; /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1) ; } REG_GROUP_END() ; } /* end of doAuxP */ /* Restore trashed data */ REG_GROUP_BEGIN(BROADCAST_ID, c1, 1, 0x1); REG_GROUP_SET(hw, c1, oldc1); REG_GROUP_END(); /* tbext */ if (gc->textureBuffer.on) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3) ; REG_GROUP_SET(hw, colBufferAddr, gc->textureBuffer.addr) ; REG_GROUP_SET(hw, colBufferStride, gc->textureBuffer.stride) ; REG_GROUP_END() ; } else { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3) ; REG_GROUP_SET(hw, colBufferAddr, gc->buffers0[gc->windowed ? 0 : gc->curBuffer]) ; #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_END() ; #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif } /* endif gc->texRender.on */ #ifdef FX_GLIDE_NAPALM /* If we did a 32bpp depth (only) clear, restore the color write masks if we need to. */ if (restoreRenderStencil) { REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 2, 0x03) ; REG_GROUP_SET(hw, renderMode, gc->state.shadow.renderMode) ; REG_GROUP_SET(hw, stencilMode, oldstencilMode) ; REG_GROUP_END(); } #endif REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 1, 1) ; REG_GROUP_SET(hw, fbzMode, fbzMode) ; REG_GROUP_END() ; } else { /* Crap. TBuffering is enabled and we can't individually * talk to a single chip with WAX (which we may have to use up above) * so we have to use the triangle engine to do TBuffer clears. UGH! */ _grTriFill(color, depth, stencil) ; } /* KoolSmoky - there is nothing else to do so return */ return; } /* end of windowed or sdram clear */ #else /* !GLIDE_INIT_HWC */ /* */ /* DOS Glide */ /* */ REG_GROUP_BEGIN(BROADCAST_ID, zaColor, 2, 0x41); { REG_GROUP_SET(hw, zaColor, zacolor); REG_GROUP_SET(hw, c1, color); } REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM if (doStencil) { REG_GROUP_BEGIN(BROADCAST_ID, stencilMode, 1, 0x1); { REG_GROUP_SET(hw, stencilMode, (oldstencilMode & 0xffffff00) | stencil); } REG_GROUP_END(); } #endif REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 3, 0x209); { /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1); /* Restore C1 and ZACOLOR */ REG_GROUP_SET(hw, zaColor, oldzacolor); REG_GROUP_SET(hw, c1, oldc1); } REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM if (doStencil) { REG_GROUP_BEGIN(BROADCAST_ID, stencilMode, 1, 0x1); { REG_GROUP_SET(hw, stencilMode, oldstencilMode); } REG_GROUP_END(); } #endif #endif /* !GLIDE_INIT_HWC */ } #undef FN_NAME } /* grBufferClearExt */ #if 0 /*--------------------------------------------------------------------------- ** grBufferClear */ GR_ENTRY(grBufferClear, void, (GrColor_t color, GrAlpha_t alpha, FxU32 depth)) { #define FN_NAME "grBufferClear" GR_BEGIN_NOFIFOCHECK("grBufferClear", 86); GDBG_INFO_MORE(gc->myLevel, "(0x%x,0x%x,0x%x)\n", color, alpha, depth); /* validate the state */ if (gc->state.invalid) _grValidateState(); { const GrColor_t oldc1 = gc->state.shadow.color1; const FxU32 oldzacolor = gc->state.shadow.zaColor; const FxU32 fbzMode = gc->state.shadow.fbzMode; FxU32 zacolor = oldzacolor; FxBool doColorP = ((fbzMode & SST_RGBWRMASK) != 0), doneP = FXFALSE, doAuxP = FXFALSE; /* Setup source registers */ if (doColorP) _grSwizzleColor(&color); if ((fbzMode & SST_ZAWRMASK) != 0) { if ((fbzMode & SST_ENALPHABUFFER) != 0) { doAuxP = FXTRUE; zacolor &= ~SST_ZACOLOR_ALPHA; zacolor |= (((FxU32) alpha) << SST_ZACOLOR_ALPHA_SHIFT); } else if ((fbzMode & SST_ENDEPTHBUFFER) != 0) { doAuxP = FXTRUE; zacolor &= ~SST_ZACOLOR_DEPTH; zacolor |= (((FxU32) depth) << SST_ZACOLOR_DEPTH_SHIFT); } } /* Why were we called? */ if (!doColorP && !doAuxP) return; /* A2 and above have functioning fastfill */ if (!doneP) { REG_GROUP_BEGIN(BROADCAST_ID, zaColor, 2, 0x41); { REG_GROUP_SET(hw, zaColor, zacolor); REG_GROUP_SET(hw, c1, color); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, fastfillCMD, 3, 0x209); { /* Execute the FASTFILL command */ REG_GROUP_SET(hw, fastfillCMD, 1); /* Restore C1 and ZACOLOR */ REG_GROUP_SET(hw, zaColor, oldzacolor); REG_GROUP_SET(hw, c1, oldc1); } REG_GROUP_END(); } } #undef FN_NAME } /* grBufferClear */ #endif #ifndef DRI_BUILD /*--------------------------------------------------------------------------- ** grBufferSwap ** ** NOTE: This routine should be COMPLETELY device-independant, ** but it isn't right now because we need to move all the ** code for the splash screen into the init library. */ GR_ENTRY(grBufferSwap, void, (FxU32 swapInterval)) { #define FN_NAME "grBufferSwap" GR_BEGIN_NOFIFOCHECK(FN_NAME,86); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",swapInterval); #ifdef FX_GLIDE_NAPALM #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) /* Window hacky stuff */ if (gc->windowed) { extern void _grFlipWindowSurface(); grFinish(); _grFlipWindowSurface(); gc->stats.bufferSwaps++; return; } #endif // 4x FSAA or greater FSAA if (0 && gc->grPixelSample >= 4) { int sample = gc->stats.bufferSwaps%4; // We want to accumulate swaps so don't swap now if (sample) { _grChipMask(0x1 << sample); gc->chipmask = sample; gc->stats.bufferSwaps++; return; } //grTBufferWriteMaskExt(0xF); } if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); } #endif /* optionally display the 3Dfx powerfield logo overlay */ if (_GlideRoot.environment.shamelessPlug) _grShamelessPlug(); #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) if (_GlideRoot.environment.aaToggleKey) { if(gc->grPixelSample > 1) { FxU16 keyState = GetAsyncKeyState(_GlideRoot.environment.aaToggleKey); if((keyState & 0x8001) == 0x8001) { static FxU32 aaEnabled = 1; aaEnabled ^= 1; if(aaEnabled) { grEnable(GR_AA_MULTI_SAMPLE); } else { grDisable(GR_AA_MULTI_SAMPLE); } } } } if(_GlideRoot.environment.aaScreenshotKey) { FxU16 keyState = GetAsyncKeyState(_GlideRoot.environment.aaScreenshotKey); if((keyState & 0x8001) == 0x8001) { grFinish(); hwcAAScreenShot(gc->bInfo, gc->curBuffer, _GlideRoot.environment.ditherHwcAA); } } #elif (GLIDE_PLATFORM & GLIDE_OS_MACOS) if (_GlideRoot.environment.aaToggleKey || _GlideRoot.environment.aaScreenshotKey) { static KeyMapByteArray key_map[2]; static int current_key_map = 0; current_key_map = (current_key_map + 1) & 1; GetKeys((FxU32*) key_map[current_key_map]); if (_GlideRoot.environment.aaToggleKey) { if(gc->grPixelSample > 1) { FxU32 key = _GlideRoot.environment.aaToggleKey; key = (key & keyCodeMask) >> 8; /* If current state is down and previous state is not down, then toggle. */ if( (key_map[current_key_map][key >> 3] & (1L << (key & 0x7))) && !(key_map[current_key_map^1][key >> 3] & (1L << (key & 0x7)))) { static FxU32 aaEnabled = 1; aaEnabled ^= 1; if(aaEnabled) { grEnable(GR_AA_MULTI_SAMPLE); } else { grDisable(GR_AA_MULTI_SAMPLE); } } } } if(_GlideRoot.environment.aaScreenshotKey) { FxU32 key = _GlideRoot.environment.aaScreenshotKey; key = (key & keyCodeMask) >> 8; /* If current state is down and previous state is not down, then toggle. */ if( (key_map[current_key_map][key >> 3] & (1L << (key & 0x7))) && !(key_map[current_key_map^1][key >> 3] & (1L << (key & 0x7)))) { grFinish(); hwcAAScreenShot(gc->bInfo, gc->curBuffer); } } } #endif #if A0_AA_SWAP_WORKAROUND /* EFFAGE... AA seems to require swap intervals > 0 */ /* However, if the user decides to use the environment */ /* variable, then well let buffer swaps happen whenever. */ /* Check with Scott to see if this is the desired behaviour. */ if(gc->grPixelSample > 1 && swapInterval == 0) swapInterval = 1; #endif /* check for environmental override */ if (_GlideRoot.environment.swapInterval >= 0) { swapInterval = _GlideRoot.environment.swapInterval; } if (swapInterval) { if (swapInterval > 1) swapInterval = ((swapInterval - 1) << 1) | 1; /* Format for hw */ } while(_grBufferNumPending() > _GlideRoot.environment.swapPendingCount); #ifndef HAL_CSIM /* Cycle the buffer indices */ { const FxU32 numBufs = gc->state.num_buffers; FxU32* bufPtrs[3]; FxU32 i; bufPtrs[0] = &gc->curBuffer; bufPtrs[1] = &gc->frontBuffer; bufPtrs[2] = &gc->backBuffer; for(i = 0; i < sizeof(bufPtrs) / sizeof(*bufPtrs); i++) { FxU32 curBufIndex = *bufPtrs[i] + 1; if (curBufIndex == numBufs) curBufIndex = 0; *bufPtrs[i] = curBufIndex; } } #if USE_PACKET_FIFO { int i, j = -1; FxU32 newBufferSwaps = (FxU32) gc->cmdTransportInfo.fifoPtr - (FxU32) gc->cmdTransportInfo.fifoStart; for ( i = 0; i < MAX_BUFF_PENDING && j == -1; i++) { if (gc->bufferSwaps[i] == 0xffffffff) { gc->bufferSwaps[i] = newBufferSwaps; j = i; } } GR_ASSERT(j != -1); gc->swapsPending++; } #endif REG_GROUP_BEGIN(BROADCAST_ID, leftOverlayBuf, 1, 0x1); REG_GROUP_SET(hw, leftOverlayBuf, gc->buffers0[gc->frontBuffer]); REG_GROUP_END(); if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, leftDesktopBuf, 1, 0x1); REG_GROUP_SET(hw, leftDesktopBuf, gc->buffers1[gc->frontBuffer]); REG_GROUP_END(); swapInterval |= SST_SWAP_DESKTOP_EN; } /* Just 0x1 for mask is OK here since we're writing one register */ REG_GROUP_BEGIN(BROADCAST_ID, swapbufferCMD, 1, 0x1); REG_GROUP_SET(hw, swapbufferCMD, swapInterval); REG_GROUP_END(); #else #if USE_PACKET_FIFO REG_GROUP_BEGIN(BROADCAST_ID, swapbufferCMD, 1, 0x1); REG_GROUP_SET(hw, swapbufferCMD, swapInterval); REG_GROUP_END(); #else GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET_DIRECT(BROADCAST_ID, hw, swapbufferCMD, 0x1); GR_CHECK_SIZE(); #endif #endif #if defined( TACO_MEMORY_FIFO_HACK ) if(_GlideRoot.environment.memFIFOHack) _FifoFlush(); #endif REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers0[gc->curBuffer]); REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif #ifdef GLIDE_DEBUG { if ((FxI32)_GlideRoot.environment.snapshot > 0) { static char saveDBG[GDBG_MAX_LEVELS]; int i; /* turn off tracing after frame 0 and the snapshot frame */ if ((gc->stats.bufferSwaps == 0) || (gc->stats.bufferSwaps == _GlideRoot.environment.snapshot + 3)) { GDBG_PRINTF(FN_NAME": FX_SNAPSHOT (%ld)\n", gc->stats.bufferSwaps); for (i = 1; i < GDBG_MAX_LEVELS; i++) { if (gc->stats.bufferSwaps == 0) saveDBG[i] = (char)GDBG_GET_DEBUGLEVEL(i); GDBG_SET_DEBUGLEVEL(i, 0); } } /* turn on tracing after the snapshot frame */ if (gc->stats.bufferSwaps == _GlideRoot.environment.snapshot) { GDBG_PRINTF(FN_NAME": FX_SNAPSHOT (%ld)\n", gc->stats.bufferSwaps); for (i = 1; i < GDBG_MAX_LEVELS; i++) { GDBG_SET_DEBUGLEVEL(i, saveDBG[i]); } } } } #endif /* GLIDE_DEBUG */ #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( gc->chipmask ); } #endif gc->stats.bufferSwaps++; /* Hey, guess what: If we don't put this freaky NOP/Flush here * things turn up missing (the initial help screen in test25, * par example) on voodoo5 agp cards. */ #ifdef FX_GLIDE_NAPALM REG_GROUP_BEGIN(BROADCAST_ID, nopCMD, 1, 0x1); REG_GROUP_SET(hw, nopCMD, 0) ; REG_GROUP_END(); #endif P6FENCE ; /* Bump & Grind if called for */ if (!gc->cmdTransportInfo.autoBump) GR_BUMP_N_GRIND; // 4x FSAA or greater FSAA if (0 && gc->grPixelSample >= 4) { _grChipMask(1); gc->chipmask = 1; // grTBufferWriteMaskExt(0x11); } GR_END(); #undef FN_NAME } /* grBufferSwap */ #else /* defined(DRI_BUILD) */ /*--------------------------------------------------------------------------- ** grBufferSwap ** ** NOTE: This routine should be COMPLETELY device-independant, ** but it isn't right now because we need to move all the ** code for the splash screen into the init library. */ GR_ENTRY(grDRIBufferSwap, void, (FxU32 swapInterval)) { FxU32 regMask; int cnt, x, y, w, h; #define FN_NAME "grBufferSwap" GR_BEGIN_NOFIFOCHECK(FN_NAME,86); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",swapInterval); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); } #endif /* optionally display the 3Dfx powerfield logo overlay */ if (_GlideRoot.environment.shamelessPlug) _grShamelessPlug(); /* check for environmental override */ if (_GlideRoot.environment.swapInterval >= 0) { swapInterval = _GlideRoot.environment.swapInterval; } if (swapInterval) { if (swapInterval > 1) swapInterval = ((swapInterval - 1) << 1) | 1; /* Format for hw */ } while(_grBufferNumPending() > 3); #if USE_PACKET_FIFO { int i, j = -1; for ( i = 0; i < MAX_BUFF_PENDING && j == -1; i++) { if (gc->bufferSwaps[i] == 0xffffffff) { gc->bufferSwaps[i] = (FxU32) gc->cmdTransportInfo.fifoPtr - (FxU32) gc->cmdTransportInfo.fifoStart; j = i; } } GR_ASSERT(j != -1); gc->swapsPending++; } #endif /* Just 0x1 for mask is OK here since we're writing one register */ REG_GROUP_BEGIN(BROADCAST_ID, swapbufferCMD, 1, 0x1); REG_GROUP_SET(hw, swapbufferCMD, swapInterval); REG_GROUP_END(); cnt=driInfo.numClip; if (cnt) { /* Copy */ regMask=0; ADDWAXMASK(regMask, srcBaseAddr, srcBaseAddr); ADDWAXMASK(regMask, srcFormat, srcBaseAddr); REG_GROUP_BEGIN_WAX(srcBaseAddr, 2, regMask); REG_GROUP_SET_WAX(hw, srcBaseAddr, gc->buffers0[1]|BIT(31)); REG_GROUP_SET_WAX(hw, srcFormat, gc->strideInTiles | ((driInfo.cpp+1)<<16)); REG_GROUP_END(); do { cnt--; x=driInfo.pClip[cnt].x1; y=driInfo.pClip[cnt].y1; w=driInfo.pClip[cnt].x2-x; h=driInfo.pClip[cnt].y2-y; regMask=0; ADDWAXMASK(regMask, srcXY, srcXY); ADDWAXMASK(regMask, dstSize, srcXY); ADDWAXMASK(regMask, dstXY, srcXY); ADDWAXMASK(regMask, command, srcXY); REG_GROUP_BEGIN_WAX(srcXY, 4, regMask); REG_GROUP_SET_WAX(hw, srcXY, x | ((driInfo.y+(y-driInfo.y))<<16)); REG_GROUP_SET_WAX(hw, dstSize, (w&0x1FFF)|((h&0x1FFF)<<16)); REG_GROUP_SET_WAX(hw, dstXY, (x&0x1FFF) | ((y&0x1FFF)<<16)); REG_GROUP_SET_WAX(hw, command, (0xCC<<24) | 0x1 | BIT(8)); REG_GROUP_END(); } while (cnt); /* Put things back as X expects them */ regMask=0; ADDWAXMASK(regMask, srcBaseAddr, srcBaseAddr); ADDWAXMASK(regMask, srcFormat, srcBaseAddr); REG_GROUP_BEGIN_WAX(srcBaseAddr, 2, regMask); REG_GROUP_SET_WAX(hw, srcBaseAddr, gc->buffers0[0]); REG_GROUP_SET_WAX(hw, srcFormat, driInfo.stride | (3<<16)); REG_GROUP_END(); } #ifdef GLIDE_DEBUG { if ((FxI32)_GlideRoot.environment.snapshot > 0) { static char saveDBG[GDBG_MAX_LEVELS]; int i; /* turn off tracing after frame 0 and the snapshot frame */ if ((gc->stats.bufferSwaps == 0) || (gc->stats.bufferSwaps == _GlideRoot.environment.snapshot + 3)) { GDBG_PRINTF(FN_NAME": FX_SNAPSHOT (%ld)\n", gc->stats.bufferSwaps); for (i = 1; i < GDBG_MAX_LEVELS; i++) { if (gc->stats.bufferSwaps == 0) saveDBG[i] = (char)GDBG_GET_DEBUGLEVEL(i); GDBG_SET_DEBUGLEVEL(i, 0); } } /* turn on tracing after the snapshot frame */ if (gc->stats.bufferSwaps == _GlideRoot.environment.snapshot) { GDBG_PRINTF(FN_NAME": FX_SNAPSHOT (%ld)\n", gc->stats.bufferSwaps); for (i = 1; i < GDBG_MAX_LEVELS; i++) { GDBG_SET_DEBUGLEVEL(i, saveDBG[i]); } } } } #endif /* GLIDE_DEBUG */ #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( gc->chipmask ); } #endif gc->stats.bufferSwaps++; GR_END(); #undef FN_NAME } /* grBufferSwap */ #endif /* defined(DRI_BUILD) */ /*--------------------------------------------------------------------------- ** grBufferNumPending */ int FX_CSTYLE _grBufferNumPending(void) { #if USE_PACKET_FIFO volatile FxU32 dummy, depth0, depth1, readPtr0, readPtr1, readPtr; volatile int i; int pend; /* Num Swaps pending */ #if CHECK_SLAVE_SWAPCMD FxU32 chip ; #endif GR_DCL_GC; /* If we're not using hole counting then we need to make sure that * any queued commands are actually flushed before checking the fifo * ptr's location. */ if (!gc->cmdTransportInfo.autoBump) GR_BUMP_N_GRIND; /* HACK HACK HACK */ do { readPtr0 = GET(gc->cRegs->cmdFifo0.readPtrL) ; dummy = _grSstStatus(); readPtr1 = GET(gc->cRegs->cmdFifo0.readPtrL) ; /* KCD: I believe that swap commands are synchronized across chips, so it should be good enough to just track the master's read pointer. */ #if CHECK_SLAVE_SWAPCMD if(_GlideRoot.environment.checkSlaveSwapCMD > 0) if (gc->chipCount) for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) readPtr1 = ((readPtr1 < GET(gc->slaveCRegs[chip]->cmdFifo0.readPtrL)) ? readPtr1 : GET(gc->slaveCRegs[chip]->cmdFifo0.readPtrL)) ; #endif } while (readPtr0 != readPtr1); readPtr = readPtr1 - gc->cmdTransportInfo.fifoOffset; if (readPtr == gc->lastSwapCheck) { do { depth0 = GET(gc->cRegs->cmdFifo0.depth); depth1 = GET(gc->cRegs->cmdFifo0.depth); #if CHECK_SLAVE_SWAPCMD if(_GlideRoot.environment.checkSlaveSwapCMD > 1) if (gc->chipCount) for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) depth1 = ((depth1 < GET(gc->slaveCRegs[chip]->cmdFifo0.depth)) ? depth1 : GET(gc->slaveCRegs[chip]->cmdFifo0.depth)) ; #endif } while (depth0 != depth1); if (depth1 == 0) { for(i = MAX_BUFF_PENDING; i >= 0; --i) gc->bufferSwaps[i] = 0xffffffff; gc->swapsPending = 0; goto NPDONE; } } else /* ** There are two cases here: One where the read pointer has wrapped around ** behind us, and one where it's ahead of us. */ if (readPtr < gc->lastSwapCheck) { /* We've wrapped */ for(i = MAX_BUFF_PENDING; i >= 0; --i) { /* If it's between the last check and the end of the FIFO or between the beginning of the FIFO and the current Read pointer, then it's gone */ if(gc->bufferSwaps[i] != 0xffffffff) { if((gc->bufferSwaps[i] >= gc->lastSwapCheck) || (gc->bufferSwaps[i] <= readPtr)) { --gc->swapsPending; gc->bufferSwaps[i] = 0xffffffff; /* Free swap slot */ } } } } else { /* It's behind us */ for(i = MAX_BUFF_PENDING; i >= 0; --i) { if(gc->bufferSwaps[i] != 0xffffffff) { if((gc->bufferSwaps[i] >= gc->lastSwapCheck) && (gc->bufferSwaps[i] <= readPtr)) { --gc->swapsPending; gc->bufferSwaps[i] = 0xffffffff; /* Free swap slot */ } } } } gc->lastSwapCheck = readPtr; NPDONE: pend = gc->swapsPending; GDBG_INFO(86,"grBufferNumPending() = %d\n", pend); return pend; #else return 0; #endif } /* grBufferNumPending */ /*--------------------------------------------------------------------------- ** grChromakeyMode */ GR_STATE_ENTRY(grChromakeyMode, void, (GrChromakeyMode_t mode)) { #define FN_NAME "_grChromakeyMode" FxU32 fbzMode; GR_BEGIN_NOFIFOCHECK("_grChromakeyMode", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", mode); fbzMode = gc->state.shadow.fbzMode; if (mode == GR_CHROMAKEY_ENABLE) fbzMode |= SST_ENCHROMAKEY; else fbzMode &= ~SST_ENCHROMAKEY; gc->state.shadow.fbzMode = fbzMode; #undef FN_NAME } /* grChromaKeyMode */ GR_STATE_ENTRY(grChromaMode, void, (GrChromaRangeMode_t mode)) { #define FN_NAME "_grChromaMode" FxU32 fbzMode, chromaRange; GR_BEGIN_NOFIFOCHECK("_grChromaMode", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", mode); fbzMode = gc->state.shadow.fbzMode; chromaRange = gc->state.shadow.chromaRange; if (mode == GR_CHROMARANGE_ENABLE_EXT) { fbzMode |= SST_ENCHROMAKEY; chromaRange |= SST_ENCHROMARANGE; } else if ((mode == GR_CHROMARANGE_DISABLE_EXT) && (gc->state.stateArgs.grChromakeyModeArgs.mode == GR_CHROMAKEY_DISABLE)) { fbzMode &= ~SST_ENCHROMAKEY; chromaRange |= ~SST_ENCHROMARANGE; } else chromaRange |= ~SST_ENCHROMARANGE; gc->state.shadow.fbzMode = fbzMode; gc->state.shadow.chromaRange = chromaRange; #undef FN_NAME } /* grChromaMode */ /*--------------------------------------------------------------------------- ** _grClipNormalizeAndGenerateRegValues ** ** This routine normalizes clip variables to screen_width and ** screen_height, then generates the values to be written to the ** registers clipLeftRight and clipBottomTop. The reason for its ** existence is that BOTH grClipWindow() and grSstControl() need to ** write these registers. */ void _grClipNormalizeAndGenerateRegValues(FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy, FxU32 *clipLeftRight, FxU32 *clipBottomTop) { #define FN_NAME "_grClipNormalizeAndGenerateRegValues" GR_DCL_GC; FxU32 tmp; GDBG_INFO(85, "%s: minx = %d, maxx = %d, miny = %d, maxy = %d\n", FN_NAME, minx, maxx, miny, maxy); GR_CHECK_COMPATABILITY(FN_NAME, ((minx > LONG_MAX) || (miny > LONG_MAX)), "Negative min clip coordinate"); /* Sort the Maxes and Mins These are the same no matter what */ if (minx > maxx) { tmp = maxx; minx = maxx; maxx = tmp; } if (miny > maxy) { tmp = maxy; miny = maxy; maxy = tmp; } if(_GlideRoot.environment.aaClip == FXTRUE) { if((gc->grPixelSample > 1) && (_GlideRoot.windowsInit == 1)) { if(minx == 0) minx = 1; if(miny == 0) miny = 1; } } if (gc->windowed) { if (gc->state.wClipping.colBufferSet && gc->state.wClipping.auxBufferSet) { maxx = MIN(maxx, MIN(gc->state.wClipping.colClip.width, gc->state.wClipping.auxClip.width)); maxy = MIN(maxy, MIN(gc->state.wClipping.colClip.height, gc->state.wClipping.auxClip.height)); gc->state.wClipping.winClip.width = maxx; gc->state.wClipping.winClip.height = maxy; } /* Else just use it */ } else { /* don't allow bogus clip coords!!! */ /* [dBorca] Hack alert: * if we want clipping into texturebuffers, we are not allowed to * clamp to screen size (which might be smaller than texture size, * namely for Napalm -- which can handle up to 2048x2048). Need to * revise this... */ if (maxx > gc->state.screen_width) maxx = gc->state.screen_width; if (maxy > gc->state.screen_height) maxy = gc->state.screen_height; } GDBG_INFO(85, "%s: normalized minx = %d, maxx = %d, miny = %d, maxy = %d\n", FN_NAME, minx, maxx, miny, maxy); *clipLeftRight = (minx << SST_CLIPLEFT_SHIFT) | (maxx << SST_CLIPRIGHT_SHIFT); *clipBottomTop = (miny << SST_CLIPBOTTOM_SHIFT) | (maxy << SST_CLIPTOP_SHIFT); if (minx & 0x00000001) minx--; if (miny & 0x00000001) miny--; if (maxx & 0x00000001) maxx++; if (maxy & 0x00000001) maxy++; #ifdef FX_GLIDE_NAPALM gc->state.shadow.clipLeftRight1 = (minx << SST_CLIPLEFT_SHIFT) | (maxx << SST_CLIPRIGHT_SHIFT); gc->state.shadow.clipBottomTop1 = (miny << SST_CLIPTOP_SHIFT) | (maxy << SST_CLIPTOP_SHIFT); #endif GDBG_INFO(85, "%s: clipLeftRight = 0x%x, clipBottomTop = 0x%x\n", FN_NAME, clipLeftRight, clipBottomTop); #undef FN_NAME } /* _grClipNormalizeAndGenerateRegValues */ /*--------------------------------------------------------------------------- ** grClipWindow */ GR_STATE_ENTRY(grClipWindow, void, (FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy)) { #define FN_NAME "_grClipWindow" FxU32 clipLeftRight, /* SST Clipping Registers */ clipBottomTop; GR_BEGIN_NOFIFOCHECK("_grClipWindow",83); GDBG_INFO_MORE(gc->myLevel,"(%d,%d %d,%d)\n",minx,miny,maxx,maxy); _grClipNormalizeAndGenerateRegValues(minx, miny, maxx, maxy, &clipLeftRight, &clipBottomTop); #if !GLIDE3 REG_GROUP_BEGIN(BROADCAST_ID, clipLeftRight, 2, 0x03); { REG_GROUP_SET(hw, clipLeftRight, clipLeftRight); REG_GROUP_SET(hw, clipBottomTop, clipBottomTop); } REG_GROUP_END(); #endif /* !GLIDE3 */ gc->state.shadow.clipLeftRight = clipLeftRight; gc->state.shadow.clipBottomTop = clipBottomTop; gc->state.clipwindowf_xmin = (float) minx; gc->state.clipwindowf_xmax = (float) maxx; gc->state.clipwindowf_ymin = (float) miny; gc->state.clipwindowf_ymax = (float) maxy; /* tbext */ if ( gc->textureBuffer.on && !gc->textureBuffer.prevState.valid ) { gc->textureBuffer.prevState.cwMinx = (float) minx; gc->textureBuffer.prevState.cwMaxx = (float) maxx; gc->textureBuffer.prevState.cwMiny = (float) miny; gc->textureBuffer.prevState.cwMaxy = (float) maxy; gc->textureBuffer.prevState.clipLeftRight = clipLeftRight; gc->textureBuffer.prevState.clipBottomTop = clipBottomTop; gc->textureBuffer.prevState.valid = FXTRUE; } /* endif gc->textureBuffer.on */ GR_END(); #undef FN_NAME } /* grClipWindow */ /*--------------------------------------------------------------------------- ** grColorCombine */ GR_STATE_ENTRY(grColorCombine, void, (GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert)) { #define FN_NAME "_grColorCombine" FxU32 fbzColorPath; GR_BEGIN_NOFIFOCHECK("_grColorCombine",85); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d,%d,%d)\n",function,factor,local,other,invert); GR_CHECK_W(myName, function < GR_COMBINE_FUNCTION_ZERO || function > GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA , "unsupported color combine function"); /* Starting w/ Voodoo^2 the ccu has texture RGB mode as well. */ GR_CHECK_W(myName, (factor & 0x7) < GR_COMBINE_FACTOR_ZERO || (factor & 0x7) > GR_COMBINE_FACTOR_TEXTURE_RGB || factor > GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA, "unsupported color combine scale factor"); GR_CHECK_W(myName, local < GR_COMBINE_LOCAL_ITERATED || local > GR_COMBINE_LOCAL_DEPTH, "unsupported color combine local color"); GR_CHECK_W(myName, other < GR_COMBINE_OTHER_ITERATED || other > GR_COMBINE_OTHER_CONSTANT, "unsupported color combine other color"); fbzColorPath = gc->state.shadow.fbzColorPath; fbzColorPath &= ~(SST_ENTEXTUREMAP | SST_RGBSELECT | SST_LOCALSELECT | SST_CC_ZERO_OTHER | SST_CC_SUB_CLOCAL | SST_CC_MSELECT | SST_CC_REVERSE_BLEND | SST_CC_ADD_CLOCAL | SST_CC_ADD_ALOCAL | SST_CC_INVERT_OUTPUT); /* this is bogus, it should be done once, somewhere. */ fbzColorPath |= SST_PARMADJUST; /* setup reverse blending first, then strip off the the high bit */ if ((factor & 0x8) == 0) fbzColorPath |= SST_CC_REVERSE_BLEND; factor &= 0x7; /* NOTE: we use boolean OR instead of logical to avoid branches */ gc->state.cc_requires_texture = ((factor == GR_COMBINE_FACTOR_TEXTURE_ALPHA) | (factor == GR_COMBINE_FACTOR_TEXTURE_RGB) | (other == GR_COMBINE_OTHER_TEXTURE)); gc->state.cc_requires_it_rgb = ((local == GR_COMBINE_LOCAL_ITERATED) | (other == GR_COMBINE_OTHER_ITERATED)); gc->state.tcc_requires_it_rgb[GR_TMU0] = FXFALSE; gc->state.tcc_requires_it_rgb[GR_TMU1] = FXFALSE; /* setup scale factor bits */ fbzColorPath |= factor << SST_CC_MSELECT_SHIFT; /* setup local color bits */ fbzColorPath |= local << SST_LOCALSELECT_SHIFT; /* setup other color bits */ fbzColorPath |= other << SST_RGBSELECT_SHIFT; /* setup invert output bits */ if (invert) fbzColorPath |= SST_CC_INVERT_OUTPUT; /* setup core color combine unit bits */ switch (function) { case GR_COMBINE_FUNCTION_ZERO: fbzColorPath |= SST_CC_ZERO_OTHER; break; case GR_COMBINE_FUNCTION_LOCAL: fbzColorPath |= SST_CC_ZERO_OTHER | SST_CC_ADD_CLOCAL; break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: fbzColorPath |= SST_CC_ZERO_OTHER | SST_CC_ADD_ALOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: fbzColorPath |= SST_CC_ADD_CLOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: fbzColorPath |= SST_CC_ADD_ALOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: fbzColorPath |= SST_CC_SUB_CLOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: fbzColorPath |= SST_CC_SUB_CLOCAL | SST_CC_ADD_CLOCAL; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: fbzColorPath |= SST_CC_SUB_CLOCAL | SST_CC_ADD_ALOCAL; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: fbzColorPath |= SST_CC_ZERO_OTHER | SST_CC_SUB_CLOCAL | SST_CC_ADD_CLOCAL; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: fbzColorPath |= SST_CC_ZERO_OTHER | SST_CC_SUB_CLOCAL | SST_CC_ADD_ALOCAL; break; } /* if either color or alpha combine requires texture then enable it */ if (gc->state.cc_requires_texture || gc->state.ac_requires_texture) fbzColorPath |= SST_ENTEXTUREMAP; gc->state.shadow.fbzColorPath = fbzColorPath; GR_END(); #undef FN_NAME } /* grColorCombine */ /* NB: These are only called when GLIDE_DEBUG is set for tracing */ #if GLIDE_DEBUG /*--------------------------------------------------------------------------- ** grDepthMask */ GR_STATE_ENTRY(grDepthMask, void, (FxBool enable)) { #define FN_NAME "_grDepthMask" GR_BEGIN_NOFIFOCHECK("_grDepthMask", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", enable); GR_CHECK_COMPATABILITY(FN_NAME, (enable && (gc->grAuxBuf == 0)), "Cannot enable depth buffer w/o allocating one"); #undef FN_NAME } /* grDepthMask */ /*--------------------------------------------------------------------------- ** grColorMask */ GR_STATE_ENTRY(grColorMask, void, (FxBool rgb, FxBool alpha)) { #define FN_NAME "_grColorMask" GR_BEGIN_NOFIFOCHECK("_grColorMask", 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x,0x%x)\n", rgb, alpha); #undef FN_NAME } /* grColorMask */ /*--------------------------------------------------------------------------- ** grFogColorValue */ GR_STATE_ENTRY(grFogColorValue, void, (GrColor_t color)) { #define FN_NAME "_grFogColorValue" GR_BEGIN_NOFIFOCHECK("_grFogColorValue", 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", color); _grSwizzleColor(&color); gc->state.shadow.fogColor = color; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, fogColor, color); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grFogColorValue */ /*--------------------------------------------------------------------------- ** grDepthBiasLevel ** ** Sets the depth bias level. */ GR_STATE_ENTRY(grDepthBiasLevel, void, (FxI32 level)) { #define FN_NAME "_grDepthBiasLevel" FxU32 zacolor; GR_BEGIN_NOFIFOCHECK("_grDepthBiasLevel", 85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",level); if ((gc->state.shadow.fbzMode & SST_WBUFFER) && (gc->grPixelSize == 4)) level = (level << 8 | 0xff); zacolor = gc->state.shadow.zaColor; zacolor = (zacolor & ~SST_ZACOLOR_DEPTH) | ((FxI16)level & SST_ZACOLOR_DEPTH); gc->state.shadow.zaColor = zacolor; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, zaColor, zacolor); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grDepthBiasLevel */ /*--------------------------------------------------------------------------- ** grChromaRange */ GR_STATE_ENTRY(grChromaRange, void, (GrColor_t max, GrChromaRangeMode_t mode)) { FxU32 chromaRange; GR_BEGIN_NOFIFOCHECK("_grChromakeyValue", 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", max); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", mode); chromaRange = gc->state.shadow.chromaRange & SST_ENCHROMARANGE; _grSwizzleColor(&max); gc->state.shadow.chromaRange = chromaRange | (max & 0x00ffffff) | (mode << 24); } /* grChromaRange */ /*--------------------------------------------------------------------------- ** grChromakeyValue */ GR_STATE_ENTRY(grChromakeyValue, void, (GrColor_t color)) { #define FN_NAME "_grChromakeyValue" GR_BEGIN_NOFIFOCHECK("_grChromakeyValue", 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", color); _grSwizzleColor(&color); gc->state.shadow.chromaKey = color; #undef FN_NAME } /* grChromaKeyValue */ #endif /* GLIDE_DEBUG */ /*--------------------------------------------------------------------------- ** grConstantColorValue */ GR_STATE_ENTRY(grConstantColorValue, void, (GrColor_t color)) { #define FN_NAME "_grConstantColorValue" GR_BEGIN_NOFIFOCHECK("_grConstantColorValue",85); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",color); _grSwizzleColor(&color); #if !GLIDE3 REG_GROUP_BEGIN(BROADCAST_ID, c0, 2, 0x03); { REG_GROUP_SET(hw, c0, color); REG_GROUP_SET(hw, c1, color); } REG_GROUP_END(); #endif /* !GLIDE3 */ gc->state.shadow.color0 = color; gc->state.shadow.color1 = color; GR_END(); #undef FN_NAME } /* grConstanColorValue */ /*--------------------------------------------------------------------------- ** grCullMode ** ** GMT: warning - gaa.c has the guts of this in-line */ GR_ENTRY(grCullMode, void, (GrCullMode_t mode)) { #define FN_NAME "grCullMode" GR_BEGIN_NOFIFOCHECK("grCullMode",85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",mode); gc->state.cull_mode = mode; #if GLIDE_HW_TRI_SETUP _grUpdateTriPacketHdr(gc->cmdTransportInfo.paramMask, mode); #endif /* GLIDE_HW_TRI_SETUP */ GR_END(); #undef FN_NAME } /* grCullMode */ /*--------------------------------------------------------------------------- ** grDepthBufferFunction */ GR_STATE_ENTRY(grDepthBufferFunction, void, (GrCmpFnc_t fnc)) { #define FN_NAME "_grDepthBufferFunction" FxU32 fbzMode; GR_BEGIN_NOFIFOCHECK("_grDepthBufferFunction",85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",fnc); fbzMode = gc->state.shadow.fbzMode; fbzMode &= ~SST_ZFUNC; fbzMode |= (fnc << SST_ZFUNC_SHIFT); gc->state.shadow.fbzMode = fbzMode; GR_END(); #undef FN_NAME } /* grDepthBufferFunction */ /*--------------------------------------------------------------------------- ** grDepthBufferMode */ GR_STATE_ENTRY(grDepthBufferMode, void, (GrDepthBufferMode_t mode)) { #define FN_NAME "_grDepthBufferMode" FxU32 fbzMode; GR_BEGIN_NOFIFOCHECK("_grDepthBufferMode", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", mode); /* This is fatal because they could stomp on the cmd fifo. */ GR_CHECK_COMPATABILITY(FN_NAME, (mode != GR_DEPTHBUFFER_DISABLE) && (gc->grAuxBuf == 0), "cannot enable depth buffer w/o allocating one"); /* turn off all the bits and then turn them back on selectively */ fbzMode = gc->state.shadow.fbzMode; fbzMode &= ~(SST_ENDEPTHBUFFER | SST_WBUFFER | SST_ENZBIAS | SST_ZCOMPARE_TO_ZACOLOR | SST_DEPTH_FLOAT_SEL); switch (mode) { case GR_DEPTHBUFFER_DISABLE: break; case GR_DEPTHBUFFER_ZBUFFER: fbzMode |= SST_ENDEPTHBUFFER | SST_ENZBIAS; break; case GR_DEPTHBUFFER_WBUFFER: /* ** if fog coordinate is enabled, we need to enable floating point z buffer for w buffering */ fbzMode |= SST_ENDEPTHBUFFER | SST_WBUFFER | SST_ENZBIAS; if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { fbzMode |= SST_DEPTH_FLOAT_SEL; fbzMode &= ~(SST_WBUFFER); } break; case GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS: fbzMode |= SST_ENDEPTHBUFFER | SST_ZCOMPARE_TO_ZACOLOR; break; case GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS: fbzMode |= SST_ENDEPTHBUFFER | SST_WBUFFER | SST_ZCOMPARE_TO_ZACOLOR; if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { fbzMode |= SST_DEPTH_FLOAT_SEL; fbzMode &= ~(SST_WBUFFER); } break; } /* ** Update hardware and Glide state */ gc->state.shadow.fbzMode = fbzMode; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, fbzMode, fbzMode); GR_CHECK_SIZE(); _grUpdateParamIndex(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grDepthBufferMode */ /*--------------------------------------------------------------------------- ** No Comment */ #ifdef GLIDE_DEBUG static FxBool _grCanSupportDepthBuffer(void) { GR_DCL_GC; if (gc->state.screen_height == 640) { if (gc->fbuf_size == 1) { return FXFALSE; } } else if (gc->state.screen_width == 800) { if ((gc->fbuf_size == 1) || (gc->fbuf_size == 2)) { return FXFALSE; } } return FXTRUE; } /* _grCanSupportDepthBuffer */ #endif /*--------------------------------------------------------------------------- ** grDisableAllEffects */ GR_ENTRY(grDisableAllEffects, void, (void)) { GDBG_INFO(87,"grDisableAllEffects()\n"); grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO); grAlphaTestFunction(GR_CMP_ALWAYS); grChromakeyMode(GR_CHROMAKEY_DISABLE); grDepthBiasLevel(0); grDepthBufferMode(GR_DEPTHBUFFER_DISABLE); grFogMode(GR_FOG_DISABLE); } /* grDisableAllEffects */ /*--------------------------------------------------------------------------- ** grStippleMode */ GR_STATE_ENTRY(grStippleMode, void, (GrStippleMode_t mode)) { #define FN_NAME "_grStippleMode" FxU32 fbzMode; GR_BEGIN_NOFIFOCHECK("_grStippleMode", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", mode); fbzMode = gc->state.shadow.fbzMode; fbzMode &= ~(SST_ENSTIPPLE | SST_ENSTIPPLEPATTERN); switch (mode) { case GR_STIPPLE_DISABLE: break; case GR_STIPPLE_PATTERN: fbzMode |= (SST_ENSTIPPLE | SST_ENSTIPPLEPATTERN); break; case GR_STIPPLE_ROTATE: fbzMode |= SST_ENSTIPPLE; break; } gc->state.shadow.fbzMode = fbzMode; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, fbzMode, fbzMode); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grStippleMode */ /*--------------------------------------------------------------------------- ** grDitherMode */ GR_STATE_ENTRY(grDitherMode, void, (GrDitherMode_t mode)) { #define FN_NAME "_grDitherMode" FxU32 fbzMode; GR_BEGIN_NOFIFOCHECK("_grDitherMode", 85); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", mode); fbzMode = gc->state.shadow.fbzMode; /****************************************************************** * 4/30/99 gregk * Forcing dither rendering matrix to 2x2 * Check to see if user selected dither subtraction * Default selection: disable dither sub * (see also _GlideInitEnvironment() in gpci.c ) ******************************************************************/ fbzMode &= ~(SST_ENDITHER | SST_DITHER2x2 | SST_ENDITHERSUBTRACT); switch (mode) { case GR_DITHER_DISABLE: break; /* Assure dither subtraction stays disabled */ /* when dithering is diabled */ case GR_DITHER_2x2: /* Never a question of which dither matrix is used */ case GR_DITHER_4x4: /* To ditherSub or not to ditherSub,that is the question */ fbzMode |= (SST_ENDITHER | SST_DITHER2x2 | SST_ENDITHERSUBTRACT); if (_GlideRoot.environment.disableDitherSub == FXTRUE) fbzMode &= ~(SST_ENDITHERSUBTRACT); break; } gc->state.shadow.fbzMode = fbzMode; #if !GLIDE3 GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, fbzMode, fbzMode); GR_CHECK_SIZE(); #endif /* !GLIDE3 */ #undef FN_NAME } /* grDitherMode */ /*--------------------------------------------------------------------------- ** grFogMode */ GR_STATE_ENTRY(grFogMode, void, (GrFogMode_t mode)) { #define FN_NAME "_grFogMode" FxU32 fogmode; GR_BEGIN_NOFIFOCHECK("_grFogMode", 85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",mode); fogmode = gc->state.shadow.fogMode; fogmode &= ~(SST_ENFOGGING | SST_FOGADD | SST_FOGMULT | SST_FOG_Z | SST_FOG_CONSTANT); switch (mode & 0xFF) { /* switch based on lower 8 bits */ case GR_FOG_DISABLE: break; /* ** disable in Glide 3. */ #if 0 case GR_FOG_WITH_ITERATED_ALPHA: fogmode |= (SST_ENFOGGING | SST_FOG_ALPHA); break; #endif /* ** iterate perspective correct fog */ case GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT: fogmode |= (SST_ENFOGGING); break; case GR_FOG_WITH_ITERATED_Z: /* Bug 735 */ fogmode |= (SST_ENFOGGING | SST_FOG_Z); break; case GR_FOG_WITH_TABLE_ON_W: fogmode |= (SST_ENFOGGING); break; } if (mode & GR_FOG_MULT2) fogmode |= SST_FOGMULT; if (mode & GR_FOG_ADD2) fogmode |= SST_FOGADD; /* GMT says that this should be enabled for CVG. It is always safe * to enable these even when fogging is not enabled. */ fogmode |= (SST_FOG_DITHER | SST_FOG_ZONES); /* ** Update the hardware and Glide state */ gc->state.shadow.fogMode = fogmode; #ifdef FX_GLIDE_NAPALM /* ** piggyback the alpha ops in grFogMode */ if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { FxU32 fogmode = gc->state.shadow.fogMode; fogmode &= ~( SST_RGB_BLEND_REVERSE | SST_RGB_BLEND_SUB | SST_A_BLEND_REVERSE | SST_A_BLEND_SUB ); switch (gc->state.stateArgs.grAlphaBlendFunctionArgs.rgb_op) { case GR_BLEND_OP_SUB: fogmode |= SST_RGB_BLEND_SUB; break; case GR_BLEND_OP_REVSUB: fogmode |= SST_RGB_BLEND_REVERSE | SST_RGB_BLEND_SUB; break; case GR_BLEND_OP_ADD: default: break; } switch (gc->state.stateArgs.grAlphaBlendFunctionArgs.alpha_op) { case GR_BLEND_OP_SUB: fogmode |= SST_A_BLEND_SUB; break; case GR_BLEND_OP_REVSUB: fogmode |= SST_A_BLEND_REVERSE | SST_A_BLEND_SUB; break; case GR_BLEND_OP_ADD: default: break; } #if 0 /* Now do this in validate state code, since we can't * just store one meaningful shadow fogMode value anyway. */ /* * Select dither matrix for AA modes * XXX Memo to Myself XXX * complete the ugly 4 sample code * this may mean re-writing the fogMode state management */ switch (gc->grPixelSample) { case 2: case 4: fogmode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND) ; fogmode |= (2 << SST_DITHER_ROTATE_AA_SHIFT) | (2 << SST_DITHER_ROTATE_BLEND_AA_SHIFT) ; break ; default: fogmode &= ~(SST_DITHER_ROTATE | SST_DITHER_ROTATE_BLEND | SST_DITHER_ROTATE_AA | SST_DITHER_ROTATE_BLEND_AA) ; } #endif gc->state.shadow.fogMode = fogmode; } #endif #undef FN_NAME } /* grFogMode */ /* ** grFogTable */ GR_ENTRY(grFogTable, void, (const GrFog_t fogtable[])) { #define FN_NAME "grFogTable" int i = 0; const int iend = (kInternalFogTableEntryCount >> 1); const GrFog_t *locTable = fogtable; GR_BEGIN_NOFIFOCHECK("grFogTable",85); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",fogtable); GR_ASSERT(fogtable != NULL); while(i < iend) { REG_GROUP_LONG_BEGIN(BROADCAST_ID, fogTable[i], 32); { int j; for (j = 0; j < 32; j++) { GrFog_t e0, e1, d0, d1; FxU32 entry; e0 = locTable[0]; /* lower entry */ e1 = locTable[1]; /* upper entry */ d0 = ((e1 - e0) << 2); /* del0 in .2 format */ d1 = (((i + j) == (iend - 1)) /* don't access beyond end of table */ ? e1 : locTable[2]); d1 = (d1 - e1) << 2; /* del1 in .2 format */ entry = ((e1 << 24) | (d1 << 16) | (e0 << 8) | d0); gc->state.shadow.fogTable[i+j] = entry; REG_GROUP_SET(hw, fogTable[i + j], entry ); locTable += 2; } } REG_GROUP_END(); i += 32; } GR_END(); #undef FN_NAME } /* grFogTable */ /*------------------------------------------------------------------- Function: grGlideShutdown Date: 3/16 Implementor(s): dow, gmt, jdt Library: Glide Description: Shutdown the Glide Library. Iterate through all hardware and call grSstWinClose(). Call InitShutdown() which unmaps all hardware from linear memory. Arguments: none Return: none -------------------------------------------------------------------*/ GR_ENTRY(grGlideShutdown, void, (void)) { if (!_GlideRoot.initialized) return; /* never made it thru startup */ /* GMT: reset the counter so we can proceed without assertions */ { GR_DCL_GC; if (gc != NULL) gc->counter = gc->expected_counter = 0; } { int i; GDBG_INFO(80, "grGlideShutdown()\n"); for(i = 0; i < _GlideRoot.hwConfig.num_sst; i++) { GrGC* gc = _GlideRoot.GCs + i; /* We can only do the fullscreen shutdown here if we actually did an open */ if (gc->open) { grSstSelect(i); grSstWinClose((GrContext_t)gc); } } /* Force all fullscreen contexts to be closed */ _GlideRoot.windowsInit = 0; /* If there are any surface contexts close them up now too */ { for(i = 0; i < MAX_NUM_CONTEXTS; i++) { GrGC* gc = _GlideRoot.surfaceGCHeap[i]; if (gc != NULL) { /* NB: We need to set the current thread's context before * continuing so that any internal glide calls have a valid * gc from tls via GR_DCL_GC. F*ck this up at your own peril. */ setThreadValue((FxU32)gc); #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) /* Flush any remaining commands and cleanup any per gc state */ grSurfaceReleaseContext((GrContext_t)gc); #endif } } } } } /* grGlideShutdown */ /*------------------------------------------------------------------- Function: _grFlushCommonStateRegs Date: 14-Oct-97 Implementor(s): dpc Description: Flushes all State Monster regs. If we're not doing Glide 3, then it's still used by grGlideSetState() Arguments: Return: -------------------------------------------------------------------*/ void _grFlushCommonStateRegs() { #define FN_NAME "_grFlushCommonStateRegs" GR_BEGIN_NOFIFOCHECK(FN_NAME, 97); /* NB: This logical write must be split into two writes since the * registers are non-contiguous (not good for packet 1) and are the * register span is larget (greater than the 14 register mask size * for packet 4). */ REG_GROUP_BEGIN(BROADCAST_ID, fbzColorPath, 11, 0x3C7F); { REG_GROUP_SET(hw, fbzColorPath, gc->state.shadow.fbzColorPath); REG_GROUP_SET(hw, fogMode, gc->state.shadow.fogMode); REG_GROUP_SET(hw, alphaMode, gc->state.shadow.alphaMode); REG_GROUP_SET(hw, fbzMode, gc->state.shadow.fbzMode); REG_GROUP_SET(hw, lfbMode, gc->state.shadow.lfbMode); REG_GROUP_SET(hw, clipLeftRight, gc->state.shadow.clipLeftRight); REG_GROUP_SET(hw, clipBottomTop, gc->state.shadow.clipBottomTop); /* nopCMD */ /* fastFillCmd */ /* swapBufferCmd */ REG_GROUP_SET(hw, fogColor, gc->state.shadow.fogColor); REG_GROUP_SET(hw, zaColor, gc->state.shadow.zaColor); REG_GROUP_SET(hw, chromaKey, gc->state.shadow.chromaKey); REG_GROUP_SET(hw, chromaRange, gc->state.shadow.chromaRange); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, stipple, 3, 0x07); { REG_GROUP_SET(hw, stipple, gc->state.shadow.stipple); REG_GROUP_SET(hw, c0, gc->state.shadow.color0); REG_GROUP_SET(hw, c1, gc->state.shadow.color1); } REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM /* ** flush napalm specific state */ if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 7, 0x0787); REG_GROUP_SET(hw, renderMode, gc->state.shadow.renderMode); REG_GROUP_SET(hw, stencilMode, gc->state.shadow.stencilMode); REG_GROUP_SET(hw, stencilOp, gc->state.shadow.stencilOp); REG_GROUP_SET(hw, fbiStencilFail, gc->state.shadow.fbiStenciltestFail); REG_GROUP_SET(hw, clipLeftRight1, gc->state.shadow.clipLeftRight1); REG_GROUP_SET(hw, clipBottomTop1, gc->state.shadow.clipBottomTop1); REG_GROUP_SET(hw, combineMode, gc->state.shadow.combineMode); gc->state.mode2ppc = (gc->state.shadow.combineMode & SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK) ? FXTRUE : FXFALSE; #if 0 /* remaining states need to be restored. */ REG_GROUP_SET(hw, sliCtrl, gc->state.fbi_config.sliCtrl); REG_GROUP_SET(hw, aaCtrl, gc->state.fbi_config.aaCtrl); REG_GROUP_SET(hw, chipMask, gc->state.fbi_config.chipMask); #endif REG_GROUP_END(); } #endif #if GLIDE3 gc->state.invalid = 0; #endif /* GLIDE3 */ GR_END(); #undef FN_NAME } /* _grFlushCommonStateRegs */ /*--------------------------------------------------------------------------- ** grGlideSetState */ GR_ENTRY(grGlideSetState, void, (const void *state)) { #define FN_NAME "grGlideSetState" GR_BEGIN_NOFIFOCHECK(FN_NAME, 87); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",state); GR_ASSERT(state != NULL); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( gc->chipmask ); _grTex2ppc(FXFALSE); } #endif /* if texture mapping changed then we need to issue a NOP command*/ { const FxBool texChangeP = (((gc->state.shadow.fbzColorPath ^ ((GrState*)state)->shadow.fbzColorPath) & SST_ENTEXTUREMAP) != 0); if (texChangeP) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0); GR_CHECK_SIZE(); } } /* copy all the state */ gc->state = *((GrState *)state); /* Update the hardware state from the saved state. */ _grFlushCommonStateRegs(); { int tmu; //GrChipID_t tmus; for(tmu = 0; tmu < gc->num_tmu; tmu++) { SstRegs* tmuregs = SST_TMU(hw, tmu); const FifoChipField chipField = (FifoChipField)(0x02UL << tmu); /* Synch flush data w/ new state */ gc->tmuMemInfo[tmu].postPacket[1] = ~gc->state.shadow.tmuState[tmu].texBaseAddr; gc->tmuMemInfo[tmu].postPacket[5] = gc->state.shadow.tmuState[tmu].texBaseAddr; REG_GROUP_BEGIN(chipField, textureMode, 7, 0x7F); { REG_GROUP_SET(tmuregs, textureMode, gc->state.shadow.tmuState[tmu].textureMode); REG_GROUP_SET(tmuregs, tLOD, gc->state.shadow.tmuState[tmu].tLOD); REG_GROUP_SET(tmuregs, tDetail, gc->state.shadow.tmuState[tmu].tDetail); REG_GROUP_SET(tmuregs, texBaseAddr, gc->state.shadow.tmuState[tmu].texBaseAddr); REG_GROUP_SET(tmuregs, texBaseAddr1, gc->state.shadow.tmuState[tmu].texBaseAddr_1); REG_GROUP_SET(tmuregs, texBaseAddr2, gc->state.shadow.tmuState[tmu].texBaseAddr_2); REG_GROUP_SET(tmuregs, texBaseAddr38, gc->state.shadow.tmuState[tmu].texBaseAddr_3_8); } REG_GROUP_END(); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); REG_GROUP_BEGIN(chipField, chromaKey, 2, 0x03); { REG_GROUP_SET(tmuregs, chromaKey, gc->state.shadow.tmuState[tmu].texchromaKey); REG_GROUP_SET(tmuregs, chromaRange, gc->state.shadow.tmuState[tmu].texchromaRange); } REG_GROUP_END(); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { REG_GROUP_BEGIN(chipField, combineMode, 1, 0x01); { REG_GROUP_SET(tmuregs, combineMode, gc->state.shadow.tmuState[tmu].combineMode); } REG_GROUP_END(); } #endif /*tmus = MultitextureAndTrilinear(); if(tmus & tmu) g3LodBiasPerChip(tmu);*/ } } #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { grTBufferWriteMaskExt(gc->state.tbufferMask); } #endif /* NOTE: since glide state includes things like hints and all cached * variables like paramIndex we needn't recompute these, BUT: we do * need to rebuild stuff that depends on them!!! */ _grUpdateParamIndex(); /* * AJB HACK CRAP * YORIGIN swapping w/ SLI isn't integrated * into the state monster... for now, force * a call to grSstOrigin */ grSstOrigin((gc->state.shadow.fbzMode & SST_YORIGIN) ? GR_ORIGIN_LOWER_LEFT : GR_ORIGIN_UPPER_LEFT) ; GR_END(); #undef FN_NAME } /* grGlideSetState */ /*--------------------------------------------------------------------------- ** grRenderBuffer ** ** Although SST1 supports triple buffering, it's a hack in the hardware, ** and the only drawbuffer modes supported by the fbzMode register are 0 ** (back) and 1 (front) */ #ifndef DRI_BUILD GR_STATE_ENTRY(grRenderBuffer, void, (GrBuffer_t buffer)) { #define FN_NAME "_grRenderBuffer" GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",buffer); /* tbext */ GR_CHECK_F(myName, ((buffer != GR_BUFFER_TEXTUREBUFFER_EXT ) && (buffer != GR_BUFFER_FRONTBUFFER ) && (buffer != GR_BUFFER_BACKBUFFER )), "invalid buffer"); { const FxU32 oldBuffer = gc->curBuffer; /* tbext */ if ( !(buffer == GR_BUFFER_TEXTUREBUFFER_EXT ) ) { gc->curBuffer = ((buffer == GR_BUFFER_FRONTBUFFER) ? gc->frontBuffer : gc->backBuffer); if (oldBuffer != gc->curBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers0[gc->curBuffer]); REG_GROUP_END(); gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif /* FX_GLIDE_NAPALM */ } /* endif oldBuffer != gc->curBuffer */ }/* endif ! buffer == GR_BUFFER_TEXTUREBUFFER_EXT */ } GR_END(); #undef FN_NAME } /* grRenderBuffer */ #else /* DRI_BUILD */ GR_STATE_ENTRY(grRenderBuffer, void, (GrBuffer_t buffer)) { #define FN_NAME "_grRenderBuffer" GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",buffer); /* tbext */ GR_CHECK_F(myName, ((buffer != GR_BUFFER_TEXTUREBUFFER_EXT ) && (buffer != GR_BUFFER_FRONTBUFFER ) && (buffer != GR_BUFFER_BACKBUFFER )), "invalid buffer"); { /* tbext */ if ( !(buffer == GR_BUFFER_TEXTUREBUFFER_EXT ) ) { gc->curBuffer = ((buffer == GR_BUFFER_FRONTBUFFER) ? gc->frontBuffer : gc->backBuffer); REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->buffers0[gc->curBuffer]); REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride); REG_GROUP_END(); gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 1, 0x1); REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); REG_GROUP_END(); } } #endif /* FX_GLIDE_NAPALM */ }/* endif ! buffer == GR_BUFFER_TEXTUREBUFFER_EXT */ } GR_END(); #undef FN_NAME } /* grRenderBuffer */ #endif /* DRI_BUILD */ GR_ENTRY(grCheckForRoom, void, (FxI32 n)) { #define FN_NAME "grCheckForRoom" GR_DCL_GC; /* dpc - 13 sep 1997 - FixMe! * Setting one packet for now. */ GR_CHECK_FOR_ROOM(n, 1); #undef FN_NAME } /*--------------------------------------------------------------------------- ** _grUpdateParamIndex ** ** Updates the paramIndex bits based on Glide state and the hints. ** */ GR_DDFUNC(_grUpdateParamIndex, void, (void)) { #define FN_NAME "_grUpdateParamIndex" GR_DCL_GC; FxU32 paramIndex = 0; const FxU32 fbzColorPath = gc->state.shadow.fbzColorPath; const FxU32 fogMode = gc->state.shadow.fogMode; const FxU32 fbzMode = gc->state.shadow.fbzMode; /* ** First, turn on every bit that we think we need. We can prune them ** back later. */ /* Turn on the texture bits based on what grTexCombine set */ if (fbzColorPath & SST_ENTEXTUREMAP) { /* No matter what, we need oow from the main grvertex structure */ static FxU32 paramI_array[] = { /* 0 */ STATE_REQUIRES_OOW_FBI, /* 1 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU0 | STATE_REQUIRES_ST_TMU0, /* 2 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU1 | STATE_REQUIRES_ST_TMU1, /* 3 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU0 | STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_W_TMU1 | STATE_REQUIRES_ST_TMU1, /* 4 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU2 | STATE_REQUIRES_ST_TMU2, /* 5 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU0 | STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_W_TMU2 | STATE_REQUIRES_ST_TMU2, /* 6 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU1 | STATE_REQUIRES_ST_TMU1 | STATE_REQUIRES_W_TMU2 | STATE_REQUIRES_ST_TMU2, /* 7 */ STATE_REQUIRES_OOW_FBI | STATE_REQUIRES_W_TMU0 | STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_W_TMU1 | STATE_REQUIRES_ST_TMU1 | STATE_REQUIRES_W_TMU2 | STATE_REQUIRES_ST_TMU2, }; GR_ASSERT(gc->state.tmuMask < sizeof(paramI_array) / sizeof(paramI_array[0])); paramIndex |= paramI_array[gc->state.tmuMask]; } /* See if we need iterated RGB */ if ((gc->state.cc_requires_it_rgb) || (gc->state.tcc_requires_it_rgb[GR_TMU0]) || (gc->state.tcc_requires_it_rgb[GR_TMU1])) { paramIndex |= STATE_REQUIRES_IT_DRGB; } /* See if we need to iterate alpha based on the value of ac_requires_it_alpha */ if ((gc->state.ac_requires_it_alpha) || (gc->state.tac_requires_it_alpha[GR_TMU0]) || (gc->state.tac_requires_it_alpha[GR_TMU1])) { paramIndex |= STATE_REQUIRES_IT_ALPHA; } /* See what fbzColorPath contributes - BUG 1084*/ if (( fbzColorPath & SST_ALOCALSELECT ) == SST_ALOCAL_Z ) { paramIndex |= STATE_REQUIRES_OOZ; } /* See what fbzMode contributes */ if (fbzMode & SST_ENDEPTHBUFFER) { if (fbzMode & SST_WBUFFER) { paramIndex |= STATE_REQUIRES_OOW_FBI; /* ** enable z iterator if we are using fog coordinate and w buffering */ if ((fogMode & SST_ENFOGGING) && (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE)) paramIndex |= STATE_REQUIRES_OOZ; } else { paramIndex |= STATE_REQUIRES_OOZ; } } /* See what fogMode contributes */ if (fogMode & SST_ENFOGGING) { if (fogMode & SST_FOG_Z) { paramIndex |= STATE_REQUIRES_OOZ; } else { paramIndex |= STATE_REQUIRES_OOW_FBI; } } /* ** Now we know everything that needs to be iterated. Prune back ** the stuff that isn't explicitly different ** ** NOTE: by GMT, STATE_REQUIRES_OOW_FBI is set whenever texture mapping ** is enabled */ #if defined(GLIDE3) && (GLIDE3_ALPHA) /* Turn off W for TMU0 if we don't have a hint */ if (paramIndex & STATE_REQUIRES_W_TMU0) { GR_ASSERT(paramIndex & STATE_REQUIRES_OOW_FBI); if (gc->state.vData.fogInfo.mode == GR_PARAM_DISABLE) { if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if (gc->state.vData.q0Info.mode == GR_PARAM_DISABLE) { paramIndex &= ~STATE_REQUIRES_W_TMU0; } } else { if ((gc->state.vData.q0Info.mode == GR_PARAM_DISABLE) || (gc->state.vData.wInfo.mode == GR_PARAM_DISABLE)) paramIndex &= ~STATE_REQUIRES_W_TMU0; } } else { /* ** win coords and no texturing */ if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if ((gc->state.vData.q0Info.mode == GR_PARAM_DISABLE) && (gc->state.vData.qInfo.mode == GR_PARAM_DISABLE)) paramIndex &= ~STATE_REQUIRES_W_TMU0; } /* ** clip coords and no texturing */ else { if ((gc->state.vData.q0Info.mode == GR_PARAM_DISABLE) && (gc->state.vData.wInfo.mode == GR_PARAM_DISABLE)) paramIndex &= ~STATE_REQUIRES_W_TMU0; } } } /* Turn off ST for TMU1 if TMU0 is active and TMU1 is not different */ if (((paramIndex & (STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_ST_TMU1)) == (STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_ST_TMU1)) && gc->state.vData.st1Info.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_ST_TMU1; /* Turn off W for TMU1 if we have a previous W, and don't have a hint */ if (paramIndex & STATE_REQUIRES_W_TMU1) { if (gc->state.vData.fogInfo.mode == GR_PARAM_DISABLE) { if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if (gc->state.vData.q1Info.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_W_TMU1; } else { if ((gc->state.vData.q1Info.mode == GR_PARAM_DISABLE) || (gc->state.vData.wInfo.mode == GR_PARAM_DISABLE)) paramIndex &= ~STATE_REQUIRES_W_TMU1; } } else { /* ** win coords and no texturing */ if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if ((gc->state.vData.q1Info.mode == GR_PARAM_DISABLE) && (gc->state.vData.qInfo.mode == GR_PARAM_DISABLE)) paramIndex &= ~STATE_REQUIRES_W_TMU1; } /* ** clip coords and no texturing */ else { if ((gc->state.vData.q1Info.mode == GR_PARAM_DISABLE) && (gc->state.vData.wInfo.mode == GR_PARAM_DISABLE)) paramIndex &= ~STATE_REQUIRES_W_TMU1; } } } #else /* Turn off W for TMU0 if we don't have a hint */ if (paramIndex & STATE_REQUIRES_W_TMU0) { GR_ASSERT(paramIndex & STATE_REQUIRES_OOW_FBI); if (!(hints & GR_STWHINT_W_DIFF_TMU0)) paramIndex &= ~STATE_REQUIRES_W_TMU0; } /* Turn off ST for TMU1 if TMU0 is active and TMU1 is not different */ if (((paramIndex & (STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_ST_TMU1)) == (STATE_REQUIRES_ST_TMU0 | STATE_REQUIRES_ST_TMU1)) && !(hints & GR_STWHINT_ST_DIFF_TMU1)) paramIndex &= ~STATE_REQUIRES_ST_TMU1; /* Turn off W for TMU1 if we have a previous W, and don't have a hint */ if ((paramIndex & STATE_REQUIRES_W_TMU1) && !(hints & GR_STWHINT_W_DIFF_TMU1)) paramIndex &= ~STATE_REQUIRES_W_TMU1; #endif #if (GLIDE_NUM_TMU > 2) /* Turn off ST for TMU1 if it's not different & any other is set up. */ if ((paramIndex & (STATE_REQUIRES_ST_TMU0 | STATE_REQURES_ST_TMU1)) && (paramIndex & STATE_REQUIRES_ST_TMU2) && !(hints & GR_STWHINT_ST_DIFF_TMU2)) paramIndex &= ~STATE_REQUIRES_ST_TMU2; /* Turn off W for TMU2 if we have a previous W, and don't have a hint */ if ((paramIndex & STATE_REQUIRES_W_TMU2) && !(hints & GR_STWHINT_W_DIFF_TMU2)) paramIndex &= ~STATE_REQUIRES_W_TMU2; #endif /* ** last check */ if (gc->state.vData.colorType == GR_U8) { if (gc->state.vData.pargbInfo.mode == GR_PARAM_DISABLE) { paramIndex &= ~STATE_REQUIRES_IT_ALPHA; paramIndex &= ~STATE_REQUIRES_IT_DRGB; } } else { if (gc->state.vData.aInfo.mode == GR_PARAM_DISABLE) { paramIndex &= ~STATE_REQUIRES_IT_ALPHA; } if (gc->state.vData.rgbInfo.mode == GR_PARAM_DISABLE) { paramIndex &= ~STATE_REQUIRES_IT_DRGB; } } if (gc->state.vData.fogInfo.mode == GR_PARAM_DISABLE) { if (gc->state.vData.zInfo.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_OOZ; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if (gc->state.vData.qInfo.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_OOW_FBI; } else { if (gc->state.vData.wInfo.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_OOW_FBI; } } else { if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { if (gc->state.vData.qInfo.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_OOZ; } else { if (gc->state.vData.wInfo.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_OOZ; } } if (gc->state.vData.st0Info.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_ST_TMU0; if (gc->state.vData.st1Info.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_ST_TMU1; if (gc->state.vData.fogInfo.mode == GR_PARAM_DISABLE) { if (gc->state.vData.q0Info.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_W_TMU0; if (gc->state.vData.q1Info.mode == GR_PARAM_DISABLE) paramIndex &= ~STATE_REQUIRES_W_TMU1; } gc->state.paramIndex = paramIndex; _grRebuildDataList(); #undef FN_NAME } /* _grUpdateParamIndex */ #if defined(GLIDE_USE_ALT_REGMAP) #define RED Fr_ALT #define DRDX Fdrdx_ALT #define DRDY Fdrdy_ALT #define GRN Fg_ALT #define DGDX Fdgdx_ALT #define DGDY Fdgdy_ALT #define BLU Fb_ALT #define DBDX Fdbdx_ALT #define DBDY Fdbdy_ALT #define ALF Fa_ALT #define DADX Fdadx_ALT #define DADY Fdady_ALT #define Z Fz_ALT #define DZDX Fdzdx_ALT #define DZDY Fdzdy_ALT #define S Fs_ALT #define DSDX Fdsdx_ALT #define DSDY Fdsdy_ALT #define T Ft_ALT #define DTDX Fdtdx_ALT #define DTDY Fdtdy_ALT #define W Fw_ALT #define DWDX Fdwdx_ALT #define DWDY Fdwdy_ALT #else #define RED Fr #define DRDX Fdrdx #define DRDY Fdrdy #define GRN Fg #define DGDX Fdgdx #define DGDY Fdgdy #define BLU Fb #define DBDX Fdbdx #define DBDY Fdbdy #define ALF Fa #define DADX Fdadx #define DADY Fdady #define Z Fz #define DZDX Fdzdx #define DZDY Fdzdy #define S Fs #define DSDX Fdsdx #define DSDY Fdsdy #define T Ft #define DTDX Fdtdx #define DTDY Fdtdy #define W Fw #define DWDX Fdwdx #define DWDY Fdwdy #endif #if GLIDE_HW_TRI_SETUP static void _grUpdateTriPacketHdr(FxU32 paramMask, const GrCullMode_t cullMode) { GR_DCL_GC; FxU32 sMode = ((cullMode != GR_CULL_DISABLE) ? kSetupCullEnable : kSetupPingPongDisable); if (sMode != kSetupPingPongDisable) sMode |= ((cullMode == GR_CULL_POSITIVE) ? kSetupCullPositive : kSetupCullNegative); #define COLOR_COMP_ARGB ((SST_SETUP_RGB | SST_SETUP_A) << SSTCP_PKT3_PMASK_SHIFT) #define COLOR_COMP_RGB (SST_SETUP_RGB << SSTCP_PKT3_PMASK_SHIFT) #define COLOR_COMP_MASK COLOR_COMP_ARGB gc->cmdTransportInfo.paramMask = paramMask; /* Compute the common case packet 3 header which just needs * the vertex count and strip/command type to be completed. */ gc->cmdTransportInfo.cullStripHdr = ((sMode << SSTCP_PKT3_SMODE_SHIFT) | paramMask | SSTCP_PKT3); /* Independent triangle hdr for grDrawTriangle */ gc->cmdTransportInfo.triPacketHdr = (gc->cmdTransportInfo.cullStripHdr | (0x3UL << SSTCP_PKT3_NUMVERTEX_SHIFT) | SSTCP_PKT3_BDDBDD); #if GLIDE_TRI_CULLING /* If we're doing sw culling for independent triangles then turn off * the hw culling so we're consistent. HW culling, however, remains * enabled for things using strips/fans. */ if (cullMode != GR_CULL_DISABLE) { gc->cmdTransportInfo.triPacketHdr &= ~(kSetupCullEnable << SSTCP_PKT3_SMODE_SHIFT); } #endif /* GLIDE_TRI_CULLING */ } #endif /* GLIDE_HW_TRI_SETUP */ #ifdef FX_GLIDE_NAPALM /*--------------------------------------------------------------------------- * _grCCExtfbzColorPath * * Color combine extension update in fbzColorPath register */ GR_DDFUNC(_grCCExtfbzColorPath, void, (GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool c_invert, GrCCUColor_t d, FxBool invert)) { #define FN_NAME "_grCCExtfbzColorPath" FxU32 fbzColorPath; GR_BEGIN_NOFIFOCHECK("_grCCExtfbzColorPath",85); GDBG_INFO_MORE(gc->myLevel, "(%d,%d,%d)\n", c, d, invert); /* color combine extension: update fbzColorPath register ** cc_mselect (part of c), cc_add_clocal (part of d), cc_add_alocal (part of d) ** cc_invert_output (invert) */ fbzColorPath = gc->state.shadow.fbzColorPath; fbzColorPath &= ~( SST_CC_MSELECT | /* cc_mselect */ SST_CC_ADD_CLOCAL | /* cc_add_clocal */ SST_CC_ADD_ALOCAL | /* cc_add_alocal */ SST_CC_INVERT_OUTPUT | /* cc_invert_output */ SST_ENTEXTUREMAP | /* disable texturing */ SST_CC_REVERSE_BLEND | /* c_invert */ SST_CC_ZERO_OTHER | /* a_mode zero */ SST_CC_SUB_CLOCAL /* b_mode zero */ ); gc->state.cc_requires_texture = ((a == GR_CMBX_TEXTURE_RGB) | (a == GR_CMBX_TEXTURE_ALPHA) | (b == GR_CMBX_TEXTURE_RGB) | (b == GR_CMBX_TEXTURE_ALPHA) | (c == GR_CMBX_TEXTURE_RGB) | (c == GR_CMBX_TEXTURE_ALPHA) | (d == GR_CMBX_TEXTURE_RGB)); if (a_mode == GR_FUNC_MODE_ZERO) fbzColorPath |= SST_CC_ZERO_OTHER; if (b_mode != GR_FUNC_MODE_ZERO) fbzColorPath |= SST_CC_SUB_CLOCAL; if (gc->state.cc_requires_texture || gc->state.ac_requires_texture) fbzColorPath |= SST_ENTEXTUREMAP; if (!c_invert) fbzColorPath |= SST_CC_REVERSE_BLEND; switch (c) { case GR_CMBX_ZERO: fbzColorPath |= SST_CC_MONE; break; case GR_CMBX_B: fbzColorPath |= SST_CC_MCLOCAL; break; case GR_CMBX_AOTHER: fbzColorPath |= SST_CC_MAOTHER; break; case GR_CMBX_ALOCAL: fbzColorPath |= SST_CC_MALOCAL; break; case GR_CMBX_TEXTURE_ALPHA: fbzColorPath |= SST_CC_MATMU; break; case GR_CMBX_TEXTURE_RGB: fbzColorPath |= SST_CC_MRGBTMU; break; case GR_CMBX_ITRGB: fbzColorPath |= SST_CC_MCMSELECT7; break; case GR_CMBX_ITALPHA: fbzColorPath |= SST_CC_MCMSELECT7; break; case GR_CMBX_CONSTANT_COLOR: fbzColorPath |= SST_CC_MCMSELECT7; break; case GR_CMBX_CONSTANT_ALPHA: fbzColorPath |= SST_CC_MCMSELECT7; break; } switch (d) { case GR_CMBX_ZERO: /* cc_add_clocal = 0, cc_add_alocal = 0 */ break; case GR_CMBX_ALOCAL: /* cc_add_clocal = 0, cc_add_alocal = 1 */ fbzColorPath |= SST_CC_ADD_ALOCAL; break; case GR_CMBX_B: /* cc_add_clocal = 1, cc_add_alocal = 0 */ fbzColorPath |= SST_CC_ADD_CLOCAL; break; case GR_CMBX_TEXTURE_RGB: /* cc_add_clocal = 1, cc_add_alocal = 1 */ fbzColorPath |= SST_CC_ADD_CLOCAL | SST_CC_ADD_ALOCAL; break; } if (invert) { fbzColorPath |= SST_CC_INVERT_OUTPUT; } gc->state.shadow.fbzColorPath = fbzColorPath; return; #undef FN_NAME } /*--------------------------------------------------------------------------- * _grACExtfbzColorPath * * Alpha combine extension update in fbzColorPath register */ GR_DDFUNC(_grACExtfbzColorPath, void, (GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, GrACUColor_t c, FxBool c_invert, GrACUColor_t d, FxBool invert)) { #define FN_NAME "_grACExtfbzColorPath" FxU32 fbzColorPath; GR_BEGIN_NOFIFOCHECK("_grACExtfbzColorPath",85); GDBG_INFO_MORE(gc->myLevel, "(%d,%d,%d)\n", c, d, invert); /* alpla combine extension ** cca_mselect (c), cca_add_clocal (part of d), cca_add_alocal (part of d) ** cca_invert_output (invert) */ fbzColorPath = gc->state.shadow.fbzColorPath; fbzColorPath &= ~( SST_CCA_MSELECT | /* cca_mselect */ SST_CCA_ADD_CLOCAL | /* cca_add_clocal */ SST_CCA_ADD_ALOCAL | /* cca_add_alocal */ SST_CCA_INVERT_OUTPUT | /* cca_invert_output */ SST_CCA_ZERO_OTHER | /* cca_zero_other */ SST_ENTEXTUREMAP | /* disable texturing */ SST_CCA_REVERSE_BLEND ); gc->state.ac_requires_texture = ((a == GR_CMBX_TEXTURE_ALPHA) | (b == GR_CMBX_TEXTURE_ALPHA) | (c == GR_CMBX_TEXTURE_ALPHA) | (d == GR_CMBX_TEXTURE_ALPHA)); if (gc->state.cc_requires_texture || gc->state.ac_requires_texture) fbzColorPath |= SST_ENTEXTUREMAP; switch (a) { case GR_CMBX_ITALPHA: case GR_CMBX_TEXTURE_ALPHA: case GR_CMBX_CONSTANT_ALPHA: break; default: fbzColorPath |= SST_CCA_ZERO_OTHER; } if (a_mode == GR_FUNC_MODE_ZERO) fbzColorPath |= SST_CCA_ZERO_OTHER; if (b_mode != GR_FUNC_MODE_ZERO) fbzColorPath |= SST_CCA_SUB_CLOCAL; if (!c_invert) fbzColorPath |= SST_CCA_REVERSE_BLEND; switch (c) { case GR_CMBX_ZERO: fbzColorPath |= SST_CCA_MONE; break; case GR_CMBX_B: fbzColorPath |= SST_CCA_MCLOCAL; break; case GR_CMBX_AOTHER: fbzColorPath |= SST_CCA_MAOTHER; break; case GR_CMBX_ALOCAL: fbzColorPath |= SST_CCA_MALOCAL; break; case GR_CMBX_TEXTURE_ALPHA: fbzColorPath |= SST_CCA_MATMU; break; case GR_CMBX_ITALPHA: fbzColorPath |= SST_CCA_MAITER; break; case GR_CMBX_CONSTANT_ALPHA: fbzColorPath |= SST_CCA_MAC1; break; } switch (d) { case GR_CMBX_ZERO: /* cca_add_clocal = 0, cca_add_alocal = 0 */ break; case GR_CMBX_ALOCAL: /* cca_add_clocal = 0, cca_add_alocal = 1 */ fbzColorPath |= SST_CCA_ADD_ALOCAL; break; case GR_CMBX_B: /* cca_add_clocal = 1, cca_add_alocal = 0 */ fbzColorPath |= SST_CCA_ADD_CLOCAL; break; case GR_CMBX_TEXTURE_ALPHA: /* cca_add_clocal = 1, cca_add_alocal = 1 */ fbzColorPath |= SST_CCA_ADD_CLOCAL | SST_CCA_ADD_ALOCAL; break; } if (invert) { fbzColorPath |= SST_CCA_INVERT_OUTPUT; } gc->state.shadow.fbzColorPath = fbzColorPath; return; #undef FN_NAME } /*--------------------------------------------------------------------------- * _grCCExtcombineMode * * Color combine extension update in combineMode register */ GR_DDFUNC(_grCCExtcombineMode, void, (GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool d_invert, FxU32 shift)) { #define FN_NAME "_grCCExtcombineMode" FxU32 combineMode; GR_BEGIN_NOFIFOCHECK("_grCCExtcombineMode",85); GDBG_INFO_MORE(gc->myLevel, "(%d,%d,%d,%d,%d,%d)\n", a, a_mode, b, b_mode, c, shift); /* color combine extension ** cc_otherselect (a), cc_localselect (b), cc_mselect_7 (part of c), ** cc_invert_other (a_mode), cc_invert_local (b_mode), cc_outshift (shift) ** bit(31) */ combineMode = gc->state.shadow.combineMode; combineMode &= ~( SST_CM_CC_OTHERSELECT | SST_CM_CC_LOCALSELECT | SST_CM_CC_MSELECT_7 | SST_CM_CC_INVERT_OTHER | SST_CM_CC_INVERT_LOCAL | SST_CM_CC_OUTSHIFT | SST_CM_USE_COMBINE_MODE | SST_CM_CC_INVERT_ADD_LOCAL ); switch (a) { case GR_CMBX_ITRGB: combineMode |= SST_CM_CC_OTHERSELECT_IRGB; break; case GR_CMBX_TEXTURE_RGB: combineMode |= SST_CM_CC_OTHERSELECT_TRGB; break; case GR_CMBX_CONSTANT_COLOR: combineMode |= SST_CM_CC_OTHERSELECT_C1_RGB; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_CC_OTHERSELECT_IA; break; case GR_CMBX_TEXTURE_ALPHA: combineMode |= SST_CM_CC_OTHERSELECT_TA; break; case GR_CMBX_CONSTANT_ALPHA: combineMode |= SST_CM_CC_OTHERSELECT_C1_A; break; case GR_CMBX_ZERO: default: combineMode |= SST_CM_CC_OTHERSELECT_ZERO; break; } switch (b) { case GR_CMBX_ITRGB: combineMode |= SST_CM_CC_LOCALSELECT_IRGB; break; case GR_CMBX_CONSTANT_COLOR: combineMode |= SST_CM_CC_LOCALSELECT_C0_RGB; break; case GR_CMBX_TEXTURE_RGB: combineMode |= SST_CM_CC_LOCALSELECT_TRGB; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_CC_LOCALSELECT_IA; break; case GR_CMBX_CONSTANT_ALPHA: combineMode |= SST_CM_CC_LOCALSELECT_C0_A; break; case GR_CMBX_TEXTURE_ALPHA: combineMode |= SST_CM_CC_LOCALSELECT_TA; break; default: combineMode |= SST_CM_CC_LOCALSELECT_ZERO; break; } switch (a_mode) { case GR_FUNC_MODE_ZERO: case GR_FUNC_MODE_X: combineMode |= SST_CM_CC_INVERT_OTHER_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_CC_INVERT_OTHER_ONE_MINUS_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_CC_INVERT_OTHER_ZERO_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_CC_INVERT_OTHER_X_MINUS_HALF; break; } switch (b_mode) { case GR_FUNC_MODE_ZERO: case GR_FUNC_MODE_X: combineMode |= SST_CM_CC_INVERT_LOCAL_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_CC_INVERT_LOCAL_ONE_MINUS_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_CC_INVERT_LOCAL_ZERO_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_CC_INVERT_LOCAL_X_MINUS_HALF; break; } switch (c) { case GR_CMBX_ITRGB: combineMode |= SST_CM_CC_MSELECT_7_IRGB; break; case GR_CMBX_CONSTANT_COLOR: combineMode |= SST_CM_CC_MSELECT_7_C1_RGB; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_CC_MSELECT_7_IA; break; case GR_CMBX_CONSTANT_ALPHA: combineMode |= SST_CM_CC_MSELECT_7_C1_A; break; } if (d_invert) combineMode |= SST_CM_CC_INVERT_ADD_LOCAL; switch (shift) { case 1: combineMode |= SST_CM_CC_OUTSHIFT_2X; break; case 2: combineMode |= SST_CM_CC_OUTSHIFT_4X; break; default: combineMode |= SST_CM_CC_OUTSHIFT_1X; break; } combineMode |= SST_CM_USE_COMBINE_MODE; gc->state.shadow.combineMode = combineMode; return; #undef FN_NAME } /*--------------------------------------------------------------------------- * _grACExtcombineMode * * Alpha combine extension update in combineMode register */ GR_DDFUNC(_grACExtcombineMode, void, (GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, FxBool d_invert, FxU32 shift)) { #define FN_NAME "_grACExtcombineMode" FxU32 combineMode; GR_BEGIN_NOFIFOCHECK("_grACExtcombineMode",85); GDBG_INFO_MORE(gc->myLevel, "(%d,%d,%d,%d,%d)\n", a, a_mode, b, b_mode, shift); /* alpha combine extension ** cca_otherselect (a), cca_localselect (b), cca_invert_other (a_mode), ** cca_invert_local (b_mode), cca_outshift (shift) ** bit (31) */ combineMode = gc->state.shadow.combineMode; combineMode &= ~( SST_CM_CCA_OTHERSELECT | SST_CM_CCA_LOCALSELECT | SST_CM_CCA_INVERT_OTHER | SST_CM_CCA_INVERT_LOCAL | SST_CM_CCA_OUTSHIFT | SST_CM_USE_COMBINE_MODE | SST_CM_CCA_INVERT_ADD_LOCAL ); switch (a) { case GR_CMBX_ITALPHA: combineMode |= SST_CM_CCA_OTHERSELECT_IA; break; case GR_CMBX_TEXTURE_ALPHA: combineMode |= SST_CM_CCA_OTHERSELECT_TA; break; case GR_CMBX_CONSTANT_ALPHA: combineMode |= SST_CM_CCA_OTHERSELECT_C1_A; break; } switch (b) { case GR_CMBX_ITALPHA: combineMode |= SST_CM_CCA_LOCALSELECT_IA; break; case GR_CMBX_CONSTANT_ALPHA: combineMode |= SST_CM_CCA_LOCALSELECT_C0_A; break; case GR_CMBX_TEXTURE_ALPHA: combineMode |= SST_CM_CCA_LOCALSELECT_TA; break; case GR_CMBX_ZERO: default: combineMode |= SST_CM_CCA_LOCALSELECT_ZERO; break; } switch (a_mode) { case GR_FUNC_MODE_X: combineMode |= SST_CM_CCA_INVERT_OTHER_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_CCA_INVERT_OTHER_ONE_MINUS_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_CCA_INVERT_OTHER_ZERO_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_CCA_INVERT_OTHER_X_MINUS_HALF; break; } switch (b_mode) { case GR_FUNC_MODE_X: combineMode |= SST_CM_CCA_INVERT_LOCAL_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_CCA_INVERT_LOCAL_ONE_MINUS_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_CCA_INVERT_LOCAL_ZERO_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_CCA_INVERT_LOCAL_X_MINUS_HALF; break; } if (d_invert) combineMode |= SST_CM_CCA_INVERT_ADD_LOCAL; switch (shift) { case 1: combineMode |= SST_CM_CCA_OUTSHIFT_2X; break; case 2: combineMode |= SST_CM_CCA_OUTSHIFT_4X; break; default: combineMode |= SST_CM_CCA_OUTSHIFT_1X; break; } combineMode |= SST_CM_USE_COMBINE_MODE; gc->state.shadow.combineMode = combineMode; return; #undef FN_NAME } /*------------------------------------------------------------------- Function: grTBufferWriteMaskExt Date: 21-July-99 Implementor(s): atai Description: Whatever Arguments: Whatever Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grTBufferWriteMaskExt, void , (FxU32 tmask) ) { #define FN_NAME "grTBufferWriteMaskExt" #if 0 /* KoolSmoky */ FxU32 tBufferSampleOffsetIndex; #endif FxU32 chipIndex, chipEnList, chipaamode[4]; GR_BEGIN_NOFIFOCHECK("grTBufferWriteMaskExt",85); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", tmask); /* the current mask will be stored in GrState */ /* check if we have atleast 2 tbuffers */ if(gc->grPixelSample <= 1) return; #if 0 /* KoolSmoky */ /* In a one-chip config, chip 0 does samples 0 and 1 */ /* In a two-chip config, chip 0 does samples 0 and 1, and chip 1 does samples 2 and 3 */ /* In a four-chip config, chips 0 and 2 do samples 0 and 1, and chips 1 and 3 do samples 2 and 3 */ switch( gc->chipCount ) { case 4: switch( gc->grPixelSample ) { case 8: /*no sli, 2 sample per chip */ chipaamode[0] = (tmask>>0) & 0x03; chipaamode[1] = (tmask>>2) & 0x03; chipaamode[2] = (tmask>>4) & 0x03; chipaamode[3] = (tmask>>6) & 0x03; tBufferSampleOffsetIndex = 9; break; case 4: /*no sli, 1 sample per chip */ chipaamode[0] = (tmask>>0) & 0x01; chipaamode[1] = (tmask>>2) & 0x01; chipaamode[2] = (tmask>>1) & 0x01; chipaamode[3] = (tmask>>3) & 0x01; tBufferSampleOffsetIndex = 8; break; case 2: if(!_GlideRoot.environment.forceOldAA) { /* 2 way SLI, 1 sample per SLI unit */ chipaamode[0] = chipaamode[2] = (tmask>>0) & 0x01; chipaamode[1] = chipaamode[3] = (tmask>>1) & 0x01; tBufferSampleOffsetIndex = 7; } else { /* 4 way SLI, 2 samples per SLI unit */ chipaamode[0] = chipaamode[1] = chipaamode[2] = chipaamode[3] = (tmask>>0) & 0x03; tBufferSampleOffsetIndex = 7; } break; } break; case 2: switch( gc->grPixelSample ) { case 4: /* no sli, 2 sample per chip */ chipaamode[0] = (tmask>>0) & 0x03; chipaamode[1] = (tmask>>2) & 0x03; tBufferSampleOffsetIndex = 3; break; case 2: if(!_GlideRoot.environment.forceOldAA) { /* no sli, 1 sample per chip */ chipaamode[0] = (tmask>>0) & 0x01; chipaamode[1] = (tmask>>1) & 0x01; tBufferSampleOffsetIndex = 2; } else { /* 2 samples per SLI pair */ chipaamode[0] = chipaamode[1] = (tmask>>0) & 0x03; tBufferSampleOffsetIndex = 1; } break; } break; case 1: switch( gc->grPixelSample ) { case 2: /* no sli, 2 sample per chip */ chipaamode[0] = (tmask>>0) & 0x03; tBufferSampleOffsetIndex = 1; break; } break; } //chipEnList = gc->chipmask; chipEnList = 0; /* completely initialize */ for (chipIndex = 0; chipIndex < gc->chipCount; chipIndex++) { switch (chipaamode[chipIndex]) { case 0: /* disable the chip, don't care about the buffers */ chipEnList &= ~(1 << chipIndex); break; case 1: /* We are only rendering to the primary buffer (sample 0 or 2) so just set up the primary buffer jitter values and disable the secondary buffer. */ chipEnList |= (1 << chipIndex); _grChipMask(1 << chipIndex); _grAAOffsetValue(_GlideRoot.environment.aaXOffset[tBufferSampleOffsetIndex], _GlideRoot.environment.aaYOffset[tBufferSampleOffsetIndex], chipIndex, chipIndex, FXTRUE, FXFALSE); /* setup color/aux buffer */ gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; gc->state.shadow.auxBufferAddr = gc->buffers0[gc->grColBuf]; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); break; case 2: /* We are only rendering to the secondary buffer (sample 1 or 3), so point the primary color buffer address at the secondary buffer, and use the secondary jitter values for this chip as the primary values, and disable the second buffer. */ chipEnList |= (1 << chipIndex); _grChipMask(1 << chipIndex); _grAAOffsetValue(_GlideRoot.environment.aaXOffset[tBufferSampleOffsetIndex], _GlideRoot.environment.aaYOffset[tBufferSampleOffsetIndex], chipIndex, chipIndex, FXTRUE, FXFALSE); /* setup color/aux buffer */ gc->state.shadow.colBufferAddr = gc->buffers1[gc->curBuffer]; gc->state.shadow.auxBufferAddr = gc->buffers1[gc->grColBuf]; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); break; case 3: /* This chip is doing both 0 and 1 or 2 and 3, so enable both sets of buffers. */ chipEnList |= (1 << chipIndex); _grChipMask(1 << chipIndex); _grAAOffsetValue(_GlideRoot.environment.aaXOffset[tBufferSampleOffsetIndex], _GlideRoot.environment.aaYOffset[tBufferSampleOffsetIndex], chipIndex, chipIndex, FXTRUE, gc->enableSecondaryBuffer); /* setup color/aux buffer */ gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; gc->state.shadow.auxBufferAddr = gc->buffers0[gc->grColBuf]; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->buffers1[gc->grColBuf] | SST_BUFFER_BASE_SELECT); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); break; default: break; } } #else /* Colourless */ /* Sanity Check. Make sure we are attempting to actually enable something */ if( (tmask&((1 << gc->grPixelSample)-1)) == 0) { return; } chipEnList = 0; /* 2 Samples Per Chip and not SLI */ if(gc->enableSecondaryBuffer && !gc->sliCount) { /* Chip 0 = Samples 0 & 1 Chip 1 = Samples 2 & 3 Chip 2 = Samples 4 & 5 Chip 3 = Samples 6 & 7 */ chipaamode[0] = ((tmask>>0) & 1) | (((tmask>>1) & 1) << 1); chipaamode[1] = ((tmask>>2) & 1) | (((tmask>>3) & 1) << 1); chipaamode[2] = ((tmask>>4) & 1) | (((tmask>>5) & 1) << 1); chipaamode[3] = ((tmask>>6) & 1) | (((tmask>>7) & 1) << 1); } /* 1 Sample per chip and not SLI */ else if(!gc->sliCount) { /* Chip 0 = Sample 0 Chip 1 = Sample 1 Chip 2 = Sample 2 Chip 3 = Sample 3 */ chipaamode[0] = (tmask>>0) & 1; chipaamode[1] = (tmask>>1) & 1; chipaamode[2] = (tmask>>2) & 1; chipaamode[3] = (tmask>>3) & 1; } /* 1 Sample per chip and SLI */ else if (gc->enableSecondaryBuffer) { /* Chip 0 = Sample 0 Chip 1 = Sample 1 Chip 2 = Sample 0 Chip 3 = Sample 1 */ chipaamode[2] = chipaamode[0] = (tmask>>0) & 1; chipaamode[3] = chipaamode[1] = (tmask>>1) & 1; } /* 2 Samples per chip and SLI */ else { /* Chip 0 = Samples 0 & 1 Chip 1 = Samples 0 & 1 Chip 2 = Samples 2 & 3 Chip 3 = Samples 2 & 3 */ chipaamode[0] = ((tmask>>0) & 1) | (((tmask>>1) & 1) << 1); chipaamode[1] = ((tmask>>0) & 1) | (((tmask>>1) & 1) << 1); chipaamode[2] = ((tmask>>2) & 1) | (((tmask>>3) & 1) << 1); chipaamode[3] = ((tmask>>2) & 1) | (((tmask>>3) & 1) << 1); } for (chipIndex = 0; chipIndex < gc->chipCount; chipIndex++) { /* Enable/Disable the chips */ if (chipaamode[chipIndex]) chipEnList |= (1 << chipIndex); else chipEnList &= ~(1 << chipIndex); /* Enable/Disable Primary and Secondary Buffers as required */ if (gc->enableSecondaryBuffer) switch (chipaamode[chipIndex]) { case 1: /* We are only rendering to the primary buffer so disable the secondary buffer. */ _grChipMask(1 << chipIndex); /* setup color/aux buffer */ gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; gc->state.shadow.auxBufferAddr = gc->buffers0[gc->grColBuf]; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); break; case 2: /* We are only rendering to the secondary buffer so point the primary color buffer address at the secondary buffer, and disable the second buffer. */ _grChipMask(1 << chipIndex); /* setup color/aux buffer */ gc->state.shadow.colBufferAddr = gc->buffers1[gc->curBuffer]; gc->state.shadow.auxBufferAddr = gc->buffers1[gc->grColBuf]; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); #endif REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); break; case 3: /* This chip is using both buffer, so enable both. */ _grChipMask(1 << chipIndex); /* setup color/aux buffer */ gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; gc->state.shadow.auxBufferAddr = gc->buffers0[gc->grColBuf]; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->buffers1[gc->grColBuf] | SST_BUFFER_BASE_SELECT); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); break; } } #endif _grChipMask( chipEnList ); gc->state.tbufferMask = tmask; gc->chipmask = chipEnList; #undef FN_NAME } /* grTBufferWriteMaskExt */ #endif /* FX_GLIDE_NAPALM */ /*--------------------------------------------------------------------------- * _grRebuildDataList * * NB: For CVG is *IMPERATIVE* that the writes to the parameter * dataList remain in the order below otherwise the parameters * will get written to the command packet in the wrong order. */ GR_DDFUNC(_grRebuildDataList, void, (void)) { #define FN_NAME "_grRebuildDataList" GR_DCL_GC; GR_DCL_HW; int curTriSize, params; FxU32 i; SstRegs *tmu0; SstRegs *tmu1; #if GLIDE3 || GLIDE_PACKED_RGB FxBool packedRGB = FXFALSE; #endif /* GLIDE3 || GLIDE_PACKED_RGB */ #ifdef GLIDE_DEBUG /* tsuIndices aren't fixed, they are programmable, ..taco static char *p_str[] = {"x","y","z","r","g","b","ooz","a","oow", "s0","t0","w0","s1","t1","w1","s2","t2","w2"}; */ #endif /* GLIDE_DEBUG */ GDBG_INFO(85,"(s) paramIndex=0x%x\n", FN_NAME, gc->state.paramIndex); curTriSize = params = 0; i = gc->state.paramIndex; #ifdef GLIDE_USE_ALT_REGMAP hw = SST_WRAP(hw,128); /* wrap 128-257 are ALTernate register mappings */ #endif /* GLIDE_USE_ALT_REGMAP */ tmu0 = SST_CHIP(hw,0xE); /* tmu 0,1,2 */ tmu1 = SST_CHIP(hw,0xC); /* tmu 1,2 */ #if GLIDE_HW_TRI_SETUP gc->cmdTransportInfo.paramMask = 0x00; #endif /* GLIDE_HW_TRI_SETUP */ #ifdef GLIDE3 gc->state.vData.vSize = 8; /* XY * 3 */ /* ** make x, y default to 0 and 1 */ /* gc->sDataList[sVtxSize++] = gc->state.vData.vertexInfo.offset + GR_VERTEX_OFFSET_X; gc->sDataList[sVtxSize++] = gc->state.vData.vertexInfo.offset + GR_VERTEX_OFFSET_Y; */ #endif /* GLIDE3 */ if (i & STATE_REQUIRES_IT_DRGB) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->cmdTransportInfo.paramMask |= SST_SETUP_RGB; gc->tsuDataList[curTriSize + 0] = GR_VERTEX_R_OFFSET << 2; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_R_OFFSET; #endif /* When using packed color we only add *ONE* item to the data list * and this signals the entire color set since it is not possible * to specify a single color component in any packet. */ #if !GLIDE_PACKED_RGB gc->tsuDataList[curTriSize + 1] = GR_VERTEX_G_OFFSET << 2; gc->tsuDataList[curTriSize + 2] = GR_VERTEX_B_OFFSET << 2; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 1] = GR_VERTEX_G_OFFSET; gc->tsuDataListByte[curTriSize + 2] = GR_VERTEX_B_OFFSET; #endif #endif /* !GLIDE_PACKED_RGB */ #elif defined(GLIDE3) gc->cmdTransportInfo.paramMask |= SST_SETUP_RGB; if (gc->state.vData.colorType == GR_FLOAT) { gc->tsuDataList[curTriSize + 0] = gc->state.vData.rgbInfo.offset; gc->tsuDataList[curTriSize + 1] = gc->state.vData.rgbInfo.offset + GR_COLOR_OFFSET_GREEN; gc->tsuDataList[curTriSize + 2] = gc->state.vData.rgbInfo.offset + GR_COLOR_OFFSET_BLUE; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = gc->state.vData.rgbInfo.offset >> 2; gc->tsuDataListByte[curTriSize + 1] = (gc->state.vData.rgbInfo.offset + GR_COLOR_OFFSET_GREEN) >> 2; gc->tsuDataListByte[curTriSize + 2] = (gc->state.vData.rgbInfo.offset + GR_COLOR_OFFSET_BLUE) >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize + 0] = 2; gc->tsuDataListScaler[curTriSize + 1] = 2; gc->tsuDataListScaler[curTriSize + 2] = 2; #endif gc->state.vData.vSize += 12; /* RGB */ } else { gc->tsuDataList[curTriSize + 0] = gc->state.vData.pargbInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = gc->state.vData.pargbInfo.offset >> 2; #endif packedRGB = FXTRUE; gc->state.vData.vSize += 4; } #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.rgbInfo.offset; gc->regDataList[curTriSize + 1].i = gc->state.vData.rgbInfo.offset + GR_COLOR_OFFSET_GREEN; gc->regDataList[curTriSize + 2].i = gc->state.vData.rgbInfo.offset + GR_COLOR_OFFSET_BLUE; gc->regDataList[curTriSize + 0].addr = (float*)&hw->RED; gc->regDataList[curTriSize + 1].addr = (float*)&hw->GRN; gc->regDataList[curTriSize + 2].addr = (float*)&hw->BLU; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ #if GLIDE_PACKED_RGB #if GLIDE3 #if !GLIDE3_VERTEX_LAYOUT //if (gc->state.vData.colorType == GR_FLOAT) { if (gc->state.vData.colorInfo.colorType == GR_FLOAT) { /* KoolSmoky */ #else /* GLIDE3_VERTEX_LAYOUT */ if (gc->state.vData.colorType == GR_FLOAT) { #endif /* GLIDE3_VERTEX_LAYOUT */ curTriSize += 3; params += 3; } else { curTriSize += 1; params += 1; packedRGB = FXTRUE; } #else /* !GLIDE3 */ curTriSize += 1; params += 1; packedRGB = FXTRUE; #endif /* GLIDE3 */ #else /* !GLIDE_PACKED_RGB */ if (gc->state.vData.colorType == GR_FLOAT) { curTriSize += 3; params += 3; } else { curTriSize += 1; params += 1; } #endif /* !GLIDE_PACKED_RGB */ } if (i & STATE_REQUIRES_IT_ALPHA) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->cmdTransportInfo.paramMask |= SST_SETUP_A; gc->tsuDataList[curTriSize + 0] = GR_VERTEX_A_OFFSET << 2; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_A_OFFSET; #endif #elif defined(GLIDE3) gc->cmdTransportInfo.paramMask |= SST_SETUP_A; if (gc->state.vData.colorType == GR_FLOAT) { gc->tsuDataList[curTriSize] = gc->state.vData.aInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.aInfo.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 2; #endif gc->state.vData.vSize += 4; } else if (!(i & STATE_REQUIRES_IT_DRGB)) { packedRGB = FXTRUE; gc->tsuDataList[curTriSize] = gc->state.vData.pargbInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.aInfo.offset >> 2; #endif gc->state.vData.vSize += 4; } #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.aInfo.offset; gc->regDataList[curTriSize + 0].addr = (float*)&hw->ALF; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) curTriSize += 1; #elif defined(GLIDE3) if ((gc->state.vData.colorType == GR_FLOAT) || (!(i & STATE_REQUIRES_IT_DRGB))) curTriSize += 1; #endif /* GLIDE_HW_TRI_SETUP */ #if GLIDE_PACKED_RGB #if GLIDE3 #if !GLIDE3_VERTEX_LAYOUT if (gc->state.vData.colorInfo.type == GR_FLOAT) { #else /* GLIDE3_VERTEX_LAYOUT */ if (gc->state.vData.colorType == GR_FLOAT) { #endif /* GLIDE3_VERTEX_LAYOUT */ params += 1; } else #endif /* GLIDE3 */ { /* Only increment the parameter packet size if we have not already * added the rgb fields. */ if ((i & STATE_REQUIRES_IT_DRGB) == 0) params += 1; packedRGB = FXTRUE; } #else /* !GLIDE_PACKED_RGB */ if ((gc->state.vData.colorType == GR_FLOAT) || !(i & STATE_REQUIRES_IT_DRGB)) params += 1; #endif /* !GLIDE_PACKED_RGB */ } if (i & STATE_REQUIRES_OOZ) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = GR_VERTEX_OOZ_OFFSET << 2; gc->cmdTransportInfo.paramMask |= SST_SETUP_Z; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_OOZ_OFFSET ; #endif #elif defined(GLIDE3) /* ** use z iterator for w if w buffering and fog coordinate enable */ if ((gc->state.shadow.fbzMode & SST_DEPTH_FLOAT_SEL) && (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS)) { gc->tsuDataList[curTriSize] = gc->state.vData.qInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.qInfo.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 0; #endif } else { gc->tsuDataList[curTriSize] = gc->state.vData.zInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.zInfo.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 1; #endif } gc->cmdTransportInfo.paramMask |= SST_SETUP_Z; gc->state.vData.vSize += 4; #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.zInfo.offset; gc->regDataList[curTriSize + 0].addr = (float*)&hw->Z; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ curTriSize += 1; params += 1; } /* we squeeze FBI.OOW in here for sequential writes in the simple case */ if (i & STATE_REQUIRES_OOW_FBI) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = GR_VERTEX_OOW_OFFSET << 2; gc->cmdTransportInfo.paramMask |= SST_SETUP_Wfbi; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_OOW_OFFSET; #endif #elif defined(GLIDE3) /* ** if fog coordinate is enabled, use w for fog coord */ if ((gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) && (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS)) { gc->tsuDataList[curTriSize] = gc->state.vData.fogInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.fogInfo.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 4; #endif } else { gc->tsuDataList[curTriSize] = gc->state.vData.qInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.qInfo.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 0; #endif } gc->cmdTransportInfo.paramMask |= SST_SETUP_Wfbi; gc->state.vData.vSize += 4; #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.qInfo.offset; gc->regDataList[curTriSize + 0].addr = (float*)&hw->W; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ curTriSize += 1; params += 1; } #if GLIDE_FP_CLAMP_TEX #if !GLIDE_FP_CLAMP || !GLIDE_HW_TRI_SETUP #error "Does not make sense to have GLIDE_FP_CLAMP_TEX w/o GLIDE_FP_CLAMP or GLIDE_HW_TRI_SETUP" #endif /* !GLIDE_FP_CLAMP || !GLIDE_HW_TRI_SETUP */ /* Simplify the test for clamping only the texture parameters by * sticking an extra empty slot into the data list. * * NB: This means that the code that runs through the parameter list * needs to increment the datalist pointer before moving onto the * texture parameters. */ gc->tsuDataList[curTriSize++] = 0; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize++] = 0; #endif #endif /* GLIDE_FP_CLAMP_TEX */ /* NOTE: this is the first */ if (i & STATE_REQUIRES_W_TMU0) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = GR_VERTEX_OOW_TMU0_OFFSET << 2; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_OOW_TMU0_OFFSET; #endif gc->cmdTransportInfo.paramMask |= SST_SETUP_W0; #elif defined(GLIDE3) /* ** if q0 is disabled and fogCoord/Q(in clip coords) is enabled, we need to move oow to w0 */ if (gc->state.vData.q0Info.mode == GR_PARAM_ENABLE) { gc->tsuDataList[curTriSize] = gc->state.vData.q0Info.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.q0Info.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 4; #endif } else { if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { gc->tsuDataList[curTriSize] = gc->state.vData.qInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.qInfo.offset >> 2; #endif } else { gc->tsuDataList[curTriSize] = gc->state.vData.wInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.wInfo.offset >> 2; #endif } #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 0; #endif } gc->cmdTransportInfo.paramMask |= SST_SETUP_W0; gc->state.vData.vSize += 4; #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.q0Info.offset; gc->regDataList[curTriSize + 0].addr = (float*)&tmu0->W; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ curTriSize += 1; params += 1; } /* TMU0 --------------------------------- */ /* always output to ALL chips, saves from having to change CHIP field */ if (i & STATE_REQUIRES_ST_TMU0) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = GR_VERTEX_SOW_TMU0_OFFSET << 2; gc->tsuDataList[curTriSize + 1] = GR_VERTEX_TOW_TMU0_OFFSET << 2; gc->cmdTransportInfo.paramMask |= SST_SETUP_ST0; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_SOW_TMU0_OFFSET; gc->tsuDataListByte[curTriSize + 1] = GR_VERTEX_TOW_TMU0_OFFSET; #endif #elif defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = gc->state.vData.st0Info.offset; gc->tsuDataList[curTriSize + 1] = gc->state.vData.st0Info.offset + GR_TEXTURE_OFFSET_T; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = gc->state.vData.st0Info.offset >> 2; gc->tsuDataListByte[curTriSize + 1] = (gc->state.vData.st0Info.offset+GR_TEXTURE_OFFSET_T) >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 3; gc->tsuDataListScaler[curTriSize+1] = 3; #endif gc->cmdTransportInfo.paramMask |= SST_SETUP_ST0; gc->state.vData.vSize += 8; #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.st0Info.offset; gc->regDataList[curTriSize + 1].i = gc->state.vData.st0Info.offset + GR_TEXTURE_OFFSET_T; gc->regDataList[curTriSize + 0].addr = (float*)&tmu0->S; gc->regDataList[curTriSize + 1].addr = (float*)&tmu0->T; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ curTriSize += 2; params += 2; } /* TMU1 --------------------------------- */ if (i & STATE_REQUIRES_W_TMU1) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = GR_VERTEX_OOW_TMU1_OFFSET << 2; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_OOW_TMU1_OFFSET; #endif gc->cmdTransportInfo.paramMask |= SST_SETUP_W1; #elif defined(GLIDE3) /* ** if q1 is disabled and fogCoord/Q(in clip coords) is enabled, we need to move oow to w1 */ if (gc->state.vData.q1Info.mode == GR_PARAM_ENABLE) { gc->tsuDataList[curTriSize] = gc->state.vData.q1Info.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.q1Info.offset >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 4; #endif } else { if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { gc->tsuDataList[curTriSize] = gc->state.vData.qInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.qInfo.offset >> 2; #endif } else { gc->tsuDataList[curTriSize] = gc->state.vData.wInfo.offset; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = gc->state.vData.wInfo.offset >> 2; #endif } #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 0; #endif } gc->cmdTransportInfo.paramMask |= SST_SETUP_W1; gc->state.vData.vSize += 4; #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.q1Info.offset; gc->regDataList[curTriSize + 0].addr = (float*)&tmu1->W; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ curTriSize += 1; params += 1; } if (i & STATE_REQUIRES_ST_TMU1) { #if GLIDE_HW_TRI_SETUP && !defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = GR_VERTEX_SOW_TMU1_OFFSET << 2; gc->tsuDataList[curTriSize + 1] = GR_VERTEX_TOW_TMU1_OFFSET << 2; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = GR_VERTEX_SOW_TMU1_OFFSET; gc->tsuDataListByte[curTriSize + 1] = GR_VERTEX_TOW_TMU1_OFFSET; #endif gc->cmdTransportInfo.paramMask |= SST_SETUP_ST1; #elif defined(GLIDE3) gc->tsuDataList[curTriSize + 0] = gc->state.vData.st1Info.offset; gc->tsuDataList[curTriSize + 1] = gc->state.vData.st1Info.offset + GR_TEXTURE_OFFSET_T; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize + 0] = gc->state.vData.st1Info.offset >> 2; gc->tsuDataListByte[curTriSize + 1] = (gc->state.vData.st1Info.offset + GR_TEXTURE_OFFSET_T) >> 2; #endif #ifdef GLIDE3_SCALER gc->tsuDataListScaler[curTriSize] = 3; gc->tsuDataListScaler[curTriSize+1] = 3; #endif gc->cmdTransportInfo.paramMask |= SST_SETUP_ST1; gc->state.vData.vSize += 8; #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize + 0].i = gc->state.vData.st1Info.offset; gc->regDataList[curTriSize + 0].addr = (float*)&tmu1->S; gc->regDataList[curTriSize + 1].i = gc->state.vData.st1Info.offset + GR_TEXTURE_OFFSET_T; gc->regDataList[curTriSize + 1].addr = (float*)&tmu1->T; #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ curTriSize += 2; params += 2; } #ifdef GLIDE_VERTEX_TABLE { FxU32 vsize = 0; for (i = 0; i < 16; i++) { gc->state.vTable[i] = vsize; vsize += gc->state.vData.vSize; } } #endif #if (GLIDE_NUM_TMU > 2) #error "GLIDE_NUM_TMU > 2: Write this code." #endif #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize].i = 0; /* terminate the list with 0,* */ #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ #if GLIDE_HW_TRI_SETUP gc->tsuDataList[curTriSize] = 0; #ifdef FAST_C_CLIP gc->tsuDataListByte[curTriSize] = 0; #endif #endif /* GLIDE_HW_TRI_SETUP */ curTriSize++; #if GLIDE_HW_TRI_SETUP /* Per vertex size: (xy [required] + parameters) * param size (32 bit word) */ gc->curVertexSize = ((2 + params) << 2); /* Packet size: 3 * vertex size */ gc->curTriSize = (gc->curVertexSize << 1) + gc->curVertexSize; /* Shift the parameter mask to just write into the packet header. */ GDBG_INFO(191, "CVG ParamMask: 0x%X\n", gc->cmdTransportInfo.paramMask); gc->cmdTransportInfo.paramMask <<= SSTCP_PKT3_PMASK_SHIFT; #if GLIDE_PACKED_RGB || GLIDE3 if (packedRGB) gc->cmdTransportInfo.paramMask |= SSTCP_PKT3_PACKEDCOLOR; #endif /* GLIDE_PACKED_RGB || GLIDE3 */ /* Update common packet 3 headers */ _grUpdateTriPacketHdr(gc->cmdTransportInfo.paramMask, gc->state.cull_mode); #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP gc->regDataList[curTriSize].i = 1; gc->regDataList[curTriSize].addr = (float*)&hw->FtriangleCMD; /* 6 X,Y values plus AREA = 7, plus parameters */ _GlideRoot.paramCount = params; _GlideRoot.curTriSize = (6 + curTriSize + (params << 1)) << 2; /* Need to know tri size without gradients for planar polygons */ _GlideRoot.curTriSizeNoGradient = _GlideRoot.curTriSize - (params << 3); #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ #if GLIDE_FP_CLAMP_TEX /* Stick one more 0 in the dataList so that the texture clamping * loop does not go one more iteration. */ gc->tsuDataList[++curTriSize] = 0; #ifdef FAST_C_CLIP gc->tsuDataListByte[++curTriSize] = 0; #endif #endif /* GLIDE_FP_CLAMP_TEX */ #ifdef GDBG_INFO_ON #if GLIDE_HW_TRI_SETUP for (i = 0; gc->tsuDataList[i]; i++) { GDBG_INFO(282," tsuDataList[%d] = %2d \n", i, gc->tsuDataList[i] >> 2 ); } #endif /* GLIDE_HW_TRI_SETUP */ #if !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP #if 0 for (i = 0; gc->regDataList[i].i; i++) { GDBG_INFO(282," dataList[%d] = %2d 0x%x [%s]\n", i, gc->regDataList[i].i >> 2, gc->regDataList[i].addr, p_str[gc->regDataList[i].i >> 2]); } #endif #endif /* !GLIDE_HW_TRI_SETUP || !GLIDE_PACKET3_TRI_SETUP */ #endif /* GDBG_INFO_ON */ #undef FN_NAME } /* _grRebuildDataList */ #if GLIDE_MULTIPLATFORM /* _grInitializeGCFuncs - initialize the gcFuncs Structure for this device. */ GR_DDFUNC(_grInitializeGCFuncs, void, (GrGC *gc)) { gc->gcFuncs._grColorCombineDelta0Mode = (void *) GR_DDNAME(_grColorCombineDelta0Mode); gc->gcFuncs._grRebuildDataList = (void *) GR_DDNAME(_grRebuildDataList); gc->gcFuncs._grTexDetailControl = (void *) GR_DDNAME(_grTexDetailControl); gc->gcFuncs._grTexDownloadNccTable = (void *) GR_DDNAME(_grTexDownloadNccTable); gc->gcFuncs._grTexDownloadPalette = (void *) GR_DDNAME(_grTexDownloadPalette); gc->gcFuncs._gumpTexCombineFunction = (void *) GR_DDNAME(_gumpTexCombineFunction); gc->gcFuncs._grUpdateParamIndex = (void *) GR_DDNAME(_grUpdateParamIndex); gc->gcFuncs._trisetup = (void *) GR_DDNAME(_trisetup); gc->gcFuncs._trisetup_nogradients = (void *) GR_DDNAME(_trisetup_nogradients); gc->gcFuncs.grAADrawLine = (void *) GR_DDNAME(grAADrawLine); gc->gcFuncs.grAADrawPoint = (void *) GR_DDNAME(grAADrawPoint); gc->gcFuncs.grAADrawPolygon = (void *) GR_DDNAME(grAADrawPolygon); gc->gcFuncs.grAADrawPolygonVertexList = (void *) GR_DDNAME(grAADrawPolygonVertexList); gc->gcFuncs.grAADrawTriangle = (void *) GR_DDNAME(grAADrawTriangle); gc->gcFuncs.grAlphaBlendFunction = (void *) GR_DDNAME(grAlphaBlendFunction); gc->gcFuncs.grAlphaCombine = (void *) GR_DDNAME(grAlphaCombine); gc->gcFuncs.grAlphaControlsITRGBLighting = (void *) GR_DDNAME(grAlphaControlsITRGBLighting); gc->gcFuncs.grAlphaTestFunction = (void *) GR_DDNAME(grAlphaTestFunction); gc->gcFuncs.grAlphaTestReferenceValue = (void *) GR_DDNAME(grAlphaTestReferenceValue); gc->gcFuncs.grBufferClear = (void *) GR_DDNAME(grBufferClear); gc->gcFuncs.grBufferNumPending = (void *) GR_DDNAME(grBufferNumPending); #ifdef DRI_BUILD gc->gcFuncs.grBufferSwap = (void *) GR_DDNAME(grDRIBufferSwap); #else /* defined(DRI_BUILD) */ gc->gcFuncs.grBufferSwap = (void *) GR_DDNAME(grBufferSwap); #endif /* defined(DRI_BUILD) */ gc->gcFuncs.grChromakeyMode = (void *) GR_DDNAME(grChromakeyMode); gc->gcFuncs.grChromakeyValue = (void *) GR_DDNAME(grChromakeyValue); gc->gcFuncs.grClipWindow = (void *) GR_DDNAME(grClipWindow); gc->gcFuncs.grColorCombine = (void *) GR_DDNAME(grColorCombine); gc->gcFuncs.grColorMask = (void *) GR_DDNAME(grColorMask); gc->gcFuncs.grConstantColorValue = (void *) GR_DDNAME(grConstantColorValue); gc->gcFuncs.grConstantColorValue4 = (void *) GR_DDNAME(grConstantColorValue4); gc->gcFuncs.grCullMode = (void *) GR_DDNAME(grCullMode); gc->gcFuncs.grDepthBiasLevel = (void *) GR_DDNAME(grDepthBiasLevel); gc->gcFuncs.grDepthBufferFunction = (void *) GR_DDNAME(grDepthBufferFunction); gc->gcFuncs.grDepthBufferMode = (void *) GR_DDNAME(grDepthBufferMode); gc->gcFuncs.grDepthMask = (void *) GR_DDNAME(grDepthMask); gc->gcFuncs.grDisableAllEffects = (void *) GR_DDNAME(grDisableAllEffects); gc->gcFuncs.grDitherMode = (void *) GR_DDNAME(grDitherMode); gc->gcFuncs.grDrawLine = (void *) GR_DDNAME(grDrawLine); gc->gcFuncs.grDrawPlanarPolygon = (void *) GR_DDNAME(grDrawPlanarPolygon); gc->gcFuncs.grDrawPlanarPolygonVertexList = (void *) GR_DDNAME(grDrawPlanarPolygonVertexList); gc->gcFuncs.grDrawPoint = (void *) GR_DDNAME(grDrawPoint); gc->gcFuncs.grDrawPolygon = (void *) GR_DDNAME(grDrawPolygon); gc->gcFuncs.grDrawPolygonVertexList = (void *) GR_DDNAME(grDrawPolygonVertexList); gc->gcFuncs.grDrawTriangle = (void *) GR_DDNAME(grDrawTriangle); gc->gcFuncs.grFogColorValue = (void *) GR_DDNAME(grFogColorValue); gc->gcFuncs.grFogMode = (void *) GR_DDNAME(grFogMode); gc->gcFuncs.grFogTable = (void *) GR_DDNAME(grFogTable); gc->gcFuncs.grGammaCorrectionValue = (void *) GR_DDNAME(grGammaCorrectionValue); gc->gcFuncs.grGlideSetState = (void *) GR_DDNAME(grGlideSetState); gc->gcFuncs.grGlideShutdown = (void *) GR_DDNAME(grGlideShutdown); gc->gcFuncs.grLfbConstantAlpha = (void *) GR_DDNAME(grLfbConstantAlpha); gc->gcFuncs.grLfbConstantDepth = (void *) GR_DDNAME(grLfbConstantDepth); gc->gcFuncs.grLfbLock = (void *)GR_DDNAME(grLfbLock); gc->gcFuncs.grLfbUnlock = (void*)GR_DDNAME(grLfbUnlock); gc->gcFuncs.grLfbWriteColorFormat = (void *) GR_DDNAME(grLfbWriteColorFormat); gc->gcFuncs.grLfbWriteColorSwizzle = (void *) GR_DDNAME(grLfbWriteColorSwizzle); gc->gcFuncs.grRenderBuffer = (void *) GR_DDNAME(grRenderBuffer); gc->gcFuncs.grSstConfigPipeline = (void *) GR_DDNAME(grSstConfigPipeline); gc->gcFuncs.grSstIdle = (void *) GR_DDNAME(grSstIdle); gc->gcFuncs.grSstIsBusy = (void *) GR_DDNAME(grSstIsBusy); gc->gcFuncs.grSstOpen = (void *) GR_DDNAME(grSstOpen); gc->gcFuncs.grSstOrigin = (void *) GR_DDNAME(grSstOrigin); gc->gcFuncs.grSstPassthruMode = (void *) GR_DDNAME(grSstPassthruMode); gc->gcFuncs.grSstPerfStats = (void *) GR_DDNAME(grSstPerfStats); gc->gcFuncs.grSstResetPerfStats = (void *) GR_DDNAME(grSstResetPerfStats); gc->gcFuncs.grSstStatus = (void *) GR_DDNAME(grSstStatus); gc->gcFuncs.grSstVRetraceOn = (void *) GR_DDNAME(grSstVRetraceOn); gc->gcFuncs.grSstVideoLine = (void *) GR_DDNAME(grSstVideoLine); gc->gcFuncs.grTexClampMode = (void *) GR_DDNAME(grTexClampMode); gc->gcFuncs.grTexCombine = (void *) GR_DDNAME(grTexCombine); gc->gcFuncs.grTexDownloadMipMapLevelPartial = (void *) GR_DDNAME(grTexDownloadMipMapLevelPartial); gc->gcFuncs.grTexFilterMode = (void *) GR_DDNAME(grTexFilterMode); gc->gcFuncs.grTexLodBiasValue = (void *) GR_DDNAME(grTexLodBiasValue); gc->gcFuncs.grTexMipMapMode = (void *) GR_DDNAME(grTexMipMapMode); gc->gcFuncs.grTexMultibase = (void *) GR_DDNAME(grTexMultibase); gc->gcFuncs.grTexMultibaseAddress = (void *) GR_DDNAME(grTexMultibaseAddress); gc->gcFuncs.grTexNCCTable = (void *) GR_DDNAME(grTexNCCTable); gc->gcFuncs.grTexSource = (void *) GR_DDNAME(grTexSource); gc->gcFuncs.guMPDrawTriangle = (void *) GR_DDNAME(guMPDrawTriangle); gc->gcFuncs.guTexSource = (void *) GR_DDNAME(guTexSource); gc->gcFuncs.ConvertAndDownloadRle=(void *) GR_DDNAME(ConvertAndDownloadRle); gc->gcFuncs.grCheckForRoom=(void *) GR_DDNAME(grCheckForRoom); } /* _grInitializeGCFuncs */ #endif glide3x/h5/glide3/src/glfb.c0100700000175300010010000023410107725034670015051 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glfb.c,v 1.7.4.16 2003/08/21 08:49:55 dborca Exp $ ** $Log: glfb.c,v $ ** Revision 1.7.4.16 2003/08/21 08:49:55 dborca ** Texture fixes by Koolsmoky ** ** Revision 1.7.4.15 2003/08/04 12:44:40 dborca ** Enabled 32bit Z writes ** ** Revision 1.7.4.14 2003/07/25 07:14:59 dborca ** ... in the name of the Linux, DRI and the sacred Glide... ** ** Revision 1.7.4.13 2003/07/24 03:51:08 anholt ** Convert h5/glide3/src/ for FreeBSD, mostly by changing #ifdef __linux__ to ** #ifdef DRI_BUILD, and removing a bit of dead code. ** ** Revision 1.7.4.12 2003/07/10 12:26:27 dborca ** no message ** ** Revision 1.7.4.11 2003/07/08 18:43:37 koolsmoky ** removed unused local variables ** ** Revision 1.7.4.10 2003/07/08 08:06:45 dborca ** updates to MMX/FPU specializations ** ** Revision 1.7.4.9 2003/07/07 23:29:05 koolsmoky ** cleaned logs ** ** Revision 1.7.4.8 2003/07/03 10:35:34 koolsmoky ** cleaned _grlfblock ** ** Revision 1.7.4.7 2003/06/29 15:10:32 koolsmoky ** added LFB read/write FPU specializations ** ** Revision 1.7.4.6 2003/06/27 15:11:07 koolsmoky ** fixed win32 compile error for LFB read/write MMX specializations ** ** Revision 1.7.4.5 2003/06/27 10:40:52 dborca ** added LFB read/write MMX specializations ** ** 14 3dfx 1.7.1.2.1.2 10/11/00 Brent Forced check in to enforce ** branching. ** 13 3dfx 1.7.1.2.1.1 08/29/00 Jonny Cochrane Some 8x FSAA code ** 12 3dfx 1.7.1.2.1.0 08/08/00 Andy Hanson Fix in grLfbReadRegion for ** 32 bit surfaces. If 32 bit is forced, and game isn't aware, we could ** overflow the destination buffer now. but it wouldn't look right anyways. ** Will add FX_GLIDE_LFB_OVERFLOW evar if a problem arises. ** 11 3dfx 1.7.1.2 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 10 3dfx 1.7.1.1 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 9 3dfx 1.7.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 8 3dfx 1.7 03/16/00 Kenneth Dyke Fix for Y origin swapped ** LFB writes. ** 7 3dfx 1.6 03/03/00 Kenneth Dyke Added support for SLI read ** abort workaround. ** 6 3dfx 1.5 03/01/00 Kenneth Dyke Disable dither rotation for ** 3D lfbs. ** 5 3dfx 1.4 03/01/00 Kenneth Dyke Fixed pixelPipe Aux buffer ** writes. ** Fix for OpenGL that requires read/writes strides to be identical. ** Fixed to use dynamic LFB stride value taken from minihwc. ** 4 3dfx 1.3 01/31/00 Kenneth Dyke Fix IS_NAPALM() macro usage ** for PowerPC systems. ** 3 3dfx 1.2 01/31/00 Kenneth Dyke Use new IS_NAPALM() macro ** for MacOS lfb stuff. ** 2 3dfx 1.1 01/31/00 Kenneth Dyke Improved LFB support for ** 32-bit buffers. Added big-endian swizzling support for PowerPC systems. ** Read locks now return pixel format in lfbInfo. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** ** 33 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 32 7/02/99 4:43p Kcd ** Improved PowerPC lfb support. ** ** 31 6/24/99 7:15p Atai ** 2 buffers per chip ** ** 30 5/26/99 4:40p Kcd ** Fixed minor compiler warning. ** ** 29 5/26/99 4:19p Kcd ** Use new LFB macros and make grLfbReadRegion & grLfbWriteRegion work ** properly for PowerPC. ** ** 28 5/19/99 3:55p Denis ** ** 27 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a tbext comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 26 4/16/99 2:49p Kcd ** Codewarrior warning fixes ** ** 25 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 24 3/24/99 6:17p Peter ** streamlined (made more dangerouse) state validation ** ** 23 3/10/99 6:47p Peter ** need to bump-n-grind in lfb lock too, fixed nested lock error condition ** ** 22 3/08/99 4:28p Mikec ** Made sure when we return raw lfb ptr in a write lock (pix pipe is off), ** the origin is not lower left. ** ** 21 1/25/99 6:33p Peter ** removed some cruft I saw when cleaning up tiled textures ** ** 20 9/10/98 12:40p Mikec ** Changed grLfbLock to be in sync with glide2x. ** ** 19 9/08/98 7:19p Atai ** fix debug info. added underline for internal routines and some \n ** ** 18 9/01/98 9:59a Dow ** Fixed stride bug for 32-bit formats. ** ** 17 8/29/98 12:14p Mikec ** Changed grLfbLock to return the current buffer lfbptr (read ptr) if it ** is writeOnly and 565 and not pixelpipe. ** ** 15 8/11/98 7:22p Atai ** fix grLfbLock read only ** ** 14 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 13 7/18/98 12:28a Jdt ** Changes to reflect new shadow register structure. ** ** 12 7/16/98 8:18a Jdt ** fxcmd.h ** ** 11 7/01/98 12:41p Jdt ** Moved some code around to do proper flushing for lfb ** accesses ** Protected hacks for Glide/Win ( FX_TACO_MEMORY_FIFO_HACK ) ** Moved towards fixing lfb read on Banshee ** ** 10 6/10/98 11:58a Peter ** lfb tiled addressing ** ** 9 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 7 4/22/98 4:57p Peter ** glide2x merge ** ** 6 4/21/98 1:34p Atai ** make 32 bit clean ** ** 5 2/01/98 7:52p Peter ** grLfbWriteRegion byte count problems ** ** 4 1/28/98 2:20p Atai ** fixed lfb state validation ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 2 1/16/98 6:44p Atai * fixed for glide 3 build * * 1 1/16/98 4:29p Atai * create glide 3 src * * 58 1/16/98 4:18p Atai * fixed lfb and grLoadGammaTable * * 57 1/06/98 3:53p Atai * remove grHint, modify grLfbWriteRegion and grGet * * 56 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 55 12/15/97 6:04p Atai * disable obsolete glide2 api for glide3 * * 54 12/15/97 5:54p Peter * swizzle reads too * * 53 12/11/97 4:15p Peter * mac lfb write region * * 52 12/01/97 5:18p Peter * h3 simulator happiness * * 51 11/25/97 12:09p Peter * nested calls to grLfbLock vs init code locking on v2 * * 50 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 49 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 48 11/06/97 3:38p Dow * More banshee stuff * * 47 11/04/97 5:04p Peter * cataclysm part deux * * 46 11/03/97 3:43p Peter * h3/cvg cataclysm * * 45 10/27/97 11:10a Peter * starting cleanup * * 44 10/09/97 8:02p Dow * State Monster 1st Cut * * 43 10/08/97 5:18p Peter * fixed grLfbLock wrt writemode_any * * 42 10/08/97 11:33a Peter * hmmmm.... * * 41 9/30/97 1:03p Peter * more debugging code * * 40 9/25/97 1:35p Peter * more fixes for csim * * 39 9/24/97 4:09p Peter * lfb/idle fixes * * 38 9/24/97 1:31p Peter * assert if grXX call inside lock/unlock * * 37 9/20/97 10:54a Peter * naked lfb writes * * 36 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 35 9/10/97 10:13p Peter * fifo logic from GaryT, non-normalized fp first cut * * 34 9/05/97 5:29p Peter * changes for direct hw * * 33 9/04/97 3:32p Peter * starting grouping serial reg writes * * 32 8/18/97 3:52p Peter * pre-hw arrival fixes/cleanup * * 31 7/30/97 2:42p Peter * more cleanup * * 30 7/28/97 2:41p Peter * turned sli code back on for cvg, but waiting for hal * * 29 7/26/97 3:04p Peter * gratuitous plug is translucent * * 28 7/02/97 12:28p Peter * removed spurious NOP, tex dl * * 27 6/26/97 10:14a Peter * cmd fifo for lfb * * 26 6/06/97 10:47a Peter * texture downloading, fixed 640x480 dimension, changed cvg dep to be the * same as sst1 * ** */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #ifdef DRI_BUILD #include #endif /* defined(DRI_BUILD) */ /*--------------------------------------------------------------------------- ** MMX specializations */ #ifdef __GNUC__ #define MMX_RESET() __asm __volatile ("emms") #define MMX_SRCLINE(src, dst, length) __asm __volatile ("\n\ movl %2, %%ecx \n\ movl %0, %%esi \n\ movl %1, %%edi \n\ cmpl $8, %%ecx \n\ jb 4f \n\ testl $2, %%esi \n\ jz 1f \n\ movw (%%esi), %%ax \n\ addl $2, %%esi \n\ movw %%ax, (%%edi) \n\ addl $2, %%edi \n\ subl $2, %%ecx \n\ .p2align 3,,7 \n\ 1: \n\ testl $4, %%esi \n\ jz 2f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ subl $4, %%ecx \n\ .p2align 3,,7 \n\ 2: \n\ movl %%ecx, %%eax \n\ andl $7, %%ecx \n\ shrl $3, %%eax \n\ jz 4f \n\ .p2align 3,,7 \n\ 3: \n\ movq (%%esi), %%mm0 \n\ addl $8, %%esi \n\ movq %%mm0, (%%edi) \n\ addl $8, %%edi \n\ decl %%eax \n\ jnz 3b \n\ .p2align 3,,7 \n\ 4: \n\ testl $4, %%ecx \n\ jz 5f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ .p2align 3,,7 \n\ 5: \n\ testl $2, %%ecx \n\ jz 6f \n\ movw (%%esi), %%ax \n\ movw %%ax, (%%edi) \n\ .p2align 3,,7 \n\ 6:"::"g"(src), "g"(dst), "g"(length):"%eax", "%ecx", "%esi", "%edi") #define MMX_DSTLINE2(src, dst, width) __asm __volatile ("\n\ movl %2, %%ecx \n\ movl %0, %%esi \n\ movl %1, %%edi \n\ cmpl $4, %%ecx \n\ jb 4f \n\ testl $2, %%edi \n\ jz 1f \n\ movw (%%esi), %%ax \n\ addl $2, %%esi \n\ movw %%ax, (%%edi) \n\ addl $2, %%edi \n\ decl %%ecx \n\ .p2align 3,,7 \n\ 1: \n\ testl $4, %%edi \n\ jz 2f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ subl $2, %%ecx \n\ .p2align 3,,7 \n\ 2: \n\ movl %%ecx, %%eax \n\ andl $3, %%ecx \n\ shrl $2, %%eax \n\ jz 4f \n\ .p2align 3,,7 \n\ 3: \n\ movq (%%esi), %%mm0 \n\ addl $8, %%esi \n\ movq %%mm0, (%%edi) \n\ addl $8, %%edi \n\ decl %%eax \n\ jnz 3b \n\ .p2align 3,,7 \n\ 4: \n\ testl $2, %%ecx \n\ jz 5f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ .p2align 3,,7 \n\ 5: \n\ testl $1, %%ecx \n\ jz 6f \n\ movw (%%esi), %%ax \n\ movw %%ax, (%%edi) \n\ .p2align 3,,7 \n\ 6:"::"g"(src), "g"(dst), "g"(width):"%eax", "%ecx", "%esi", "%edi") #define MMX_DSTLINE4(src, dst, width) __asm __volatile ("\n\ movl %2, %%ecx \n\ movl %0, %%esi \n\ movl %1, %%edi \n\ cmpl $2, %%ecx \n\ jb 4f \n\ testl $1, %%edi \n\ jz 2f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ decl %%ecx \n\ .p2align 3,,7 \n\ 2: \n\ movl %%ecx, %%eax \n\ andl $1, %%ecx \n\ shrl %%eax \n\ jz 4f \n\ .p2align 3,,7 \n\ 3: \n\ movq (%%esi), %%mm0 \n\ addl $8, %%esi \n\ movq %%mm0, (%%edi) \n\ addl $8, %%edi \n\ decl %%eax \n\ jnz 3b \n\ .p2align 3,,7 \n\ 4: \n\ testl $1, %%ecx \n\ jz 5f \n\ movl (%%esi), %%eax \n\ movl %%eax, (%%edi) \n\ .p2align 3,,7 \n\ 5:"::"g"(src), "g"(dst), "g"(width):"%eax", "%ecx", "%esi", "%edi") #else #define MMX_RESET() __asm { emms } /* Desc: copy one row of pixels * * In : length = number of bytes (pixels*bytesperpixel). Must be even (which * holds true, because we don't support 8bit. Also the existing * code assumes this, so this won't be a problem. * src = source buffer * dst = destination buffer * * Note: Aligns src (LFB) before copying. Clobbers eax, ecx, esi, edi */ #define MMX_SRCLINE(src, dst, length) __asm {\ __asm mov ecx, length \ __asm mov esi, src \ __asm mov edi, dst \ __asm cmp ecx, 8 \ __asm jb small_move \ __asm test esi, 2 \ __asm jz check4 \ __asm mov ax, [esi] \ __asm add esi, 2 \ __asm mov [edi], ax \ __asm add edi, 2 \ __asm sub ecx, 2 \ __asm align 8 \ __asm check4: \ __asm test esi, 4 \ __asm jz aligned8 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm sub ecx, 4 \ __asm align 8 \ __asm aligned8: \ __asm mov eax, ecx \ __asm and ecx, 7 \ __asm shr eax, 3 \ __asm jz small_move \ __asm align 8 \ __asm big_move: \ __asm movq mm0, [esi] \ __asm add esi, 8 \ __asm movq [edi], mm0 \ __asm add edi, 8 \ __asm dec eax \ __asm jnz big_move \ __asm align 8 \ __asm small_move: \ __asm test ecx, 4 \ __asm jz check2 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm align 8 \ __asm check2: \ __asm test ecx, 2 \ __asm jz finish \ __asm mov ax, [esi] \ __asm mov [edi], ax \ __asm align 8 \ __asm finish: \ } /* Desc: copy one row of 16bit pixels * * In : width = number of pixels * src = source buffer * dst = destination buffer * * Note: Aligns dst (LFB) before copying. Clobbers eax, ecx, esi, edi */ #define MMX_DSTLINE2(src, dst, width) __asm {\ __asm mov ecx, width \ __asm mov esi, src \ __asm mov edi, dst \ __asm cmp ecx, 4 \ __asm jb small_move_mmx_dstline2 \ __asm test edi, 2 \ __asm jz check4_mmx_dstline2 \ __asm mov ax, [esi] \ __asm add esi, 2 \ __asm mov [edi], ax \ __asm add edi, 2 \ __asm dec ecx \ __asm align 8 \ __asm check4_mmx_dstline2: \ __asm test edi, 4 \ __asm jz aligned8_mmx_dstline2 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm sub ecx, 2 \ __asm align 8 \ __asm aligned8_mmx_dstline2: \ __asm mov eax, ecx \ __asm and ecx, 3 \ __asm shr eax, 2 \ __asm jz small_move_mmx_dstline2 \ __asm align 8 \ __asm big_move_mmx_dstline2: \ __asm movq mm0, [esi] \ __asm add esi, 8 \ __asm movq [edi], mm0 \ __asm add edi, 8 \ __asm dec eax \ __asm jnz big_move_mmx_dstline2 \ __asm align 8 \ __asm small_move_mmx_dstline2: \ __asm test ecx, 2 \ __asm jz check2_mmx_dstline2 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm align 8 \ __asm check2_mmx_dstline2: \ __asm test ecx, 1 \ __asm jz finish_mmx_dstline2 \ __asm mov ax, [esi] \ __asm mov [edi], ax \ __asm align 8 \ __asm finish_mmx_dstline2: \ } /* Desc: copy one row of 32bit pixels * * In : width = number of pixels * src = source buffer * dst = destination buffer * * Note: Aligns dst (LFB) before copying. Clobbers eax, ecx, esi, edi */ #define MMX_DSTLINE4(src, dst, width) __asm {\ __asm mov ecx, width \ __asm mov esi, src \ __asm mov edi, dst \ __asm cmp ecx, 2 \ __asm jb small_move_mmx_dstline4 \ __asm test edi, 4 \ __asm jz aligned8_mmx_dstline4 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm dec ecx \ __asm align 8 \ __asm aligned8_mmx_dstline4: \ __asm mov eax, ecx \ __asm and ecx, 1 \ __asm shr eax, 1 \ __asm jz small_move_mmx_dstline4 \ __asm align 8 \ __asm big_move_mmx_dstline4: \ __asm movq mm0, [esi] \ __asm add esi, 8 \ __asm movq [edi], mm0 \ __asm add edi, 8 \ __asm dec eax \ __asm jnz big_move_mmx_dstline4 \ __asm align 8 \ __asm small_move_mmx_dstline4: \ __asm test ecx, 1 \ __asm jz finish_mmx_dstline4 \ __asm mov eax, [esi] \ __asm mov [edi], eax \ __asm align 8 \ __asm finish_mmx_dstline4: \ } #endif /*--------------------------------------------------------------------------- ** FPU specializations */ #ifdef __GNUC__ #define FPU_SRCLINE(src, dst, length) __asm __volatile ("\n\ movl %2, %%ecx \n\ movl %0, %%esi \n\ movl %1, %%edi \n\ cmpl $8, %%ecx \n\ jb 4f \n\ testl $2, %%esi \n\ jz 1f \n\ movw (%%esi), %%ax \n\ addl $2, %%esi \n\ movw %%ax, (%%edi) \n\ addl $2, %%edi \n\ subl $2, %%ecx \n\ .p2align 3,,7 \n\ 1: \n\ testl $4, %%esi \n\ jz 2f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ subl $4, %%ecx \n\ .p2align 3,,7 \n\ 2: \n\ movl %%ecx, %%eax \n\ andl $7, %%ecx \n\ shrl $3, %%eax \n\ jz 4f \n\ .p2align 3,,7 \n\ 3: \n\ fildq (%%esi) \n\ addl $8, %%esi \n\ fistpq (%%edi) \n\ addl $8, %%edi \n\ decl %%eax \n\ jnz 3b \n\ .p2align 3,,7 \n\ 4: \n\ testl $4, %%ecx \n\ jz 5f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ .p2align 3,,7 \n\ 5: \n\ testl $2, %%ecx \n\ jz 6f \n\ movw (%%esi), %%ax \n\ movw %%ax, (%%edi) \n\ .p2align 3,,7 \n\ 6:"::"g"(src), "g"(dst), "g"(length):"%eax", "%ecx", "%esi", "%edi") #define FPU_DSTLINE2(src, dst, width) __asm __volatile ("\n\ movl %2, %%ecx \n\ movl %0, %%esi \n\ movl %1, %%edi \n\ cmpl $4, %%ecx \n\ jb 4f \n\ testl $2, %%edi \n\ jz 1f \n\ movw (%%esi), %%ax \n\ addl $2, %%esi \n\ movw %%ax, (%%edi) \n\ addl $2, %%edi \n\ decl %%ecx \n\ .p2align 3,,7 \n\ 1: \n\ testl $4, %%edi \n\ jz 2f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ subl $2, %%ecx \n\ .p2align 3,,7 \n\ 2: \n\ movl %%ecx, %%eax \n\ andl $3, %%ecx \n\ shrl $2, %%eax \n\ jz 4f \n\ .p2align 3,,7 \n\ 3: \n\ fildq (%%esi) \n\ addl $8, %%esi \n\ fistpq (%%edi) \n\ addl $8, %%edi \n\ decl %%eax \n\ jnz 3b \n\ .p2align 3,,7 \n\ 4: \n\ testl $2, %%ecx \n\ jz 5f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ .p2align 3,,7 \n\ 5: \n\ testl $1, %%ecx \n\ jz 6f \n\ movw (%%esi), %%ax \n\ movw %%ax, (%%edi) \n\ .p2align 3,,7 \n\ 6:"::"g"(src), "g"(dst), "g"(width):"%eax", "%ecx", "%esi", "%edi") #define FPU_DSTLINE4(src, dst, width) __asm __volatile ("\n\ movl %2, %%ecx \n\ movl %0, %%esi \n\ movl %1, %%edi \n\ cmpl $2, %%ecx \n\ jb 4f \n\ testl $1, %%edi \n\ jz 2f \n\ movl (%%esi), %%eax \n\ addl $4, %%esi \n\ movl %%eax, (%%edi) \n\ addl $4, %%edi \n\ decl %%ecx \n\ .p2align 3,,7 \n\ 2: \n\ movl %%ecx, %%eax \n\ andl $1, %%ecx \n\ shrl %%eax \n\ jz 4f \n\ .p2align 3,,7 \n\ 3: \n\ fildq (%%esi) \n\ addl $8, %%esi \n\ fistpq (%%edi) \n\ addl $8, %%edi \n\ decl %%eax \n\ jnz 3b \n\ .p2align 3,,7 \n\ 4: \n\ testl $1, %%ecx \n\ jz 5f \n\ movl (%%esi), %%eax \n\ movl %%eax, (%%edi) \n\ .p2align 3,,7 \n\ 5:"::"g"(src), "g"(dst), "g"(width):"%eax", "%ecx", "%esi", "%edi") #else #define FPU_SRCLINE(src, dst, length) __asm {\ __asm mov ecx, length \ __asm mov esi, src \ __asm mov edi, dst \ __asm cmp ecx, 8 \ __asm jb small_move_fpu_srcline \ __asm test esi, 2 \ __asm jz check4_fpu_srcline \ __asm mov ax, [esi] \ __asm add esi, 2 \ __asm mov [edi], ax \ __asm add edi, 2 \ __asm sub ecx, 2 \ __asm align 8 \ __asm check4_fpu_srcline: \ __asm test esi, 4 \ __asm jz aligned8_fpu_srcline \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm sub ecx, 4 \ __asm align 8 \ __asm aligned8_fpu_srcline: \ __asm mov eax, ecx \ __asm and ecx, 7 \ __asm shr eax, 3 \ __asm jz small_move_fpu_srcline \ __asm align 8 \ __asm big_move_fpu_srcline: \ __asm fild qword ptr [esi] \ __asm add esi, 8 \ __asm fistp qword ptr [edi] \ __asm add edi, 8 \ __asm dec eax \ __asm jnz big_move_fpu_srcline \ __asm align 8 \ __asm small_move_fpu_srcline: \ __asm test ecx, 4 \ __asm jz check2_fpu_srcline \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm align 8 \ __asm check2_fpu_srcline: \ __asm test ecx, 2 \ __asm jz finish_fpu_srcline \ __asm mov ax, [esi] \ __asm mov [edi], ax \ __asm align 8 \ __asm finish_fpu_srcline: \ } #define FPU_DSTLINE2(src, dst, width) __asm {\ __asm mov ecx, width \ __asm mov esi, src \ __asm mov edi, dst \ __asm cmp ecx, 4 \ __asm jb small_move_fpu_dstline2 \ __asm test edi, 2 \ __asm jz check4_fpu_dstline2 \ __asm mov ax, [esi] \ __asm add esi, 2 \ __asm mov [edi], ax \ __asm add edi, 2 \ __asm dec ecx \ __asm align 8 \ __asm check4_fpu_dstline2: \ __asm test edi, 4 \ __asm jz aligned8_fpu_dstline2 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm sub ecx, 2 \ __asm align 8 \ __asm aligned8_fpu_dstline2: \ __asm mov eax, ecx \ __asm and ecx, 3 \ __asm shr eax, 2 \ __asm jz small_move_fpu_dstline2 \ __asm align 8 \ __asm big_move_fpu_dstline2: \ __asm fild qword ptr [esi] \ __asm add esi, 8 \ __asm fistp qword ptr [edi] \ __asm add edi, 8 \ __asm dec eax \ __asm jnz big_move_fpu_dstline2 \ __asm align 8 \ __asm small_move_fpu_dstline2: \ __asm test ecx, 2 \ __asm jz check2_fpu_dstline2 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm align 8 \ __asm check2_fpu_dstline2: \ __asm test ecx, 1 \ __asm jz finish_fpu_dstline2 \ __asm mov ax, [esi] \ __asm mov [edi], ax \ __asm align 8 \ __asm finish_fpu_dstline2: \ } #define FPU_DSTLINE4(src, dst, width) __asm {\ __asm mov ecx, width \ __asm mov esi, src \ __asm mov edi, dst \ __asm cmp ecx, 2 \ __asm jb small_move_fpu_dstline4 \ __asm test edi, 4 \ __asm jz aligned8_fpu_dstline4 \ __asm mov eax, [esi] \ __asm add esi, 4 \ __asm mov [edi], eax \ __asm add edi, 4 \ __asm dec ecx \ __asm align 8 \ __asm aligned8_fpu_dstline4: \ __asm mov eax, ecx \ __asm and ecx, 1 \ __asm shr eax, 1 \ __asm jz small_move_fpu_dstline4 \ __asm align 8 \ __asm big_move_fpu_dstline4: \ __asm fild qword ptr [esi] \ __asm add esi, 8 \ __asm fistp qword ptr [edi] \ __asm add edi, 8 \ __asm dec eax \ __asm jnz big_move_fpu_dstline4 \ __asm align 8 \ __asm small_move_fpu_dstline4: \ __asm test ecx, 1 \ __asm jz finish_fpu_dstline4 \ __asm mov eax, [esi] \ __asm mov [edi], eax \ __asm align 8 \ __asm finish_fpu_dstline4: \ } #endif /*--------------------------------------------------------------------------- ** grLfbConstantAlpha */ GR_ENTRY(grLfbConstantAlpha, void, (GrAlpha_t alpha)) { GR_BEGIN_NOFIFOCHECK("grLfbConstantAlpha",82); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",alpha); gc->state.lfb_constant_alpha = alpha; GR_END(); } /* grLfbConstantAlpha */ /*--------------------------------------------------------------------------- ** grLfbConstantDepth */ GR_ENTRY(grLfbConstantDepth, void, (FxU32 depth)) { GR_BEGIN_NOFIFOCHECK("grLfbConstantDepth",82); GDBG_INFO_MORE(gc->myLevel,"(0x%x)\n",depth); gc->state.lfb_constant_depth = depth; GR_END(); } /* grLfbConstantDepth */ /*------------------------------------------------------------------- Function: grLfbLock Date: 2/19 Implementor(s): jdt Library: Glide Description: Secures a pointer to a requested frame buffer and guarantees ordered access to that buffer. Arguments: type - type of lock, one of: GR_LOCK_WRITE_ONLY GR_LOCK_READ_ONLY buffer - which buffer to lock, one of: GR_BUFFER_FRONTBUFFER GR_BUFFER_BACKBUFFER GR_BUFFER_AUXBUFFER writeMode - desired destination color format origin - desired lfb origin pixelPipeline - flag whether to process through pixpipe info - pointer to info structure Return: FXTRUE - lock is successful FXFALSE - lock fails -------------------------------------------------------------------*/ #if LFB_DISABLE_SLAVE_FIFO static FxU32 slaveBaseSize; #endif static FxBool _grLfbLock (GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, FxBool pixelPipeline, GrLfbInfo_t *info) { #define FN_NAME "_grLfbLock" FxBool rv = FXTRUE; const FxBool idleLockP = ((type & GR_LFB_NOIDLE) == 0); FxU32 lfbMode, zaColor, fbzMode, renderMode, _3dlfb = FXFALSE; GrLfbWriteMode_t fbMode = 0; GrLfbWriteMode_t depthMode = 0; GR_BEGIN_NOFIFOCHECK_RET("_grLfbLock", 82); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,0x%x)\n", type, buffer, info); GR_CHECK_COMPATABILITY(FN_NAME, !info, "Null info structure passed."); /* there is only one revision extant */ GR_CHECK_COMPATABILITY(FN_NAME, info->size != sizeof(GrLfbInfo_t), "uninitialized info structure passed."); /* Pray that no one has made any glide calls that touch the hardware... */ #ifdef FX_GLIDE_NAPALM /* works only for minihwc with env FX_GLIDE_A0_READ_ABORT set. unused for linhwc. */ if(gc->sliCount > 1 && type == GR_LFB_READ_ONLY) hwcSLIReadDisable(gc->bInfo); #endif #if defined(GLIDE3) _grValidateState(); #endif /* Load now flushed state */ lfbMode = gc->state.shadow.lfbMode; fbzMode = gc->state.shadow.fbzMode; zaColor = gc->state.shadow.zaColor; type = type & ~(GR_LFB_NOIDLE); if (gc->lockPtrs[((type == GR_LFB_WRITE_ONLY_EXPLICIT_EXT) ? GR_LFB_WRITE_ONLY : type)] != (FxU32)-1) { GDBG_INFO(83, "Read lock failure due to existing lock\n"); GR_RETURN(FXFALSE); } if (rv) { switch(type) { case GR_LFB_READ_ONLY: lfbMode &= ~(SST_LFB_READBUFSELECT | SST_LFB_YORIGIN); switch(buffer) { case GR_BUFFER_FRONTBUFFER: case GR_BUFFER_BACKBUFFER: /* tbext */ case GR_BUFFER_TEXTUREBUFFER_EXT: lfbMode |= SST_LFB_READCOLORBUFFER; break; case GR_BUFFER_AUXBUFFER: /* tbext */ case GR_BUFFER_TEXTUREAUXBUFFER_EXT: lfbMode |= SST_LFB_READDEPTHABUFFER; break; default: GR_CHECK_F(myName, 1, "illegal buffer parameter passed"); GR_RETURN(FXFALSE); break; } /* New: Since we now have multiple read formats, we set the writeFormat in the passed in lfbInfo struct to match what the actual framebuffer format is. */ { FxU32 fbMode = 0; FxU32 depthMode = 0; switch(gc->grPixelFormat) { case GR_PIXFMT_ARGB_1555: case GR_PIXFMT_AA_2_ARGB_1555: case GR_PIXFMT_AA_4_ARGB_1555: case GR_PIXFMT_AA_8_ARGB_1555: /* 8xaa */ fbMode = GR_LFBWRITEMODE_1555; depthMode = GR_LFBWRITEMODE_ZA16; break; case GR_PIXFMT_ARGB_8888: case GR_PIXFMT_AA_2_ARGB_8888: case GR_PIXFMT_AA_4_ARGB_8888: case GR_PIXFMT_AA_8_ARGB_8888: /* 8xaa */ fbMode = GR_LFBWRITEMODE_8888; depthMode = GR_LFBWRITEMODE_Z32; break; case GR_PIXFMT_RGB_565: case GR_PIXFMT_AA_2_RGB_565: case GR_PIXFMT_AA_4_RGB_565: case GR_PIXFMT_AA_8_RGB_565: /* 8xaa */ default: fbMode = GR_LFBWRITEMODE_565; depthMode = GR_LFBWRITEMODE_ZA16; break; } info->writeMode = (((buffer == GR_BUFFER_AUXBUFFER) || (buffer == GR_BUFFER_TEXTUREAUXBUFFER_EXT)) ? depthMode : fbMode); } lfbMode |= (origin ? SST_LFB_YORIGIN : 0); break; case GR_LFB_WRITE_ONLY: case GR_LFB_WRITE_ONLY_EXPLICIT_EXT: /* Set up the constant depth register because it may have * been trashed by a call to grDepthBiasLevel * (depthbiaslevel and constant depth use the same register) */ zaColor = (((FxU32) gc->state.lfb_constant_depth) << SST_ZACOLOR_DEPTH_SHIFT); zaColor |= (gc->state.lfb_constant_alpha << SST_ZACOLOR_ALPHA_SHIFT); /* disable depth biasing */ fbzMode &= ~(SST_ENZBIAS); lfbMode &= ~(SST_LFB_YORIGIN | SST_LFB_FORMAT | SST_LFB_ENPIXPIPE); #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) && SET_BSWAP /* For MacOS/PowerPC we always want to enable at least byte swapping, and for the 16-bit pixel formats we want to enable word swapping as well. */ lfbMode &= ~(SST_LFB_WRITE_BYTESWAP | SST_LFB_WRITE_SWAP16); lfbMode |= SST_LFB_WRITE_BYTESWAP; #endif /* (GLIDE_PLATFORM & GLIDE_OS_MACOS) */ switch(writeMode) { case GR_LFBWRITEMODE_RESERVED1: case GR_LFBWRITEMODE_RESERVED2: case GR_LFBWRITEMODE_RESERVED3: case GR_LFBWRITEMODE_RESERVED4: case GR_LFBWRITEMODE_RESERVED5: case GR_LFBWRITEMODE_RESERVED6: case GR_LFBWRITEMODE_RESERVED7: rv = FXFALSE; } /* Default to hw */ switch(gc->grPixelFormat) { case GR_PIXFMT_ARGB_1555: case GR_PIXFMT_AA_2_ARGB_1555: case GR_PIXFMT_AA_4_ARGB_1555: case GR_PIXFMT_AA_8_ARGB_1555: /* 8xaa */ fbMode = GR_LFBWRITEMODE_1555; depthMode = GR_LFBWRITEMODE_ZA16; break; case GR_PIXFMT_ARGB_8888: case GR_PIXFMT_AA_2_ARGB_8888: case GR_PIXFMT_AA_4_ARGB_8888: case GR_PIXFMT_AA_8_ARGB_8888: /* 8xaa */ fbMode = GR_LFBWRITEMODE_8888; depthMode = GR_LFBWRITEMODE_Z32; break; case GR_PIXFMT_RGB_565: case GR_PIXFMT_AA_2_RGB_565: case GR_PIXFMT_AA_4_RGB_565: case GR_PIXFMT_AA_8_RGB_565: /* 8xaa */ default: fbMode = GR_LFBWRITEMODE_565; depthMode = GR_LFBWRITEMODE_ZA16; break; } if (writeMode == GR_LFBWRITEMODE_ANY) { writeMode = (((buffer == GR_BUFFER_AUXBUFFER) || (buffer == GR_BUFFER_TEXTUREAUXBUFFER_EXT)) ? depthMode : fbMode); } #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) && SET_BSWAP /* I'd do this in the switch() up above if writeMode wasn't being munged */ switch(writeMode) { case GR_LFBWRITEMODE_565: case GR_LFBWRITEMODE_555: case GR_LFBWRITEMODE_1555: case GR_LFBWRITEMODE_ZA16: lfbMode |= SST_LFB_WRITE_SWAP16; } #endif /* (GLIDE_PLATFORM & GLIDE_OS_MACOS) */ switch(buffer) { case GR_BUFFER_FRONTBUFFER: case GR_BUFFER_BACKBUFFER: /* tbext */ case GR_BUFFER_TEXTUREBUFFER_EXT: rv = ((writeMode != GR_LFBWRITEMODE_ZA16) && (writeMode != GR_LFBWRITEMODE_Z32)); break; case GR_BUFFER_AUXBUFFER: /* tbext */ case GR_BUFFER_TEXTUREAUXBUFFER_EXT: rv = (writeMode == GR_LFBWRITEMODE_ZA16) || (writeMode == GR_LFBWRITEMODE_Z32); break; default: GR_CHECK_F(myName, 1, "illegal buffer parameter passed"); GR_RETURN(FXFALSE); break; } lfbMode |= (writeMode << SST_LFB_FORMAT_SHIFT); lfbMode |= (origin ? SST_LFB_YORIGIN : 0); if (pixelPipeline) { lfbMode |= SST_LFB_ENPIXPIPE; fbzMode &= ~SST_YORIGIN; fbzMode |= (origin ? SST_YORIGIN : 0); } info->writeMode = writeMode; break; default: GDBG_INFO(gc->myLevel, "Lock failed because of invalid lock type."); GR_RETURN(FXFALSE); break; } } if (rv) { const FxU32 lockCount = gc->cmdTransportInfo.lfbLockCount; gc->lockPtrs[((type == GR_LFB_WRITE_ONLY_EXPLICIT_EXT) ? GR_LFB_WRITE_ONLY : type)] = buffer; gc->cmdTransportInfo.lfbLockCount = 0x00UL; /* Setup the hw w/ the settings computed above. */ switch(type) { case GR_LFB_READ_ONLY: /* I'm not sure why this is actually doing anything on UMA * architectures since reads are always done via direct LFB * accesses anyway, and nothing in this register affects that. -- KCD */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, lfbMode, lfbMode); GR_CHECK_SIZE(); break; case GR_LFB_WRITE_ONLY: case GR_LFB_WRITE_ONLY_EXPLICIT_EXT: REG_GROUP_BEGIN(BROADCAST_ID, fbzMode, 3, 0x103); { REG_GROUP_SET(hw, fbzMode, fbzMode); REG_GROUP_SET(hw, lfbMode, lfbMode); REG_GROUP_SET(hw, zaColor, zaColor); } REG_GROUP_END(); break; } gc->state.shadow.lfbMode = lfbMode; /* Get the current lfb buffer */ { /* FixMe: Is this true if we're triple buffering? */ FxU32 colBufferIndex = 0; switch(buffer) { case GR_BUFFER_FRONTBUFFER: colBufferIndex = gc->frontBuffer; break; case GR_BUFFER_BACKBUFFER: colBufferIndex = gc->backBuffer; break; case GR_BUFFER_AUXBUFFER: colBufferIndex = gc->grColBuf; break; /* tbext */ case GR_BUFFER_TEXTUREBUFFER_EXT: if ( gc->textureBuffer.on ) { } else { colBufferIndex = gc->backBuffer; } break; case GR_BUFFER_TEXTUREAUXBUFFER_EXT: if ( gc->textureAuxBuffer.on ) { } else { colBufferIndex = gc->grColBuf; } break; default: GR_CHECK_F(myName, 1, "illegal buffer parameter passed"); GR_RETURN(FXFALSE); break; } if (rv) { #ifdef DRI_BUILD if (!colBufferIndex) { info->strideInBytes = driInfo.stride; } else { info->strideInBytes = gc->bInfo->buffInfo.bufLfbStride; } #else /* defined(DRI_BUILD) */ /* * This is the default for 3D LFBs, * which are always 2048 pixels wide. */ info->strideInBytes = 0x1000; #endif /* defined(DRI_BUILD) */ info->origin = origin; /* tbext. Kind of ugly. Kind of duplicate / unfolded code ** needs checking before collapsing ** Something seems really busted here: in the 2 first cases ** (read only and 2d lfb) we return a stride which is the actual ** stride we are setting the registers to (which is a stride in linear space) ** But in the case of 3d lfb, WE HAVE TO RETURN THE ORIGINAL TILED STRIDE ** even though we are setting the registers to the linear one. This means ** the application that makes a grlfblock IS ACTUALLY USING (OR HAS TO USE) ** the tiled stride to be able to access the supposedly LINEAR lfb space... */ if(gc->textureBuffer.on && (buffer == GR_BUFFER_TEXTUREBUFFER_EXT || buffer == GR_BUFFER_TEXTUREAUXBUFFER_EXT)) { if(type == GR_LFB_READ_ONLY) { info->lfbPtr = (void *)((FxU32)gc->rawLfb + gc->textureBuffer.addr); info->strideInBytes = gc->textureBuffer.stride; #if __POWERPC__ if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if(gc->grPixelSize == 2) { info->lfbPtr = (void *)((FxU32)info->lfbPtr + gc->bInfo->pciInfo.swizzleOffset[3]); } else { info->lfbPtr = (void *)((FxU32)info->lfbPtr + gc->bInfo->pciInfo.swizzleOffset[1]); } } #endif } #if !__POWERPC__ /* Next, If it is writeOnly and 565 and not pixelpipe, we just return the current buffer lfbPtr as the write ptr. This fixes those games that use the lfb write pointer to do lfb reads. --mikec */ else if((type == GR_LFB_WRITE_ONLY) && (writeMode == (FxI32)fbMode) && (!pixelPipeline) && /* Origin must be upper left since we will return raw lfb */ (origin != GR_ORIGIN_LOWER_LEFT)) { info->lfbPtr = (void *)((FxU32)gc->rawLfb + gc->textureBuffer.addr); info->strideInBytes = gc->textureBuffer.stride; } #endif else { #ifdef DRI_BUILD /* * For DRI, we just return the correct address and * stride. */ info->strideInBytes = gc->bInfo->buffInfo.bufLfbStride; info->lfbPtr = (void *)gc->lfbBuffers[colBufferIndex]; #else /* defined(DRI_BUILD) */ info->lfbPtr = (void *)gc->lfb_ptr; #endif /* defined(DRI_BUILD) */ /* [dBorca] need to revise this */ #ifndef DRI_BUILD switch(writeMode) { case GR_LFBWRITEMODE_565_DEPTH: case GR_LFBWRITEMODE_555_DEPTH: case GR_LFBWRITEMODE_1555_DEPTH: case GR_LFBWRITEMODE_888: case GR_LFBWRITEMODE_8888: case GR_LFBWRITEMODE_Z32: info->strideInBytes <<= 1; break; } #endif /* defined(DRI_BUILD) */ } REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->textureBuffer.addr ); REG_GROUP_SET(hw, colBufferStride, gc->textureBuffer.stride ); REG_GROUP_END(); } else { /* else !gc->textureBuffer.on */ if(type == GR_LFB_READ_ONLY) { info->lfbPtr = (void *)gc->lfbBuffers[colBufferIndex]; #ifdef DRI_BUILD if(!colBufferIndex) { info->strideInBytes = driInfo.stride; } else #endif /* defined(DRI_BUILD) */ info->strideInBytes = gc->bInfo->buffInfo.bufLfbStride; #if __POWERPC__ if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if(gc->grPixelSize == 2) { info->lfbPtr = (void *)((FxU32)info->lfbPtr + gc->bInfo->pciInfo.swizzleOffset[3]); } else { info->lfbPtr = (void *)((FxU32)info->lfbPtr + gc->bInfo->pciInfo.swizzleOffset[1]); } } #endif } #if !__POWERPC__ /* Next, If it is writeOnly and 565 (or matches the FB format exactly) and not pixelpipe, we just return the current buffer lfbPtr as the write ptr. This fixes those games that use the lfb write pointer to do lfb reads. --mikec */ /* Note: It also appears that OpenGL depends on this, since they always * take both a read and write lock, but only save off the stride value * from the latter one. So if we return different strides OpenGL's lfb * accesses will be whacked. -- KCD */ else if ((type == GR_LFB_WRITE_ONLY) && (writeMode == fbMode) && (!pixelPipeline) && /* Origin must be upper left since we will return raw lfb */ (origin != GR_ORIGIN_LOWER_LEFT)) { info->lfbPtr = (void *)gc->lfbBuffers[colBufferIndex]; info->strideInBytes = gc->bInfo->buffInfo.bufLfbStride; gc->state.shadow.colBufferAddr = gc->buffers0[colBufferIndex]; } #endif else { gc->state.shadow.colBufferAddr = gc->buffers0[colBufferIndex]; /* tbext */ if ( gc->textureBuffer.on ) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); REG_GROUP_SET(hw, colBufferAddr, gc->buffers0[colBufferIndex]); REG_GROUP_SET(hw, colBufferStride,gc->state.shadow.colBufferStride); REG_GROUP_END(); /* %%KCD - Make sure we don't program the colBufferAddr to point to * the AUX buffer if the user is trying to do pixel pipe writes to * the AUX buffer! */ } else if (colBufferIndex < (FxU32)gc->grColBuf) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, colBufferAddr, gc->buffers0[colBufferIndex]); GR_CHECK_SIZE(); } /* Make sure dither rotation is disabled for 3D LFBs. */ _3dlfb = FXTRUE; #ifdef DRI_BUILD /* * For DRI, we just return the correct address and * stride. */ info->strideInBytes = gc->bInfo->buffInfo.bufLfbStride; info->lfbPtr = (void *)gc->lfbBuffers[colBufferIndex]; #else /* defined(DRI_BUILD) */ info->lfbPtr = (void *)gc->lfb_ptr; #endif /* defined(DRI_BUILD) */ /* [dBorca] need to revise this */ #ifndef DRI_BUILD switch(writeMode) { case GR_LFBWRITEMODE_565_DEPTH: case GR_LFBWRITEMODE_555_DEPTH: case GR_LFBWRITEMODE_1555_DEPTH: case GR_LFBWRITEMODE_888: case GR_LFBWRITEMODE_8888: case GR_LFBWRITEMODE_Z32: info->strideInBytes <<= 1; break; } #endif /* defined(DRI_BUILD) */ } } #ifdef FX_GLIDE_NAPALM /* SLI Effage. It seems that in order for flipped LFBs to work right, * we have to have renderMode set up the same way rendering would want it, * otherwise bad stuff happens. */ if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { renderMode = gc->state.shadow.renderMode; fbzMode = gc->state.shadow.fbzMode; /* See above. */ if(_3dlfb) gc->state.shadow.renderMode &= ~SST_RM_DITHER_ROTATION; /* This will screw with some shadow registers, so put them back. */ _grSstOrigin(origin); gc->state.shadow.renderMode = renderMode; gc->state.shadow.fbzMode = fbzMode; } #endif if (idleLockP) { /* This is required to flush the write buffers before the * actual LFB accesses. */ P6FENCE; /* If we're not using hole counting then we need to make sure that * any queued commands are actually flushed before checking the fifo * ptr's location. */ if (!gc->cmdTransportInfo.autoBump) GR_BUMP_N_GRIND; grFinish(); } /* Pray that no one makes any glide calls that touch the hardware... */ #ifdef FX_GLIDE_NAPALM /* works only for minihwc with env FX_GLIDE_A0_READ_ABORT set. unused for linhwc. */ if(gc->sliCount > 1 && type == GR_LFB_READ_ONLY) hwcSLIReadEnable(gc->bInfo); #endif #if LFB_DISABLE_SLAVE_FIFO /* Disable slave command FIFO */ if(gc->chipCount > 1) { FxU32 depth; do { depth = GR_SLAVE_CAGP_GET(0, depth); } while(depth != 0); } slaveBaseSize = GR_SLAVE_CAGP_GET(0, baseSize); GR_SLAVE_CAGP_SET(0, baseSize, 0); #endif /* Increment lock count */ gc->cmdTransportInfo.lfbLockCount = lockCount + 1; } } } GR_RETURN(rv); #undef FN_NAME } /* _grLfbLock */ /* Hack to correct locks of forced 32 bit surfaces */ static FxU16 *forced_32bpp_lock_buffer = 0; static FxBool grLfbReadRegionOrigin (GrBuffer_t src_buffer, GrOriginLocation_t origin, FxU32 src_x, FxU32 src_y, FxU32 src_width, FxU32 src_height, FxU32 dst_stride, void *dst_data); GR_ENTRY(grLfbLock, FxBool,(GrLock_t _type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, FxBool pixelPipeline, GrLfbInfo_t *info)) { #define FN_NAME "grLfbLock" FxBool rv = FXTRUE; FxBool wantHwc = FXFALSE; FxBool forbidden = FXFALSE; GrLock_t type; GR_BEGIN_NOFIFOCHECK_RET("grLfbLock", 82); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,0x%x)\n", _type, buffer, info); GR_CHECK_COMPATABILITY(FN_NAME, !info, "Null info structure passed."); /* there is only one revision extant */ GR_CHECK_COMPATABILITY(FN_NAME, info->size != sizeof(GrLfbInfo_t), "uninitialized info structure passed."); type = _type & ~(GR_LFB_NOIDLE); if (gc->lockPtrs[type] != (FxU32)-1) { GDBG_INFO(79, "Read lock failure due to existing lock\n"); GR_RETURN(FXFALSE); } #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* fix me! */ /* Read using HWC if we want dithering and using FSAA or 16 bpp mode */ wantHwc = ((_GlideRoot.environment.useHwcAAforLfbRead & 2) && /* using HWC and */ _GlideRoot.environment.ditherHwcAA && /* want dithering and */ ((gc->bInfo->h3pixelSample > 1) || (gc->bInfo->h3pixelSize == 2))); /* using FSAA or 16 bit mode */ #endif /* If we are using forced 32 bpp mode, the app is expecting 16 bit data */ /* Or we want to be using HwcAA for the Lfb read lock */ /* We need to use a hack for reading in OpenGL since they do 2 locks. Why, oh why, oh why...*/ if ((gc->state.forced32BPP || wantHwc) && /* using forced 32 bpp mode or using HWC and */ (!_GlideRoot.environment.is_opengl || _GlideRoot.environment.oglLfbLockHack) && /* not OpenGL or using OpenGL lock hacks and */ (buffer == GR_BUFFER_FRONTBUFFER || buffer == GR_BUFFER_BACKBUFFER)) /* is front or back buffer */ { if (_GlideRoot.environment.is_opengl && type == GR_LFB_WRITE_ONLY && (gc->lockPtrs[GR_LFB_READ_ONLY] == (FxU32)buffer)) { const FxU32 lockCount = gc->cmdTransportInfo.lfbLockCount; GDBG_INFO_MORE(82,"OpenGL Locking forced 32bit->16bit hack(%d, %d)\n", _type, buffer); /* check if the buffer exists */ if(!forced_32bpp_lock_buffer) GR_RETURN(FXFALSE); /* Now set the lock pointer */ gc->lockPtrs[type] = (FxU32) buffer; /* Setup the info structure */ info->lfbPtr = forced_32bpp_lock_buffer; info->writeMode = GR_LFBWRITEMODE_565; info->strideInBytes = gc->state.screen_width * 2; info->origin = origin; gc->cmdTransportInfo.lfbLockCount = lockCount + 1; GDBG_INFO_MORE(82,"OpenGL Locked forced hack (%d, %d)\n", _type, buffer); GR_RETURN(FXFALSE); } else if (type == GR_LFB_READ_ONLY) { const FxU32 lockCount = gc->cmdTransportInfo.lfbLockCount; /* Force origin */ /* origin = GR_ORIGIN_UPPER_LEFT; */ /* Just play with the useHwcAAforLfbRead setting to tell the ReadRegion */ /* function what we want to do */ FxU32 old_useHwcAAforLfbRead = _GlideRoot.environment.useHwcAAforLfbRead; if (wantHwc) _GlideRoot.environment.useHwcAAforLfbRead |= 1; else _GlideRoot.environment.useHwcAAforLfbRead = 0; GDBG_INFO_MORE(82,"Locking forced (%d, %d)\n", _type, buffer); forced_32bpp_lock_buffer = malloc (gc->state.screen_width * gc->state.screen_height * 2); rv = grLfbReadRegionOrigin(buffer, origin, 0, 0, gc->state.screen_width, gc->state.screen_height, gc->state.screen_width*2, forced_32bpp_lock_buffer); /* Reset the useHwcAAforLfbRead setting */ _GlideRoot.environment.useHwcAAforLfbRead = old_useHwcAAforLfbRead; /* Failed to read */ if (!rv) { free (forced_32bpp_lock_buffer); forced_32bpp_lock_buffer = 0; GR_RETURN(FXFALSE); } /* Now set the lock pointer */ gc->lockPtrs[type] = (FxU32) buffer; /* Setup the info structure */ info->lfbPtr = forced_32bpp_lock_buffer; info->writeMode = GR_LFBWRITEMODE_565; info->strideInBytes = gc->state.screen_width * 2; info->origin = origin; gc->cmdTransportInfo.lfbLockCount = lockCount + 1; GDBG_INFO_MORE(82,"Locked forced (%d, %d)\n", _type, buffer); GR_RETURN(FXFALSE); } } GDBG_INFO_MORE(82,"Conventional Lock (%d, %d)\n", _type, buffer); return _grLfbLock(_type, buffer, writeMode, origin, pixelPipeline, info); #undef FN_NAME } /*------------------------------------------------------------------- Function: grLfbUnlock Date: 2/21 Implementor(s): jdt Library: Glide Description: Unlock a previously locked buffer Arguments: type - type of lock (read only/write only) buffer - which buffer to unlock Return: FXTRUE - success FXFALSE - failure -------------------------------------------------------------------*/ static FxBool _grLfbUnlock (GrLock_t type, GrBuffer_t buffer) { #define FN_NAME "_grLfbUnlock" FxBool rval = FXFALSE; GR_BEGIN_NOFIFOCHECK_RET("_grLfbUnLock", 83); GDBG_INFO_MORE(gc->myLevel,"(%d, %d)\n", type, buffer); type = type & ~(GR_LFB_NOIDLE); GR_CHECK_COMPATABILITY(FN_NAME, type != GR_LFB_WRITE_ONLY && type != GR_LFB_READ_ONLY, "Bad type"); /* tbext */ GR_CHECK_COMPATABILITY(FN_NAME, buffer != GR_BUFFER_FRONTBUFFER && buffer != GR_BUFFER_BACKBUFFER && buffer != GR_BUFFER_TEXTUREBUFFER_EXT && buffer != GR_BUFFER_TEXTUREAUXBUFFER_EXT && buffer != GR_BUFFER_AUXBUFFER, "Bad buffer"); rval = (gc->lockPtrs[type] == (FxU32)buffer); if (rval) { const FxU32 lockCount = gc->cmdTransportInfo.lfbLockCount; /* Clear the current lfb lock state */ gc->cmdTransportInfo.lfbLockCount = 0; gc->lockPtrs[type] = (FxU32)-1; #ifdef FX_GLIDE_NAPALM /* works only for minihwc with env FX_GLIDE_A0_READ_ABORT set. unused for linhwc. */ if(gc->sliCount > 1 && type == GR_LFB_READ_ONLY) { hwcSLIReadDisable(gc->bInfo); } #endif #if LFB_DISABLE_SLAVE_FIFO /* Enable slave command FIFO */ if(gc->chipCount > 1) { GR_SLAVE_CAGP_SET(0, baseSize, slaveBaseSize); } #endif /* tbext */ if ( gc->textureBuffer.on ) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, colBufferAddr, gc->textureBuffer.addr ); GR_CHECK_SIZE(); if ( buffer != GR_BUFFER_TEXTUREBUFFER_EXT && buffer != GR_BUFFER_TEXTUREAUXBUFFER_EXT ) { /* need to restore the stride also */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, colBufferStride, gc->textureBuffer.stride ); GR_CHECK_SIZE(); } } else { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, colBufferAddr, gc->buffers0[gc->curBuffer]); GR_CHECK_SIZE(); gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; } if (type == GR_LFB_WRITE_ONLY) { GR_SET_EXPECTED_SIZE(sizeof(FxU32) << 1, 2); { /* Restore depth bias level */ GR_SET(BROADCAST_ID, hw, zaColor, gc->state.shadow.zaColor); /* turn back on depth biasing */ GR_SET(BROADCAST_ID, hw, fbzMode, gc->state.shadow.fbzMode); } GR_CHECK_SIZE(); } /* Restore dither rotation (and/or Y origin bit) */ if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, renderMode, gc->state.shadow.renderMode); GR_CHECK_SIZE(); if (gc->sliCount > 1) _grEnableSliCtrl() ; } if(lockCount) gc->cmdTransportInfo.lfbLockCount = lockCount - 1; #ifdef FX_GLIDE_NAPALM if(gc->sliCount > 1 && type == GR_LFB_READ_ONLY) { if(gc->cmdTransportInfo.lfbLockCount != 0) { grFinish(); /* works only for minihwc with env FX_GLIDE_A0_READ_ABORT set. unused for linhwc. */ hwcSLIReadEnable(gc->bInfo); } else { /* works only for minihwc with env FX_GLIDE_A0_READ_ABORT set. unused for linhwc. */ hwcSLIReadDisable(gc->bInfo); } } #endif } GR_RETURN(rval); #undef FN_NAME } /* _grLfbUnlock */ /* Hack to correct locks of forced 32 bit surfaces */ GR_ENTRY(grLfbUnlock, FxBool, (GrLock_t _type, GrBuffer_t buffer)) { #define FN_NAME "grLfbUnlock" FxBool rval = FXFALSE; FxBool wantHwc = FXFALSE; GrLock_t type; GR_BEGIN_NOFIFOCHECK_RET("grLfbUnLock", 83); GDBG_INFO_MORE(gc->myLevel,"(%d, %d)\n", _type, buffer); type = _type & ~(GR_LFB_NOIDLE); GR_CHECK_COMPATABILITY(FN_NAME, type != GR_LFB_WRITE_ONLY && type != GR_LFB_READ_ONLY, "Bad type"); /* tbext */ GR_CHECK_COMPATABILITY(FN_NAME, buffer != GR_BUFFER_FRONTBUFFER && buffer != GR_BUFFER_BACKBUFFER && buffer != GR_BUFFER_TEXTUREBUFFER_EXT && buffer != GR_BUFFER_TEXTUREAUXBUFFER_EXT && buffer != GR_BUFFER_AUXBUFFER, "Bad buffer"); #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* fix me! */ /* Read using HWC if we want dithering and using FSAA or 16 bpp mode */ wantHwc = ((_GlideRoot.environment.useHwcAAforLfbRead & 2) && /* using HWC and */ _GlideRoot.environment.ditherHwcAA && /* want dithering and */ ((gc->bInfo->h3pixelSample > 1) || (gc->bInfo->h3pixelSize == 2))); /* using FSAA or 16 bit mode */ #endif /* If we are using forced 32 bpp mode, the app is expecting 16 bit data */ /* Or we want to be using HwcAA for the Lfb read lock */ /* We need to use a hack for reading in OpenGL since they do 2 locks. Why, oh why, oh why...*/ if ((gc->state.forced32BPP || wantHwc) && (!_GlideRoot.environment.is_opengl || _GlideRoot.environment.oglLfbLockHack) && (buffer == GR_BUFFER_FRONTBUFFER || buffer == GR_BUFFER_BACKBUFFER)) { if (_GlideRoot.environment.is_opengl && type == GR_LFB_WRITE_ONLY && (gc->lockPtrs[GR_LFB_READ_ONLY] == (FxU32)buffer)) { const FxU32 lockCount = gc->cmdTransportInfo.lfbLockCount; GDBG_INFO_MORE(82,"OpenGL UnLocking forced 32bit->16bit hack(%d, %d)\n", _type, buffer); // Not this buffer that is locked if (gc->lockPtrs[type] != (FxU32) buffer) return FXFALSE; // Set unlocked gc->lockPtrs[type] = (FxU32) -1; if(lockCount) gc->cmdTransportInfo.lfbLockCount = lockCount - 1; GDBG_INFO_MORE(82,"OpenGL UnLocked forced hack (%d, %d)\n", _type, buffer); return FXTRUE; } else if (type == GR_LFB_READ_ONLY) { const FxU32 lockCount = gc->cmdTransportInfo.lfbLockCount; GDBG_INFO_MORE(82,"Unlocking forced (%d, %d)\n", _type, buffer); // Not this buffer that is locked if (gc->lockPtrs[type] != (FxU32) buffer) return FXFALSE; // Set unlocked gc->lockPtrs[type] = (FxU32) -1; // But, the buffer didn't exist if (!forced_32bpp_lock_buffer) return FXFALSE; // Free the buffer free (forced_32bpp_lock_buffer); forced_32bpp_lock_buffer = 0; if(lockCount) gc->cmdTransportInfo.lfbLockCount = lockCount - 1; GDBG_INFO_MORE(82,"Unlocked forced (%d, %d)\n", _type, buffer); return FXTRUE; } } return _grLfbUnlock(_type, buffer); #undef FN_NAME } #if GLIDE_DEBUG /*--------------------------------------------------------------------------- ** grLfbWriteColorFormat ** */ GR_STATE_ENTRY(grLfbWriteColorFormat, void, (GrColorFormat_t colorFormat)) { #define FN_NAME "_grLfbWriteColorFormat" FxU32 lfbMode; GR_BEGIN_NOFIFOCHECK("_grLfbWriteColorFormat",82); GDBG_INFO_MORE(gc->myLevel,"(%d)\n",colorFormat); GR_CHECK_F(myName, colorFormat < 0 || colorFormat > 0x3, "invalid color format"); lfbMode = gc->state.shadow.lfbMode; lfbMode &= ~SST_LFB_RGBALANES; lfbMode |= (colorFormat << SST_LFB_RGBALANES_SHIFT); gc->state.shadow.lfbMode = lfbMode; GR_END(); #undef FN_NAME } /* grLfbWriteColorFormat */ /*--------------------------------------------------------------------------- ** grLfbWriteColorSwizzle - set up SST for byte swizzling and word swapping ** ** Registers/Bits Affected: ** lfbMode: bit(11), bit(12) ** ** WARNING: GMT: SST_LFB_WRITE_SWAP16 changes pixel addressing!!! */ GR_STATE_ENTRY(grLfbWriteColorSwizzle, void, (FxBool swizzleBytes, FxBool swapWords)) { #define FN_NAME "_grLfbWriteColorSwizzle" FxU32 lfbMode; GR_BEGIN_NOFIFOCHECK("_grLfbWriteColorSwizzle",82); GDBG_INFO_MORE(gc->myLevel,"(%d,%d)\n",swizzleBytes,swapWords); /* Clear out the bits we'll set back if appropriate */ lfbMode = gc->state.shadow.lfbMode; lfbMode &= ~(SST_LFB_WRITE_SWAP16 | SST_LFB_WRITE_BYTESWAP); if (swizzleBytes) lfbMode |= SST_LFB_WRITE_BYTESWAP; if (swapWords) lfbMode |= SST_LFB_WRITE_SWAP16; gc->state.shadow.lfbMode = lfbMode; GR_END(); #undef FN_NAME } /* grLfbWriteColorSwizzle */ #endif /* GLIDE_DEBUG */ FxBool _grLfbWriteRegion(FxBool pixPipelineP, GrBuffer_t dst_buffer, FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, FxU32 src_width, FxU32 src_height, FxI32 src_stride, const void *src_data) { #define FN_NAME "_grLfbWriteRegion" FxBool rv = FXTRUE; GrLfbInfo_t info; GrLfbWriteMode_t writeMode; GR_BEGIN_NOFIFOCHECK_RET("_grLfbWriteRegion", 82); GDBG_INFO_MORE(gc->myLevel, "(0x%x, %s, %d, %d, %d, %d, %d, %d, 0x%x)\n", dst_buffer, (pixPipelineP ? "Enable" : "Disable"), dst_x, dst_y, src_format, src_width, src_height, src_stride, src_data); /* don't waste time */ if (!(src_width && src_height)) { goto done; } writeMode = ((src_format == GR_LFB_SRC_FMT_RLE16) ? GR_LFBWRITEMODE_565 : src_format); info.size = sizeof(info); #define SET_LFB_STRAIGHT (!HAL_CSIM && !SET_SWIZZLEHACK && !SET_BSWAP) /* Hack alert: more tests? */ if (_grLfbLock(GR_LFB_WRITE_ONLY_EXPLICIT_EXT, dst_buffer, writeMode, GR_ORIGIN_UPPER_LEFT, pixPipelineP, &info)) { FxU32 *srcData; /* Tracking Source Pointer */ FxU32 *dstData; /* Tracking Destination Pointer */ FxU32 scanline; /* scanline number */ #if !SET_LFB_STRAIGHT FxU32 *end; /* Demarks End of each Scanline */ FxI32 srcJump; /* bytes to next scanline */ FxU32 dstJump; /* bytes to next scanline */ FxU32 length; /* bytes to copy in scanline */ int aligned; /* word aligned? */ #endif srcData = (FxU32 *) src_data; dstData = (FxU32 *) (((char*)info.lfbPtr)+ (dst_y*info.strideInBytes)); scanline = src_height; switch(src_format) { /* 16-bit aligned */ case GR_LFB_SRC_FMT_565: case GR_LFB_SRC_FMT_555: case GR_LFB_SRC_FMT_1555: case GR_LFB_SRC_FMT_ZA16: dstData = (FxU32*)(((FxU16*)dstData) + dst_x); #if SET_LFB_STRAIGHT if (_GlideRoot.CPUType.os_support & _CPU_FEATURE_MMX) { do { MMX_DSTLINE2(srcData, dstData, src_width); /* adjust for next line */ ((FxU8 *)srcData) += src_stride; ((FxU8 *)dstData) += info.strideInBytes; } while (--scanline); MMX_RESET(); break; } else { do { FPU_DSTLINE2(srcData, dstData, src_width); /* adjust for next line */ ((FxU8 *)srcData) += src_stride; ((FxU8 *)dstData) += info.strideInBytes; } while (--scanline); break; } #else length = src_width * 2; aligned = !((int)dstData&0x2); srcJump = src_stride - length; dstJump = info.strideInBytes - length; if (aligned) { while(scanline--) { end = (FxU32*)((char*)srcData + length - 2); while(srcData < end) { SET_LFB(dstData[0], srcData[0]); dstData++; srcData++; } if (((int)length) & 0x2) { SET_LFB_16((*(FxU16*)&(dstData[0])), (*(FxU16*)&(srcData[0]))); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } } else { while(scanline--) { end = (FxU32*)((char*)srcData + length - 2); SET_LFB_16((*(FxU16*)&(dstData[0])), (*(FxU16*)&(srcData[0]))); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); while(srcData < end) { SET_LFB(dstData[0], srcData[0]); dstData++; srcData++; } if (!(length & 0x2)) { SET_LFB_16((*(FxU16*)&(dstData[0])), (*(FxU16*)&(srcData[0]))); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } } #endif break; /* 32-bit aligned */ case GR_LFB_SRC_FMT_888: case GR_LFB_SRC_FMT_8888: case GR_LFB_SRC_FMT_565_DEPTH: case GR_LFB_SRC_FMT_555_DEPTH: case GR_LFB_SRC_FMT_1555_DEPTH: case GR_LFBWRITEMODE_Z32: dstData = ((FxU32*)dstData) + dst_x; #if SET_LFB_STRAIGHT if (_GlideRoot.CPUType.os_support & _CPU_FEATURE_MMX) { do { MMX_DSTLINE4(srcData, dstData, src_width); /* adjust for next line */ ((FxU8 *)srcData) += src_stride; ((FxU8 *)dstData) += info.strideInBytes; } while (--scanline); MMX_RESET(); break; } else { do { FPU_DSTLINE4(srcData, dstData, src_width); /* adjust for next line */ ((FxU8 *)srcData) += src_stride; ((FxU8 *)dstData) += info.strideInBytes; } while (--scanline); break; } #else length = src_width * 4; srcJump = src_stride - length; dstJump = info.strideInBytes - length; while(scanline--) { end = (FxU32*)((char*)srcData + length); while(srcData < end) { SET_LFB(dstData[0], srcData[0]); dstData++; srcData++; } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } #endif break; case GR_LFB_SRC_FMT_RLE16: /* needs to be implemented */ rv = FXFALSE; break; } _grLfbUnlock(GR_LFB_WRITE_ONLY, dst_buffer); } else { rv = FXFALSE; } #undef SET_LFB_STRAIGHT done: GR_RETURN(rv); #undef FN_NAME } /* _grLfbWriteRegion */ /*------------------------------------------------------------------- Function: grLfbWriteRegion Date: 3/5 Implementor(s): jdt Library: Glide Description: Write a pixel rectangle to the frame buffer as efficiently as possible Arguments: dst_buffer - buffer to which to copy data dst_x,dst_y - destination image start coordinates src_format - data format of source image src_width, src_height - dimensions of source image src_stride - stride of source image in bytes, not meaningful for RLE images src_data - pointer to source data memory Return: FXTRUE succeed FXFALSE fail -------------------------------------------------------------------*/ #if defined(GLIDE3) && defined(GLIDE3_ALPHA) GR_ENTRY(grLfbWriteRegion, FxBool, (GrBuffer_t dst_buffer, FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, FxU32 src_width, FxU32 src_height, FxBool pixelPipeline, FxI32 src_stride, void *src_data)) #else GR_ENTRY(grLfbWriteRegion, FxBool, (GrBuffer_t dst_buffer, FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, FxU32 src_width, FxU32 src_height, FxI32 src_stride, void *src_data)) #endif { FxBool rv = FXTRUE; GR_BEGIN_NOFIFOCHECK_RET("grLfbWriteRegion",82); GDBG_INFO_MORE(gc->myLevel, "(0x%x,%d,%d,%d,%d,%d,%d,0x%x)\n", dst_buffer, dst_x, dst_y, src_format, src_width, src_height, src_stride, src_data); #if defined(GLIDE3) && defined(GLIDE3_ALPHA) if ((_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type == GR_SSTTYPE_SST96) && (pixelPipeline == FXTRUE)) rv = FXFALSE; else rv = _grLfbWriteRegion(pixelPipeline, dst_buffer, dst_x, dst_y, src_format, src_width, src_height, src_stride, src_data); #else rv = _grLfbWriteRegion(FXFALSE, dst_buffer, dst_x, dst_y, src_format, src_width, src_height, src_stride, src_data); #endif GR_RETURN(rv); } /* grLfbWriteRegion */ /*------------------------------------------------------------------- Function: grLfbReadRegion Date: 3/12 Implementor(s): jdt Library: Glide Description: Grab a rectangle from the frame buffer into user supplied memory Arguments: src_buffer - buffer to read from src_x - x coordinate of upper left corner rectangle to read src_y - y coordinate of upper left corner of rectangle to read src_width - width of rectangle to read src_height - height of rectangle to read dst_stride - distance between scanlines in destination buffer dst_data - pointer to user memory in which to place image Return: FXTRUE - success FXFALSE - failure -------------------------------------------------------------------*/ #if !__POWERPC__ static FxBool grLfbReadRegionOrigin (GrBuffer_t src_buffer, GrOriginLocation_t origin, FxU32 src_x, FxU32 src_y, FxU32 src_width, FxU32 src_height, FxU32 dst_stride, void *dst_data) { #define FN_NAME "grLfbReadRegion" FxU32 bpp; FxBool rv; FxBool wantHwc = FXFALSE; GrLfbInfo_t info; GR_BEGIN_NOFIFOCHECK_RET("grLfbReadRegion",82); GDBG_INFO_MORE(gc->myLevel, "(0x%x,%d,%d,%d,%d,%d,0x%x)\n", src_buffer, src_x, src_y, src_width, src_height, dst_stride, dst_data); /* don't waste time */ if (!(src_width && src_height)) { rv=FXTRUE; goto done; } bpp=gc->bInfo->h3pixelSize; info.size = sizeof(info); rv=FXFALSE; #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* [dBorca] fixme :D */ /* Read using HWC if we want dithering and using FSAA or 16 bpp mode */ wantHwc = ((_GlideRoot.environment.useHwcAAforLfbRead & 2) && /* using HWC and */ _GlideRoot.environment.ditherHwcAA && /* want dithering and */ ((gc->bInfo->h3pixelSample > 1) || (gc->bInfo->h3pixelSize == 2))); /* using FSAA or 16 bit mode */ /* We want to use the 'advanced' and slow capture method */ if(wantHwc) { FxU32 colBufferIndex = 0; FxU32 bpp = 0; if(gc->state.forced32BPP) { bpp = gc->state.forced32BPP; } else { switch(gc->grPixelFormat) { case GR_PIXFMT_ARGB_1555: case GR_PIXFMT_AA_2_ARGB_1555: case GR_PIXFMT_AA_4_ARGB_1555: case GR_PIXFMT_AA_8_ARGB_1555: /* 8xaa */ bpp = 15; break; case GR_PIXFMT_ARGB_8888: case GR_PIXFMT_AA_2_ARGB_8888: case GR_PIXFMT_AA_4_ARGB_8888: case GR_PIXFMT_AA_8_ARGB_8888: /* 8xaa */ bpp = 32; break; case GR_PIXFMT_RGB_565: case GR_PIXFMT_AA_2_RGB_565: case GR_PIXFMT_AA_4_RGB_565: case GR_PIXFMT_AA_8_RGB_565: /* 8xaa */ default: bpp = 16; break; } switch(src_buffer) { case GR_BUFFER_FRONTBUFFER: colBufferIndex = gc->frontBuffer; break; case GR_BUFFER_BACKBUFFER: colBufferIndex = gc->backBuffer; break; } } hwcAAReadRegion(gc->bInfo, colBufferIndex, src_x, src_y, src_width, src_height, dst_stride, dst_data, bpp, _GlideRoot.environment.ditherHwcAA); rv=FXTRUE; goto done; } #endif if (_grLfbLock(GR_LFB_READ_ONLY, src_buffer, GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { FxU32 *src; FxI32 len; #if 0 FxU32 *dst; FxU32 src_adjust,dst_adjust,tmp; #endif src=(FxU32 *) (((char*)info.lfbPtr)+ (src_y*info.strideInBytes) + (src_x * bpp)); len = src_width * bpp; if(!gc->state.forced32BPP) { if(_GlideRoot.CPUType.os_support & _CPU_FEATURE_MMX) { do { MMX_SRCLINE(src, dst_data, len); /* adjust for next line */ ((FxU8 *)src) += info.strideInBytes; ((FxU8 *)dst_data) += dst_stride; } while (--src_height); MMX_RESET(); } else { do { FPU_SRCLINE(src, dst_data, len); /* adjust for next line */ ((FxU8 *)src) += info.strideInBytes; ((FxU8 *)dst_data) += dst_stride; } while (--src_height); } goto okay; } #if 0 dst=dst_data; /* set length - alignment fix*/ tmp=(((FxU32)src)&2); len -= tmp; src_adjust=info.strideInBytes - tmp; dst_adjust=dst_stride - tmp; /* should be endian and pixel size safe */ /* it would be nice to test if quad blocks were faster */ /* like mmx loads and stores */ if(!gc->state.forced32BPP) { while(src_height--) { /* adjust starting alignment */ if (((FxU32)src)&3) { *((FxU16 *)dst)++=*((FxU16 *)src)++; } /* read in dwords of pixels */ if(len) { FxU32 byte_index=0; FxU32 aligned=len&(~3); /* copies aligned dwords */ do { *((FxU32 *)(((FxU32)dst) + byte_index))=*((FxU32 *)(((FxU32)src) + byte_index)); } while((byte_index+=4)state.forced32BPP == 16) { while(src_height--) { /* read in dwords of pixels */ if(len) { FxU32 byte_index=0; FxU32 byte_index2=0; /* copies aligned dwords */ do { FxU32 s =*((FxU32 *)(((FxU32)src) + byte_index)); FxU16 d = (FxU16) (s & 0xF8) >> 3; d |= (s & 0xFC00) >> 5; d |= (s & 0xF80000) >> 8; *((FxU16 *)(((FxU32)dst_data) + (byte_index2))) = d; byte_index +=4; } while((byte_index2+=2)<(src_width*2)); } /* adjust for next line */ ((FxU8 *)src)+=info.strideInBytes; ((FxU8 *)dst_data) += dst_stride; } } else if (gc->state.forced32BPP == 15) { while(src_height--) { /* read in dwords of pixels */ if(len) { FxU32 byte_index=0; FxU32 byte_index2=0; /* copies aligned dwords */ do { FxU32 s =*((FxU32 *)(((FxU32)src) + byte_index)); FxU16 d = (FxU16) (s & 0xF8) >> 3; d |= (s & 0xF800) >> 6; d |= (s & 0xF80000) >> 9; *((FxU16 *)(((FxU32)dst_data) + (byte_index2))) = d; byte_index +=4; } while((byte_index2+=2)<(src_width*2)); } /* adjust for next line */ ((FxU8 *)src)+=info.strideInBytes; ((FxU8 *)dst_data) += dst_stride; } } okay: rv=FXTRUE; /* unlock buffer */ _grLfbUnlock(GR_LFB_READ_ONLY,src_buffer); } done: GR_RETURN(rv); } GR_ENTRY(grLfbReadRegion, FxBool, (GrBuffer_t src_buffer, FxU32 src_x, FxU32 src_y, FxU32 src_width, FxU32 src_height, FxU32 dst_stride, void *dst_data)) { return grLfbReadRegionOrigin(src_buffer, GR_ORIGIN_UPPER_LEFT, src_x, src_y, src_width, src_height, dst_stride, dst_data); } #else /* if __POWERPC__ */ GR_ENTRY(grLfbReadRegion, FxBool, (GrBuffer_t src_buffer, FxU32 src_x, FxU32 src_y, FxU32 src_width, FxU32 src_height, FxU32 dst_stride, void *dst_data)) { #define FN_NAME "grLfbReadRegion" FxBool rv = FXTRUE; GrLfbInfo_t info; GR_BEGIN_NOFIFOCHECK_RET("grLfbReadRegion",82); GDBG_INFO_MORE(gc->myLevel, "(0x%x,%d,%d,%d,%d,%d,0x%x)\n", src_buffer, src_x, src_y, src_width, src_height, dst_stride, dst_data); info.size = sizeof(info); if (_grLfbLock(GR_LFB_READ_ONLY, src_buffer, GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { FxU32 *srcData; /* Tracking Source Pointer */ FxU32 *dstData; /* Tracking Destination Pointer */ FxU32 *end; /* Demarks End of each Scanline */ FxU32 srcJump; /* bytes to next scanline */ FxU32 dstJump; /* bytes to next scanline */ FxU32 length; /* bytes to copy in scanline */ FxU32 scanline; /* scanline number */ int aligned; /* word aligned? */ FxU32 odd; /* is src_y odd? (for sli) */ dstData = (FxU32 *) dst_data; srcData = (FxU32 *) (((char*)info.lfbPtr)+ (src_y*info.strideInBytes) + (src_x<<1)); scanline = src_height; length = src_width * 2; dstJump = dst_stride - length; srcJump = info.strideInBytes - length; aligned = !((int)srcData&0x2); odd = (src_y+src_height) & 0x1; #if __POWERPC__ if(!(IS_NAPALM(gc->bInfo->pciInfo.deviceID))) { #endif if (aligned) { while(scanline--) { end = (FxU32*)((char*)srcData + length - 2); while(srcData < end) { *dstData++ = GET_LFB(*srcData++); } if (((int)length) & 0x2) { (*(FxU16*)dstData) = (FxU16)GET_LFB_16(*srcData); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } } else { while(scanline--) { end = (FxU32*)((char*)srcData + length - 2); (*(FxU16*)dstData) = (FxU16)GET_LFB_16(*srcData); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); while(srcData < end) { *dstData++ = GET_LFB(*srcData++); } if (!(((int)length) & 0x2)) { (*(FxU16*)dstData) = (FxU16)GET_LFB_16(*srcData); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } } #if __POWERPC__ } else { if (aligned) { while(scanline--) { end = (FxU32*)((char*)srcData + length - 2); while(srcData < end) { *dstData++ = *srcData++; } if (((int)length) & 0x2) { (*(FxU16*)dstData) = (*(FxU16 *)srcData); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } } else { while(scanline--) { end = (FxU32*)((char*)srcData + length - 2); (*(FxU16*)dstData) = (*(FxU16 *)srcData); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); while(srcData < end) { *dstData++ = *srcData++; } if (!(((int)length) & 0x2)) { (*(FxU16*)dstData) = (*(FxU16 *)srcData); dstData = (FxU32*)(((FxU16*)dstData) + 1); srcData = (FxU32*)(((FxU16*)srcData) + 1); } dstData = (FxU32*)(((char*)dstData)+dstJump); srcData = (FxU32*)(((char*)srcData)+srcJump); } } } #endif _grLfbUnlock(GR_LFB_READ_ONLY, src_buffer); } else { rv = FXFALSE; } GR_RETURN(rv); #undef FN_NAME }/* grLfbReadRegion */ #endif /* if __POWERPC__ */ glide3x/h5/glide3/src/glide.h0100700000175300010010000007303207725034670015234 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED */ /* ** GLIDE.H ** ** The following #defines are relevant when using Glide: ** ** One of the following "platform constants" must be defined during ** compilation: ** ** __DOS__ Defined for 32-bit DOS applications ** __WIN32__ Defined for 32-bit Windows applications ** __sparc__ Defined for Sun Solaris/SunOS ** __linux__ Defined for Linux applications ** __FreeBSD__ Defined for FreeBSD applications ** __NetBSD__ Defined for NetBSD applications ** __OpenBSD__ Defined for OpenBSD applications ** __IRIX__ Defined for SGI Irix applications ** */ #ifndef __GLIDE_H__ #define __GLIDE_H__ #include <3dfx.h> #include #include #ifdef __cplusplus extern "C" { #endif /* ** ----------------------------------------------------------------------- ** TYPE DEFINITIONS ** ----------------------------------------------------------------------- */ typedef FxU32 GrColor_t; typedef FxU8 GrAlpha_t; typedef FxU32 GrMipMapId_t; typedef FxU32 GrStipplePattern_t; typedef FxU8 GrFog_t; typedef FxU32 GrContext_t; typedef int (FX_CALL *GrProc)(); /* ** ----------------------------------------------------------------------- ** CONSTANTS AND TYPES ** ----------------------------------------------------------------------- */ #define GR_NULL_MIPMAP_HANDLE ((GrMipMapId_t) -1) #define GR_MIPMAPLEVELMASK_EVEN FXBIT(0) #define GR_MIPMAPLEVELMASK_ODD FXBIT(1) #define GR_MIPMAPLEVELMASK_BOTH (GR_MIPMAPLEVELMASK_EVEN | GR_MIPMAPLEVELMASK_ODD ) #define GR_LODBIAS_BILINEAR 0.5 #define GR_LODBIAS_TRILINEAR 0.0 typedef FxI32 GrChipID_t; #define GR_TMU0 0x0 #define GR_TMU1 0x1 #define GR_TMU2 0x2 #define GR_FBI 0x0 typedef FxI32 GrCombineFunction_t; #define GR_COMBINE_FUNCTION_ZERO 0x0 #define GR_COMBINE_FUNCTION_NONE GR_COMBINE_FUNCTION_ZERO #define GR_COMBINE_FUNCTION_LOCAL 0x1 #define GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2 #define GR_COMBINE_FUNCTION_SCALE_OTHER 0x3 #define GR_COMBINE_FUNCTION_BLEND_OTHER GR_COMBINE_FUNCTION_SCALE_OTHER #define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4 #define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5 #define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6 #define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7 #define GR_COMBINE_FUNCTION_BLEND GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL #define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8 #define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9 #define GR_COMBINE_FUNCTION_BLEND_LOCAL GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL #define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10 typedef FxI32 GrCombineFactor_t; #define GR_COMBINE_FACTOR_ZERO 0x0 #define GR_COMBINE_FACTOR_NONE GR_COMBINE_FACTOR_ZERO #define GR_COMBINE_FACTOR_LOCAL 0x1 #define GR_COMBINE_FACTOR_OTHER_ALPHA 0x2 #define GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3 #define GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4 #define GR_COMBINE_FACTOR_TEXTURE_RGB 0x5 #define GR_COMBINE_FACTOR_DETAIL_FACTOR GR_COMBINE_FACTOR_TEXTURE_ALPHA #define GR_COMBINE_FACTOR_LOD_FRACTION 0x5 #define GR_COMBINE_FACTOR_ONE 0x8 #define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9 #define GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa #define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb #define GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc #define GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA #define GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd typedef FxI32 GrCombineLocal_t; #define GR_COMBINE_LOCAL_ITERATED 0x0 #define GR_COMBINE_LOCAL_CONSTANT 0x1 #define GR_COMBINE_LOCAL_NONE GR_COMBINE_LOCAL_CONSTANT #define GR_COMBINE_LOCAL_DEPTH 0x2 typedef FxI32 GrCombineOther_t; #define GR_COMBINE_OTHER_ITERATED 0x0 #define GR_COMBINE_OTHER_TEXTURE 0x1 #define GR_COMBINE_OTHER_CONSTANT 0x2 #define GR_COMBINE_OTHER_NONE GR_COMBINE_OTHER_CONSTANT typedef FxI32 GrAlphaSource_t; #define GR_ALPHASOURCE_CC_ALPHA 0x0 #define GR_ALPHASOURCE_ITERATED_ALPHA 0x1 #define GR_ALPHASOURCE_TEXTURE_ALPHA 0x2 #define GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA 0x3 typedef FxI32 GrColorCombineFnc_t; #define GR_COLORCOMBINE_ZERO 0x0 #define GR_COLORCOMBINE_CCRGB 0x1 #define GR_COLORCOMBINE_ITRGB 0x2 #define GR_COLORCOMBINE_ITRGB_DELTA0 0x3 #define GR_COLORCOMBINE_DECAL_TEXTURE 0x4 #define GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB 0x5 #define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB 0x6 #define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0 0x7 #define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA 0x8 #define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA 0x9 #define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB 0xa #define GR_COLORCOMBINE_TEXTURE_ADD_ITRGB 0xb #define GR_COLORCOMBINE_TEXTURE_SUB_ITRGB 0xc #define GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA 0xd #define GR_COLORCOMBINE_DIFF_SPEC_A 0xe #define GR_COLORCOMBINE_DIFF_SPEC_B 0xf #define GR_COLORCOMBINE_ONE 0x10 typedef FxI32 GrAlphaBlendFnc_t; #define GR_BLEND_ZERO 0x0 #define GR_BLEND_SRC_ALPHA 0x1 #define GR_BLEND_SRC_COLOR 0x2 #define GR_BLEND_DST_COLOR GR_BLEND_SRC_COLOR #define GR_BLEND_DST_ALPHA 0x3 #define GR_BLEND_ONE 0x4 #define GR_BLEND_ONE_MINUS_SRC_ALPHA 0x5 #define GR_BLEND_ONE_MINUS_SRC_COLOR 0x6 #define GR_BLEND_ONE_MINUS_DST_COLOR GR_BLEND_ONE_MINUS_SRC_COLOR #define GR_BLEND_ONE_MINUS_DST_ALPHA 0x7 #define GR_BLEND_RESERVED_8 0x8 #define GR_BLEND_RESERVED_9 0x9 #define GR_BLEND_RESERVED_A 0xa #define GR_BLEND_RESERVED_B 0xb #define GR_BLEND_RESERVED_C 0xc #define GR_BLEND_RESERVED_D 0xd #define GR_BLEND_RESERVED_E 0xe #define GR_BLEND_ALPHA_SATURATE 0xf #define GR_BLEND_PREFOG_COLOR GR_BLEND_ALPHA_SATURATE typedef FxI32 GrAspectRatio_t; #define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ #define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ #define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ #define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ #define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ #define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ #define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ typedef FxI32 GrBuffer_t; #define GR_BUFFER_FRONTBUFFER 0x0 #define GR_BUFFER_BACKBUFFER 0x1 #define GR_BUFFER_AUXBUFFER 0x2 #define GR_BUFFER_DEPTHBUFFER 0x3 #define GR_BUFFER_ALPHABUFFER 0x4 #define GR_BUFFER_TRIPLEBUFFER 0x5 typedef FxI32 GrChromakeyMode_t; #define GR_CHROMAKEY_DISABLE 0x0 #define GR_CHROMAKEY_ENABLE 0x1 typedef FxI32 GrChromaRangeMode_t; #define GR_CHROMARANGE_RGB_ALL_EXT 0x0 #define GR_CHROMARANGE_DISABLE_EXT 0x00 #define GR_CHROMARANGE_ENABLE_EXT 0x01 typedef FxI32 GrTexChromakeyMode_t; #define GR_TEXCHROMA_DISABLE_EXT 0x0 #define GR_TEXCHROMA_ENABLE_EXT 0x1 #define GR_TEXCHROMARANGE_RGB_ALL_EXT 0x0 typedef FxI32 GrCmpFnc_t; #define GR_CMP_NEVER 0x0 #define GR_CMP_LESS 0x1 #define GR_CMP_EQUAL 0x2 #define GR_CMP_LEQUAL 0x3 #define GR_CMP_GREATER 0x4 #define GR_CMP_NOTEQUAL 0x5 #define GR_CMP_GEQUAL 0x6 #define GR_CMP_ALWAYS 0x7 typedef FxI32 GrColorFormat_t; #define GR_COLORFORMAT_ARGB 0x0 #define GR_COLORFORMAT_ABGR 0x1 #define GR_COLORFORMAT_RGBA 0x2 #define GR_COLORFORMAT_BGRA 0x3 typedef FxI32 GrCullMode_t; #define GR_CULL_DISABLE 0x0 #define GR_CULL_NEGATIVE 0x1 #define GR_CULL_POSITIVE 0x2 typedef FxI32 GrDepthBufferMode_t; #define GR_DEPTHBUFFER_DISABLE 0x0 #define GR_DEPTHBUFFER_ZBUFFER 0x1 #define GR_DEPTHBUFFER_WBUFFER 0x2 #define GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS 0x3 #define GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS 0x4 typedef FxI32 GrDitherMode_t; #define GR_DITHER_DISABLE 0x0 #define GR_DITHER_2x2 0x1 #define GR_DITHER_4x4 0x2 typedef FxI32 GrStippleMode_t; #define GR_STIPPLE_DISABLE 0x0 #define GR_STIPPLE_PATTERN 0x1 #define GR_STIPPLE_ROTATE 0x2 typedef FxI32 GrFogMode_t; #define GR_FOG_DISABLE 0x0 #define GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT 0x1 #define GR_FOG_WITH_TABLE_ON_Q 0x2 #define GR_FOG_WITH_TABLE_ON_W GR_FOG_WITH_TABLE_ON_Q #define GR_FOG_WITH_ITERATED_Z 0x3 #define GR_FOG_WITH_ITERATED_ALPHA_EXT 0x4 #define GR_FOG_MULT2 0x100 #define GR_FOG_ADD2 0x200 typedef FxU32 GrLock_t; #define GR_LFB_READ_ONLY 0x00 #define GR_LFB_WRITE_ONLY 0x01 #define GR_LFB_IDLE 0x00 #define GR_LFB_NOIDLE 0x10 #define GR_LFB_WRITE_ONLY_EXPLICIT_EXT 0x02 /* explicitly not allow reading from the lfb pointer */ typedef FxI32 GrLfbBypassMode_t; #define GR_LFBBYPASS_DISABLE 0x0 #define GR_LFBBYPASS_ENABLE 0x1 typedef FxI32 GrLfbWriteMode_t; #define GR_LFBWRITEMODE_565 0x0 /* RGB:RGB */ #define GR_LFBWRITEMODE_555 0x1 /* RGB:RGB */ #define GR_LFBWRITEMODE_1555 0x2 /* ARGB:ARGB */ #define GR_LFBWRITEMODE_RESERVED1 0x3 #define GR_LFBWRITEMODE_888 0x4 /* RGB */ #define GR_LFBWRITEMODE_8888 0x5 /* ARGB */ #define GR_LFBWRITEMODE_RESERVED2 0x6 #define GR_LFBWRITEMODE_RESERVED3 0x7 #define GR_LFBWRITEMODE_RESERVED4 0x8 #define GR_LFBWRITEMODE_RESERVED5 0x9 #define GR_LFBWRITEMODE_RESERVED6 0xa #define GR_LFBWRITEMODE_RESERVED7 0xb #define GR_LFBWRITEMODE_565_DEPTH 0xc /* RGB:DEPTH */ #define GR_LFBWRITEMODE_555_DEPTH 0xd /* RGB:DEPTH */ #define GR_LFBWRITEMODE_1555_DEPTH 0xe /* ARGB:DEPTH */ #define GR_LFBWRITEMODE_ZA16 0xf /* DEPTH:DEPTH */ #define GR_LFBWRITEMODE_ANY 0xFF typedef FxI32 GrOriginLocation_t; #define GR_ORIGIN_UPPER_LEFT 0x0 #define GR_ORIGIN_LOWER_LEFT 0x1 #define GR_ORIGIN_ANY 0xFF typedef struct { int size; void *lfbPtr; FxU32 strideInBytes; GrLfbWriteMode_t writeMode; GrOriginLocation_t origin; } GrLfbInfo_t; typedef FxI32 GrLOD_t; #define GR_LOD_LOG2_256 0x8 #define GR_LOD_LOG2_128 0x7 #define GR_LOD_LOG2_64 0x6 #define GR_LOD_LOG2_32 0x5 #define GR_LOD_LOG2_16 0x4 #define GR_LOD_LOG2_8 0x3 #define GR_LOD_LOG2_4 0x2 #define GR_LOD_LOG2_2 0x1 #define GR_LOD_LOG2_1 0x0 typedef FxI32 GrMipMapMode_t; #define GR_MIPMAP_DISABLE 0x0 /* no mip mapping */ #define GR_MIPMAP_NEAREST 0x1 /* use nearest mipmap */ #define GR_MIPMAP_NEAREST_DITHER 0x2 /* GR_MIPMAP_NEAREST + LOD dith */ typedef FxI32 GrSmoothingMode_t; #define GR_SMOOTHING_DISABLE 0x0 #define GR_SMOOTHING_ENABLE 0x1 typedef FxI32 GrTextureClampMode_t; #define GR_TEXTURECLAMP_WRAP 0x0 #define GR_TEXTURECLAMP_CLAMP 0x1 #define GR_TEXTURECLAMP_MIRROR_EXT 0x2 typedef FxI32 GrTextureCombineFnc_t; #define GR_TEXTURECOMBINE_ZERO 0x0 /* texout = 0 */ #define GR_TEXTURECOMBINE_DECAL 0x1 /* texout = texthis */ #define GR_TEXTURECOMBINE_OTHER 0x2 /* this TMU in passthru mode */ #define GR_TEXTURECOMBINE_ADD 0x3 /* tout = tthis + t(this+1) */ #define GR_TEXTURECOMBINE_MULTIPLY 0x4 /* texout = tthis * t(this+1) */ #define GR_TEXTURECOMBINE_SUBTRACT 0x5 /* Sutract from upstream TMU */ #define GR_TEXTURECOMBINE_DETAIL 0x6 /* detail--detail on tthis */ #define GR_TEXTURECOMBINE_DETAIL_OTHER 0x7 /* detail--detail on tthis+1 */ #define GR_TEXTURECOMBINE_TRILINEAR_ODD 0x8 /* trilinear--odd levels tthis*/ #define GR_TEXTURECOMBINE_TRILINEAR_EVEN 0x9 /*trilinear--even levels tthis*/ #define GR_TEXTURECOMBINE_ONE 0xa /* texout = 0xFFFFFFFF */ typedef FxI32 GrTextureFilterMode_t; #define GR_TEXTUREFILTER_POINT_SAMPLED 0x0 #define GR_TEXTUREFILTER_BILINEAR 0x1 typedef FxI32 GrTextureFormat_t; /* KoolSmoky - */ #define GR_TEXFMT_8BIT 0x0 #define GR_TEXFMT_RGB_332 GR_TEXFMT_8BIT #define GR_TEXFMT_YIQ_422 0x1 #define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ #define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ #define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 #define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ #define GR_TEXFMT_RSVD0 0x6 /* GR_TEXFMT_P_8_RGBA */ #define GR_TEXFMT_P_8_6666 GR_TEXFMT_RSVD0 #define GR_TEXFMT_P_8_6666_EXT GR_TEXFMT_RSVD0 #define GR_TEXFMT_RSVD1 0x7 #define GR_TEXFMT_16BIT 0x8 #define GR_TEXFMT_ARGB_8332 GR_TEXFMT_16BIT #define GR_TEXFMT_AYIQ_8422 0x9 #define GR_TEXFMT_RGB_565 0xa #define GR_TEXFMT_ARGB_1555 0xb #define GR_TEXFMT_ARGB_4444 0xc #define GR_TEXFMT_ALPHA_INTENSITY_88 0xd #define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ #define GR_TEXFMT_RSVD2 0xf #define GR_TEXFMT_RSVD4 GR_TEXFMT_RSVD2 typedef FxU32 GrTexTable_t; #define GR_TEXTABLE_NCC0 0x0 #define GR_TEXTABLE_NCC1 0x1 #define GR_TEXTABLE_PALETTE 0x2 #define GR_TEXTABLE_PALETTE_6666_EXT 0x3 typedef FxU32 GrNCCTable_t; #define GR_NCCTABLE_NCC0 0x0 #define GR_NCCTABLE_NCC1 0x1 typedef FxU32 GrTexBaseRange_t; #define GR_TEXBASE_256 0x3 #define GR_TEXBASE_128 0x2 #define GR_TEXBASE_64 0x1 #define GR_TEXBASE_32_TO_1 0x0 typedef FxU32 GrEnableMode_t; #define GR_MODE_DISABLE 0x0 #define GR_MODE_ENABLE 0x1 #define GR_AA_ORDERED 0x01 #define GR_ALLOW_MIPMAP_DITHER 0x02 #define GR_PASSTHRU 0x03 #define GR_SHAMELESS_PLUG 0x04 #define GR_VIDEO_SMOOTHING 0x05 typedef FxU32 GrCoordinateSpaceMode_t; #define GR_WINDOW_COORDS 0x00 #define GR_CLIP_COORDS 0x01 /* Types of data in strips */ #define GR_FLOAT 0 #define GR_U8 1 /* Parameters for strips */ #define GR_PARAM_XY 0x01 #define GR_PARAM_Z 0x02 #define GR_PARAM_W 0x03 #define GR_PARAM_Q 0x04 #define GR_PARAM_FOG_EXT 0x05 #define GR_PARAM_A 0x10 #define GR_PARAM_RGB 0x20 #define GR_PARAM_PARGB 0x30 #define GR_PARAM_ST0 0x40 #define GR_PARAM_ST1 GR_PARAM_ST0+1 #define GR_PARAM_ST2 GR_PARAM_ST0+2 #define GR_PARAM_Q0 0x50 #define GR_PARAM_Q1 GR_PARAM_Q0+1 #define GR_PARAM_Q2 GR_PARAM_Q0+2 #define GR_PARAM_DISABLE 0x00 #define GR_PARAM_ENABLE 0x01 /* ** grDrawVertexArray/grDrawVertexArrayContiguous primitive type */ #define GR_POINTS 0 #define GR_LINE_STRIP 1 #define GR_LINES 2 #define GR_POLYGON 3 #define GR_TRIANGLE_STRIP 4 #define GR_TRIANGLE_FAN 5 #define GR_TRIANGLES 6 #define GR_TRIANGLE_STRIP_CONTINUE 7 #define GR_TRIANGLE_FAN_CONTINUE 8 /* ** grGet/grReset types */ #define GR_BITS_DEPTH 0x01 #define GR_BITS_RGBA 0x02 #define GR_FIFO_FULLNESS 0x03 #define GR_FOG_TABLE_ENTRIES 0x04 #define GR_GAMMA_TABLE_ENTRIES 0x05 #define GR_GLIDE_STATE_SIZE 0x06 #define GR_GLIDE_VERTEXLAYOUT_SIZE 0x07 #define GR_IS_BUSY 0x08 #define GR_LFB_PIXEL_PIPE 0x09 #define GR_MAX_TEXTURE_SIZE 0x0a #define GR_MAX_TEXTURE_ASPECT_RATIO 0x0b #define GR_MEMORY_FB 0x0c #define GR_MEMORY_TMU 0x0d #define GR_MEMORY_UMA 0x0e #define GR_NUM_BOARDS 0x0f #define GR_NON_POWER_OF_TWO_TEXTURES 0x10 #define GR_NUM_FB 0x11 #define GR_NUM_SWAP_HISTORY_BUFFER 0x12 #define GR_NUM_TMU 0x13 #define GR_PENDING_BUFFERSWAPS 0x14 #define GR_REVISION_FB 0x15 #define GR_REVISION_TMU 0x16 #define GR_STATS_LINES 0x17 /* grGet/grReset */ #define GR_STATS_PIXELS_AFUNC_FAIL 0x18 #define GR_STATS_PIXELS_CHROMA_FAIL 0x19 #define GR_STATS_PIXELS_DEPTHFUNC_FAIL 0x1a #define GR_STATS_PIXELS_IN 0x1b #define GR_STATS_PIXELS_OUT 0x1c #define GR_STATS_PIXELS 0x1d /* grReset */ #define GR_STATS_POINTS 0x1e /* grGet/grReset */ #define GR_STATS_TRIANGLES_IN 0x1f #define GR_STATS_TRIANGLES_OUT 0x20 #define GR_STATS_TRIANGLES 0x21 /* grReset */ #define GR_SWAP_HISTORY 0x22 #define GR_SUPPORTS_PASSTHRU 0x23 #define GR_TEXTURE_ALIGN 0x24 #define GR_VIDEO_POSITION 0x25 #define GR_VIEWPORT 0x26 #define GR_WDEPTH_MIN_MAX 0x27 #define GR_ZDEPTH_MIN_MAX 0x28 #define GR_VERTEX_PARAMETER 0x29 #define GR_BITS_GAMMA 0x2a #define GR_GET_RESERVED_1 0x1000 /* ** grGetString types */ #define GR_EXTENSION 0xa0 #define GR_HARDWARE 0xa1 #define GR_RENDERER 0xa2 #define GR_VENDOR 0xa3 #define GR_VERSION 0xa4 /* ** ----------------------------------------------------------------------- ** STRUCTURES ** ----------------------------------------------------------------------- */ typedef struct { GrLOD_t smallLodLog2; GrLOD_t largeLodLog2; GrAspectRatio_t aspectRatioLog2; GrTextureFormat_t format; void *data; } GrTexInfo; typedef struct GrSstPerfStats_s { FxU32 pixelsIn; /* # pixels processed (minus buffer clears) */ FxU32 chromaFail; /* # pixels not drawn due to chroma key */ FxU32 zFuncFail; /* # pixels not drawn due to Z comparison */ FxU32 aFuncFail; /* # pixels not drawn due to alpha comparison */ FxU32 pixelsOut; /* # pixels drawn (including buffer clears) */ } GrSstPerfStats_t; typedef struct { GrScreenResolution_t resolution; GrScreenRefresh_t refresh; int numColorBuffers; int numAuxBuffers; } GrResolution; typedef GrResolution GlideResolution; #define GR_QUERY_ANY ((FxU32)(~0)) typedef FxU32 GrLfbSrcFmt_t; #define GR_LFB_SRC_FMT_565 0x00 #define GR_LFB_SRC_FMT_555 0x01 #define GR_LFB_SRC_FMT_1555 0x02 #define GR_LFB_SRC_FMT_888 0x04 #define GR_LFB_SRC_FMT_8888 0x05 #define GR_LFB_SRC_FMT_565_DEPTH 0x0c #define GR_LFB_SRC_FMT_555_DEPTH 0x0d #define GR_LFB_SRC_FMT_1555_DEPTH 0x0e #define GR_LFB_SRC_FMT_ZA16 0x0f #define GR_LFB_SRC_FMT_RLE16 0x80 #ifdef H3D #define GR_HINT_H3DENABLE 4 #undef GR_HINTTYPE_MAX #define GR_HINTTYPE_MAX 4 #endif /* ** ----------------------------------------------------------------------- ** FUNCTION PROTOTYPES ** ----------------------------------------------------------------------- */ #ifndef FX_GLIDE_NO_FUNC_PROTO /* ** rendering functions */ FX_ENTRY void FX_CALL grDrawPoint( const void *pt ); FX_ENTRY void FX_CALL grDrawLine( const void *v1, const void *v2 ); FX_ENTRY void FX_CALL grDrawTriangle( const void *a, const void *b, const void *c ); FX_ENTRY void FX_CALL grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode); FX_ENTRY void FX_CALL grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers); FX_ENTRY void FX_CALL grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride); /* ** Antialiasing Functions */ FX_ENTRY void FX_CALL grAADrawTriangle( const void *a, const void *b, const void *c, FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias ); /* ** buffer management */ FX_ENTRY void FX_CALL grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU32 depth ); FX_ENTRY void FX_CALL grBufferSwap( FxU32 swap_interval ); FX_ENTRY void FX_CALL grRenderBuffer( GrBuffer_t buffer ); /* ** error management */ typedef void (*GrErrorCallbackFnc_t)( const char *string, FxBool fatal ); FX_ENTRY void FX_CALL grErrorSetCallback( GrErrorCallbackFnc_t fnc ); /* ** SST routines */ FX_ENTRY void FX_CALL grFinish(void); FX_ENTRY void FX_CALL grFlush(void); FX_ENTRY GrContext_t FX_CALL grSstWinOpen( FxU32 hWnd, GrScreenResolution_t screen_resolution, GrScreenRefresh_t refresh_rate, GrColorFormat_t color_format, GrOriginLocation_t origin_location, int nColBuffers, int nAuxBuffers); FX_ENTRY FxBool FX_CALL grSstWinClose( GrContext_t context ); FX_ENTRY void FX_CALL grSetNumPendingBuffers(FxI32 NumPendingBuffers); FX_ENTRY FxBool FX_CALL grSelectContext( GrContext_t context ); FX_ENTRY void FX_CALL grSstOrigin(GrOriginLocation_t origin); FX_ENTRY void FX_CALL grSstSelect( int which_sst ); /* ** Glide configuration and special effect maintenance functions */ FX_ENTRY void FX_CALL grAlphaBlendFunction( GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df ); FX_ENTRY void FX_CALL grAlphaCombine( GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert ); FX_ENTRY void FX_CALL grAlphaControlsITRGBLighting( FxBool enable ); FX_ENTRY void FX_CALL grAlphaTestFunction( GrCmpFnc_t function ); FX_ENTRY void FX_CALL grAlphaTestReferenceValue( GrAlpha_t value ); FX_ENTRY void FX_CALL grChromakeyMode( GrChromakeyMode_t mode ); FX_ENTRY void FX_CALL grChromakeyValue( GrColor_t value ); FX_ENTRY void FX_CALL grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ); FX_ENTRY void FX_CALL grColorCombine( GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert ); FX_ENTRY void FX_CALL grColorMask( FxBool rgb, FxBool a ); FX_ENTRY void FX_CALL grCullMode( GrCullMode_t mode ); FX_ENTRY void FX_CALL grConstantColorValue( GrColor_t value ); FX_ENTRY void FX_CALL grDepthBiasLevel( FxI32 level ); FX_ENTRY void FX_CALL grDepthBufferFunction( GrCmpFnc_t function ); FX_ENTRY void FX_CALL grDepthBufferMode( GrDepthBufferMode_t mode ); FX_ENTRY void FX_CALL grDepthMask( FxBool mask ); FX_ENTRY void FX_CALL grDisableAllEffects( void ); FX_ENTRY void FX_CALL grDitherMode( GrDitherMode_t mode ); FX_ENTRY void FX_CALL grFogColorValue( GrColor_t fogcolor ); FX_ENTRY void FX_CALL grFogMode( GrFogMode_t mode ); FX_ENTRY void FX_CALL grFogTable( const GrFog_t ft[] ); FX_ENTRY void FX_CALL grLoadGammaTable( FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue); FX_ENTRY void FX_CALL grSplash(float x, float y, float width, float height, FxU32 frame); FX_ENTRY FxU32 FX_CALL grGet( FxU32 pname, FxU32 plength, FxI32 *params ); FX_ENTRY const char * FX_CALL grGetString( FxU32 pname ); FX_ENTRY FxI32 FX_CALL grQueryResolutions( const GrResolution *resTemplate, GrResolution *output ); FX_ENTRY FxBool FX_CALL grReset( FxU32 what ); FX_ENTRY GrProc FX_CALL grGetProcAddress( char *procName ); FX_ENTRY void FX_CALL grEnable( GrEnableMode_t mode ); FX_ENTRY void FX_CALL grDisable( GrEnableMode_t mode ); FX_ENTRY void FX_CALL grCoordinateSpace( GrCoordinateSpaceMode_t mode ); FX_ENTRY void FX_CALL grDepthRange( FxFloat n, FxFloat f ); FX_ENTRY void FX_CALL grStippleMode( GrStippleMode_t mode ); FX_ENTRY void FX_CALL grStipplePattern( GrStipplePattern_t mode ); FX_ENTRY void FX_CALL grViewport( FxI32 x, FxI32 y, FxI32 width, FxI32 height ); /* ** texture mapping control functions */ FX_ENTRY FxU32 FX_CALL grTexCalcMemRequired( GrLOD_t lodmin, GrLOD_t lodmax, GrAspectRatio_t aspect, GrTextureFormat_t fmt); FX_ENTRY FxU32 FX_CALL grTexTextureMemRequired( FxU32 evenOdd, GrTexInfo *info ); FX_ENTRY FxU32 FX_CALL grTexMinAddress( GrChipID_t tmu ); FX_ENTRY FxU32 FX_CALL grTexMaxAddress( GrChipID_t tmu ); FX_ENTRY void FX_CALL grTexNCCTable( GrNCCTable_t table ); FX_ENTRY void FX_CALL grTexSource( GrChipID_t tmu, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info ); FX_ENTRY void FX_CALL grTexClampMode( GrChipID_t tmu, GrTextureClampMode_t s_clampmode, GrTextureClampMode_t t_clampmode ); FX_ENTRY void FX_CALL grTexCombine( GrChipID_t tmu, GrCombineFunction_t rgb_function, GrCombineFactor_t rgb_factor, GrCombineFunction_t alpha_function, GrCombineFactor_t alpha_factor, FxBool rgb_invert, FxBool alpha_invert ); FX_ENTRY void FX_CALL grTexDetailControl( GrChipID_t tmu, int lod_bias, FxU8 detail_scale, float detail_max ); FX_ENTRY void FX_CALL grTexFilterMode( GrChipID_t tmu, GrTextureFilterMode_t minfilter_mode, GrTextureFilterMode_t magfilter_mode ); FX_ENTRY void FX_CALL grTexLodBiasValue(GrChipID_t tmu, float bias ); FX_ENTRY void FX_CALL grTexDownloadMipMap( GrChipID_t tmu, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info ); FX_ENTRY void FX_CALL grTexDownloadMipMapLevel( GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data ); FX_ENTRY FxBool FX_CALL grTexDownloadMipMapLevelPartial( GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data, int start, int end ); FX_ENTRY void FX_CALL grTexDownloadTable( GrTexTable_t type, void *data ); FX_ENTRY void FX_CALL grTexDownloadTablePartial( GrTexTable_t type, void *data, int start, int end ); FX_ENTRY void FX_CALL grTexMipMapMode( GrChipID_t tmu, GrMipMapMode_t mode, FxBool lodBlend ); FX_ENTRY void FX_CALL grTexMultibase( GrChipID_t tmu, FxBool enable ); FX_ENTRY void FX_CALL grTexMultibaseAddress( GrChipID_t tmu, GrTexBaseRange_t range, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info ); /* ** linear frame buffer functions */ FX_ENTRY FxBool FX_CALL grLfbLock( GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, FxBool pixelPipeline, GrLfbInfo_t *info ); FX_ENTRY FxBool FX_CALL grLfbUnlock( GrLock_t type, GrBuffer_t buffer ); FX_ENTRY void FX_CALL grLfbConstantAlpha( GrAlpha_t alpha ); FX_ENTRY void FX_CALL grLfbConstantDepth( FxU32 depth ); FX_ENTRY void FX_CALL grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords); FX_ENTRY void FX_CALL grLfbWriteColorFormat(GrColorFormat_t colorFormat); FX_ENTRY FxBool FX_CALL grLfbWriteRegion( GrBuffer_t dst_buffer, FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, FxU32 src_width, FxU32 src_height, FxBool pixelPipeline, FxI32 src_stride, void *src_data ); FX_ENTRY FxBool FX_CALL grLfbReadRegion( GrBuffer_t src_buffer, FxU32 src_x, FxU32 src_y, FxU32 src_width, FxU32 src_height, FxU32 dst_stride, void *dst_data ); /* ** glide management functions */ FX_ENTRY void FX_CALL grGlideInit( void ); FX_ENTRY void FX_CALL grGlideShutdown( void ); FX_ENTRY void FX_CALL grGlideGetState( void *state ); FX_ENTRY void FX_CALL grGlideSetState( const void *state ); FX_ENTRY void FX_CALL grGlideGetVertexLayout( void *layout ); FX_ENTRY void FX_CALL grGlideSetVertexLayout( const void *layout ); #endif /* FX_GLIDE_NO_FUNC_PROTO */ #ifdef __cplusplus } #endif #include #endif /* __GLIDE_H__ */ glide3x/h5/glide3/src/glide.rc0100700000175300010010000000573007725034670015411 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glide.rc,v 1.1.8.2 2003/06/05 08:23:53 koolsmoky Exp $ ** $Log: glide.rc,v $ ** Revision 1.1.8.2 2003/06/05 08:23:53 koolsmoky ** Cleaned up win32 makefiles. Added work around for v5 6000 dac problem. Completed merging screen shot routines. ** ** ** Revision 1.1 2000/06/15 00:27:42 joseph ** Initial checkin into SourceForge. ** */ #define OFFICIAL 1 #define FINAL 1 #include #include "rcver.h" ///////////////////////////////////////////////////////////////////////////// // // Version // #ifndef GLIDE3 #define VERSIONNAME "glide2x.dll\0" #else #define VERSIONNAME "glide3x.dll\0" #endif VS_VERSION_INFO VERSIONINFO FILEVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER PRODUCTVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER FILEFLAGSMASK 0x0030003FL FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) FILEOS VOS_DOS_WINDOWS32 FILETYPE VFT_DRV FILESUBTYPE VFT2_DRV_INSTALLABLE BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "3dfx Interactive, Inc.\0" #ifdef BETA VALUE "FileDescription", "*BETA* do NOT distribute without permission.\0" VALUE "FileVersion", VERSIONSTR " BETA" #else VALUE "FileDescription", "3dfx Interactive, Inc. Glide\256 DLL\0" VALUE "FileVersion", VERSIONSTR #endif VALUE "InternalName", VERSIONNAME VALUE "LegalCopyright", "Copyright \251 3dfx Interactive, Inc. 2003\0" VALUE "OriginalFilename", VERSIONNAME VALUE "ProductName", PRODNAME #ifdef BETA VALUE "ProductVersion", VERSIONSTR " BETA" #else VALUE "ProductVersion", VERSIONSTR #endif VALUE "Graphics Subsystem", HWSTR VALUE "Contact", CONTACTSTR END END BLOCK "VarFileInfo" BEGIN /* the following line should be extended for localized versions */ VALUE "Translation", 0x409, 1252 END END glide3x/h5/glide3/src/glide3.rx0100700000175300010010000000015707725034670015517 0ustar johndoeNone/GR_DDFUNC\((.*),/ /GR_ENTRY\((.*),/ /GR_DIENTRY\((.*),/ /GR_STATE_ENTRY\((.*),/_\1/ /GR_EXT_ENTRY\((.*),/_\1/ glide3x/h5/glide3/src/glidesys.h0100700000175300010010000001165207725034670015773 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glidesys.h,v 1.3.4.3 2003/07/24 03:51:08 anholt Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 4 11/05/98 11:18a Russp ** Fix GLIDE_NUM_TMU error check (change "&&" to "||") ** ** 3 7/24/98 1:41p Hohn ** ** 2 6/15/98 10:50a Peter ** made csim compile time option * * 1 1/16/98 4:29p Atai * create glide 3 src * * 10 12/09/97 12:20p Peter * mac glide port * * 9 11/04/97 4:00p Dow * Banshee Mods * * 8 8/18/97 3:52p Peter * pre-hw arrival fixes/cleanup * * 7 6/02/97 4:09p Peter * Compile w/ gcc for Dural * * 6 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 5 5/21/97 6:05a Peter */ #ifndef __GLIDESYS_H__ #define __GLIDESYS_H__ /* n** ----------------------------------------------------------------------- ** COMPILER/ENVIRONMENT CONFIGURATION ** ----------------------------------------------------------------------- */ /* Endianness is stored in bits [30:31] */ #define GLIDE_ENDIAN_SHIFT 30 #define GLIDE_ENDIAN_LITTLE (0x1 << GLIDE_ENDIAN_SHIFT) #define GLIDE_ENDIAN_BIG (0x2 << GLIDE_ENDIAN_SHIFT) /* OS is stored in bits [0:6] */ #define GLIDE_OS_SHIFT 0 #define GLIDE_OS_UNIX 0x1 #define GLIDE_OS_DOS32 0x2 #define GLIDE_OS_WIN32 0x4 #define GLIDE_OS_MACOS 0x8 #define GLIDE_OS_OS2 0x10 #define GLIDE_OS_OTHER 0x40 /* For Proprietary Arcade HW */ /* Sim vs. Hardware is stored in bits [7:8] */ #define GLIDE_SST_SHIFT 7 #define GLIDE_SST_SIM (0x1 << GLIDE_SST_SHIFT) #define GLIDE_SST_HW (0x2 << GLIDE_SST_SHIFT) /* Hardware Type is stored in bits [9:13] */ #define GLIDE_HW_SHIFT 9 #define GLIDE_HW_SST1 (0x1 << GLIDE_HW_SHIFT) #define GLIDE_HW_SST96 (0x2 << GLIDE_HW_SHIFT) #define GLIDE_HW_H3 (0x4 << GLIDE_HW_SHIFT) #define GLIDE_HW_SST2 (0x8 << GLIDE_HW_SHIFT) #define GLIDE_HW_CVG (0x10 << GLIDE_HW_SHIFT) /* ** Make sure we handle all instances of WIN32 */ #ifndef __WIN32__ # if defined (_WIN32) || defined (WIN32) || defined(__NT__) # define __WIN32__ # endif #endif /* We need two checks on the OS: one for endian, the other for OS */ /* Check for endianness */ #if defined(__IRIX__) || defined(__sparc__) || defined(MACOS) # define GLIDE_ENDIAN GLIDE_ENDIAN_BIG #else # define GLIDE_ENDIAN GLIDE_ENDIAN_LITTLE #endif /* Check for OS */ #if defined(__IRIX__) || defined(__sparc__) || defined(__linux__) || \ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) # define GLIDE_OS GLIDE_OS_UNIX #elif defined(__DOS__) # define GLIDE_OS GLIDE_OS_DOS32 #elif defined(__WIN32__) # define GLIDE_OS GLIDE_OS_WIN32 #elif defined(macintosh) # define GLIDE_OS GLIDE_OS_MACOS #else #error "Unknown OS" #endif /* Check for Simulator vs. Hardware */ #if HAL_CSIM || HWC_CSIM # define GLIDE_SST GLIDE_SST_SIM #else # define GLIDE_SST GLIDE_SST_HW #endif /* Check for type of hardware */ #ifdef SST96 # define GLIDE_HW GLIDE_HW_SST96 #elif defined(H3) # define GLIDE_HW GLIDE_HW_H3 #elif defined(SST2) # define GLIDE_HW GLIDE_HW_SST2 #elif defined(CVG) # define GLIDE_HW GLIDE_HW_CVG #else /* Default to SST1 */ # define GLIDE_HW GLIDE_HW_SST1 #endif #define GLIDE_PLATFORM (GLIDE_ENDIAN | GLIDE_OS | GLIDE_SST | GLIDE_HW) /* ** Control the number of TMUs */ #ifndef GLIDE_NUM_TMU # define GLIDE_NUM_TMU 2 #endif #if ((GLIDE_NUM_TMU < 0) || (GLIDE_NUM_TMU > 3)) # error "GLIDE_NUM_TMU set to an invalid value" #endif #endif /* __GLIDESYS_H__ */ glide3x/h5/glide3/src/glideutl.h0100700000175300010010000000742207725034670015761 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glideutl.h,v 1.3.4.2 2003/06/05 08:23:53 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 4 7/24/98 1:41p Hohn ** ** 3 1/30/98 4:27p Atai ** gufog* prototype ** ** 1 1/29/98 4:00p Atai * * 1 1/16/98 4:29p Atai * create glide 3 src * * 11 1/07/98 11:18a Atai * remove GrMipMapInfo and GrGC.mm_table in glide3 * * 10 1/06/98 6:47p Atai * undo grSplash and remove gu routines * * 9 1/05/98 6:04p Atai * move 3df gu related data structure from glide.h to glideutl.h * * 8 12/18/97 2:13p Peter * fogTable cataclysm * * 7 12/15/97 5:52p Atai * disable obsolete glide2 api for glide3 * * 6 8/14/97 5:32p Pgj * remove dead code per GMT * * 5 6/12/97 5:19p Pgj * Fix bug 578 * * 4 3/05/97 9:36p Jdt * Removed guFbWriteRegion added guEncodeRLE16 * * 3 1/16/97 3:45p Dow * Embedded fn protos in ifndef FX_GLIDE_NO_FUNC_PROTO */ /* Glide Utility routines */ #ifndef __GLIDEUTL_H__ #define __GLIDEUTL_H__ #ifdef __cplusplus extern "C" { #endif /* ** 3DF texture file structs */ typedef struct { FxU32 width, height; int small_lod, large_lod; GrAspectRatio_t aspect_ratio; GrTextureFormat_t format; } Gu3dfHeader; typedef struct { FxU8 yRGB[16]; FxI16 iRGB[4][3]; FxI16 qRGB[4][3]; FxU32 packed_data[12]; } GuNccTable; typedef struct { FxU32 data[256]; } GuTexPalette; typedef union { GuNccTable nccTable; GuTexPalette palette; } GuTexTable; typedef struct { Gu3dfHeader header; GuTexTable table; void *data; FxU32 mem_required; /* memory required for mip map in bytes. */ } Gu3dfInfo; #ifndef FX_GLIDE_NO_FUNC_PROTO /* ** Gamma functions */ FX_ENTRY void FX_CALL guGammaCorrectionRGB( FxFloat red, FxFloat green, FxFloat blue ); /* ** fog stuff */ FX_ENTRY float FX_CALL guFogTableIndexToW( int i ); FX_ENTRY void FX_CALL guFogGenerateExp( GrFog_t *fogtable, float density ); FX_ENTRY void FX_CALL guFogGenerateExp2( GrFog_t *fogtable, float density ); FX_ENTRY void FX_CALL guFogGenerateLinear(GrFog_t *fogtable, float nearZ, float farZ ); /* ** hi-level texture manipulation tools. */ FX_ENTRY FxBool FX_CALL gu3dfGetInfo( const char *filename, Gu3dfInfo *info ); FX_ENTRY FxBool FX_CALL gu3dfLoad( const char *filename, Gu3dfInfo *data ); #endif /* FX_GLIDE_NO_FUNC_PROTO */ #ifdef __cplusplus } #endif #endif /* __GLIDEUTL_H__ */ glide3x/h5/glide3/src/gpci.c0100700000175300010010000032167107725034670015072 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gpci.c,v 1.4.2.16 2003/08/26 15:40:11 koolsmoky Exp $ ** $Log: ** 44 3dfx 1.34.1.2.1.511/08/00 Drew McMinn Create initialise read and ** use useAppGamma flag, to allow us to disable applications changing gamma ** values. ** 43 3dfx 1.34.1.2.1.410/11/00 Brent Forced check in to enforce ** branching. ** 42 3dfx 1.34.1.2.1.309/26/00 Andy Hanson Add environment variable of ** glide group so they can do wacky things safely. ** 41 3dfx 1.34.1.2.1.208/29/00 Jonny Cochrane Some 8x FSAA code ** 40 3dfx 1.34.1.2.1.108/01/00 Andy Hanson Fixed issue with source ** ignoring setting of GLIDE_SPLASH define. ** Fixed issue with setting of splash state when it wasn't going to be run. ** 39 3dfx 1.34.1.2.1.006/28/00 troy thornton added initialization of ** correct jitter values ** 38 3dfx 1.34.1.2 06/20/00 Joseph Kain Fixed errors introduced in ** merge. ** 37 3dfx 1.34.1.1 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 36 3dfx 1.34.1.0 06/15/00 Bill White Merged changes to support ** Linux. ** ** 35 3dfx 1.34 04/21/00 Kenneth Dyke Magic FX_GLIDE_NO_HW ** support. ** 34 3dfx 1.33 04/13/00 Kenneth Dyke Added support for new style ** 2-sample AA mode. ** 33 3dfx 1.32 04/10/00 Kenneth Dyke Added magical screenshot ** hotkey. ** 32 3dfx 1.31 03/30/00 Kenneth Dyke Changed defaults for column ** band width and SLI band height. ** 31 3dfx 1.30 03/25/00 Adam Briggs added support for ** SSTH3_SLI_AA_CONFIGURATION (the env var the control panel uses to force AA ** modes) ** 30 3dfx 1.29 03/24/00 Chris Dow Added code to fence every n ** writes (not to exceed 0x10000) where n is either 0x10000 or indicated by ** the environment variable FX_GLIDE_FENCE_LIMIT ** ** 29 3dfx 1.28 03/23/00 Kenneth Dyke Change 2PPC band height ** default to 2. ** 28 3dfx 1.27 03/21/00 Kenneth Dyke Performance tweaks to ** default env vars. Added env for disabling SLI band height clamp. ** 27 3dfx 1.26 03/16/00 Adam Briggs default FX_GLIDE_WAX_ON to ** 1 ** 26 3dfx 1.25 03/16/00 Kenneth Dyke User-adjustable LOD bias ** value. ** 25 3dfx 1.24 03/14/00 Adam Briggs enable analog sli in 2X ** modes or when forced ** 24 3dfx 1.23 03/08/00 Kenneth Dyke New use isMapped boardInfo ** flag instead of broken gc flag. ** 23 3dfx 1.22 03/06/00 Kenneth Dyke Added backdoor hack to ** toggle AA on and off on the fly. ** 22 3dfx 1.21 02/18/00 Adam Briggs added FX_GLIDE_WAX_ON var ** which must be set to 1 to enable the newly uncommented SLI WAX buffer ** clears ** 21 3dfx 1.20 02/08/00 Kenneth Dyke Initialize sliBandHeight in ** the proper place. ** 20 3dfx 1.19 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 19 3dfx 1.18 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 18 3dfx 1.17 01/23/00 Adam Briggs set & recognize the SSTTYPE ** var for Voodoo4 ** 17 3dfx 1.16 01/21/00 Adam Briggs some changes to get the ** correct linear mappings for slave regs and use them to sync the fifos in ** sli mode ** 16 3dfx 1.15 01/18/00 Kenneth Dyke Added environment variables ** for configuring AA jitter offsets. ** 15 3dfx 1.14 01/16/00 Kenneth Dyke Triangle column width ** tweaking. ** 14 3dfx 1.13 01/16/00 Kenneth Dyke Changed defaults for 32-bit ** and AA environment variables. ** 13 3dfx 1.12 01/07/00 Adam Briggs Moved freeThreadStorage ** from grShutdown to the DllMain process detach code. This fixes PRS#12190, ** 12192 and 12196. ** 12 3dfx 1.11 12/10/99 Kenneth Dyke Ugh. Undid some changes ** for backwards compatibility. ** ** 11 3dfx 1.10 12/08/99 Kenneth Dyke Fixed stupid macro problem. ** 10 3dfx 1.9 12/08/99 Kenneth Dyke Environment variable ** checking is now actually sane and based on the value of the variable and ** not just its presence. ** 9 3dfx 1.8 12/03/99 Adam Briggs set sli bandheight to ** FX_GLIDE_SLI_BAND_HEIGHT instead of zero(!) ** 8 3dfx 1.7 11/11/99 Adam Briggs My bad: Apparently V3 ** cards have zero chips on them, so don't even bother with the first step ** through the SLI slave reg loops. ** 7 3dfx 1.6 11/09/99 Larry warner Make the world safe for h3. ** 6 3dfx 1.5 11/09/99 Adam Briggs Added support for reading ** the Status reg on slave chips in order to form a more perfect flush ** function. ** 5 3dfx 1.4 11/05/99 Anthony tai added ** FX_GLIDE_SWAPPENDINGCOUNT. Default=1. Range 0-3 ** 4 3dfx 1.3 10/08/99 Adam Briggs Supported FX_GLIDE_BPP & ** FX_GLIDE_AA_SAMPLE environment vars so the user can override the pixel ** format in grSstWinOpen calls ** 3 3dfx 1.2 09/22/99 Larry warner Created download procedures ** for FXT1 format. ** 2 3dfx 1.1 09/13/99 Anthony tai added napalm tmu case ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** ** 74 8/31/99 5:48p Atai ** fixed chip count ** ** 73 8/19/99 7:55p Larryw ** FXT1 Tsplit changes. ** ** 72 8/05/99 5:03p Larryw ** FXT1 format works now. ** ** 71 8/04/99 10:27a Atai ** hack to enable chip count ** ** 70 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 69 7/26/99 12:11p Atai ** initialize pci registers for sli/aa ** ** 68 7/21/99 3:59p Atai ** added sliBandHeight env var ** ** 67 7/18/99 11:11a Atai ** added 2 pixel per clock ** ** 66 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 65 7/06/99 5:00p Atai ** sync with tot csim ** ** 64 7/06/99 2:46p Atai ** initailize gbc env var ** ** 63 6/24/99 7:13p Atai ** initialize combine_ext_mode with 0 ** ** 62 6/18/99 10:39p Atai ** added csim env var to specify chip # ** ** 61 6/14/99 5:16p Larryw ** Added 32-bit texture format support. ** ** 60 6/08/99 6:04p Stb_sbrooks ** Added fifoSize environment var ** ** 59 6/03/99 5:23p Russp ** Add in some ifdef'd code to allow variable texture alignment ** ** 58 6/03/99 12:15p Kcd ** PowerPC still uses C vertex routines when C triangle setup is turned ** off. ** ** 57 6/03/99 11:18a Atai ** force deviceID to 7 for code development ** ** 56 5/28/99 3:45p Atai ** added base_ptr value for grTexMaxAddress ** ** 55 5/21/99 9:22a Stb_gkincade ** Put in check for : is GETENV(SSTH3_ALPHADITHERMODE) a null string? ** ** 53 5/20/99 9:03a Atai ** is GETENV("SSTH3_ALPHADITHERMODE") a null string? ** ** 52 5/13/99 2:38p Stb_gkincade ** Added user support for turning on/off dither substraction ** ** 51 4/29/99 10:17p Atai ** disable context code in csim ** ** 50 4/22/99 3:53p Dow ** Alt-Tab on NT ** ** 49 4/16/99 2:55p Kcd ** PowerPC PCI Bump & Grind ** ** 48 4/10/99 2:21p Atai ** fixed sstRegs ** ** 47 4/10/99 1:54p Atai ** added ioReg, cReg, gReg, and rawLfb ** ** 46 4/07/99 7:18p Atai ** added uma extension ** ** 45 4/01/99 7:55p Peter ** made names and comments more meaningful ** ** 44 3/31/99 9:02p Dow ** context loosing means no writing to hw ** ** 43 3/30/99 3:21p Atai ** use hwcGetenv if hwc is used ** ** 42 3/17/99 5:08p Peter ** removed whacky stuff now that the command fifo threshold stuff appears ** to make all happy (including the k7) ** ** 41 3/14/99 1:48p Peter ** cmd's bng optimization ** ** 40 3/12/99 2:24p Dow ** Remove 3DNow for K7 (temp workaround) ** ** 39 2/18/99 3:59p Kcd ** Fixed _grGlideInitEnvironment to build on non-Win32 systems. ** ** 38 2/17/99 6:38p Atai ** Fixed hack which broke grGet(GR_NUM_BOARDS,,) ** ** 37 2/11/99 1:38p Atai ** sync buffer swap pending code, the right way. ** ** 36 1/25/99 6:33p Peter ** removed some cruft I saw when cleaning up tiled textures ** ** 35 1/20/99 10:54a Dow ** Voodoo 3 id for apps ** ** 34 12/14/98 2:20p Dow ** $#@! ** ** 33 12/07/98 11:33a Peter ** norbert's re-fixes of my merge ** ** 32 12/03/98 11:12p Dow ** added GLIDE_FGETENV for floating-point ** ** 31 12/03/98 10:39p Dow ** Removed registry code ** ** 30 12/02/98 2:06p Dow ** Fixed Control Panel stuff for W95 & WNT ** ** 29 12/02/98 1:00p Atai ** Hack. Setup up triangle and vertex array routine ** ** 28 12/02/98 11:11a Dow ** Fixed Control Panel ** ** 27 12/02/98 10:38a Dow ** Fixed Registry path for NT ** ** 26 11/18/98 7:50p Atai ** use env var FX_GLIDE_NUM_TMU ** ** 25 11/17/98 7:03p Atai ** added env var "FX_GLIDE_DISABLE_TMU1" ** ** 24 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 23 11/09/98 3:34p Mikec ** Glide read registry on NT. ** ** 22 11/02/98 5:34p Peter ** tls per thread for fullscreen contexts ** ** 21 10/16/98 1:24p Peter ** c trisetup fixes ** ** 20 10/14/98 3:38p Dow ** Gamma stuff ** ** 19 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 18 9/04/98 11:35a Peter ** re-open fix for nt (thanks to taco/rob/nt bob) ** ** 17 8/29/98 4:35p Dow ** Thread Optimization stuff ** ** 16 8/27/98 9:27p Atai ** fix env variable for glide3x ** ** 15 8/21/98 3:48p Jdt ** Added DLLMAIN function to restore desktop during critical failure. ** ** 14 8/03/98 6:40a Jdt ** multi-thread changes ** ** 13 7/01/98 12:41p Jdt ** Removed global p6FenceVar ** ** 12 5/28/98 2:07p Peter ** banshee merge ** ** 11 5/06/98 1:51p Peter ** more real banshee for glide3 ** ** 10 5/05/98 2:22p Peter ** banshee is really banshee ** ** 9 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 7 4/22/98 4:57p Peter ** glide2x merge ** ** 6 2/10/98 7:04p Atai ** change module name ** ** 5 1/30/98 4:51p Peter ** fixed sli-detect for multiple pairs ** ** 4 1/30/98 4:29p Peter ** no uswc for sli slave ** ** 3 1/20/98 11:03a Peter ** env var to force triple buffering * * 2 1/16/98 5:41p Peter * fixed sense of lod_dither * * 1 1/16/98 4:29p Atai * create glide 3 src * * 92 1/14/98 10:22a Peter * no more hacks * * 91 1/08/98 7:09p Peter * real hw stuff modulo makefile change * * 90 1/07/98 11:18a Atai * remove GrMipMapInfo and GrGC.mm_table in glide3 * * 89 1/07/98 10:22a Peter * lod dithering env var * * 88 12/17/97 10:08a Peter * fast system comdex twiddling * * 87 12/09/97 4:20p Peter * 0x100 fbiRev ofset for v2 * * 86 12/09/97 12:20p Peter * mac glide port * * 85 12/05/97 4:26p Peter * watcom warnings * * 84 12/03/97 2:36p Peter * upped comdex reset defaults * * 83 12/02/97 9:48a Dow * Removed some spurious code I inadvertantly added. * * 82 11/21/97 6:24p Dow * Banshee Lying about being Rush stuf * * 81 11/21/97 11:19a Dow * Made Banshee report Voodoo2 * * 80 11/20/97 6:39p Peter * fixed direct_exec w/ csim * * 79 11/19/97 2:49p Peter * env vars in registry for win32 * * 78 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 77 11/15/97 7:43p Peter * more comdex silliness * * 76 11/14/97 11:10p Peter * open vs hw init confusion * * 75 11/14/97 5:02p Peter * more comdex stuff * * 74 11/14/97 12:09a Peter * comdex thing and some other stuff * * 73 11/12/97 9:54p Peter * fixed all the effage from new config * * 72 11/12/97 9:37p Dow * Textures on Banshee half work * * 71 11/12/97 9:22a Dow * h3 mods * * 70 11/08/97 3:34p Peter * fixed stupid gdbg_info crasher * * 69 11/04/97 4:00p Dow * Banshee Mods * * 68 11/03/97 3:43p Peter * h3/cvg cataclysm * * 67 11/01/97 12:11p Pgj * glide.dll ---> glide2x.dll * * 66 10/31/97 8:53a Peter * last lying change, really * * 65 10/30/97 3:42p Peter * protected the last bit of nonsense * * 64 10/30/97 3:37p Peter * spoof sst1 stuff * * 63 10/29/97 2:45p Peter * C version of Taco's packing code * * 62 10/23/97 5:28p Peter * sli fifo thing * * 61 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 60 9/10/97 10:13p Peter * fifo logic from GaryT, non-normalized fp first cut * * 59 9/05/97 5:29p Peter * changes for direct hw * * 58 9/01/97 3:18p Peter * correct integer rounding for pts * * 57 8/30/97 5:59p Tarolli * init and hal fixups * * 56 8/30/97 1:19p Peter * first cut at using blit to clear, more to come to do inner rects * * 55 8/18/97 3:52p Peter * pre-hw arrival fixes/cleanup * * 54 7/30/97 2:42p Peter * shared and sanitized * * 53 7/28/97 2:41p Peter * turned sli code back on for cvg, but waiting for hal * * 52 7/25/97 11:40a Peter * removed dHalf, change field name to match real use for cvg * * 51 7/08/97 2:47p Peter * fixed merge stupidity from last checkin * * 50 7/02/97 12:28p Peter * removed spurious NOP, tex dl * * 49 6/24/97 4:02p Peter * proper cmd fifo placement * * 48 6/23/97 4:46p Peter * fixed my effage * 47 6/23/97 4:43p Peter * cleaned up #defines etc for a nicer tree ** */ #include #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #if GLIDE_PLATFORM & GLIDE_OS_WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #endif #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #ifdef HAL_CSIM #if H3 #include #endif #include #elif HSIM #include #endif #endif /* (GLIDE_PLATFORM & GLIDE_SST_SIM) */ #if GLIDE3 #define kRevisionOffset 0x00UL #else #define kRevisionOffset 0x100UL #endif #ifdef GLIDE_TEST_TEXTURE_ALIGNMENT FxU32 SST_TEXTURE_ALIGN; #endif /* null function procs that will get called when !gc->contextP. */ static FxI32 FX_CALL _trisetup_null(const void* a, const void* b, const void* c) { /* Not really accurate, but pretend its been culled for some reason */ return 0; } static void FX_CALL _grDrawVertexList_null(FxU32 pkType, FxU32 type, FxI32 mode, FxI32 count, void* ptrs) { /* Do Nothing */ } static void FX_CALL _grDrawTriangles_null(FxI32 mode, FxI32 count, void* vPtrs) { /* Do Nothing */ } static void FX_CALL _grTexDownload_null(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { /* Do Nothing */ } /* Collection of all of the known procs for a given system. * - arch specialization * - grState valid checking * - coordinate system (window/clip) * - culling mode (nocull/cull) */ static GrTriSetupProc _triSetupProcs[][2][2][2] = { /* Default arch procs */ { /* Window coords */ { { _trisetup_Default_win_nocull_valid, _trisetup_Default_win_cull_valid }, { _trisetup_Default_win_nocull_invalid, _trisetup_Default_win_cull_invalid }, }, /* Clip coordinates */ { { _vptrisetup_cull, _vptrisetup_cull }, { _vptrisetup_cull, _vptrisetup_cull }, }, }, #if GL_AMD3D /* 3DNow!(tm) Procs */ { /* Window coords */ { { _trisetup_3DNow_win_nocull_valid, _trisetup_3DNow_win_cull_valid }, { _trisetup_3DNow_win_nocull_invalid, _trisetup_3DNow_win_cull_invalid }, }, /* Clip coordinates */ { { _trisetup_clip_coor_thunk, _trisetup_clip_coor_thunk }, { _trisetup_clip_coor_thunk, _trisetup_clip_coor_thunk }, }, }, #endif /* GL_AMD3D */ #if GL_SSE /* SSE Procs */ { /* Window coords */ { { _trisetup_SSE_win_nocull_valid, _trisetup_SSE_win_cull_valid }, { _trisetup_SSE_win_nocull_invalid, _trisetup_SSE_win_cull_invalid }, }, /* Clip coordinates */ { { _trisetup_SSE_clip_coor_thunk, _trisetup_SSE_clip_coor_thunk }, { _trisetup_SSE_clip_coor_thunk, _trisetup_SSE_clip_coor_thunk }, }, }, #endif /* GL_SSE */ /* null arch procs */ { /* Window coords */ { { _trisetup_null, _trisetup_null }, { _trisetup_null, _trisetup_null }, }, /* Clip coordinates */ { { _trisetup_null, _trisetup_null }, { _trisetup_null, _trisetup_null }, }, }, }; /* NB: This is the only set of asm specializations taht needs to be * unset for C_TRISETUP. Currently, teh grDrawTriangle code will only * vector to the asm code if C_TRISETUP is not set. */ #if GLIDE_USE_C_TRISETUP || __POWERPC__ static GrVertexListProc _vertexListProcs[][2] = { { _grDrawVertexList, _grDrawVertexList }, #if GL_AMD3D { _grDrawVertexList, _grDrawVertexList }, #endif /* GL_AMD3D */ #if GL_SSE { _grDrawVertexList, _grDrawVertexList }, #endif /* GL_SSE */ { _grDrawVertexList_null, _grDrawVertexList_null }, }; #else /* Use asm code */ static GrVertexListProc _vertexListProcs[][2] = { { _drawvertexlist, _vpdrawvertexlist }, #if GL_AMD3D { _grDrawVertexList_3DNow_Window, _grDrawVertexList_3DNow_Clip }, #endif /* GL_AMD3D */ #if GL_SSE { _grDrawVertexList_SSE_Window, _grDrawVertexList_SSE_Clip }, #endif /* GL_SSE */ { _grDrawVertexList_null, _grDrawVertexList_null }, }; #endif /* Use asm code */ static GrTexDownloadProc _texDownloadProcs[][4][5] = { /* Default Procs */ { { _grTexDownload_Default_4_4, /* used only for DXT1 8x4 mipmaps (two 4x4 mipmaps side by side). download only 4x4. */ _grTexDownload_Default_4_8, _grTexDownload_Default_4_WideS, _grTexDownload_Default_4_WideS, _grTexDownload_Default_4_WideS }, { _grTexDownload_Default_8_1, _grTexDownload_Default_8_2, _grTexDownload_Default_8_4, _grTexDownload_Default_8_WideS, _grTexDownload_Default_8_WideS }, { _grTexDownload_Default_16_1, _grTexDownload_Default_16_2, _grTexDownload_Default_16_WideS, _grTexDownload_Default_16_WideS, _grTexDownload_Default_16_WideS }, { _grTexDownload_Default_32_1, /* unused */ _grTexDownload_Default_32_1, _grTexDownload_Default_32_WideS, _grTexDownload_Default_32_WideS, /* unused */ _grTexDownload_Default_32_WideS } }, #if GL_AMD3D { { _grTexDownload_Default_4_4, /* used only for DXT1 8x4 mipmaps (two 4x4 mipmaps side by side). download only 4x4. */ _grTexDownload_Default_4_8, _grTexDownload_3DNow_MMX, _grTexDownload_3DNow_MMX, _grTexDownload_3DNow_MMX }, { _grTexDownload_Default_8_1, _grTexDownload_Default_8_2, _grTexDownload_Default_8_4, _grTexDownload_3DNow_MMX, _grTexDownload_3DNow_MMX }, { _grTexDownload_Default_16_1, _grTexDownload_Default_16_2, _grTexDownload_3DNow_MMX, _grTexDownload_3DNow_MMX, _grTexDownload_3DNow_MMX }, { _grTexDownload_Default_32_1, /* unused */ _grTexDownload_Default_32_1, _grTexDownload_3DNow_MMX, _grTexDownload_3DNow_MMX, /* unused */ _grTexDownload_3DNow_MMX } }, #endif /* GL_AMD3D */ #if GL_MMX { { _grTexDownload_Default_4_4, /* used only for DXT1 8x4 mipmaps (two 4x4 mipmaps side by side). download only 4x4. */ _grTexDownload_Default_4_8, _grTexDownload_MMX, _grTexDownload_MMX, _grTexDownload_MMX }, { _grTexDownload_Default_8_1, _grTexDownload_Default_8_2, _grTexDownload_Default_8_4, _grTexDownload_MMX, _grTexDownload_MMX }, { _grTexDownload_Default_16_1, _grTexDownload_Default_16_2, _grTexDownload_MMX, _grTexDownload_MMX, _grTexDownload_MMX }, { _grTexDownload_Default_32_1, /* unused */ _grTexDownload_Default_32_1, _grTexDownload_MMX, _grTexDownload_MMX, /* unused */ _grTexDownload_MMX } }, #endif /* GL_MMX */ #if GL_SSE2 { { _grTexDownload_Default_4_4, /* used only for DXT1 8x4 mipmaps (two 4x4 mipmaps side by side). download only 4x4. */ _grTexDownload_Default_4_8, _grTexDownload_SSE2_64, _grTexDownload_SSE2_128, _grTexDownload_SSE2_128 }, { _grTexDownload_Default_8_1, _grTexDownload_Default_8_2, _grTexDownload_Default_8_4, _grTexDownload_SSE2_64, _grTexDownload_SSE2_128 }, { _grTexDownload_Default_16_1, _grTexDownload_Default_16_2, _grTexDownload_SSE2_64, _grTexDownload_SSE2_128, _grTexDownload_SSE2_128 }, { _grTexDownload_Default_32_1, /* unused */ _grTexDownload_Default_32_1, _grTexDownload_SSE2_64, _grTexDownload_SSE2_128, /* unused */ _grTexDownload_SSE2_128 } }, #endif /* GL_SSE2 */ /* NULL download procs */ { { _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null }, { _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null }, { _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null }, { _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null, _grTexDownload_null } }, }; /* Some macros to prevent RSI */ #define GC _GlideRoot.GCs[ctx] #define SST _GlideRoot.hwConfig.SSTs[ctx] #define REGSTR_PATH_3DFXSW "Software\\3Dfx Interactive\\Voodoo2" #define REGSTR_PATH_GLIDE REGSTR_PATH_3DFXSW"\\Glide" /*------------------------------------------------------------------- Function: _grSstDetectResources Date: -- Implementor(s): Dow, Gmt, Jdt Library: Glide Description: Discover devices on the PCI bus. Discover configuration of detected devices. Initialize all Glide GC's Recognized devices depend upon compile time flags This code should NOT initialize the hardware any more than is necessary for discovery of configuration Arguments: none Return: FXTRUE - at least one device was detected FXFALSE - no devices were detected. -------------------------------------------------------------------*/ FxBool _grSstDetectResources(void) { static FxBool calledP = FXFALSE; FxBool rv = FXFALSE; FxU32 ctx; GDBG_INFO(280, "_grSstDetectResources()\n"); if (!calledP) { #if GLIDE_INIT_HAL FxU32 count = HAL_MAX_BOARDS; FxU32 chipCount = 1; /* The first time through the init code we need to map * all of the boards. Future calls can just grab this * info out of the halInfo that we have here. */ FxU32 device; HalInfo* halInfo = fxHalInit(0); if (halInfo == NULL) goto __errExit; { /* ** hack alert!! ** by default, there is no device around so we hack the device ** number in here (copy code from diag). */ char* envChipNum = GETENV("FX_GLIDE_NUM_CHIPS"); FxBool useMultiFunctionDevices=FXFALSE; FxU32 busNumber, deviceNumber, functionNumber; FxU32 counter; if (envChipNum) chipCount = atoi(envChipNum); switch(chipCount) { case 4: busNumber = 3; deviceNumber = 2; functionNumber = 0; halInfo->boardInfo[2].pciBusNumber = busNumber; halInfo->boardInfo[2].pciDeviceNumber = deviceNumber; halInfo->boardInfo[2].pciFunctionNumber = functionNumber; halInfo->boardInfo[2].deviceNumber = busNumber * 32 + deviceNumber; busNumber = 3; deviceNumber = 2; functionNumber = 1; halInfo->boardInfo[3].pciBusNumber = busNumber; halInfo->boardInfo[3].pciDeviceNumber = deviceNumber; halInfo->boardInfo[3].pciFunctionNumber = functionNumber; halInfo->boardInfo[3].deviceNumber = busNumber * 32 + deviceNumber; case 2: busNumber = 2; deviceNumber = 1; functionNumber = 1; halInfo->boardInfo[1].pciBusNumber = busNumber; halInfo->boardInfo[1].pciDeviceNumber = deviceNumber; halInfo->boardInfo[1].pciFunctionNumber = functionNumber; halInfo->boardInfo[1].deviceNumber = busNumber * 32 + deviceNumber; useMultiFunctionDevices=FXTRUE; case 1: default: busNumber = 2; deviceNumber = 1; functionNumber = 0; halInfo->boardInfo[0].pciBusNumber = busNumber; halInfo->boardInfo[0].pciDeviceNumber = deviceNumber; halInfo->boardInfo[0].pciFunctionNumber = functionNumber; halInfo->boardInfo[0].deviceNumber = busNumber * 32 + deviceNumber; break; } /* Initialize the csim boards/chips */ for(counter=0; counterboardInfo[counter].sstCSIM = csimInit(counter); if(useMultiFunctionDevices) csimMakeMultiFunctionDevice(halInfo->boardInfo[counter].sstCSIM); CSIM_PRIVATE(halInfo->boardInfo[counter].sstCSIM)->environment.chipCount = chipCount; CSIM_PRIVATE(halInfo->boardInfo[counter].sstCSIM)->environment.sliBandHeight = _GlideRoot.environment.sliBandHeight; } } #if (GLIDE_PLATFORM & GLIDE_SST_SIM) /* The simulator can support any number of boards through * successive calls to fxHalMapBoard. */ { const char* envBoardNum = GETENV("FX_SIM_BOARDS"); FxU32 temp; count = (((envBoardNum != NULL) && (sscanf(envBoardNum, "%ld", &temp) == 1)) ? temp : 1); if (count > HAL_MAX_BOARDS) { GDBG_INFO(0, "Error: FX_SIM_BOARDS(%ld) > %d. Using %d.\n", count, HAL_MAX_BOARDS, HAL_MAX_BOARDS); count = HAL_MAX_BOARDS; } count *= chipCount; } #endif /* (GLIDE_PLATFORM & GLIDE_SST_SIM) */ for(ctx = device = 0; device < count; device++) { SstRegs* devRegs; devRegs = fxHalMapBoard(device); } for(ctx = device = 0; device < count; device++) { /* See RSI-prevention macros for usage of [ctx] */ const FxDeviceInfo* curDev = NULL; FxBool regInitP = FXFALSE; SstRegs* devRegs; devRegs = fxHalMapBoard(device); if ((device % chipCount) == 0) GC.is_master = FXTRUE; else GC.is_master = FXFALSE; GC.chipCount = chipCount; GC.sliBandHeight = _GlideRoot.environment.sliBandHeight; curDev = halInfo->boardInfo + device; GC.halInfo = halInfo; if (devRegs != NULL) { FxU32 tmuMem = 0x00; SST.type = GR_SSTTYPE_Banshee; if (!fxHalInitRegisters(curDev->virtAddr[0])) goto __errRegFailure; #if USE_PACKET_FIFO && GLIDE_DEBUG && HAL_CSIM if ((halInfo->csim == 1) && (GETENV("FX_FIFO_DIRECT_EXEC") != NULL)) { // halInfo->csim = -1; GDBG_INFO(80, "Turning on direct fifo execution\n"); } #endif /* USE_PACKET_FIFO && GLIDE_DEBUG && HAL_CSIM */ #ifdef DIRECT_IO GC.sstRegs = (SstRegs *) (curDev->physAddr[0] + 0x200000); GC.ioRegs = (SstIORegs *) (curDev->physAddr[0]); GC.cRegs = (SstCRegs *) (curDev->physAddr[0] + 0x80000); GC.rawLfb = (FxU32 *) curDev->physAddr[1]; #endif /* DIRECT_IO */ /* This device is ready to go. */ regInitP = FXTRUE; /* Set up pointers to the various address spaces within the hw */ GC.base_ptr = (FxU32*)SST_BASE_ADDRESS(curDev->physAddr[0]); GC.reg_ptr = (FxU32*)devRegs; GC.lfb_ptr = (FxU32*)SST_LFB_ADDRESS(curDev->physAddr[0]); GC.tex_ptr = (FxU32*)SST_TEX_ADDRESS(curDev->physAddr[0]); GC.sstRegs = devRegs; GC.ioRegs = (SstIORegs *) SST_IO_ADDRESS(devRegs); GC.cRegs = (SstCRegs *) SST_CMDAGP_ADDRESS(devRegs); GC.gRegs = (SstGRegs *) SST_GUI_ADDRESS(devRegs); #define SST_RAW_LFB_ADDRESS(sst) (SST_RAW_LFB_OFFSET+SST_BASE_ADDRESS(sst)) GC.rawLfb = (FxU32 *) SST_RAW_LFB_ADDRESS(devRegs); /* GC.rawLfb = (FxU32 *) SST_LFB_ADDRESS(devRegs); */ #ifdef FX_GLIDE_NAPALM /* force the deviceID to 7 for code development */ { static hwcBoardInfo tmpbInfo; GC.bInfo = &tmpbInfo; GC.bInfo->pciInfo.deviceID = SST_DEVICE_ID_AP_OEM ; } #endif /* Video parameters */ GC.grSstRez = GR_RESOLUTION_NONE; GC.grSstRefresh = curDev->fbiVideoRefresh; /* Chip configuration */ GC.num_tmu = curDev->numberTmus; GC.fbuf_size = curDev->fbiMemSize; _GlideRoot.hwConfig.num_sst++; SST.sstBoard.SST96Config.fbRam = curDev->fbiMemSize; SST.sstBoard.SST96Config.nTexelfx = curDev->numberTmus; { const FxU32 curTmuMemSize = 0x2; SST.sstBoard.SST96Config.tmuConfig.tmuRev = (2 + kRevisionOffset); SST.sstBoard.SST96Config.tmuConfig.tmuRam = curTmuMemSize; tmuMem += curTmuMemSize; /* Clear the tmu state */ memset(&GC.tmu_state[0], 0, sizeof(GC.tmu_state[0])); GC.tmu_state[0].total_mem = (curTmuMemSize << 20); GC.tmu_state[0].ncc_mmids[0] = GC.tmu_state[0].ncc_mmids[1] = GR_NULL_MIPMAP_HANDLE; } rv = FXTRUE; ctx++; } __errRegFailure: /* Either this is not the hw we're expecting, or we could not * init/map the board for some reason. Either way try to cleanup. */ if (!regInitP && (devRegs != NULL)) { fxHalShutdown(devRegs); } } /* Done setting up. Don't do the silly mapping thing again. */ #else /* GLIDE_INIT_HWC */ /* There's a left brace before the #if */ hwcBoardInfo *bInfo; hwcInfo *hInfo; /* Info about all the relavent boards */ int tmu; //char* envChipNum; /* unused */ //FxU32 chipCount = 1; /* unused */ if ((hInfo = hwcInit(0x121a, 0x9)) == NULL) if ((hInfo = hwcInit(0x121a, 0x5)) == NULL) /* Voodoo3 */ if ((hInfo = hwcInit(0x121a, 0x3)) == NULL) goto __errExit; /* Iterate through boards found */ for (ctx = 0; ctx < hInfo->nBoards; ctx++) { bInfo = &hInfo->boardInfo[ctx]; GC.bInfo = bInfo; /* ** hack alert!! ** the chipCount should come from the minivdd ** KoolSmoky - chipCount should be after hwcInit(0x....) because ** it calls GETENV. */ /*envChipNum = GETENV("FX_GLIDE_NUM_CHIPS", GC.bInfo->RegPath); if (envChipNum) chipCount = atoi(envChipNum);*/ /* unused */ if (bInfo->pciInfo.deviceID == SST_DEVICE_ID_H3) SST.type = GR_SSTTYPE_Banshee; #ifdef FX_GLIDE_NAPALM else if (IS_NAPALM(bInfo->pciInfo.deviceID)) SST.type = GR_SSTTYPE_Voodoo4; #endif else SST.type = GR_SSTTYPE_Voodoo3; if (!hwcMapBoard(bInfo, HWC_BASE_ADDR_MASK)) { GrErrorCallback(hwcGetErrorString(), FXTRUE); } if (!hwcInitRegisters(bInfo)) { GrErrorCallback(hwcGetErrorString(), FXTRUE); } /* NB: We cannot fail to map this board after this point */ //GC.hwInitP = FXTRUE; _GlideRoot.hwConfig.num_sst++; GC.base_ptr = (FxU32 *) bInfo->regInfo.sstBase; GC.sstRegs = (SstRegs *) bInfo->regInfo.sstBase; GC.ioRegs = (SstIORegs *) bInfo->regInfo.ioMemBase; GC.cRegs = (SstCRegs *) bInfo->regInfo.cmdAGPBase; GC.lfb_ptr = (FxU32 *) bInfo->regInfo.lfbBase; GC.rawLfb = (FxU32 *) bInfo->regInfo.rawLfbBase; GC.chipCount = bInfo->pciInfo.numChips; /* KCD: This can't be done here, since the environment variables may not have been set up yet! */ /* GC.sliBandHeight = _GlideRoot.environment.sliBandHeight; */ #ifdef FX_GLIDE_NAPALM /* AJB- Point at slave chip regs */ { FxU32 chip ; if (GC.chipCount) for (chip = 0 ; chip < GC.chipCount - 1 ; chip++) { GC.slaveSstRegs[chip] = (SstRegs *)bInfo->regInfo.slaveSstBase[chip] ; GC.slaveCRegs[chip] = (SstCRegs *)bInfo->regInfo.slaveCmdBase[chip] ; } } #endif /* Video Parameters */ GC.grSstRez = GR_RESOLUTION_NONE; GC.grSstRefresh = 0L; /* ** Hack. Setup up triangle and vertex array routine */ if (_GlideRoot.deviceArchProcs.curTriProcs) { GC.archDispatchProcs.coorModeTriVector = (*_GlideRoot.deviceArchProcs.curTriProcs) + 0; GC.archDispatchProcs.drawVertexList = _GlideRoot.deviceArchProcs.curVertexListProcs[0]; } /* This is a uma device */ switch (hInfo->boardInfo[ctx].pciInfo.deviceID) { case SST_DEVICE_ID_H3: /* Banshee */ GC.num_tmu = 1; GC.fbuf_size = (bInfo->h3Mem - 2); break; case SST_DEVICE_ID_H4: /* Avenger low speed */ case SST_DEVICE_ID_H4_OEM: /* Avenger high speed */ /* ** For 8M board, we may only use one tmu for higher resolution. ** Need to re-visit the issue. 11/5/98 */ GC.num_tmu = 2; GC.fbuf_size = (bInfo->h3Mem - 4); break; default: /* KoolSmoky - This is NAPALM. */ if ((hInfo->boardInfo[ctx].pciInfo.deviceID >= SST_DEVICE_ID_L_AP) && (hInfo->boardInfo[ctx].pciInfo.deviceID <= SST_DEVICE_ID_H_AP)) { GC.num_tmu = 2; GC.fbuf_size = (bInfo->h3Mem - 4); } else { GC.num_tmu = 1; GC.fbuf_size = (bInfo->h3Mem - 2); } break; } if (bInfo->h3Mem == 4) { GC.num_tmu = 1; GC.fbuf_size = (bInfo->h3Mem - 2); } if (GETENV("FX_GLIDE_NUM_TMU", GC.bInfo->RegPath)) { int num_tmu = atoi(GETENV("FX_GLIDE_NUM_TMU", GC.bInfo->RegPath)); /* XXX: what happens if someone requests invalid number of TMUs? */ if(num_tmu > 1) { GC.num_tmu = 2; GC.fbuf_size = (bInfo->h3Mem - 4); } else { GC.num_tmu = 1; GC.fbuf_size = (bInfo->h3Mem - 2); } } GC.state.grEnableArgs.combine_ext_mode = GR_MODE_DISABLE; /* KoolSmoky - UMA for the TMUs */ GC.state.grEnableArgs.texture_uma_mode = GR_MODE_DISABLE; if( GETENV("FX_GLIDE_TEXTURE_UMA", GC.bInfo->RegPath) ) { if( atoi(GETENV("FX_GLIDE_TEXTURE_UMA", GC.bInfo->RegPath)) == 1 ) { GC.state.grEnableArgs.texture_uma_mode = GR_MODE_ENABLE; } else { GC.state.grEnableArgs.texture_uma_mode = GR_MODE_DISABLE; } } SST.sstBoard.SST96Config.fbRam = GC.fbuf_size; SST.sstBoard.SST96Config.nTexelfx = GC.num_tmu; SST.sstBoard.SST96Config.tmuConfig.tmuRev = (2 + kRevisionOffset); SST.sstBoard.SST96Config.tmuConfig.tmuRam = 0x0; /* Clear the tmu state */ for (tmu = 0; tmu < GC.num_tmu; tmu++) { memset(&GC.tmu_state[tmu], 0, sizeof(GC.tmu_state[0])); GC.tmu_state[tmu].total_mem = (0x2 << 20); GC.tmu_state[tmu].ncc_mmids[0] = GC.tmu_state[tmu].ncc_mmids[1] = GR_NULL_MIPMAP_HANDLE; } } /* iterate through boards found */ #endif } /* Did we previously find boards? */ rv = (_GlideRoot.hwConfig.num_sst != 0); calledP = FXTRUE; goto __errExit; /* Keep warnings happy */ __errExit: return rv; } /* _grSstDetectResources */ static void displayBoardInfo(int i, GrHwConfiguration *hwc) { if ((hwc->SSTs[i].type == GR_SSTTYPE_VOODOO) || (hwc->SSTs[i].type == GR_SSTTYPE_Voodoo2)) { int tmuNum; GDBG_INFO(80,"SST board %d: 3Dfx Voodoo%s\n", i, ((hwc->SSTs[i].type == GR_SSTTYPE_VOODOO) ? " Graphics" : "^2")); if (hwc->SSTs[i].sstBoard.VoodooConfig.sliDetect) { GDBG_INFO(80,"\tScanline Interleaved\n"); } GDBG_INFO(80,"\tPixelfx rev 0x%lX with %d MB Frame Buffer\n", hwc->SSTs[i].sstBoard.VoodooConfig.fbiRev, hwc->SSTs[i].sstBoard.VoodooConfig.fbRam); GDBG_INFO(80,"\t%d Texelfx chips:\n", hwc->SSTs[i].sstBoard.VoodooConfig.nTexelfx); for (tmuNum = 0; tmuNum < hwc->SSTs[i].sstBoard.VoodooConfig.nTexelfx; tmuNum++) { GDBG_INFO(80,"\t\tTexelfx %d: Rev 0x%lX, %d MB Texture\n", tmuNum, hwc->SSTs[i].sstBoard.VoodooConfig.tmuConfig[tmuNum].tmuRev, hwc->SSTs[i].sstBoard.VoodooConfig.tmuConfig[tmuNum].tmuRam); } } else if (hwc->SSTs[i].type == GR_SSTTYPE_SST96) { GDBG_INFO(80,"SST board %d: 3Dfx Voodoo Rush\n", i); GDBG_INFO(80,"\tFBI Jr. with %d MB Frame Buffer\n", hwc->SSTs[i].sstBoard.SST96Config.fbRam); GDBG_INFO(80,"\tTexelfx chips: 1\n"); } else if (hwc->SSTs[i].type == GR_SSTTYPE_Voodoo2) { GDBG_INFO(80,"SST board %d: 3Dfx Voodoo2\n", i); } else if (hwc->SSTs[i].type == GR_SSTTYPE_Banshee) { GDBG_INFO(80,"SST board %d: 3Dfx Banshee\n", i); } else if (hwc->SSTs[i].type == GR_SSTTYPE_Voodoo3) { GDBG_INFO(80,"SST board %d: 3Dfx Voodoo3\n", i); } else if (hwc->SSTs[i].type == GR_SSTTYPE_Voodoo4) { GDBG_INFO(80,"SST board %d: 3dfx Voodoo4/5\n", i); } else { GDBG_INFO(80,"error: SSTs %d: unknown type\n",i); } } /* displayBoardInfo */ void _GlideInitEnvironment(int which) { #define FN_NAME "_GlideInitEnvironment" int i; FxU32 ditherMode; const char* envStr; FxU32 ctx = which; double pi = 3.1415926535; const char* envStr2; if (_GlideRoot.initialized) /* only execute once */ return; GDBG_INIT(); /* init the GDEBUG libraray */ GDBG_INFO(80,"%s()\n", FN_NAME); GDBG_INFO(0,"GLIDE DEBUG LIBRARY\n"); /* unconditional display */ #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) _GlideRoot.OS = hwcGetOS(); #if defined(FX_DLL_ENABLE) && (GLIDE_PLATFORM & GLIDE_OS_WIN32) { /* GMT: display the DLL pathname for sanity checking */ char buf[132] = "failed"; GetModuleFileName(GetModuleHandle("glide3x.dll"), buf, sizeof(buf)); GDBG_INFO(0,"DLL path: %s\n",buf); } #endif #endif /* Check for user environment tweaks */ #define GLIDE_GETENV(__envVar, __regPath, __defVal) \ (((envStr = GETENV(__envVar, __regPath)) == NULL) ? (__defVal) : atol(envStr)) #define GLIDE_FGETENV(__envVar, __regPath, __defVal) \ (((envStr = GETENV(__envVar, __regPath)) == NULL) ? (__defVal) : (float) atof(envStr)) #define GLIDE_34GETENV(__envVar, __regPath, __defVal) \ (((signed char)(atof(((envStr = GETENV(__envVar, __regPath)) == NULL) ? (__defVal) : (envStr))*16.0f)+8)&0x7f) #define GLIDE_34GETENV_X(__envVar_x, __envVar_y, __regPath, __defVal_x, __defVal_y) \ (signed char)((((atof(((envStr = GETENV(__envVar_x, __regPath)) == NULL) ? __defVal_x : envStr) * cos(_GlideRoot.environment.aaGridRotation*pi/180)) \ - (atof(((envStr2 = GETENV(__envVar_y, __regPath)) == NULL) ? __defVal_y : envStr2) * sin(_GlideRoot.environment.aaGridRotation*pi/180)) \ ) * _GlideRoot.environment.aaJitterDisp + _GlideRoot.environment.aaPixelOffset)*16.0f)&0x7f #define GLIDE_34GETENV_Y(__envVar_x, __envVar_y, __regPath, __defVal_x, __defVal_y) \ (signed char)((((atof(((envStr = GETENV(__envVar_x, __regPath)) == NULL) ? __defVal_x : envStr) * sin(_GlideRoot.environment.aaGridRotation*pi/180)) \ + (atof(((envStr2 = GETENV(__envVar_y, __regPath)) == NULL) ? __defVal_y : envStr2) * cos(_GlideRoot.environment.aaGridRotation*pi/180)) \ ) * _GlideRoot.environment.aaJitterDisp + _GlideRoot.environment.aaPixelOffset)*16.0f)&0x7f #ifdef GLIDE_TEST_TEXTURE_ALIGNMENT SST_TEXTURE_ALIGN = GLIDE_GETENV("FX_GLIDE_TEX_ALIGN", GC.bInfo->RegPath, 0x10UL); #endif _GlideRoot.environment.triBoundsCheck = GETENV("FX_GLIDE_BOUNDS_CHECK", GC.bInfo->RegPath) != NULL; GDBG_INFO(80," triBoundsCheck: %d\n",_GlideRoot.environment.triBoundsCheck); #ifdef GLIDE_SPLASH _GlideRoot.environment.noSplash = GETENV("FX_GLIDE_NO_SPLASH", GC.bInfo->RegPath) != NULL; #else _GlideRoot.environment.noSplash = 1; #endif GDBG_INFO(80," noSplash: %d\n",_GlideRoot.environment.noSplash); _GlideRoot.environment.shamelessPlug = GETENV("FX_GLIDE_SHAMELESS_PLUG", GC.bInfo->RegPath) != NULL; GDBG_INFO(80," shamelessPlug: %d\n",_GlideRoot.environment.shamelessPlug); _GlideRoot.environment.ignoreReopen = GETENV("FX_GLIDE_IGNORE_REOPEN", GC.bInfo->RegPath) != NULL; GDBG_INFO(80," ignoreReopen: %d\n",_GlideRoot.environment.ignoreReopen); _GlideRoot.environment.disableDitherSub = GETENV("FX_GLIDE_NO_DITHER_SUB", GC.bInfo->RegPath) != NULL; GDBG_INFO(80," disableDitherSub: %d\n",_GlideRoot.environment.disableDitherSub); _GlideRoot.environment.fifoSize = GETENV("FX_GLIDE_FIFO_SIZE", GC.bInfo->RegPath) != NULL; GDBG_INFO(80," fifoSize: %d\n",_GlideRoot.environment.fifoSize); _GlideRoot.environment.noHW = GETENV("FX_GLIDE_NO_HW", GC.bInfo->RegPath) != NULL; GDBG_INFO(80," noHW: %d\n",_GlideRoot.environment.noHW); //_GlideRoot.environment.aaPixelOffset = GLIDE_FGETENV("FX_GLIDE_AA_PIXELCENTER", GC.bInfo->RegPath, 4.0f); /* original glide3x offset was 8.0f */ //GDBG_INFO(80," aaPixelOffset: %f\n",_GlideRoot.environment.aaPixelOffset); //_GlideRoot.environment.aaJitterDisp = GLIDE_FGETENV("FX_GLIDE_AA_JITTERDISP", GC.bInfo->RegPath, 18.0f); /* original value 16.0f */ //GDBG_INFO(80," aaJitterDisp: %f\n",_GlideRoot.environment.aaJitterDisp); //_GlideRoot.environment.aaGridRotation = GLIDE_FGETENV("FX_GLIDE_AA_GRIDROTATION", GC.bInfo->RegPath, 27.5f); /* original values 2xaa=45deg 4xaa,8xaa=27.5deg */ //GDBG_INFO(80," aaGridRotation: %f\n",_GlideRoot.environment.aaGridRotation); /* set default glide state to not openGL app. _GlideInitEnvironment() must not be called multiple times. */ _GlideRoot.environment.is_opengl = FXFALSE; /* note - glide now uses a string representation for the AA jitter values */ /* This is the "old" way of doing two-sample AA, where each chip does two samples. */ _GlideRoot.environment.aaXOffset[1][0] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaXOffset[1][1] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaXOffset[1][2] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaXOffset[1][3] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaYOffset[1][0] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); _GlideRoot.environment.aaYOffset[1][1] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); _GlideRoot.environment.aaYOffset[1][2] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); _GlideRoot.environment.aaYOffset[1][3] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); /* This is a nasty evil hack! This rearranges the sample offsets to deal with the new way of doing two sample AA */ _GlideRoot.environment.aaXOffset[2][0] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaXOffset[2][1] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaXOffset[2][2] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaXOffset[2][3] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); _GlideRoot.environment.aaYOffset[2][0] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); _GlideRoot.environment.aaYOffset[2][1] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); _GlideRoot.environment.aaYOffset[2][2] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); _GlideRoot.environment.aaYOffset[2][3] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); /* This is the "normal" layout for 4-sample AA */ _GlideRoot.environment.aaXOffset[3][0] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_DEF); _GlideRoot.environment.aaXOffset[3][1] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_DEF); _GlideRoot.environment.aaXOffset[3][2] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_DEF); _GlideRoot.environment.aaXOffset[3][3] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[3][0] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP0_DEF); _GlideRoot.environment.aaYOffset[3][1] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP0_DEF); _GlideRoot.environment.aaYOffset[3][2] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[3][3] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP1_DEF); /* these are the correct jitter vaules */ /* set pixel center offset for 2xaa */ _GlideRoot.environment.aaPixelOffset = GLIDE_FGETENV("FX_GLIDE_AA_PIXELCENTER", GC.bInfo->RegPath, 0.25f); GDBG_INFO(80," aaPixelOffset: %f\n",_GlideRoot.environment.aaPixelOffset); /* set jitter dispersity for 2xaa */ _GlideRoot.environment.aaJitterDisp = GLIDE_FGETENV("FX_GLIDE_AA_JITTERDISP", GC.bInfo->RegPath, 1.125f); GDBG_INFO(80," aaJitterDisp: %f\n",_GlideRoot.environment.aaJitterDisp); /* set rotation for 2xaa */ _GlideRoot.environment.aaGridRotation = GLIDE_FGETENV("FX_GLIDE_AA_GRIDROTATION", GC.bInfo->RegPath, 45.0f) - 45.0f; GDBG_INFO(80," aaGridRotation: %f\n",_GlideRoot.environment.aaGridRotation); _GlideRoot.environment.aaXOffset[4][0] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][1] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][2] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][3] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//LIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][4] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][5] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][6] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[4][7] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][0] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][1] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][2] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][3] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][4] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][5] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][6] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[4][7] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][0] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][1] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][2] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][3] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][4] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][5] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][6] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaXOffset[5][7] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][0] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][1] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][2] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][3] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][4] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][5] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][6] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); _GlideRoot.environment.aaYOffset[5][7] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); /* set jitter dispersity for 4xaa */ /* set pixel center offset for 4xaa */ _GlideRoot.environment.aaPixelOffset = GLIDE_FGETENV("FX_GLIDE_AA_PIXELCENTER", GC.bInfo->RegPath, 0.1875f); GDBG_INFO(80," aaPixelOffset: %f\n",_GlideRoot.environment.aaPixelOffset); _GlideRoot.environment.aaJitterDisp = GLIDE_FGETENV("FX_GLIDE_AA_JITTERDISP", GC.bInfo->RegPath, 1.0f); GDBG_INFO(80," aaJitterDisp: %f\n",_GlideRoot.environment.aaJitterDisp); /* set rotation for 4xaa */ _GlideRoot.environment.aaGridRotation = GLIDE_FGETENV("FX_GLIDE_AA_GRIDROTATION", GC.bInfo->RegPath, 27.5f) - 27.5f; GDBG_INFO(80," aaGridRotation: %f\n",_GlideRoot.environment.aaGridRotation); _GlideRoot.environment.aaXOffset[6][0] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][1] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][2] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][3] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][4] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][5] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][6] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaXOffset[6][7] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][0] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][1] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][2] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][3] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][4] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][5] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][6] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaYOffset[6][7] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF); /* jcochrane 4 chip offsets * * About: The strange ordering would allow FSAA to still * work regardless of the SLI/Samples per chip configuration */ /* 4chip 2xaa */ _GlideRoot.environment.aaXOffset[7][0] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); // 25 _GlideRoot.environment.aaXOffset[7][1] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); // 75 _GlideRoot.environment.aaXOffset[7][2] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); // 75 _GlideRoot.environment.aaXOffset[7][3] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); // 25 _GlideRoot.environment.aaXOffset[7][4] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); // 25 _GlideRoot.environment.aaXOffset[7][5] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); // 75 _GlideRoot.environment.aaXOffset[7][6] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_DEF); // 75 _GlideRoot.environment.aaXOffset[7][7] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_DEF); // 25 _GlideRoot.environment.aaYOffset[7][0] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); // 25 _GlideRoot.environment.aaYOffset[7][1] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); // 75 _GlideRoot.environment.aaYOffset[7][2] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); // 75 _GlideRoot.environment.aaYOffset[7][3] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); // 25 _GlideRoot.environment.aaYOffset[7][4] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); // 25 _GlideRoot.environment.aaYOffset[7][5] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); // 75 _GlideRoot.environment.aaYOffset[7][6] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_DEF); // 75 _GlideRoot.environment.aaYOffset[7][7] = GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_DEF); // 25 /* 4chip 4xaa */ _GlideRoot.environment.aaXOffset[8][0] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_DEF); // 375 _GlideRoot.environment.aaXOffset[8][1] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_DEF); _GlideRoot.environment.aaXOffset[8][2] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_DEF); // 875 _GlideRoot.environment.aaXOffset[8][3] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_DEF); _GlideRoot.environment.aaXOffset[8][4] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_DEF); // 125 _GlideRoot.environment.aaXOffset[8][5] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_DEF); _GlideRoot.environment.aaXOffset[8][6] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_DEF); // 625 _GlideRoot.environment.aaXOffset[8][7] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_DEF); _GlideRoot.environment.aaYOffset[8][0] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP0_DEF); // 125 _GlideRoot.environment.aaYOffset[8][1] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[8][2] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP0_DEF); // _GlideRoot.environment.aaYOffset[8][3] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[8][4] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[8][5] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CHP0_DEF); _GlideRoot.environment.aaYOffset[8][6] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[8][7] = GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CHP0_DEF); /* these are the old offsets */ /* 4chip 2xaa _GlideRoot.environment.aaXOffset[7][0] = 0x04; _GlideRoot.environment.aaXOffset[7][1] = 0x00; _GlideRoot.environment.aaXOffset[7][2] = 0x0c; _GlideRoot.environment.aaXOffset[7][3] = 0x00; _GlideRoot.environment.aaXOffset[7][4] = 0x04; _GlideRoot.environment.aaXOffset[7][5] = 0x00; _GlideRoot.environment.aaXOffset[7][6] = 0x0c; _GlideRoot.environment.aaXOffset[7][7] = 0x00; _GlideRoot.environment.aaYOffset[7][0] = 0x04; _GlideRoot.environment.aaYOffset[7][1] = 0x00; _GlideRoot.environment.aaYOffset[7][2] = 0x0c; _GlideRoot.environment.aaYOffset[7][3] = 0x00; _GlideRoot.environment.aaYOffset[7][4] = 0x04; _GlideRoot.environment.aaYOffset[7][5] = 0x00; _GlideRoot.environment.aaYOffset[7][6] = 0x0c; _GlideRoot.environment.aaYOffset[7][7] = 0x00; */ /* 4chip 4xaa _GlideRoot.environment.aaXOffset[8][0] = 0x06; _GlideRoot.environment.aaXOffset[8][1] = 0x00; _GlideRoot.environment.aaXOffset[8][2] = 0x0e; _GlideRoot.environment.aaXOffset[8][3] = 0x00; _GlideRoot.environment.aaXOffset[8][4] = 0x02; _GlideRoot.environment.aaXOffset[8][5] = 0x00; _GlideRoot.environment.aaXOffset[8][6] = 0x0a; _GlideRoot.environment.aaXOffset[8][7] = 0x00; _GlideRoot.environment.aaYOffset[8][0] = 0x02; _GlideRoot.environment.aaYOffset[8][1] = 0x00; _GlideRoot.environment.aaYOffset[8][2] = 0x06; _GlideRoot.environment.aaYOffset[8][3] = 0x00; _GlideRoot.environment.aaYOffset[8][4] = 0x0a; _GlideRoot.environment.aaYOffset[8][5] = 0x00; _GlideRoot.environment.aaYOffset[8][6] = 0x0e; _GlideRoot.environment.aaYOffset[8][7] = 0x00; */ /* 4chip 8xaa */ #if 0 _GlideRoot.environment.aaXOffset[9][0] = 0x06; _GlideRoot.environment.aaXOffset[9][1] = 0x04; _GlideRoot.environment.aaXOffset[9][2] = 0x0e; _GlideRoot.environment.aaXOffset[9][3] = 0x0a; _GlideRoot.environment.aaXOffset[9][4] = 0x02; _GlideRoot.environment.aaXOffset[9][5] = 0x0c; _GlideRoot.environment.aaXOffset[9][6] = 0x0a; _GlideRoot.environment.aaXOffset[9][7] = 0x06; _GlideRoot.environment.aaYOffset[9][0] = 0x02; _GlideRoot.environment.aaYOffset[9][1] = 0x06; _GlideRoot.environment.aaYOffset[9][2] = 0x06; _GlideRoot.environment.aaYOffset[9][3] = 0x04; _GlideRoot.environment.aaYOffset[9][4] = 0x0a; _GlideRoot.environment.aaYOffset[9][5] = 0x0a; _GlideRoot.environment.aaYOffset[9][6] = 0x0e; _GlideRoot.environment.aaYOffset[9][7] = 0x0c; #else _GlideRoot.environment.aaXOffset[9][0] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP0_DEF); _GlideRoot.environment.aaXOffset[9][1] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP0_DEF); _GlideRoot.environment.aaXOffset[9][2] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP1_DEF); _GlideRoot.environment.aaXOffset[9][3] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP1_DEF); _GlideRoot.environment.aaXOffset[9][4] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X4", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP2_DEF); _GlideRoot.environment.aaXOffset[9][5] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X5", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP2_DEF); _GlideRoot.environment.aaXOffset[9][6] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X6", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP3_DEF); _GlideRoot.environment.aaXOffset[9][7] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X7", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP3_DEF); _GlideRoot.environment.aaYOffset[9][0] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP0_DEF); _GlideRoot.environment.aaYOffset[9][1] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP0_DEF); _GlideRoot.environment.aaYOffset[9][2] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[9][3] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP1_DEF); _GlideRoot.environment.aaYOffset[9][4] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y4", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP2_DEF); _GlideRoot.environment.aaYOffset[9][5] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y5", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP2_DEF); _GlideRoot.environment.aaYOffset[9][6] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y6", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP3_DEF); _GlideRoot.environment.aaYOffset[9][7] = GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y7", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP3_DEF); #endif /* jcochrane 4 chip offsets * Not any more, now they are Colourless offsets * * About: The strange ordering would allow FSAA to still * work regardless of the SLI/Samples per chip configuration */ /* these are the correct jitter vaules */ /* 4chip 2xaa */ /* set pixel center offset for 2xaa */ _GlideRoot.environment.aaPixelOffset = GLIDE_FGETENV("FX_GLIDE_AA_PIXELCENTER", GC.bInfo->RegPath, 0.25f); GDBG_INFO(80," aaPixelOffset: %f\n",_GlideRoot.environment.aaPixelOffset); /* set jitter dispersity for 2xaa */ _GlideRoot.environment.aaJitterDisp = GLIDE_FGETENV("FX_GLIDE_AA_JITTERDISP", GC.bInfo->RegPath, 1.125f); GDBG_INFO(80," aaJitterDisp: %f\n",_GlideRoot.environment.aaJitterDisp); /* set rotation for 2xaa */ _GlideRoot.environment.aaGridRotation = GLIDE_FGETENV("FX_GLIDE_AA_GRIDROTATION", GC.bInfo->RegPath, 45.0f) - 45.0f; GDBG_INFO(80," aaGridRotation: %f\n",_GlideRoot.environment.aaGridRotation); _GlideRoot.environment.aaXOffset[10][0] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaXOffset[10][1] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaXOffset[10][2] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaXOffset[10][3] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaXOffset[10][4] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaXOffset[10][5] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaXOffset[10][6] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaXOffset[10][7] = GLIDE_34GETENV_X("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaYOffset[10][0] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaYOffset[10][1] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaYOffset[10][2] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaYOffset[10][3] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaYOffset[10][4] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); // 25 _GlideRoot.environment.aaYOffset[10][5] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaYOffset[10][6] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X1", "FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_2SMPL_CORRECT_DEF, SECBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_2SMPL_CORRECT_DEF); // 75 _GlideRoot.environment.aaYOffset[10][7] = GLIDE_34GETENV_Y("FX_GLIDE_AA2_OFFSET_X0", "FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_2SMPL_CORRECT_DEF, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA2_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_2SMPL_CORRECT_DEF); // 25 /* 4chip 4xaa */ /* set pixel center offset for 4xaa */ _GlideRoot.environment.aaPixelOffset = GLIDE_FGETENV("FX_GLIDE_AA_PIXELCENTER", GC.bInfo->RegPath, 0.1875f); GDBG_INFO(80," aaPixelOffset: %f\n",_GlideRoot.environment.aaPixelOffset); /* set jitter dispersity for 4xaa */ _GlideRoot.environment.aaJitterDisp = GLIDE_FGETENV("FX_GLIDE_AA_JITTERDISP", GC.bInfo->RegPath, 1.0f); GDBG_INFO(80," aaJitterDisp: %f\n",_GlideRoot.environment.aaJitterDisp); /* set rotation for 4xaa */ _GlideRoot.environment.aaGridRotation = GLIDE_FGETENV("FX_GLIDE_AA_GRIDROTATION", GC.bInfo->RegPath, 27.5f) - 27.5f; GDBG_INFO(80," aaGridRotation: %f\n",_GlideRoot.environment.aaGridRotation); _GlideRoot.environment.aaXOffset[11][0] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CORRECT_CHP0_DEF); // 375 _GlideRoot.environment.aaXOffset[11][1] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CORRECT_CHP1_DEF); _GlideRoot.environment.aaXOffset[11][2] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CORRECT_CHP0_DEF); // 875 _GlideRoot.environment.aaXOffset[11][3] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CORRECT_CHP1_DEF); _GlideRoot.environment.aaXOffset[11][4] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CORRECT_CHP1_DEF); // 125 _GlideRoot.environment.aaXOffset[11][5] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CORRECT_CHP0_DEF); _GlideRoot.environment.aaXOffset[11][6] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CORRECT_CHP1_DEF); // 625 _GlideRoot.environment.aaXOffset[11][7] = GLIDE_34GETENV_X("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CORRECT_CHP0_DEF); _GlideRoot.environment.aaYOffset[11][0] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CORRECT_CHP0_DEF); // 125 _GlideRoot.environment.aaYOffset[11][1] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CORRECT_CHP1_DEF); _GlideRoot.environment.aaYOffset[11][2] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CORRECT_CHP0_DEF); // _GlideRoot.environment.aaYOffset[11][3] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CORRECT_CHP1_DEF); _GlideRoot.environment.aaYOffset[11][4] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X2", "FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CORRECT_CHP1_DEF); _GlideRoot.environment.aaYOffset[11][5] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X0", "FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_4SMPL_CORRECT_CHP0_DEF); _GlideRoot.environment.aaYOffset[11][6] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X3", "FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CORRECT_CHP1_DEF); _GlideRoot.environment.aaYOffset[11][7] = GLIDE_34GETENV_Y("FX_GLIDE_AA4_OFFSET_X1", "FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_4SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_4SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA4_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_4SMPL_CORRECT_CHP0_DEF); /* 4chip 8xaa */ /* set pixel center offset for 8xaa */ _GlideRoot.environment.aaPixelOffset = GLIDE_FGETENV("FX_GLIDE_AA_PIXELCENTER", GC.bInfo->RegPath, 0.1875f); GDBG_INFO(80," aaPixelOffset: %f\n",_GlideRoot.environment.aaPixelOffset); /* set jitter dispersity for 8xaa */ _GlideRoot.environment.aaJitterDisp = GLIDE_FGETENV("FX_GLIDE_AA_JITTERDISP", GC.bInfo->RegPath, 1.0f); GDBG_INFO(80," aaJitterDisp: %f\n",_GlideRoot.environment.aaJitterDisp); /* set rotation for 8xaa */ _GlideRoot.environment.aaGridRotation = GLIDE_FGETENV("FX_GLIDE_AA_GRIDROTATION", GC.bInfo->RegPath, 27.5f) - 27.5f; GDBG_INFO(80," aaGridRotation: %f\n",_GlideRoot.environment.aaGridRotation); _GlideRoot.environment.aaXOffset[12][0] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X0", "FX_GLIDE_AA8_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X0", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][1] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X1", "FX_GLIDE_AA8_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X1", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][2] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X2", "FX_GLIDE_AA8_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X2", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][3] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X3", "FX_GLIDE_AA8_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X3", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][4] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X4", "FX_GLIDE_AA8_OFFSET_Y4", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP2_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP2_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X4", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP2_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][5] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X5", "FX_GLIDE_AA8_OFFSET_Y5", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP2_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP2_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X5", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP2_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][6] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X6", "FX_GLIDE_AA8_OFFSET_Y6", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP3_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP3_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X6", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP3_CORRECT_DEF); _GlideRoot.environment.aaXOffset[12][7] = GLIDE_34GETENV_X("FX_GLIDE_AA8_OFFSET_X7", "FX_GLIDE_AA8_OFFSET_Y7", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP3_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP3_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_X7", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP3_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][0] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X0", "FX_GLIDE_AA8_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP0_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y0", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][1] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X1", "FX_GLIDE_AA8_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP0_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP0_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y1", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP0_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][2] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X2", "FX_GLIDE_AA8_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP1_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y2", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][3] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X3", "FX_GLIDE_AA8_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP1_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP1_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y3", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP1_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][4] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X4", "FX_GLIDE_AA8_OFFSET_Y4", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP2_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP2_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y4", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP2_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][5] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X5", "FX_GLIDE_AA8_OFFSET_Y5", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP2_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP2_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y5", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP2_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][6] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X6", "FX_GLIDE_AA8_OFFSET_Y6", GC.bInfo->RegPath, PRIBUFVTXOFFX_8SMPL_CHP3_CORRECT_DEF, PRIBUFVTXOFFY_8SMPL_CHP3_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y6", GC.bInfo->RegPath, PRIBUFVTXOFFY_8SMPL_CHP3_CORRECT_DEF); _GlideRoot.environment.aaYOffset[12][7] = GLIDE_34GETENV_Y("FX_GLIDE_AA8_OFFSET_X7", "FX_GLIDE_AA8_OFFSET_Y7", GC.bInfo->RegPath, SECBUFVTXOFFX_8SMPL_CHP3_CORRECT_DEF, SECBUFVTXOFFY_8SMPL_CHP3_CORRECT_DEF);//GLIDE_34GETENV("FX_GLIDE_AA8_OFFSET_Y7", GC.bInfo->RegPath, SECBUFVTXOFFY_8SMPL_CHP3_CORRECT_DEF); /* * AJB- Support the slightly silly way the DirectX gang controls * SLI & AA from the 3dfx tools control panel, just to make * life a little easier for Reid. * * Here is a breakdown of the bizarre table of magic numbers: * * 0 - SLI & AA disable * 1 - SLI disabled, 2 sample AA enabled * 2 - 2-way SLI enabled, AA disabled * 3 - 2-way SLI enabled, 2 sample AA enabled * 4 - SLI disabled, 4 sample AA enabled * 5 - 4-way SLI enabled, AA disabled * 6 - 4-way SLI enabled, 2 sample AA enabled * 7 - 2-way SLI enabled, 4 sample AA enabled * 8 - SLI disabled, 8 sample AA enabled * * to add to the silliness: * * settings 0 & 1 are valid for all configurations * settings 2, 3 & 4 are valid for 2 chip boards only * settings 5, 6 & 7 are valid for 4 chip boards only * * to make life easier on everyone, we won't enforce the board * type restriction and we will default to use whatever SLI * is available with no AA if the variable cannot be found. */ _GlideRoot.environment.forceSingleChip = 0 ; _GlideRoot.environment.aaSample = 0 ; switch(GLIDE_GETENV("SSTH3_SLI_AA_CONFIGURATION", GC.bInfo->RegPath, 2L)) { case 1: _GlideRoot.environment.aaSample = 2 ; case 0: _GlideRoot.environment.forceSingleChip = 1 ; break ; case 3: case 6: _GlideRoot.environment.aaSample = 2 ; break ; case 4: case 7: _GlideRoot.environment.aaSample = 4 ; break; //8xaa case 8: _GlideRoot.environment.aaSample = 8 ; break ; default: break ; } /* ** AJB- This lets Joe bag-o-donuts force 32bpp & AA rendering ** for apps that call grSstWinOpen. */ _GlideRoot.environment.outputBpp = GLIDE_GETENV("FX_GLIDE_BPP", GC.bInfo->RegPath, 0L); /* check for a valid value */ if(_GlideRoot.environment.outputBpp != 32 || _GlideRoot.environment.outputBpp != 15) { _GlideRoot.environment.outputBpp = 0; } /* Note- If the old school Glide env. vars for AA sample & Num chips * are active, they should ALWAYS override the control panel variable */ if (GETENV("FX_GLIDE_AA_SAMPLE", GC.bInfo->RegPath)) _GlideRoot.environment.aaSample = atol(GETENV("FX_GLIDE_AA_SAMPLE", GC.bInfo->RegPath)) ; if (GLIDE_GETENV("FX_GLIDE_NUM_CHIPS", GC.bInfo->RegPath, 0L) > 1) _GlideRoot.environment.forceSingleChip = 0 ; /* ** CHD - This let's Joe bag-o-croissant force rendering-column width. */ _GlideRoot.environment.columnWidth = GLIDE_GETENV("FX_GLIDE_COLUMN_WIDTH", GC.bInfo->RegPath, 32L) ; /* * AJB- This lets those lucky people with non-flaky SLI slave chips * enable the WAX functions that cause us unlucky folks to hang. */ _GlideRoot.environment.waxon = GLIDE_GETENV("FX_GLIDE_WAX_ON", GC.bInfo->RegPath, 1L) ; /* * KCD- Let user toggle AA on and off on the fly to impress their friends. */ _GlideRoot.environment.aaToggleKey = GLIDE_GETENV("FX_GLIDE_AA_TOGGLE_KEY", GC.bInfo->RegPath, 0L) ; /* Save off 32-bit screenshots from four-sample 16-bit AA buffers */ _GlideRoot.environment.aaScreenshotKey = GLIDE_GETENV("FX_GLIDE_SCREENSHOT_KEY", GC.bInfo->RegPath, 0L) ; /* Which way to do 2-sample AA? */ _GlideRoot.environment.forceOldAA = GLIDE_GETENV("FX_GLIDE_FORCE_OLD_AA", GC.bInfo->RegPath, 0L); /* * AJB- 1= Always analog sli, 0= Glide decides, -1= always digital */ _GlideRoot.environment.analogSli = GLIDE_GETENV("FX_GLIDE_ANALOG_SLI", GC.bInfo->RegPath, 0L) ; _GlideRoot.environment.lodBias = GLIDE_GETENV("FX_GLIDE_LOD_BIAS", GC.bInfo->RegPath, 0L) ; /****************************************************************** * 5/4/99 gregk * Adding user support for turning on/off dither substraction * According to Alpha Blending Quality Tab of control panel choices * Optimal/Sharper -> disable dither subtraction * Smoother -> enable dither subtraction ******************************************************************/ ditherMode = GLIDE_GETENV("SSTH3_ALPHADITHERMODE", GC.bInfo->RegPath, 1L); switch(ditherMode) { default: case OPTIMAL: /* Or Automatic? */ case SHARPER: _GlideRoot.environment.disableDitherSub = FXTRUE; break; case SMOOTHER: _GlideRoot.environment.disableDitherSub = FXFALSE; break; } GDBG_INFO(80," disableDitherSub: %d\n",_GlideRoot.environment.disableDitherSub); _GlideRoot.environment.texLodDither = GLIDE_GETENV("FX_GLIDE_LOD_DITHER", GC.bInfo->RegPath, 0L) ? SST_TLODDITHER : 0; GDBG_INFO(80," texLodDither: %d\n",_GlideRoot.environment.texLodDither); _GlideRoot.environment.texSubLodDither = GLIDE_GETENV("FX_GLIDE_LOD_SUBSAMPLE_DITHER", GC.bInfo->RegPath, 1L) ; GDBG_INFO(80," texSubLodDither: %d\n",_GlideRoot.environment.texSubLodDither ); /* Allows us to use the OpenGL LFBLock hack to get around the double lock */ _GlideRoot.environment.oglLfbLockHack = GLIDE_GETENV("FX_GL_LFBLOCK_HACK", GC.bInfo->RegPath, 1L) ; GDBG_INFO(80," oglLfbLockHack: %d\n",_GlideRoot.environment.oglLfbLockHack ); /* 0 = None (default), 1 = grLfbReadRegion(), 2 = grLfbLock(), 3 = Both */ _GlideRoot.environment.useHwcAAforLfbRead = GLIDE_GETENV("FX_GLIDE_USE_HWC_AA_FOR_LFB_READ", GC.bInfo->RegPath, 0L) ; GDBG_INFO(80," useHwcAAforLfbRead: %d\n",_GlideRoot.environment.useHwcAAforLfbRead ); /* 0 = No dithering when doing HWC AA dumps, 1 = error diffusion dithering enabled (default) */ _GlideRoot.environment.ditherHwcAA = GLIDE_GETENV("FX_GLIDE_DITHER_HWC_AA", GC.bInfo->RegPath, 1L) ; GDBG_INFO(80," ditherHwcAA: %d\n",_GlideRoot.environment.ditherHwcAA ); _GlideRoot.environment.nColorBuffer = GLIDE_GETENV("FX_GLIDE_ALLOC_COLOR", GC.bInfo->RegPath, -1L); GDBG_INFO(80," nColorBuffer: %d\n",_GlideRoot.environment.nColorBuffer); _GlideRoot.environment.tmuMemory = GLIDE_GETENV("FX_GLIDE_TMU_MEMSIZE", GC.bInfo->RegPath, -1L); GDBG_INFO(80,"\ttmuMemory: %d\n",_GlideRoot.environment.tmuMemory); _GlideRoot.environment.nAuxBuffer = GLIDE_GETENV("FX_GLIDE_ALLOC_AUX", GC.bInfo->RegPath, -1L); GDBG_INFO(80," nAuxBuffer: %d\n",_GlideRoot.environment.nAuxBuffer); _GlideRoot.environment.swFifoLWM = GLIDE_GETENV("FX_GLIDE_LWM", GC.bInfo->RegPath, -1L); GDBG_INFO(80," swFifoLWM: %d\n",_GlideRoot.environment.swFifoLWM); _GlideRoot.environment.swapInterval = GLIDE_GETENV("FX_GLIDE_SWAPINTERVAL", GC.bInfo->RegPath, -1L); GDBG_INFO(80," swapInterval: %d\n",_GlideRoot.environment.swapInterval); _GlideRoot.environment.snapshot = GLIDE_GETENV("FX_SNAPSHOT", GC.bInfo->RegPath, -1L); GDBG_INFO(80," snapshot: %d\n",_GlideRoot.environment.snapshot); _GlideRoot.environment.guardbandclipping = GLIDE_GETENV("FX_GLIDE_GBC", GC.bInfo->RegPath, 1L); GDBG_INFO(80," guardbandclipping: %d\n",_GlideRoot.environment.guardbandclipping); /* KoolSmoky - enable 2ppc only in certain condition. -1=disable 1=enable 0=glide desides. always enabled. */ _GlideRoot.environment.do2ppc = GLIDE_GETENV("FX_GLIDE_2PPC", GC.bInfo->RegPath, 1L); GDBG_INFO(80," do2ppc : %d\n",_GlideRoot.environment.do2ppc); _GlideRoot.environment.band2ppc = GLIDE_GETENV("FX_GLIDE_2PPC_BAND", GC.bInfo->RegPath, 2L); GDBG_INFO(80," band2ppc : %d\n",_GlideRoot.environment.band2ppc); _GlideRoot.environment.sliBandHeight = GLIDE_GETENV("FX_GLIDE_SLI_BAND_HEIGHT", GC.bInfo->RegPath, 0L); GDBG_INFO(80," sliBandHeight : %d\n",_GlideRoot.environment.sliBandHeight); _GlideRoot.environment.aaClip = GLIDE_GETENV("FX_GLIDE_AA_CLIP", GC.bInfo->RegPath, 1L); GDBG_INFO(80," aaClip : %d\n",_GlideRoot.environment.aaClip); /* KoolSmoky - there is a possibility that grEnable(GR_OPENGL_MODE_EXT) is called once * but grSstSelect is called multiple times, so we won't retreive the sliBandHeightForce * envar if it's already set to openGL app. * Okay, changed the way _GlideInitEnvironment() will be called. will be called only once. if( _GlideRoot.environment.sliBandHeightForce != FXTRUE ) */ _GlideRoot.environment.sliBandHeightForce = GLIDE_GETENV("FX_GLIDE_FORCE_SLI_BAND_HEIGHT", GC.bInfo->RegPath, 0L); GDBG_INFO(80," sliBandHeightForce : %d\n",_GlideRoot.environment.sliBandHeightForce); _GlideRoot.environment.swapPendingCount = GLIDE_GETENV("FX_GLIDE_SWAPPENDINGCOUNT", GC.bInfo->RegPath, 1L); if (_GlideRoot.environment.swapPendingCount > 3) _GlideRoot.environment.swapPendingCount = 3; if (_GlideRoot.environment.swapPendingCount < 0) _GlideRoot.environment.swapPendingCount = 0; GDBG_INFO(80," swapPendingCount : %d\n",_GlideRoot.environment.swapPendingCount); /* KoolSmoky - the default RGB gamma reset to 1.3 */ _GlideRoot.environment.gammaR = GLIDE_FGETENV("SSTH3_RGAMMA", GC.bInfo->RegPath, 1.3f); _GlideRoot.environment.gammaG = GLIDE_FGETENV("SSTH3_GGAMMA", GC.bInfo->RegPath, 1.3f); _GlideRoot.environment.gammaB = GLIDE_FGETENV("SSTH3_BGAMMA", GC.bInfo->RegPath, 1.3f); _GlideRoot.environment.useAppGamma = GLIDE_GETENV("FX_GLIDE_USE_APP_GAMMA", GC.bInfo->RegPath, 1L); /* Get CPU Info */ _cpuid (&_GlideRoot.CPUType); #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* Pass retrieved CPU Info into minihwc */ hwcSetCPUInfo(&_GlideRoot.CPUType); #endif /* Setup the basic proc tables based on the cpu type. */ { //int mmx_3dnow; /* Default case - rasterization routines */ _GlideRoot.deviceArchProcs.curTriProcs = _triSetupProcs + 0; _GlideRoot.deviceArchProcs.curDrawTrisProc = _grDrawTriangles_Default; _GlideRoot.deviceArchProcs.curVertexListProcs = _vertexListProcs[0]; /* Default case - texture download procs */ _GlideRoot.deviceArchProcs.curTexProcs = _texDownloadProcs + 0; /* null proc case */ #define ARRAY_LAST(__array) ((sizeof(__array) / sizeof((__array)[0])) - 1) _GlideRoot.deviceArchProcs.nullTriProcs = _triSetupProcs + ARRAY_LAST(_triSetupProcs); _GlideRoot.deviceArchProcs.nullDrawTrisProc = _grDrawTriangles_null; _GlideRoot.deviceArchProcs.nullVertexListProcs = _vertexListProcs[ARRAY_LAST(_vertexListProcs)]; _GlideRoot.deviceArchProcs.nullTexProcs = _texDownloadProcs + ARRAY_LAST(_texDownloadProcs); #undef ARRAY_LAST /* Check for vendor specific optimization cases */ GDBG_INFO( 0," CPU Vendor: %s\n", _GlideRoot.CPUType.v_name); GDBG_INFO(80," MMX Support: %c\n", _GlideRoot.CPUType.os_support&_CPU_FEATURE_MMX ? 'Y' : 'N'); GDBG_INFO(80," SSE Support: %c\n", _GlideRoot.CPUType.os_support&_CPU_FEATURE_SSE ? 'Y' : 'N'); GDBG_INFO(80," SSE2 Support: %c\n", _GlideRoot.CPUType.os_support&_CPU_FEATURE_SSE2 ? 'Y' : 'N'); GDBG_INFO(80," 3DNow Support: %c\n", _GlideRoot.CPUType.os_support&_CPU_FEATURE_3DNOW ? 'Y' : 'N'); GDBG_INFO(80," MMX+ Support: %c\n", _GlideRoot.CPUType.os_support&_CPU_FEATURE_MMXPLUS ? 'Y' : 'N'); GDBG_INFO(80,"3DNow+ Support: %c\n", _GlideRoot.CPUType.os_support&_CPU_FEATURE_3DNOWPLUS ? 'Y' : 'N'); /* No CPU Extensions Allowed */ if (GLIDE_GETENV("FX_GLIDE_NO_CPU_EXTENSIONS", GC.bInfo->RegPath, 0L)) { _GlideRoot.CPUType.feature = _GlideRoot.CPUType.os_support = 0; GDBG_INFO(0,"CPU Extensions disabled\n"); } #if GL_MMX if (_GlideRoot.CPUType.os_support & _CPU_FEATURE_MMX) { /* check for MMX feature */ GDBG_INFO(0,"Using MMX Texture Download Functions\n"); _GlideRoot.deviceArchProcs.curTexProcs = _texDownloadProcs + 2; } #endif /* GL_MMX */ #if GL_SSE if (_GlideRoot.CPUType.os_support & _CPU_FEATURE_SSE) { /* check for SSE FP feature */ GDBG_INFO(0,"Using SSE Geometry Functions\n"); _GlideRoot.deviceArchProcs.curTriProcs = _triSetupProcs + 2; _GlideRoot.deviceArchProcs.curDrawTrisProc = _grDrawTriangles_SSE; _GlideRoot.deviceArchProcs.curVertexListProcs = _vertexListProcs[2]; } #endif /* GL_SSE */ #if GL_AMD3D if (_GlideRoot.CPUType.os_support & _CPU_FEATURE_3DNOW) { /* check for 3DNow! feature */ GDBG_INFO(0,"Using 3DNow! Texture Download Functions\n"); _GlideRoot.deviceArchProcs.curTexProcs = _texDownloadProcs + 1; GDBG_INFO(0,"Using 3DNow! Geometry Functions\n"); _GlideRoot.deviceArchProcs.curTriProcs = _triSetupProcs + 1; _GlideRoot.deviceArchProcs.curDrawTrisProc = _grDrawTriangles_3DNow; _GlideRoot.deviceArchProcs.curVertexListProcs = _vertexListProcs[1]; } #endif /* GL_AMD3D */ #if GL_SSE2 if (_GlideRoot.CPUType.os_support & _CPU_FEATURE_SSE2) { /* check for SSE2 feature */ GDBG_INFO(0,"Using SSE2 Texture Download Functions\n"); _GlideRoot.deviceArchProcs.curTexProcs = _texDownloadProcs + 3; } #endif /* GL_SSE2*/ } #if __POWERPC__ && PCI_BUMP_N_GRIND _GlideRoot.environment.autoBump = FXFALSE; #else _GlideRoot.environment.autoBump = (GETENV("FX_GLIDE_BUMP", GC.bInfo->RegPath) == NULL); _GlideRoot.environment.forceAutoBump = (GETENV("FX_GLIDE_FORCEBUMP", GC.bInfo->RegPath) == NULL); #if CHECK_SLAVE_SWAPCMD _GlideRoot.environment.checkSlaveSwapCMD = GLIDE_GETENV("FX_GLIDE_CHECKSLAVESWAPCMD", GC.bInfo->RegPath, 0L); #endif #if TACO_MEMORY_FIFO_HACK _GlideRoot.environment.memFIFOHack = (GETENV("FX_GLIDE_MEMFIFOHACK", GC.bInfo->RegPath) != NULL); #endif #endif GDBG_INFO(80, "\tautoBump: %s\n", _GlideRoot.environment.autoBump ? "FXTRUE" : "FXFALSE"); if (GETENV("FX_GLIDE_BUMPSIZE", GC.bInfo->RegPath)) sscanf(GETENV("FX_GLIDE_BUMPSIZE", GC.bInfo->RegPath), "%x", &_GlideRoot.environment.bumpSize); else #if __POWERPC__ _GlideRoot.environment.bumpSize = 0x1000; #else _GlideRoot.environment.bumpSize = 0x10000; #endif _GlideRoot.environment.fenceLimit = GLIDE_GETENV("FX_GLIDE_FENCE_LIMIT", GC.bInfo->RegPath, 0x10000); if (_GlideRoot.environment.fenceLimit > 0x10000) _GlideRoot.environment.fenceLimit = 0x10000; /* Pre-convert the bump size from bytes to words */ _GlideRoot.environment.bumpSize >>= 2UL; GDBG_INFO(80, "\tbumpSize: 0x%x\n", _GlideRoot.environment.bumpSize); /* constant pool */ _GlideRoot.pool.f0 = 0.0F; _GlideRoot.pool.fHalf= 0.5F; _GlideRoot.pool.f1 = 1.0F; _GlideRoot.pool.f255 = 255.0F; #if GLIDE_PACKED_RGB _GlideRoot.pool.fBiasHi = (float)(0x01 << 15); _GlideRoot.pool.fBiasLo = (float)(0x01 << 23); #endif /* GLIDE_PACKED_RGB */ /* KoolSmoky - current_sst is not always 0 */ /* _GlideRoot.current_sst = 0; */ /* make sure there's a valid GC */ _GlideRoot.current_sst = ctx; /* dBorca - moved to grGlideInit grErrorSetCallback(_grErrorDefaultCallback); */ /* KoolSmoky - Moved to grGlideInit if ( !_grSstDetectResources() ) { #ifdef GLIDE_INIT_HWC GrErrorCallback( hwcGetErrorString(), FXTRUE ); #endif } */ /* display info for all sst devices */ for (i = 0; i < _GlideRoot.hwConfig.num_sst; i++) { displayBoardInfo(i, &_GlideRoot.hwConfig); } _GlideRoot.initialized = FXTRUE; /* save this for the end */ } /* _GlideInitEnvironment */ #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { switch( ul_reason_for_call ) { case DLL_PROCESS_DETACH: GDBG_INFO(80, "DllMain: DLL_PROCESS_DETACH\n"); grGlideShutdown(); #ifdef GLIDE_INIT_HWC hwcUnmapMemory(); hwcClearContextData(); #endif /* A clear thinking person might assume that this should go * in grGlideShutdown, however Microsoft claims it should * go here in DLL_PROCESS_DETACH... More importantly, moving * this call to here fixes PRS#12190, 12192 and 12196 * (several games that like to do wacky crap with threads). */ freeThreadStorage(); break; case DLL_PROCESS_ATTACH: GDBG_INFO(80, "DllMain: DLL_PROCESS_ATTACH\n"); break; case DLL_THREAD_ATTACH: GDBG_INFO(80, "DllMain: DLL_THREAD_ATTACH\n"); /* If we're in the fullscreen case it is legal to call into glide * from multiple threads, but the application is required to do * their own thread syncronization w/ glide as a single resource. * If we've already checked for the hw and they have called * grSstWinOpen at least once to open a fullscreen context then we * need to attach the current context (eg. the gc) to the current tls. */ if(_GlideRoot.initialized && /* scanned for hw? */ (_GlideRoot.windowsInit > 0)) { /* outstanding fullscreen contexts? */ GR_DCL_GC; /* If there is no current gc in tls then set the current context. */ if (gc == NULL) setThreadValue((FxU32)&_GlideRoot.GCs[_GlideRoot.current_sst]); } break; case DLL_THREAD_DETACH: GDBG_INFO(80, "DllMain: DLL_THREAD_DETACH\n"); break; default: GDBG_INFO(80, "DllMain: Unhandled message.\n"); break; } return TRUE; } /* DllMain */ #endif glide3x/h5/glide3/src/gsfc.c0100700000175300010010000010373207725034670015066 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gsfc.c,v 1.3.4.3 2003/08/21 08:49:55 dborca Exp $ ** $Log: ** 20 3dfx 1.17.1.0.1.010/11/00 Brent Forced check in to enforce ** branching. ** 19 3dfx 1.17.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 18 3dfx 1.17 04/25/00 Adam Briggs Ack: don't clear the lost ** context dword in set rendering surface--it is cleared when the context is ** allocated. ** 17 3dfx 1.16 03/31/00 Adam Briggs Agh! don't EXIT when we ** can't get info on a surface! just set the lost context dword. ** 16 3dfx 1.15 03/31/00 Kenneth Dyke Make sure gc->chipCount is ** set to 1. ** 15 3dfx 1.14 03/24/00 Kenneth Dyke Make sure gc->chipmask has ** all chips enabled. ** 14 3dfx 1.13 03/08/00 Kenneth Dyke Don't cache hardware ** register pointers. ** 13 3dfx 1.12 03/08/00 Kenneth Dyke New use isMapped boardInfo ** flag instead of broken gc flag. ** 12 3dfx 1.11 03/07/00 Don Mullis Generalize glide3 to handle ** sub-byte-size texels. ** ** 11 3dfx 1.10 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 10 3dfx 1.9 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 9 3dfx 1.8 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 8 3dfx 1.7 01/27/00 Adam Briggs if one variable is good, ** two variables are better (as long as they are both initialized) ** 7 3dfx 1.6 11/10/99 Adam Briggs Made grBufferClear(Ext) ** cooperate with linear surfaces & texture buffers ** 6 3dfx 1.5 10/29/99 Adam Briggs set h3pixelSize in ** grSurfaceSetRenderingSurface instead of _grGetSurfaceInfo (to prevent ** problems w/ 16bit textures while 32bit rendering) ** 5 3dfx 1.4 10/08/99 Anthony tai prevent v3 doing ** _grChipMask ** 4 3dfx 1.3 10/07/99 Larry warner Fix ** grSurfaceCalcTextureWHD() so that it supports 32 and 4 bit texture ** formats. ** 3 3dfx 1.2 09/17/99 Anthony tai fixed h3 build ** 2 3dfx 1.1 09/16/99 Anthony tai added 32 bpp rendermode ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 53 8/23/99 3:14p Kcd ** New MacOS 8 surface stuff. ** ** 52 8/20/99 4:56p Atai ** fixed packet4 register bit mask for window glide ** ** 51 8/18/99 4:30p Martin ** Commented out a small bit of broken code. ** ** 50 8/17/99 5:10p Kcd ** Updated Mac surface stuff to newer API. ** ** 49 8/16/99 11:18a Adamb ** Merged in V3_OEM_100 fixes ** ** 48 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 47 7/22/99 8:14p Larryw ** Texture format byte-depth improvements ** ** 46 6/24/99 7:10p Atai ** new grSurfaceSetRenderingSurface interface and use 2 buffers per chip ** ** 45 5/24/99 2:49p Jamesb ** Added ptrLostContext field to exported command transport struct. ** ** 44 4/25/99 1:07p Atai ** undo hwcMapBoard mods when glide create surface context ** ** 43 4/23/99 5:09p Atai ** map board when we create surface context ** ** 42 4/16/99 2:56p Kcd ** MacOS Surface Extensions (temporary). ** ** 41 4/10/99 1:24p Atai ** fixed code to compile in packet fifo mode ** ** 40 4/09/99 4:22p Dow ** Fixes for lost surfaces ** ** 39 3/22/99 9:12a Peter ** cleanup include paths ** ** 38 3/14/99 1:46p Peter ** temp implemntation of my surface extension extension ** ** 37 3/11/99 6:42p Dow ** Resolution help ** ** 36 3/05/99 10:38p Peter ** fixed the surface fifo state race condition (thanks to Ken Dyke) ** ** 35 2/18/99 5:55p Peter ** testing glide_platform has to be after glidesys.h has been included ** ** 34 2/18/99 3:45p Kcd ** Disabled Surface Extensions for non-Win32 platforms. ** ** 33 2/02/99 4:41p Peter ** computation of passed/whd texture surface size, initial/cleanup state ** cleanup, null rendering fix ** ** 32 1/25/99 6:35p Peter ** tiled texture cleanup, don't flush if nothing was written on the ** context release ** ** 31 1/14/99 7:48p Peter ** grSurfaceCaclTextureWHD ** ** 30 1/06/99 11:30a Peter ** cleanup win fifo locking ** ** 29 1/04/99 12:03p Peter ** use window contexts for sending state ** ** 28 12/23/98 2:01p Peter ** nt currently has mutexing problems via ddraw and extescape ** ** 27 12/21/98 3:01p Peter ** cleaned up shutdow semantics ** ** 26 12/14/98 6:19p Dow ** Fixed for current surface extension spec ** ** 25 12/11/98 1:36p Peter ** flush and free fifo when releasing ** ** 24 12/09/98 11:50a Jeske ** fix for static compile... note that static building glide3 still dosn't ** work.. ** ** 23 12/05/98 2:50p Dow ** Added one more case for attach ** ** 22 11/30/98 6:57p Peter ** video memory fifo's ** ** 21 11/17/98 7:06p Atai ** get num tmu from _GlideRoot ** ** 20 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 19 11/09/98 5:07p Dow ** Texturing from tiled rendered surfaces works now ** ** 18 10/30/98 3:45p Dow ** Fixed Tiled/Linear color/aux bug ** ** 17 10/20/98 8:28p Peter ** shared files and fixed whackage ** ** 16 8/30/98 9:20p Wheeler ** Set # color bufs to 2 in windowed mode (makes depth clears work). ** ** 15 8/30/98 9:54a Jdt ** Remove spurious buffer clear from grSurfaceSetRenderingSurface ** ** 14 8/29/98 4:55p Jdt ** Fixed implementation of grSurfaceReleaseSurface ** ** 13 8/06/98 7:50p Dow ** BInfo stuff for SDRAM detection ** ** 12 8/03/98 6:40a Jdt ** multi-thread changes ** ** 11 8/02/98 5:01p Dow ** Glide Surface Extension ** ** 10 7/21/98 10:53a Jdt ** Added retail-build error checking for grSurfaceSetTextureSurface ** ** 9 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 8 7/18/98 10:40a Dow ** TMU Mem ** ** 7 7/18/98 12:28a Jdt ** Fixes for both tiled and linear surface address computation. ** ** 6 7/16/98 10:26p Dow ** moved some stuff down to minihwc & added aux & tex ** ** 5 7/16/98 8:18a Jdt ** fxcmd.h fixed bug in gc heap allocator ** ** 4 7/14/98 10:14a Dow ** indentation ** ** 3 7/13/98 9:57p Jdt ** Added to build. First implementation of SetRenderSurface and ** CreateContext ** ** 2 7/09/98 6:47p Dow ** ** 1 7/09/98 11:37a Dow ** Initial Checkin ** */ /* Surface extension currently only really works on Windows anyway */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #include "rcver.h" #include "gsfc.h" #if (GLIDE_PLATFORM & (GLIDE_OS_WIN32|GLIDE_OS_MACOS)) #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) /* FixMe: dpc - 22 mar 99 * This little bit of stupidity is so that we can get the * various fifo types that the 2d driver knows about. */ #include "..\..\minihwc\hwcext.h" #elif (GLIDE_PLATFORM & GLIDE_OS_MACOS) #include #include #endif /* ** This array is us still twisting around the knives to not allocate ** memory. Surfaces are stored in here if they are presented to ** grSurfaceSetRenderingSurface() with the argument that they are not ** going to be used for texturing surfaces. If they are later used ** for that purpose, we hock up an error. */ #define GSFC_MAX_RENDER_SURFACES 0x400 static FxU32 renderSurfaces[GSFC_MAX_RENDER_SURFACES]; /*------------------------------------------------------------------- Function: grSurfaceCreateContext Date: 09-Jul-98 Implementor(s): dow, taco Description: Create a Glide State Vector and Bind it to a ContextID which is passed back to the application. A glide state vector consists of all persistent hardware state except for the contents of client surfaces ( aux, color, texture ). Arguments: type - surface type - fullscreen or windowed. Windowed is currently the only valid argument Return: An integer naming the new state vector. The context name is used for grSelectContext() -------------------------------------------------------------------*/ /* NOTE: THIS FUNCTION CAN BE CALLED WHEN THERE IS NO VALID GC */ GR_EXT_ENTRY(grSurfaceCreateContext, GrContext_t, ( GrSurfaceContextType_t type ) ) { #define FN_NAME "grSurfaceCreateContext" #ifdef GLIDE_INIT_HWC GrContext_t rv; GrGC *ctx; int i; GDBG_INFO( 80, "%s(0x%X)\n", FN_NAME, type); rv = 0; /* validate */ if ( type != GR_SURFACECONTEXT_WINDOWED ) { GDBG_INFO( 80, "GR_SURFACECONTEXT_FULLSCREEN not yet implemented\n" ); } else { /* Search for a free context */ /* XXX Taco - BEGIN OS SEMAPHORE LOCK */ beginCriticalSection(); for( i = 0; i < MAX_NUM_CONTEXTS; i++ ) { if ( _GlideRoot.surfaceGCHeap[i] == 0 ) { const FxU32 hwcContextId = hwcAllocWinContext(_GlideRoot.GCs[_GlideRoot.current_sst].bInfo); if (hwcContextId == 0x00UL) continue; ctx = &_GlideRoot.surfaceGCs[i]; _GlideRoot.surfaceGCHeap[i] = ctx; ctx->num_tmu = _GlideRoot.GCs[_GlideRoot.current_sst].num_tmu; ctx->bInfo = _GlideRoot.GCs[_GlideRoot.current_sst].bInfo; ctx->chipCount = 1; /* Can only use one chip in windowed mode. */ /* Make sure board has been mapped! */ if(!ctx->bInfo->isMapped) { if (!hwcMapBoard(ctx->bInfo, HWC_BASE_ADDR_MASK)) { GrErrorCallback( FN_NAME": Failed to re-map the hw.", FXFALSE ); return 0; } if (!hwcInitRegisters(ctx->bInfo)) { GrErrorCallback( FN_NAME": Failed to re-initialize the hw.", FXFALSE ); return 0; } } /* Don't assume that because the board was mapped that these didn't change! */ ctx->sstRegs = (SstRegs*)ctx->bInfo->regInfo.sstBase; ctx->ioRegs = (SstIORegs*)ctx->bInfo->regInfo.ioMemBase; ctx->cRegs = (SstCRegs*)ctx->bInfo->regInfo.cmdAGPBase; ctx->lfb_ptr = (FxU32*)ctx->bInfo->regInfo.lfbBase; ctx->rawLfb = (FxU32*)ctx->bInfo->regInfo.rawLfbBase; ctx->tex_ptr = (FxU32*)SST_TEX_ADDRESS(ctx->bInfo->regInfo.sstBase); ctx->winContextId = hwcContextId; /* NULL out context fifo ptr info which gets set on the first * grSurfaceSetXXXSurface call. */ memset(&ctx->cmdTransportInfo, 0, sizeof(ctx->cmdTransportInfo)); ctx->windowed = FXTRUE; rv = (GrContext_t)ctx; hwcShareContextData(ctx->bInfo, &(ctx->lostContext)); ctx->cmdTransportInfo.ptrLostContext = &(ctx->lostContext); *ctx->lostContext = FXFALSE; setThreadValue(rv); break; } } /* XXX Taco - END OS SEMAPHORE LOCK */ endCriticalSection(); } GDBG_INFO(80, "%s() => 0x%x---------------------\n", FN_NAME, rv ); return rv; #else /* !GLIDE_INIT_HWC */ return 0; #endif #undef FN_NAME } /* grSurfaceCreateContext */ /*------------------------------------------------------------------- Function: grSurfaceReleaseContext Date: 09-Jul-98 Implementor(s): dow Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grSurfaceReleaseContext, void , (GrContext_t ctx) ) { #define FN_NAME "grSurfaceReleaseContext" #ifdef GLIDE_INIT_HWC int i; GDBG_INFO( 80, "%s(0x%X)\n", FN_NAME, ctx); /* XXX Taco - BEGIN OS SEMAPHORE LOCK */ beginCriticalSection(); for( i = 0; i < MAX_NUM_CONTEXTS; i++ ) { if (ctx == (GrContext_t)(_GlideRoot.surfaceGCs + i)) { GrGC* gc = (GrGC*)ctx; const struct cmdTransportInfo* fifoInfo = &gc->cmdTransportInfo; /* MDM-Richardson - OpenGL does not call winclose so we will * have to deal with the context close here. */ /* * But on Win98 unmapping the memory doesn't do anything, and * we may have multiple context's open on the same board! If Win98 * actually worked right, this would break every other open * context by yanking out the hardware mapping! %%KCD */ #if (GLIDE_OS & GLIDE_OS_WIN32) if ((_GlideRoot.OS == OS_WIN32_95) || (_GlideRoot.OS == OS_WIN32_98) || (_GlideRoot.OS == OS_WIN32_ME)) hwcUnmapMemory9x ( gc->bInfo ); #endif /* Free any windowed fifo associated w/ the context */ if (fifoInfo->fifoPtr != NULL) { hwcUnlockWinFifo(gc->bInfo, &gc->cmdTransportInfo.hwcFifoInfo); hwcFreeWinFifo(gc->bInfo, &gc->cmdTransportInfo.hwcFifoInfo); } /* Clear the current context info, including selection */ hwcFreeWinContext(gc->bInfo, gc->winContextId); setThreadValue(0x00UL); _GlideRoot.surfaceGCHeap[i] = 0; gc->open = FXFALSE; gc->windowed = FXFALSE; gc->curSurface = NULL; gc->state.shadow.colBufferAddr = gc->state.shadow.colBufferStride = 0x00UL; gc->auxSurface = NULL; gc->state.shadow.auxBufferAddr = gc->state.shadow.auxBufferAddr = 0x00UL; for(i = 0; i < GLIDE_NUM_TMU; i++) { struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + i; gc->texSurface[i] = NULL; memInfo->tramLfbAddr = memInfo->tramOffset = memInfo->tramSize = 0x00UL; } break; } } /* XXX Taco - END OS SEMAPHORE LOCK */ endCriticalSection(); /* This means an invalid context was passed */ GR_ASSERT(i != MAX_NUM_CONTEXTS); #endif #undef FN_NAME } /* grSurfaceReleaseContext */ static FxBool _grSurfaceAttachFifo(GrGC* gc, GrSurface_t sfc) { #define FN_NAME "_grSurfaceAttachFifo" #ifdef GLIDE_INIT_HWC struct cmdTransportInfo* gcFifo = &gc->cmdTransportInfo; FxBool retVal = FXFALSE; GDBG_INFO(80, FN_NAME "(%x, %x)\n", gc, sfc); if (gcFifo->hwcFifoInfo.fifoType == HWCEXT_FIFO_INVALID) { /* Fallback fifo setup. */ gcFifo->hwcFifoInfo.cmdBuf.baseAddr = (FxU32)&gcFifo->windowedFifo; gcFifo->hwcFifoInfo.cmdBuf.allocUnit = sizeof(gcFifo->windowedFifo); gcFifo->hwcFifoInfo.stateBuf.baseAddr = (FxU32)&gcFifo->windowedState; gcFifo->hwcFifoInfo.stateBuf.allocUnit = sizeof(gcFifo->windowedState); GR_WINFIFO_BEGIN(); { retVal = hwcAllocWinFifo(gc->bInfo, &gcFifo->hwcFifoInfo, sfc); if (retVal) hwcLockWinFifo(gc->bInfo, &gc->cmdTransportInfo.hwcFifoInfo); } GR_WINFIFO_END(); if (!retVal) goto __errFifoAlloc; /* Intial fifo state stuff */ gcFifo->fifoStart = (FxU32*)gcFifo->hwcFifoInfo.cmdBuf.baseAddr; gcFifo->fifoSize = gc->cmdTransportInfo.hwcFifoInfo.cmdBuf.size; gcFifo->fifoEnd = (FxU32*)((FxU8*)gcFifo->fifoStart + gcFifo->fifoSize); /* Set the pointer for the state buffer */ gcFifo->stateBuffer = (GrStateBuffer*)gc->cmdTransportInfo.hwcFifoInfo.stateBuf.baseAddr; /* Checking frequencies are based on the allocation unit of the fifo */ gcFifo->fifoPtr = gcFifo->fifoStart; gcFifo->fifoRoom = gcFifo->hwcFifoInfo.cmdBuf.allocUnit - FIFO_END_ADJUST; /* Make sure we don't ever do bump & grind stuff with surface FIFOs. */ gcFifo->autoBump = FXTRUE; /* Starting from the first command buffer */ gcFifo->curCommandBuf = 0x00UL; gcFifo->numQueuedBuf = 0x01UL; gcFifo->numCommandBuf = (gcFifo->hwcFifoInfo.cmdBuf.size / gcFifo->hwcFifoInfo.cmdBuf.allocUnit); /* Set default state */ #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); gc->chipmask = SST_CHIP_MASK_ALL_CHIPS; } #endif initGC(gc); assertDefaultState(); #ifdef FX_GLIDE_NAPALM if (gc->bInfo->h3pixelSize == 4) _grRenderMode(GR_PIXFMT_ARGB_8888); #endif gc->state.shadow.fbzMode = ( SST_ENRECTCLIP | SST_ENZBIAS ); gc->state.shadow.colBufferAddr = gc->state.shadow.colBufferStride = gc->state.shadow.auxBufferAddr = gc->state.shadow.auxBufferStride = 0x00UL; /* For performance reasons, the hardware-visible state buffer must be stored in little endian format. Ask KCD for details. */ #if __POWERPC__ { FxU32 *src, *dst, i; src = (FxU32 *)&gc->state.shadow; dst = (FxU32 *)gcFifo->stateBuffer; for(i = 0; i < (sizeof(GrStateBuffer)/sizeof(FxU32)); i++) { SET(*dst++,*src++); } } #else /* !__POWERPC__ */ memcpy(gcFifo->stateBuffer, &gc->state.shadow, sizeof(GrStateBuffer)); #endif retVal = FXTRUE; } __errFifoAlloc: ; return retVal; #else return FXFALSE; #endif #undef FN_NAME } /* _grSurfaceAttachFifo */ #ifdef GLIDE_INIT_HWC static FxBool _grGetSurfaceInfo(GrGC* gc, GrSurface_t sfc, hwcSurfaceInfo* sfcInfo) { #define FN_NAME "grGetSurfaceInfo" FxBool surfInfoP; GR_WINFIFO_BEGIN(); { surfInfoP = hwcGetSurfaceInfo(gc->bInfo, (FxU32*)sfc, sfcInfo); if (!surfInfoP) { GDBG_INFO(0, FN_NAME ": hwcGetSurfaceInfo Failed.\n"); *gc->lostContext = TRUE ; } _grSurfaceAttachFifo(gc, sfc); } GR_WINFIFO_END(); return surfInfoP; } #undef FN_NAME #endif /*------------------------------------------------------------------- Function: grSurfaceSetRenderingSurface Date: 09-Jul-98 Implementor(s): dow Description: Attaches a rendering surface to the context. Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grSurfaceSetRenderingSurface, void , (GrSurface_t sfc, FxBool textureP) ) { #define FN_NAME "grSurfaceSetRenderingSurface" #ifdef GLIDE_INIT_HWC FxU32 _colBufferAddr = 0x00UL, _colBufferStride = 0x00UL; hwcSurfaceInfo sfcInfo; GR_DCL_GC; GR_DCL_HW; GR_DEBUG_DCL(FN_NAME, 180); FXUNUSED(hw); if (!gc) return; /*GR_BEGIN_NOFIFOCHECK(FN_NAME, 80);*/ GDBG_INFO_MORE(gc->myLevel, "(0x%X)\n", sfc); if (!gc->windowed) return; if (sfc == 0x00UL) goto __errNullSurface; if (!_grGetSurfaceInfo(gc, sfc, &sfcInfo)) { GDBG_INFO(80, "%s: Could not get surface info.\n", FN_NAME); GDBG_INFO(80, "\t%s\n", hwcGetErrorString()); return; } GDBG_INFO(180, "%s: sfcInfo:\n", FN_NAME); GDBG_INFO(180, " tileBase: 0x%x\n", sfcInfo.tileBase); GDBG_INFO(180, " lpLFB: 0x%x\n", sfcInfo.lpLFB); GDBG_INFO(180, " lpSurface: 0x%x\n", sfcInfo.lpSurface); GDBG_INFO(180, " pciStride: 0x%x\n", sfcInfo.pciStride); GDBG_INFO(180, " hwStride: 0x%x\n", sfcInfo.hwStride); GDBG_INFO(180, " isTiled: 0x%x\n", sfcInfo.isTiled); GDBG_INFO(180, " width: 0x%x\n", sfcInfo.width); GDBG_INFO(180, " height: 0x%x\n", sfcInfo.height); GDBG_INFO(180, " fbOffset: 0x%x\n", sfcInfo.fbOffset); gc->grPixelSize = gc->bInfo->h3pixelSize = sfcInfo.bitdepth / 8; gc->grPixelSample = 1 ; #ifdef FX_GLIDE_NAPALM if (gc->bInfo->h3pixelSize == 4) _grRenderMode(GR_PIXFMT_ARGB_8888); #if (GLIDE_OS & GLIDE_OS_MACOS) else _grRenderMode(GR_PIXFMT_ARGB_1555); #endif #endif #ifdef GDBG_INFO_ON hwcCheckTarget(sfcInfo.fbOffset, sfcInfo.width, sfcInfo.height, sfcInfo.bitdepth, 0x1000000, 0 ); #endif gc->colTiled = sfcInfo.isTiled ; // AJB- grBufferClear needs to know this if ( !sfcInfo.isTiled ) { /* NB: Banshee (and derivatives) have a 16-byte alignment * restriction on the stride and offset for color/aux buffers, but * it is left to the client to correctly adjust for this when * setting the values. */ GR_ASSERT((sfcInfo.fbOffset & 0x0FUL) == 0x00UL); GR_ASSERT((sfcInfo.fbStride & 0x0FUL) == 0x00UL); } #if 0 if (!textureP) { int i = 0; FxBool slotFound = FXFALSE; do { if (renderSurfaces[i] == 0) { renderSurfaces[i] = (FxU32) sfc; slotFound = FXTRUE; } i++; } while (i < GSFC_MAX_RENDER_SURFACES && !slotFound); if (!slotFound) _doGrErrorCallback("SURFACE", "Max Surfaces exceeded!", FXTRUE); } #endif _colBufferAddr = sfcInfo.fbOffset; _colBufferStride = sfcInfo.fbStride; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 2, 0x3); { REG_GROUP_SET(hw, colBufferAddr, _colBufferAddr ); REG_GROUP_SET(hw, colBufferStride, _colBufferStride ); } REG_GROUP_END(); GDBG_INFO(80, "%s: width = %d\n", FN_NAME, sfcInfo.width); GDBG_INFO(80, "%s: height = %d\n", FN_NAME, sfcInfo.height); gc->state.wClipping.colClip.width = sfcInfo.width; gc->state.wClipping.colClip.height = sfcInfo.height; gc->state.wClipping.colBufferSet = FXTRUE; /* NB: This will modify the clipped width */ grClipWindow(0, 0, sfcInfo.width, sfcInfo.height); grViewport(0, 0, gc->state.wClipping.winClip.width, gc->state.wClipping.winClip.height); gc->grColBuf = ((sfc != 0x00UL) << 0x01UL); gc->curSurface = sfc; gc->buffers0[0] = gc->buffers0[1] = _colBufferAddr; gc->state.shadow.colBufferAddr = _colBufferAddr; gc->state.shadow.colBufferStride = _colBufferStride; __errNullSurface: if (sfc == 0x00UL) gc->state.wClipping.colBufferSet = FXFALSE; GDBG_INFO(180, "%s: _colBufferAddr = 0x%x\n", FN_NAME, _colBufferAddr); GDBG_INFO(180, "%s: _colBufferStride = 0x%x\n", FN_NAME, _colBufferStride); GR_END(); #endif #undef FN_NAME } /* grSurfaceSetRenderingSurface */ /*------------------------------------------------------------------- Function: grSurfaceSetAuxSurface Date: 09-Jul-98 Implementor(s): dow Description: Attaches an aux buffer surface to the context. Note that this surface is a DirectDraw surface in the windowed case, and a Glide surface in the full-screen case. Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grSurfaceSetAuxSurface, void , (GrSurface_t sfc) ) { #define FN_NAME "grSurfaceSetAuxSurface" #ifdef GLIDE_INIT_HWC FxU32 _auxBufferAddr = 0x00UL, _auxBufferStride = 0x00UL; hwcSurfaceInfo sfcInfo; GR_BEGIN_NOFIFOCHECK(FN_NAME, 80); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", sfc); if (!gc->windowed) return; if (sfc == 0x00UL) goto __errNullSurface; if (!_grGetSurfaceInfo(gc, sfc, &sfcInfo)) { GDBG_INFO(80, "%s: Could not get surface info.\n", FN_NAME); GDBG_INFO(80, "\t%s\n", hwcGetErrorString()); return; } GDBG_INFO(180, "%s: sfcInfo:\n", FN_NAME); GDBG_INFO(180, " tileBase: 0x%x\n", sfcInfo.tileBase); GDBG_INFO(180, " lpLFB: 0x%x\n", sfcInfo.lpLFB); GDBG_INFO(180, " lpSurface: 0x%x\n", sfcInfo.lpSurface); GDBG_INFO(180, " pciStride: 0x%x\n", sfcInfo.pciStride); GDBG_INFO(180, " hwStride: 0x%x\n", sfcInfo.hwStride); GDBG_INFO(180, " isTiled: 0x%x\n", sfcInfo.isTiled); GDBG_INFO(180, " width: 0x%x\n", sfcInfo.width); GDBG_INFO(180, " height: 0x%x\n", sfcInfo.height); #ifdef GDBG_INFO_ON hwcCheckTarget(sfcInfo.fbOffset, sfcInfo.width, sfcInfo.height, sfcInfo.bitdepth, 0x1000000, 0 ); #endif gc->auxTiled = sfcInfo.isTiled ; // AJB- grBufferClear needs to know this if ( !sfcInfo.isTiled ) { /* NB: Banshee (and derivatives) have a 16-byte alignment * restriction on the stride and offset for color/aux buffers, but * it is left to the client to correctly adjust for this when * setting the values. */ GR_ASSERT((sfcInfo.fbOffset & 0x0FUL) == 0x00UL); GR_ASSERT((sfcInfo.fbStride & 0x0FUL) == 0x00UL); } _auxBufferAddr = sfcInfo.fbOffset; _auxBufferStride = sfcInfo.fbStride; REG_GROUP_BEGIN(BROADCAST_ID, auxBufferAddr, 2, 0x3); REG_GROUP_SET(hw, auxBufferAddr, _auxBufferAddr ); REG_GROUP_SET(hw, auxBufferStride, _auxBufferStride ); REG_GROUP_END(); GDBG_INFO(80, "%s: width = %d\n", FN_NAME, sfcInfo.width); GDBG_INFO(80, "%s: height = %d\n", FN_NAME, sfcInfo.height); gc->state.screen_width = sfcInfo.width; gc->state.screen_height = sfcInfo.height; gc->state.wClipping.auxClip.width = sfcInfo.width; gc->state.wClipping.auxClip.height = sfcInfo.height; gc->state.wClipping.auxBufferSet = FXTRUE; /* NB: This will modify the clipped width */ grClipWindow(0, 0, sfcInfo.width, sfcInfo.height); grViewport(0, 0, gc->state.wClipping.auxClip.width, gc->state.wClipping.auxClip.height); __errNullSurface: if (sfc == 0L) gc->state.wClipping.colBufferSet = FXFALSE; GDBG_INFO(180, "%s: _auxBufferAddr = 0x%x\n", FN_NAME, _auxBufferAddr); GDBG_INFO(180, "%s: _auxBufferStride = 0x%x\n", FN_NAME, _auxBufferStride); gc->auxSurface = sfc; gc->grAuxBuf = (sfc != 0x00UL); /* NB: If the surface is not valid then the stride will be 'cleared' * which should be enough to prevent rendering conflicts w/ other * surfaces/apps. */ gc->buffers0[2] = _auxBufferAddr; gc->state.shadow.auxBufferAddr = _auxBufferAddr; gc->state.shadow.auxBufferStride = _auxBufferStride; GR_END(); #endif #undef FN_NAME } /* grSurfaceSetAuxSurface */ /*------------------------------------------------------------------- Function: grSurfaceSetTextureSurface Date: 09-Jul-98 Implementor(s): dow Description: Attaches a texture buffer surface to the context. Until another texture buffer is specified, grTexMinAddress, grTexMaxAddress, grTexDownloadMipmap*, and grTexSource act in relation to the buffer specified by grSurfaceTexture. Notes: grSurfaceTexture is to be used only with windowed Glide. Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grSurfaceSetTextureSurface, void , (GrChipID_t tmu, GrSurface_t sfc) ) { #define FN_NAME "grSurfaceSetTextureSurface" #ifdef GLIDE_INIT_HWC hwcSurfaceInfo sfcInfo; GR_BEGIN_NOFIFOCHECK(FN_NAME, 80); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", sfc); GR_CHECK_TMU(FN_NAME, tmu); { struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; if (sfc == NULL) goto __errExit; if (gc->windowed) { #if 0 int i = 0; do { if (renderSurfaces[i] == (FxU32) sfc) _doGrErrorCallback("SURFACE", "Render surface illegally used as texture!", FXTRUE); i++; } while (i < GSFC_MAX_RENDER_SURFACES); #endif if (!_grGetSurfaceInfo(gc, sfc, &sfcInfo)) { GDBG_INFO(80, "%s: Could not get surface info.\n", FN_NAME); GDBG_INFO(80, "\t%s\n", hwcGetErrorString()); goto __errExit; } GDBG_INFO(180, "%s: sfcInfo:\n", FN_NAME); GDBG_INFO(180, " tileBase: 0x%x\n", sfcInfo.tileBase); GDBG_INFO(180, " lpLFB: 0x%x\n", sfcInfo.lpLFB); GDBG_INFO(180, " lpSurface: 0x%x\n", sfcInfo.lpSurface); GDBG_INFO(180, " pciStride: 0x%x\n", sfcInfo.pciStride); GDBG_INFO(180, " hwStride: 0x%x\n", sfcInfo.hwStride); GDBG_INFO(180, " isTiled: 0x%x\n", sfcInfo.isTiled); GDBG_INFO(180, " width: 0x%x\n", sfcInfo.width); GDBG_INFO(180, " height: 0x%x\n", sfcInfo.height); GDBG_INFO(180, " depth: 0x%x\n", sfcInfo.bitdepth); #ifdef GDBG_INFO_ON hwcCheckTarget(sfcInfo.fbOffset, sfcInfo.width, sfcInfo.height, sfcInfo.bitdepth, 0x1000000, 0 ); #endif memInfo->texTiled = sfcInfo.isTiled; if (memInfo->texTiled) { memInfo->texStrideTiles = sfcInfo.hwStride; memInfo->texStrideBytes = sfcInfo.pciStride; } memInfo->tramLfbAddr = (FxU32)sfcInfo.lpSurface - (FxU32)sfcInfo.lpLFB; memInfo->tramOffset = sfcInfo.fbOffset; memInfo->tramSize = sfcInfo.width * sfcInfo.height * sfcInfo.bitdepth / 8; GDBG_INFO(80, FN_NAME ": tramOffset[%d] = 0x%x\n", tmu, memInfo->tramOffset); GDBG_INFO(80, FN_NAME ": tramSize[%d] = 0x%x\n", tmu, memInfo->tramSize); GDBG_INFO(80, FN_NAME ": tramLfbAddr[%d] = 0x%x\n", tmu, memInfo->tramLfbAddr); } else { hwcBufferDesc *bd; bd = (hwcBufferDesc *) sfc; memInfo->tramOffset = bd->bufOffset; memInfo->tramSize = bd->bufSize; } if (0) { __errExit: /* Clear glide texturing */ memInfo->tramLfbAddr = memInfo->tramOffset = memInfo->tramSize = 0x00UL; } gc->tmu_state[tmu].total_mem = memInfo->tramSize; } gc->texSurface[tmu] = sfc; GR_END(); #endif #undef FN_NAME } /* grSurfaceSetTextureSurface */ /*------------------------------------------------------------------- Function: grSurfaceCalcTextureWHD Date: 14-Dec-98 Implementor(s): dow Description: See the very nice ascii art w/ _grTexCalcMipmapLevelOffsetTiled in gtex.c for a description of the memory layout for tiled textures. Textures in linear memory take up the same amount of memory so thinking of everything as tiled makes the implementation simpler. Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grSurfaceCalcTextureWHD, FxBool , (GrTexInfo *tInfo, FxU32 *w, FxU32 *h, FxU32 *d) ) { #define FN_NAME "grSurfaceCalcTextureWHD" FxU32 offset = 0; FxBool retVal = FXFALSE; GR_CHECK_F(FN_NAME, tInfo->format < 0, "invalid texture format"); *d = _grBitsPerTexel[tInfo->format]; GR_CHECK_F(FN_NAME, *d == 0, "invalid texture format"); retVal = (*d != 0); if (retVal) { /* gsfctabl.h contains the boundingBoxWH array, which we include here: */ #include "gsfctabl.h" FxU32 fmtType, internalWidth, internalHeight; switch(tInfo->format) { case GR_TEXFMT_ARGB_CMP_FXT1: fmtType = 1; break; case GR_TEXFMT_ARGB_CMP_DXT1: /* XXX check this! */ case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: fmtType = 2; break; default: fmtType = 0; break; } internalWidth = (FxU32)(boundingBoxWH[fmtType] [G3_ASPECT_TRANSLATE(tInfo->aspectRatioLog2)] [tInfo->largeLodLog2][tInfo->smallLodLog2][0]); internalHeight = (FxU32)(boundingBoxWH[fmtType] [G3_ASPECT_TRANSLATE(tInfo->aspectRatioLog2)] [tInfo->largeLodLog2][tInfo->smallLodLog2][1]); if (w != NULL) *w = internalWidth; if (h != NULL) *h = internalHeight; } return retVal; #undef FN_NAME } /* grSurfaceCalcTextureWHD */ /* Returns the # of glide compatible devices in the system. If devList * is non-NULL and listCount is non-zero, devList is filled in w/ * information about the current glide device to system device * mapping. If there is not enough space in the client passed list to * fill in all of the device information a partial list is returned to * the client along w/ the full count. */ GR_EXT_ENTRY(grDeviceQuery, FxU32, (GrDeviceInfo_t devList[], FxU32 listCount)) { #define FN_NAME "grDeviceQuery" #ifdef GLIDE_INIT_HWC FxU32 retVal; /* Pass over the actual device list rather than the current * device. This does not need to be protected since we're not * claiming any resources here. */ for(retVal = 0; retVal < (FxU32)_GlideRoot.hwConfig.num_sst; retVal++) { if ((devList != NULL) && (retVal < (FxU32)listCount)) { devList[retVal].glideDeviceId = retVal; #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) devList[retVal].systemDeviceId = _GlideRoot.GCs[retVal].bInfo->hdc; #else devList[retVal].systemDeviceId = _GlideRoot.GCs[retVal].bInfo->hMon; #endif } } return retVal; #else /* !GLIDE_INIT_HWC */ return 0; #endif #undef FN_NAME } /* grDeviceQuery */ #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) GR_EXT_ENTRY(grSurfaceCreate, GrSurface_t , (GrSurfaceDesc_t *sfcDesc)) { #define FN_NAME "grSurfaceCreate" GR_DCL_GC; return gdxSurfaceAlloc(gc->bInfo, gc->bInfo->hMon, sfcDesc); #undef FN_NAME } GR_EXT_ENTRY(grSurfaceRelease, void , (GrSurface_t sfc) ) { #define FN_NAME "grSurfaceRelease" gdxSurfaceFree(sfc); #undef FN_NAME } GR_EXT_ENTRY(grSurfaceGetDesc, void , (GrSurface_t sfc, GrSurfaceDesc_t *sfcDesc)) { #define FN_NAME "grSurfaceGetDesc" gdxSurfaceGetDesc(sfc, sfcDesc); #undef FN_NAME } #endif /* (GLIDE_PLATFORM & GLIDE_OS_MACOS) */ #endif /* (GLIDE_PLATFORM & (GLIDE_OS_WIN32 | GLIDE_OS_MACOS)) */ glide3x/h5/glide3/src/gsfc.h0100700000175300010010000001120307725034670015062 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gsfc.h,v 1.3.4.2 2003/06/05 08:23:54 koolsmoky Exp $ ** $Log: ** 4 3dfx 1.1.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 3 3dfx 1.1.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 2 3dfx 1.1 11/08/99 Kenneth Dyke New callback prototype for ** MacOS. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 10 8/23/99 2:13p Kcd ** Mac additions. ** ** 9 8/17/99 5:10p Kcd ** Updated Mac surface stuff to newer API. ** ** 8 6/24/99 7:10p Atai ** new grSurfaceSetRenderingSurface interface ** ** 7 4/16/99 2:56p Kcd ** MacOS Surface extensions. ** ** 6 3/14/99 1:46p Peter ** temp implemntation of my surface extension extension ** ** 5 12/14/98 6:19p Dow ** Fixed for current surface extension spec ** ** 4 8/02/98 5:01p Dow ** Glide Surface Extension ** ** 3 7/13/98 9:57p Jdt ** Added to build. First implementation of SetRenderSurface and ** CreateContext ** ** 2 7/09/98 6:47p Dow ** ** 1 7/09/98 11:37a Dow ** Initial Checkin ** */ #ifndef GSFC_H #define GSFC_H #include <3dfx.h> #include #define GR_SURFACE_EXTENSION 0x1000 typedef FxU32 GrSurfaceContextType_t; #define GR_SURFACECONTEXT_WINDOWED 0 #define GR_SURFACECONTEXT_FULLSCREEN 1 typedef void * GrSurface_t; typedef FxU32 GrSurfaceTexType_t; #define GR_SURFACETEXTYPE_FB 0 #define GR_SURFACETEXTYPE_AGP 1 /* New Enumerants for GR_GET */ #define GR_SURFACE_SIZE (GR_SURFACE_EXTENSION | 0x1) #define GR_SURFACE_TEXTURE (GR_SURFACE_EXTENSION | 0x2) typedef struct { FxU32 glideDeviceId; void* systemDeviceId; FxU32 reserved; } GrDeviceInfo_t; extern GrContext_t FX_CALL grSurfaceCreateContext(GrSurfaceContextType_t t); extern void FX_CALL grSurfaceReleaseContext(GrContext_t ctx); extern void FX_CALL grSurfaceSetRenderingSurface(GrSurface_t sfc, FxBool textureP); extern void FX_CALL grSurfaceSetAuxSurface(GrSurface_t sfc); extern void FX_CALL grSurfaceSetTextureSurface(GrChipID_t tmu, GrSurface_t sfc); extern FxBool FX_CALL grSurfaceCalcTextureWHD(GrTexInfo *tInfo, FxU32 *w, FxU32 *h, FxU32 *d); /* Returns the # of glide compatible devices in the system. If devList * is non-NULL and listCount is non-zero, devList is filled in w/ * information about the current glide device to system device * mapping. If there is not enough space in the client passed list to * fill in all of the device information a partial list is returned to * the client along w/ the full count. */ extern FxU32 FX_CALL grDeviceQuery(GrDeviceInfo_t devList[], FxU32 listCount); #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) /* MacOS Glide Surface Extensions */ #define GR_SURFACE_NOTIFY_LOST 0x01 typedef struct { FxU32 surface; FxU32 width; FxU32 height; FxU32 pitch; FxU32 bytesPerPixel; FxU32 pixelFormat; void (*notifyCallback)(GrSurface_t sfc, void *userData, FxU32 code); void *userData; /* Anything you want */ /* OS Specific Info */ void *systemPortId; /* Drawing port type thing (read-only) */ void *systemDeviceId; /* Same as systemDeviceId from GrDeviceInfo_t (ready-only) */ /* For future expansion */ FxU32 reserved; } GrSurfaceDesc_t; extern GrSurface_t FX_CALL grSurfaceCreate(GrSurfaceDesc_t *desc); extern void FX_CALL grSurfaceRelease(GrSurface_t sfc); extern void FX_CALL grSurfaceGetDesc(GrSurface_t sfc, GrSurfaceDesc_t *sfcDesc); #endif #endif /* GSFC_H */ glide3x/h5/glide3/src/gsfctabl.h0100700000175300010010000022144607725034670015741 0ustar johndoeNone/* * This table was generated automatically by * $/users/larryw/glide/special/mktable2.c. It doesn't have * to be autogenerated every time you build glide; only when * a major change takes place (for example, the introduction * of a new texture format with unusual characteristics, such * as FXT1). The dimensions are: * [fmtType][ar][largeLod][smallLod][width_or_height] */ /* KoolSmoky - added DXT support but need to use the correct * data array. where is mktable2.c? need to comeback on this. */ static const FxU16 boundingBoxWH[3][7][12][12][2] = { { /* normal texture formats */ { /* 8:1 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 2, 2}, { 2, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 3}, { 4, 2}, { 4, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 4}, { 8, 3}, { 8, 2}, { 8, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 6}, { 16, 5}, { 16, 4}, { 16, 3}, { 16, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 6}, { 48, 5}, { 48, 4}, { 48, 4}, { 48, 4}, { 32, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 8}, { 112, 8}, { 112, 8}, { 112, 8}, { 112, 8}, { 96, 8}, { 64, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 256, 32}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 768, 64}, { 512, 64}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 128}, { 0, 0}, }, { /* largeLod: 11 */ {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {2048, 256}, }, }, { /* 4:1 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 2, 2}, { 2, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 3}, { 4, 2}, { 4, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 5}, { 8, 4}, { 8, 3}, { 8, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 9}, { 16, 8}, { 16, 7}, { 16, 6}, { 16, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 9}, { 48, 8}, { 48, 8}, { 48, 8}, { 48, 8}, { 32, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 16}, { 112, 16}, { 112, 16}, { 112, 16}, { 112, 16}, { 96, 16}, { 64, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 256, 64}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 768, 128}, { 512, 128}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 256}, { 0, 0}, }, { /* largeLod: 11 */ {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {2048, 512}, }, }, { /* 2:1 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 2, 2}, { 2, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 4}, { 4, 3}, { 4, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 8}, { 8, 7}, { 8, 6}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 16}, { 16, 15}, { 16, 14}, { 16, 12}, { 16, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 16}, { 48, 16}, { 48, 16}, { 48, 16}, { 48, 16}, { 32, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 32}, { 112, 32}, { 112, 32}, { 112, 32}, { 112, 32}, { 96, 32}, { 64, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 256, 128}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 768, 256}, { 512, 256}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 512}, { 0, 0}, }, { /* largeLod: 11 */ {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {2048,1024}, }, }, { /* 1:1 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 2, 3}, { 2, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 7}, { 4, 6}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 15}, { 8, 14}, { 8, 12}, { 8, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 31}, { 16, 30}, { 16, 28}, { 16, 24}, { 16, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 32}, { 48, 32}, { 48, 32}, { 48, 32}, { 48, 32}, { 32, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 64}, { 112, 64}, { 112, 64}, { 112, 64}, { 112, 64}, { 96, 64}, { 64, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 256, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 768, 512}, { 512, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1024}, { 0, 0}, }, { /* largeLod: 11 */ {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {2048,2048}, }, }, { /* 1:2 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 1, 3}, { 1, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 2, 7}, { 2, 6}, { 2, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 4, 15}, { 4, 14}, { 4, 12}, { 4, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 8, 31}, { 8, 30}, { 8, 28}, { 8, 24}, { 8, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 24, 32}, { 24, 32}, { 24, 32}, { 24, 32}, { 24, 32}, { 16, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 56, 64}, { 56, 64}, { 56, 64}, { 56, 64}, { 56, 64}, { 48, 64}, { 32, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 128, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 384, 512}, { 256, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1024}, { 0, 0}, }, { /* largeLod: 11 */ {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1024,2048}, }, }, { /* 1:4 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 1, 3}, { 1, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 1, 7}, { 1, 6}, { 1, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 2, 15}, { 2, 14}, { 2, 12}, { 2, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 4, 31}, { 4, 30}, { 4, 28}, { 4, 24}, { 4, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 12, 32}, { 12, 32}, { 12, 32}, { 12, 32}, { 12, 32}, { 8, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 28, 64}, { 28, 64}, { 28, 64}, { 28, 64}, { 28, 64}, { 24, 64}, { 16, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 64, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 192, 512}, { 128, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1024}, { 0, 0}, }, { /* largeLod: 11 */ { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 512,2048}, }, }, { /* 1:8 aspect ratio; normal texture formats */ { /* largeLod: 0 */ { 1, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 1, 3}, { 1, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 1, 7}, { 1, 6}, { 1, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 1, 15}, { 1, 14}, { 1, 12}, { 1, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 2, 31}, { 2, 30}, { 2, 28}, { 2, 24}, { 2, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 6, 32}, { 6, 32}, { 6, 32}, { 6, 32}, { 6, 32}, { 4, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 14, 64}, { 14, 64}, { 14, 64}, { 14, 64}, { 14, 64}, { 12, 64}, { 8, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 16, 192}, { 16, 192}, { 16, 192}, { 16, 192}, { 16, 192}, { 16, 192}, { 16, 192}, { 16, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 48, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 32, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 112, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 96, 512}, { 64, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1024}, { 0, 0}, }, { /* largeLod: 11 */ { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 256,2048}, }, }, }, { /* FXT1 texture format */ { /* 8:1 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 16}, { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 20}, { 16, 16}, { 16, 12}, { 16, 8}, { 16, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 20}, { 48, 16}, { 48, 12}, { 48, 8}, { 48, 4}, { 32, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 20}, { 112, 16}, { 112, 12}, { 112, 8}, { 112, 8}, { 96, 8}, { 64, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 36}, { 128, 32}, { 128, 28}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 36}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 256, 32}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 768, 64}, { 512, 64}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 128}, { 0, 0}, }, { /* largeLod: 11 */ {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {2048, 256}, }, }, { /* 4:1 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 16}, { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 20}, { 16, 16}, { 16, 12}, { 16, 8}, { 16, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 20}, { 48, 16}, { 48, 12}, { 48, 8}, { 48, 8}, { 32, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 20}, { 112, 16}, { 112, 16}, { 112, 16}, { 112, 16}, { 96, 16}, { 64, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 52}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 256, 64}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 768, 128}, { 512, 128}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 256}, { 0, 0}, }, { /* largeLod: 11 */ {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {2048, 512}, }, }, { /* 2:1 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 16}, { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 24}, { 16, 20}, { 16, 16}, { 16, 12}, { 16, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 24}, { 48, 20}, { 48, 16}, { 48, 16}, { 48, 16}, { 32, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 32}, { 112, 32}, { 112, 32}, { 112, 32}, { 112, 32}, { 96, 32}, { 64, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 256, 128}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 768, 256}, { 512, 256}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 512}, { 0, 0}, }, { /* largeLod: 11 */ {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {2048,1024}, }, }, { /* 1:1 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 20}, { 8, 16}, { 8, 12}, { 8, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 36}, { 16, 32}, { 16, 28}, { 16, 24}, { 16, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 36}, { 48, 32}, { 48, 32}, { 48, 32}, { 48, 32}, { 32, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 64}, { 112, 64}, { 112, 64}, { 112, 64}, { 112, 64}, { 96, 64}, { 64, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 256, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 768, 512}, { 512, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1024}, { 0, 0}, }, { /* largeLod: 11 */ {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {2048,2048}, }, }, { /* 1:2 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 20}, { 8, 16}, { 8, 12}, { 8, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 8, 36}, { 8, 32}, { 8, 28}, { 8, 24}, { 8, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 24, 36}, { 24, 32}, { 24, 32}, { 24, 32}, { 24, 32}, { 16, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 56, 64}, { 56, 64}, { 56, 64}, { 56, 64}, { 56, 64}, { 48, 64}, { 32, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 128, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 384, 512}, { 256, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1024}, { 0, 0}, }, { /* largeLod: 11 */ {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1024,2048}, }, }, { /* 1:4 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 20}, { 8, 16}, { 8, 12}, { 8, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 8, 36}, { 8, 32}, { 8, 28}, { 8, 24}, { 8, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 16, 36}, { 16, 32}, { 16, 32}, { 16, 32}, { 16, 32}, { 8, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 32, 64}, { 32, 64}, { 32, 64}, { 32, 64}, { 32, 64}, { 24, 64}, { 16, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 64, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 192, 512}, { 128, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1024}, { 0, 0}, }, { /* largeLod: 11 */ { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 512,2048}, }, }, { /* 1:8 aspect ratio; FXT1 texture format */ { /* largeLod: 0 */ { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 20}, { 8, 16}, { 8, 12}, { 8, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 8, 36}, { 8, 32}, { 8, 28}, { 8, 24}, { 8, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 16, 36}, { 16, 32}, { 16, 32}, { 16, 32}, { 16, 32}, { 8, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 24, 64}, { 24, 64}, { 24, 64}, { 24, 64}, { 24, 64}, { 16, 64}, { 8, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 24, 192}, { 24, 192}, { 24, 192}, { 24, 192}, { 24, 192}, { 16, 192}, { 16, 192}, { 16, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 56, 256}, { 56, 256}, { 56, 256}, { 56, 256}, { 56, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 32, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 120, 512}, { 120, 512}, { 120, 512}, { 120, 512}, { 120, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 96, 512}, { 64, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1024}, { 0, 0}, }, { /* largeLod: 11 */ { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 256,2048}, }, }, }, { /* DXT1,2,3,4,5 texture format */ { /* 8:1 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 16}, { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 20}, { 16, 16}, { 16, 12}, { 16, 8}, { 16, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 20}, { 48, 16}, { 48, 12}, { 48, 8}, { 48, 4}, { 32, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 20}, { 112, 16}, { 112, 12}, { 112, 8}, { 112, 8}, { 96, 8}, { 64, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 24}, { 128, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 384, 32}, { 256, 32}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 896, 64}, { 768, 64}, { 512, 64}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 192}, {1024, 128}, { 0, 0}, }, { /* largeLod: 11 */ {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {3072, 256}, {2048, 256}, }, }, { /* 4:1 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 16}, { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 20}, { 16, 16}, { 16, 12}, { 16, 8}, { 16, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 20}, { 48, 16}, { 48, 12}, { 48, 8}, { 48, 8}, { 32, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 20}, { 112, 16}, { 112, 16}, { 112, 16}, { 112, 16}, { 96, 16}, { 64, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 52}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 48}, { 128, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 384, 64}, { 256, 64}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 896, 128}, { 768, 128}, { 512, 128}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 384}, {1024, 256}, { 0, 0}, }, { /* largeLod: 11 */ {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {3072, 512}, {2048, 512}, }, }, { /* 2:1 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 16}, { 8, 12}, { 8, 8}, { 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 24}, { 16, 20}, { 16, 16}, { 16, 12}, { 16, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 24}, { 48, 20}, { 48, 16}, { 48, 16}, { 48, 16}, { 32, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 32}, { 112, 32}, { 112, 32}, { 112, 32}, { 112, 32}, { 96, 32}, { 64, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 96}, { 128, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 384, 128}, { 256, 128}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 896, 256}, { 768, 256}, { 512, 256}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 768}, {1024, 512}, { 0, 0}, }, { /* largeLod: 11 */ {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {3072,1024}, {2048,1024}, }, }, { /* 1:1 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 8, 20}, { 8, 16}, { 8, 12}, { 8, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 16, 36}, { 16, 32}, { 16, 28}, { 16, 24}, { 16, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 48, 36}, { 48, 32}, { 48, 32}, { 48, 32}, { 48, 32}, { 32, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 112, 64}, { 112, 64}, { 112, 64}, { 112, 64}, { 112, 64}, { 96, 64}, { 64, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 192}, { 128, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 384, 256}, { 256, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 896, 512}, { 768, 512}, { 512, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1536}, {1024,1024}, { 0, 0}, }, { /* largeLod: 11 */ {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {3072,2048}, {2048,2048}, }, }, { /* 1:2 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 4, 20}, { 4, 16}, { 4, 12}, { 4, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 8, 36}, { 8, 32}, { 8, 28}, { 8, 24}, { 8, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 24, 36}, { 24, 32}, { 24, 32}, { 24, 32}, { 24, 32}, { 16, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 56, 64}, { 56, 64}, { 56, 64}, { 56, 64}, { 56, 64}, { 48, 64}, { 32, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 192}, { 64, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 192, 256}, { 128, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 448, 512}, { 384, 512}, { 256, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1536}, { 512,1024}, { 0, 0}, }, { /* largeLod: 11 */ {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1536,2048}, {1024,2048}, }, }, { /* 1:4 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 4, 20}, { 4, 16}, { 4, 12}, { 4, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 4, 36}, { 4, 32}, { 4, 28}, { 4, 24}, { 4, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 12, 36}, { 12, 32}, { 12, 32}, { 12, 32}, { 12, 32}, { 8, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 28, 64}, { 28, 64}, { 28, 64}, { 28, 64}, { 28, 64}, { 24, 64}, { 16, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 192}, { 32, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 96, 256}, { 64, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 224, 512}, { 192, 512}, { 128, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1536}, { 256,1024}, { 0, 0}, }, { /* largeLod: 11 */ { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 768,2048}, { 512,2048}, }, }, { /* 1:8 aspect ratio; DXT1,2,3,4,5 texture format */ { /* largeLod: 0 */ { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 1 */ { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 2 */ { 4, 12}, { 4, 8}, { 4, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 3 */ { 4, 20}, { 4, 16}, { 4, 12}, { 4, 8}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 4 */ { 4, 36}, { 4, 32}, { 4, 28}, { 4, 24}, { 4, 16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 5 */ { 8, 36}, { 8, 32}, { 8, 32}, { 8, 32}, { 8, 32}, { 4, 32}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 6 */ { 16, 64}, { 16, 64}, { 16, 64}, { 16, 64}, { 16, 64}, { 12, 64}, { 8, 64}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 7 */ { 20, 192}, { 20, 192}, { 20, 192}, { 20, 192}, { 20, 192}, { 16, 192}, { 16, 192}, { 16, 128}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 8 */ { 52, 256}, { 52, 256}, { 52, 256}, { 52, 256}, { 52, 256}, { 48, 256}, { 48, 256}, { 48, 256}, { 32, 256}, { 0, 0}, { 0, 0}, { 0, 0}, }, { /* largeLod: 9 */ { 116, 512}, { 116, 512}, { 116, 512}, { 116, 512}, { 116, 512}, { 112, 512}, { 112, 512}, { 112, 512}, { 96, 512}, { 64, 512}, { 0, 0}, { 0, 0}, }, { /* largeLod: 10 */ { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1536}, { 128,1024}, { 0, 0}, }, { /* largeLod: 11 */ { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 384,2048}, { 256,2048}, }, }, }, }; glide3x/h5/glide3/src/gsplash.c0100700000175300010010000001425207725034670015603 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gsplash.c,v 1.3.4.2 2003/06/05 08:23:54 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 28 3/19/99 11:30a Peter ** protect against splash screen not restoring app state ** ** 27 2/20/99 5:25a Mark ** fixed breakage in grSplash ** ** 26 2/19/99 8:03p Peter ** new splash ** ** 25 2/18/99 3:48p Kcd ** Fixed conflict with MacOS type. ** ** 24 1/25/99 6:32p Peter ** cleaned up some translation macros and tables ** ** 23 12/04/98 11:04a Russp ** Put an #ifdef in to gsplash.c to get it working in the sst2 tree ** ** 22 12/03/98 4:45p Atai ** exit grSplash if aux buffer equals zero ** ** 21 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 20 7/31/98 5:42p Russp ** make work with sst2 ** ** 19 7/23/98 5:25p Russp ** get rid of redundant grVertexLayout calls ** ** 18 7/20/98 11:23a Russp ** get working in sst2 tree ** ** 17 7/18/98 12:29a Jdt ** changes to reflect new shadow register structure ** ** 16 6/23/98 11:05a Peter ** more compile fixes ** ** 15 6/22/98 3:35p Peter ** concatenation this way is evil ** ** 14 6/22/98 2:25p Russp ** Add SST2 specific ifdef's ** ** 13 6/18/98 2:44p Atai ** fixed 1894 ** ** 12 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 10 2/09/98 10:28a Atai ** set grSpash default to windows coords ** ** 9 2/06/98 4:25p Atai ** remove GrTmuVertex ** ** 8 2/05/98 2:30p Atai ** fixed bug#1222. ** ** 7 1/28/98 6:36p Atai ** remove z,w, min_max definition ** ** 6 1/28/98 1:13p Peter ** Stupid swap state form gratuitous splash screen ** ** 5 1/26/98 12:32p Atai ** glide 3 header clean up ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 23 1/09/98 6:48p Atai * grTexInfo, GR_LOD_* and GR_ASPECT_* * * 21 1/06/98 6:47p Atai * undo grSplash and remove gu routines * * 20 12/18/97 2:13p Peter * fogTable cataclysm * * 19 12/15/97 5:52p Atai * disable obsolete glide2 api for glide3 * * 18 12/09/97 10:20a Peter * removed extraneous cruft * * 17 11/14/97 5:03p Peter * picking up the torch... removed #!@#$% c++ comments * * 16 10/23/97 5:30p Peter * packed rgb happiness * * 15 7/31/97 11:14a Peter * merge w/ sst1 glide tree, hopefully * * 13 7/07/97 3:05p Dow * Moved fouled clears * * 12 3/18/97 9:07p Dow * Got rid of #$#%#$ // comments * * 11 3/16/97 12:42a Jdt * Removed watcom warning * * 10 3/13/97 10:53p Jdt * Rewrote with simple optimizations. Changed prototype for * multi-resolution, and running as a better shameless plug. * * 9 3/13/97 2:52a Jdt * Added arguments to splash. * * 8 3/09/97 10:31a Dow * Added GR_DIENTRY for di glide functions * * 7 3/01/97 6:24p Jdt * Made splash force yorigin. * * 6 1/02/97 1:06p Dow * Fixed state bug * * 3 11/17/96 11:16p Garymct * Updated grSplash code to set all of the necessary state itself rather * than expecting the caller to do so. */ #include #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" /*------------------------------------------------------------------- Function: grSplash Date: 3/13 Implementor(s): GaryMcT Library: Glide Description: Render the opening splash screen animation, or render a single frame of the splash screen. Arguments: x, y - upper left hand coord of window w, h - width and height of window to render _frame - frame number to render (~0 to render all frames) Return: none -------------------------------------------------------------------*/ GR_DIENTRY(grSplash,void,(float x, float y, float w, float h, FxU32 frameNumber)) { #define FN_NAME "grSplash" #if (GLIDE_PLATFORM & GLIDE_HW_SST2) GR_BEGIN_NOFIFOCHECK("grSplash", 85, 1); #else GR_BEGIN_NOFIFOCHECK("grSplash", 85); #endif GDBG_INFO_MORE(gc->myLevel,"(%f,%f,%f,%f,%d)\n", x, y, w, h, frameNumber); #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #if (GLIDE_PLATFORM & GLIDE_HW_SST2) #else { GrState glideState; /* Protect ourselves from the splash screen */ grGlideGetState(&glideState); { if (gc->pluginInfo.splashProc != NULL) (*gc->pluginInfo.splashProc)(x, y, w, h, frameNumber); } grGlideSetState((const void*)&glideState); } #endif #endif /* (GLIDE_PLATFORM & GLIDE_OS_WIN32) */ GR_END(); #undef FN_NAME } glide3x/h5/glide3/src/gsst.c0100700000175300010010000042004707725034670015125 0ustar johndoeNone/* -*-c++-*- */ /* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gsst.c,v 1.5.4.16 2003/08/21 08:49:55 dborca Exp $ ** $Log: ** 69 3dfx 1.52.1.3.1.1111/08/00 Drew McMinn Create initialise read and ** use useAppGamma flag, to allow us to disable applications changing gamma ** values. ** 68 3dfx 1.52.1.3.1.1010/13/00 Matt McClure Exposed ** grSetNumPendingBuffers for OGL. ** 67 3dfx 1.52.1.3.1.910/11/00 Brent Forced check in to enforce ** branching. ** 66 3dfx 1.52.1.3.1.810/09/00 Jonny Cochrane calculate chipScreenHeight ** correctly for 4 way SLI ** 65 3dfx 1.52.1.3.1.709/26/00 Matt McClure Changed opengl name to ** is_opengl instead of SliBandHeightForce. ** 64 3dfx 1.52.1.3.1.609/25/00 Matt McClure Added code to allow release ** of the Exclusive mode context on grSSTWinClose for OpenGL. ** 63 3dfx 1.52.1.3.1.509/15/00 Jonny Cochrane 2x FSAA for 4500 ** 62 3dfx 1.52.1.3.1.408/31/00 Andy Hanson Fix to allow digital SLI up ** through 1600 by X resolutions. ** 61 3dfx 1.52.1.3.1.308/29/00 Jonny Cochrane Some 8x FSAA code ** 60 3dfx 1.52.1.3.1.208/01/00 Andy Hanson Fixed issue with source ** ignoring setting of GLIDE_SPLASH define. ** Fixed issue with setting of splash state when it wasn't going to be run. ** 59 3dfx 1.52.1.3.1.107/12/00 troy thornton Cleaned up grSstWinOpen to ** always call grSstWinOpenExt ** 58 3dfx 1.52.1.3.1.006/28/00 troy thornton added code to allow app. to ** use correct jitter values only if AA is not forced ** 57 3dfx 1.52.1.3 06/20/00 Joseph Kain Fixed errors introduced by ** my previous merge. ** 56 3dfx 1.52.1.2 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 55 3dfx 1.52.1.1 06/15/00 Bill White Merged changes to support ** Linux. ** ** 54 3dfx 1.52.1.0 05/28/00 Stephane Huaulme fixed Mac Headers crap ** (UI3.3) ** 53 3dfx 1.52 04/25/00 Adam Briggs make grSelectContext ** actually return a useful value in windowed mode ** 52 3dfx 1.51 04/25/00 Kenneth Dyke Fix single buffered video ** overlay init. ** 51 3dfx 1.50 04/25/00 Kenneth Dyke Fixed overlay mode for SLI ** non-AA modes. ** 50 3dfx 1.49 04/21/00 Kenneth Dyke Disabled new style 2sample ** aa on 4-way boards until it works. ** 49 3dfx 1.48 04/16/00 Kenneth Dyke Nuke splash screen when SLI ** band height is forced (for OpenGL). ** 48 3dfx 1.47 04/14/00 Kenneth Dyke Make sure we don't clobber ** SST_PARMADJUST when we set the column rendering width. ** 47 3dfx 1.46 04/13/00 Kenneth Dyke Added support for new style ** 2-sample AA mode. ** 46 3dfx 1.45 04/11/00 Chris Dow Fixed TMU sizing bug and ** cleaned up some noodles. ** 45 3dfx 1.44 04/06/00 Kenneth Dyke Don't trash render masks ** whenever we set the renderMode. ** 44 3dfx 1.43 03/30/00 Kenneth Dyke Do automagic SLI band ** height setting. ** 43 3dfx 1.42 03/25/00 Adam Briggs added support for ** SSTH3_SLI_AA_CONFIGURATION (the env var the control panel uses to force AA ** modes) ** 42 3dfx 1.41 03/23/00 Kenneth Dyke Make sure we maintain state ** across all chips. Change default LOD bias to 0.5f. ** 41 3dfx 1.40 03/21/00 Kenneth Dyke Tweaks for overlay video ** format. ** Support for not clamping SLI band height. ** Allow user to override 16-bit rendering to 15-bit. ** 40 3dfx 1.39 03/19/00 Kenneth Dyke Make sure 2ppc band height ** is just set once. ** Make sure extended alpha blend modes and stencil masks are set to a known ** value. ** 39 3dfx 1.38 03/14/00 Adam Briggs enable analog sli in 2X ** modes or when forced ** 38 3dfx 1.37 03/13/00 Kenneth Dyke Make sure 3D is idle when ** we close down Glide. ** 37 3dfx 1.36 03/11/00 Kenneth Dyke Make sure slave registers ** are kept up to date after board is mapped in. ** 36 3dfx 1.35 03/08/00 Kenneth Dyke Don't cache hardware ** register pointers. ** 35 3dfx 1.34 03/08/00 Kenneth Dyke New use isMapped boardInfo ** flag instead of broken gc flag. ** 34 3dfx 1.33 03/07/00 Adam Briggs implemented half-mode sli & ** aa restrictions ** 33 3dfx 1.32 02/28/00 Adam Briggs replaced hwcQueryContext ** call with a reference to the lost context dword ** 32 3dfx 1.31 02/28/00 Kenneth Dyke Fixed dither rotation stuff ** for 4-sample AA. We also no longer clobber the fog mode setting. ** ** 31 3dfx 1.30 02/14/00 Kenneth Dyke Constrain SLI band height ** to make sure Y origin swapping works right. ** Fixed memory requirement calculation to take into account SLI and AA. ** ** 30 3dfx 1.29 02/08/00 Adam Briggs got rid of a divide by zero ** that would occur on voodoo3 ** 29 3dfx 1.28 02/08/00 Kenneth Dyke Initialize sliBandHeight in ** the proper place. ** 28 3dfx 1.27 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 27 3dfx 1.26 01/31/00 Kenneth Dyke Changes to deal with ** hardware AA issue. ** 26 3dfx 1.25 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 25 3dfx 1.24 01/30/00 Adam Briggs get napalm status correctly ** 24 3dfx 1.23 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 23 3dfx 1.22 01/23/00 Adam Briggs initializing h3nwaysli ** properly greatly aids in 4-sample AA init ** 22 3dfx 1.21 01/21/00 Adam Briggs closer to working on 2 chip ** sli ** 21 3dfx 1.20 01/19/00 Kenneth Dyke Fixed unitialized variable ** in command transport struct for grSstWinOpenExt. ** 20 3dfx 1.19 01/18/00 Kenneth Dyke Get proper AA jitter ** values. ** 19 3dfx 1.18 01/16/00 Kenneth Dyke Sandbox stuff. ** 32-bit/AA override stuff ** Triangle column width stuff. ** 18 3dfx 1.17 01/16/00 Kenneth Dyke Fixes to allow better ** 32-bit/AA overrides. ** Fixes to make non-565 rendering modes work right in minihwc. ** Other various bring up fixes. ** 17 3dfx 1.16 01/04/00 Adam Briggs changed grGetGammaTable to ** be an extension called grGetGammaTableExt ** 16 3dfx 1.15 01/04/00 Chuck Smith Added grGetGammaTable ** funciton so that the OpenGL ICD can make use of the hwcGetGammaTable ** function ** 15 3dfx 1.14 12/10/99 Leo Galway Removed previous hi-res ** mode information for Glide3. These modes were only necessary for ** Cornerstone (or future hi-res) support in RT4.2 source branch and ** proceeded to break the V3 and V2 builds (from 3dfx view), hence they have ** been removed. ** 14 3dfx 1.13 12/08/99 Leo Galway Added mode information for ** 1600x1280, 1792x1440, 1920x1080, 1920x1200, 2046x1536 (as a result of ** glide being tested with Cornerstone modes). Although not all of these ** modes are currently capable under Glide, their inclusion prevents Glide ** apps from displaying in incorrect modes when these hi-res modes are ** selected. Search for SUSTAINED_ENGINEERING_CHANGE_BEGIN. ** 13 3dfx 1.12 12/03/99 Adam Briggs Added some code for ** y-origin swapping in sli mode (which doesn't seem to work on winsim ** anyway) ** 12 3dfx 1.11 11/22/99 Kenneth Dyke Use hwcIdleWinFifo(). ** 11 3dfx 1.10 11/11/99 Adam Briggs My bad: Apparently V3 ** cards have zero chips on them, so don't even bother with the first step ** through the SLI slave reg loops. ** 10 3dfx 1.9 11/10/99 Adam Briggs Made grBufferClear(Ext) ** cooperate with linear surfaces & texture buffers ** 9 3dfx 1.8 11/09/99 Larry warner Make the world safe for h3. ** 8 3dfx 1.7 11/09/99 Adam Briggs Added support for reading ** the Status reg on slave chips in order to form a more perfect flush ** function. ** 7 3dfx 1.6 10/22/99 Anthony tai disable 2ppc in winclose ** 6 3dfx 1.5 10/21/99 Larry warner Fix typo. ** 5 3dfx 1.4 10/21/99 Anthony tai fixed h3 build ** 4 3dfx 1.3 10/20/99 Anthony tai initialize tmu combine ** register packet header ** 3 3dfx 1.2 10/08/99 Adam Briggs Supported FX_GLIDE_BPP & ** FX_GLIDE_AA_SAMPLE environment vars so the user can override the pixel ** format in grSstWinOpen calls ** 2 3dfx 1.1 10/04/99 Matt McClure Ported Glide Context ** Switching code from V3_OEM_100. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 159 9/09/99 4:24p Adamb ** set renderMode SST_RM_YORIGIN_TOP_SHIFT to height - 1 instead of height ** since coords are zero based. ** ** 158 9/07/99 10:44a Atai ** fixed h3 build ** ** 157 9/03/99 4:32p Atai ** disable aaCtrl and sliCtrl in winclose ** ** 155 8/31/99 5:49p Atai ** added pixel sample for cfgAALfbCtrl ** ** 154 8/20/99 4:56p Atai ** fixed packet4 register bit mask for window glide ** ** 153 8/17/99 5:10p Kcd ** AGP Command FIFO fixes. ** ** 152 8/16/99 11:18a Adamb ** Merged in V3_OEM_100 fixes ** ** 151 8/11/99 5:09p Atai ** enable 2nd buffer ** ** 150 8/11/99 3:44p Atai ** added multichip support for minihwc ** ** 149 8/04/99 3:35p Atai ** 32 bpp happy ** ** 148 7/28/99 11:20a Atai ** fixed h3 build ** ** 147 7/27/99 6:18p Atai ** use grSstWinOpenExt for napalm ** ** 146 7/26/99 12:11p Atai ** initialize pci registers for sli/aa ** ** 145 7/22/99 1:18p Atai ** added grTBufferMaskExt ** ** 144 7/21/99 4:05p Atai ** added sli ctrl code ** ** 143 7/19/99 2:52p Atai ** added variable for sli ** ** 142 7/18/99 2:25p Atai ** change 2ppc enabling condition ** ** 141 7/18/99 1:59p Atai ** added grAlphaBlendFunctionExt ** ** 139 7/14/99 6:23p Larryw ** Remove obsolete G3_LOD_TRANSLATE() macro ** Define _grMipMapOffset[][] at compile time ** Fix 2k texture address-finding ** ** 138 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 137 7/12/99 12:35p Atai ** initialize tmu base address for napalm ** ** 136 7/06/99 2:51p Atai ** enable gbc and fixed minor things. ** ** 135 6/25/99 2:11p Atai ** more 2 buffers stuff ** ** 134 6/24/99 7:19p Atai ** 2 sample aa ** ** 133 6/21/99 1:27p Atai ** overwrtie napalm memory allocation stuff ** ** 132 6/19/99 11:27p Atai ** fixed fbOffset ** ** 131 6/18/99 10:41p Atai ** reset fbOffset ** ** 130 6/16/99 7:26p Larryw ** Took out some lines from my last install that don't belong there. ** ** 129 6/16/99 7:00p Larryw ** Y-origin subtraction. ** ** 128 6/14/99 4:28p Atai ** more on 2nd buffer allocation ** ** 127 6/14/99 3:19p Atai ** added secondary buffer info ** ** 126 6/14/99 2:05p Atai ** added grPixelFormat and grPixelSample. ** ** 124 6/13/99 6:07p Atai ** remove aa type for winopen ext ** ** 123 6/09/99 5:23p Atai ** added _grChipMask ** ** 122 6/09/99 12:02p Atai ** change csim tram size for 2k x 2k texture testing ** ** 121 6/04/99 11:00a Atai ** added stencil functions ** ** 120 6/03/99 4:26p Atai ** added chipMask ** ** 119 6/01/99 2:33p Atai ** Added grSstWinOpe Ext ** ** 117 5/28/99 12:55p Atai ** fixed clip coord, fog coord ext with w-buffering ** ** 115 5/26/99 4:18p Kcd ** Enable LFB byte and word swizzling by default for PowerPC systems. ** ** 114 5/24/99 2:49p Jamesb ** Added ptrLostContext field to exported command transport struct. ** ** 113 5/19/99 3:55p Denis ** ** 112 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a tbext comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 111 4/16/99 2:57p Kcd ** PowerPC PCI Bump & Grind ** ** 110 4/15/99 5:34p Dow ** Protected WinClose ** ** 109 4/10/99 2:21p Atai ** set contexP to 1 ** ** 108 4/10/99 1:24p Atai ** fixed code to compile in packet fifo mode ** ** 107 4/09/99 4:52p Dow ** Get lostcontext each time ** ** 106 4/07/99 7:18p Atai ** added uma extension ** ** 105 4/05/99 8:25p Dow ** Alt tab mostly happy ** ** 104 4/05/99 4:05p Atai ** I removed hwcShareContextData code in my previous check-in ** ** 103 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 100 4/02/99 11:51a Peter ** only monitor state changes not every time ** ** 99 4/01/99 7:55p Peter ** change to allow fsem recovery ** ** 98 3/31/99 9:02p Dow ** context loosing means no writing to hw ** ** 97 3/24/99 6:17p Peter ** reduce nop flush for chain downloads ** ** 96 3/22/99 5:38p Peter ** single load of splash ** ** 95 3/19/99 11:30a Peter ** protect against splash screen not restoring app state ** ** 94 3/17/99 5:08p Peter ** removed whacky stuff now that the command fifo threshold stuff appears ** to make all happy (including the k7) ** ** 93 3/14/99 1:48p Peter ** cmd's bng optimization ** ** 92 3/12/99 2:27p Dow ** Turn off hole counting for PIII and K7 ** ** 91 3/11/99 6:42p Dow ** Resolution help ** ** 90 3/10/99 10:42a Peter ** bump-n-grind workaround for katmai until the bug is better ** characterized ** ** 89 3/05/99 10:33p Peter ** fixed the surface fifo state race condition (thanks to Ken Dyke) ** ** 88 3/02/99 2:04p Peter ** removed tmu check that should be done in grTexCombine ** ** 87 2/27/99 12:25p Dow ** gsst.c ** ** 86 2/26/99 10:27a Peter ** Mmmm.... 8.3 ** ** 85 2/19/99 8:03p Peter ** new splash ** ** 84 2/18/99 3:51p Kcd ** Fixed dumb Codewarrior warning. ** ** 83 2/18/99 3:05p Atai ** Hack for Fifa99! Fifa99 calls guGammaCorrectionRGB after they use ** grGlideShutdown. Check if we have a null gc. ** ** 82 2/13/99 2:01p Dow ** Added code for new resolutions ** ** 81 2/11/99 1:38p Atai ** sync buffer swap pending code, the right way. ** ** 80 2/05/99 9:38a Atai ** fixed grSelectContext return value. If the gc is open, return FXTRUE. ** ** 79 2/02/99 4:41p Peter ** debugging info to grFlush ** ** 78 1/25/99 6:35p Peter ** tiled texture cleanup, default lfb buffer when single buffering ** ** 77 1/06/99 11:30a Peter ** cleanup win fifo locking ** ** 76 12/23/98 2:01p Peter ** nt currently has mutexing problems via ddraw and extescape ** ** 75 12/11/98 1:36p Peter ** made grFlush's operation more obvious ** ** 74 12/09/98 6:25p Atai ** grTexCombine did the right thing for the un-used TMU. Initialize the ** 2nd TMU value to take care of "set FX_GLIDE_NUM_TMU=1" ** ** 73 12/09/98 5:10p Atai ** set MAXLOD = MINLOD = 8 in _grUpdateParamIndex if ST1 is not used ** ** 72 12/09/98 2:02p Atai ** Added _grTexForceLod back. Set tLOD min = max = 8 for the 2nd TMU by ** default for Avenger to increase single texturing tri fillrate. ** ** 71 12/09/98 10:22a Dow ** Fixed infinite recursion on shutdown ** ** 70 12/08/98 2:23p Dow ** Fixed effage in grSstWinClose when invalid context is passed ** ** 69 12/03/98 11:26p Dow ** Code 'cleanup' heheh ** ** 68 12/02/98 2:07p Dow ** removed spurious call to guGammaCorrectionRGB ** ** 67 11/30/98 6:57p Peter ** video memory fifo's ** ** 66 11/25/98 12:10p Atai ** fixed sdram buffer clear (gc->state.shadow.auxBufferStride not ** initialized) ** ** 65 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 64 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 63 11/12/98 3:12p Mikec ** In winOpen, moved setting color format in gc to after splash. Fixed the ** red screen bug after splash (RGBA format). ** ** 62 11/02/98 5:34p Peter ** tls per thread for fullscreen contexts ** ** 61 10/14/98 3:38p Dow ** Gamma stuff ** ** 60 10/14/98 1:47p Jdt ** Fix state restore buffer and add archDispatchProcs setup to ** selectContext ** ** 59 10/13/98 8:47p Dow ** Works with 4MB boards ** ** 58 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 57 10/08/98 10:29a Dow ** Fixes triple buffering ** ** 56 9/18/98 10:52a Dow ** VidMode Stuff ** ** 55 9/14/98 9:57a Jdt ** ** 54 9/11/98 10:45p Jdt ** switch over to statically allocated in-memory fifo. ** ** 53 9/09/98 1:33p Atai ** callback the error routine if window handle is not valid in ** grSstWinOpen ** ** 52 9/04/98 11:35a Peter ** re-open fix for nt (thanks to taco/rob/nt bob) ** ** 51 8/31/98 4:03p Dow ** Contol Panel ** ** 50 8/30/98 1:34p Dow ** State & other optimizations ** ** 49 8/29/98 2:29p Peter ** set context value in case grGlideInit was called from a different ** thread ** ** 48 8/28/98 4:37p Atai ** 1. added MIN_FIFO_SIZE for memory checking ** 2. hack for resolution checking if we have 8M board and triple ** buffering on ** ** 47 8/27/98 9:27p Atai ** fix env variable for glide3x ** ** 46 8/27/98 5:57p Dow ** Indentation ** ** 45 8/26/98 9:59p Jdt ** Compute and store pointer to aux buffer. ** ** 44 8/21/98 3:48p Jdt ** Fixed flush bug that was causing exit. ** ** 43 8/03/98 10:40a Atai ** rename slpash dll to "3dfxspl3.dll" ** ** 42 8/03/98 6:41a Jdt ** removed gc argument from assertDefaultState, multi-thread changes ** ** 41 8/02/98 5:01p Dow ** Glide Surface Extension ** ** 39 7/20/98 10:49p Jdt ** Don't send chromarange to all chips on H3.... ** ** 38 7/18/98 1:45p Jdt ** Removed TACO_MEMORY_FIFO_HACK ** ** 37 7/18/98 10:41a Dow ** Num TMU ** ** 36 7/18/98 12:30a Jdt ** Remove reference to colorcombinedelta0mode ** Added initialzation for state restoreation buffer to initGC. ** Changes to reflect new shadow register structure. ** ** 35 7/17/98 10:44a Atai ** fixed grTexNCCTable and clip coords st with aspect ratio ** ** 34 7/16/98 8:19a Jdt ** TACO_MEMORY_FIFO_HACK now enables 1 window glide in window. ** ** more direct read protection. ** ** 33 7/13/98 10:43p Jdt ** Various Surface Implementation Changes ** ** 32 7/13/98 9:57p Jdt ** Removed guTexMemReset() ** ** Made initGC public. ** ** 31 7/01/98 12:41p Jdt ** Reorganized grSstWinOpen, factoring out initialization functionality ** that will be shared between fullscreen and windowed ** operation. ** Protected hacks for Glide/Win ( FX_TACO_MEMORY_FIFO_HACK ) ** ** 28 6/12/98 11:35a Atai ** temporary disable guGammaCorrectionRGB ** ** 27 6/11/98 12:53p Atai ** remove grGammaCorrectionValue ** ** 26 6/10/98 12:53p Atai ** replace grSstControl with grEnable/grDisable(GR_PASSTHRU) ** ** 25 6/10/98 11:58a Peter ** lfb tiled addressing ** ** 24 6/04/98 12:12p Peter ** splash dll rename ** ** 23 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 22 4/30/98 10:34a Peter ** merged w/ cvg again ** ** 20 4/22/98 4:57p Peter ** glide2x merge ** ** 19 3/30/98 3:28p Atai ** set gamma to 1.3 ** ** 18 3/13/98 4:03p Peter ** start glide3 merge ** ** 17 3/02/98 7:26p Peter ** clear slop on sli systems when changing y origin ** ** 16 2/23/98 11:44a Peter ** merged monitor detection and fixed compilation error from recent ** videobuffer changes ** ** 15 2/12/98 3:40p Peter ** single buffering for opengl ** ** 14 2/10/98 7:04p Atai ** fix grvertexlayout for migration dll ** ** 13 2/05/98 3:07p Atai ** fix migration dll ** ** 12 1/30/98 4:58p Atai ** fix gamma table parameters ** ** 11 1/30/98 4:29p Peter ** no uswc for sli slave ** ** 10 1/26/98 12:20p Atai ** fix grVertexLayout in grSplash() ** ** 9 1/26/98 11:30a Atai ** update to new glide.h ** ** 8 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 7 1/20/98 11:03a Peter ** env var to force triple buffering ** ** 6 1/18/98 12:03p Atai ** sync to rev 17 spec * * 5 1/17/98 2:26p Atai * fix grvertexlayout * * 4 1/17/98 1:12p Atai * set default as back buffer * * 3 1/16/98 6:54p Atai * disable gamma table for now * * 1 1/16/98 4:29p Atai * create glide 3 src * * 116 1/16/98 4:18p Atai * fixed lfb and grLoadGammaTable * * 115 1/16/98 10:47a Peter * fixed idle effage * * 114 1/16/98 10:16a Atai * fixed grSstIldle * * 113 1/10/98 4:01p Atai * inititialize vertex layout, viewport, added defines * * 110 1/06/98 6:47p Atai * undo grSplash and remove gu routines * * 109 1/06/98 3:53p Atai * remove grHint, modify grLfbWriteRegion and grGet * * 107 12/18/97 2:12p Peter * grSstControl on v2 * * 106 12/17/97 4:48p Peter * groundwork for CrybabyGlide * * 105 12/17/97 4:06p Atai * added grChromaRange(), grGammaCorrecionRGB(), grRest(), and grGet() * functions * * 104 12/16/97 1:33p Atai * added grGammaCorrectionRGB() * * 103 12/16/97 10:03a Atai * fixed gutexmemreset for glide2 * * 101 12/09/97 12:20p Peter * mac glide port * * 100 12/05/97 4:26p Peter * watcom warnings * * 99 12/03/97 11:35a Peter * is busy thing * * 98 11/25/97 12:09p Peter * nested calls to grLfbLock vs init code locking on v2 * * 97 11/21/97 1:02p Peter * v^2 supported resolutions * * 96 11/21/97 11:19a Dow * Added RESOLUTION_NONE hack for Banshee * * 95 11/19/97 2:49p Peter * env vars in registry for win32 * * 94 11/19/97 2:22p Dow * gsst.c * * 93 11/18/97 4:50p Peter * chipfield stuff cleanup and w/ direct writes * * 92 11/18/97 4:00p Atai * fixed the GR_BEGIN and GR_END error in previous check-in * * 91 11/18/97 3:27p Atai * update vData * optimize state monster * * 90 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 89 11/16/97 2:20p Peter * cleanup * * 88 11/15/97 7:43p Peter * more comdex silliness * * 87 11/14/97 11:10p Peter * open vs hw init confusion * * 86 11/14/97 5:02p Peter * more comdex stuff * * 85 11/14/97 4:47p Dow * New splash screen * * 84 11/14/97 12:09a Peter * comdex thing and some other stuff * * 83 11/12/97 9:37p Dow * Banshee crap * * 82 11/12/97 2:27p Peter * simulator happiness w/o fifo * * 81 11/12/97 1:09p Dow * H3 Stuf * * 80 11/12/97 9:22a Dow * H3 Mods * * 79 11/06/97 3:46p Peter * sli shutdown problem * * 78 11/06/97 3:38p Dow * More banshee stuff * * 77 11/04/97 5:04p Peter * cataclysm part deux * * 76 11/04/97 3:58p Dow * Banshee stuff * * 75 11/03/97 3:43p Peter * h3/cvg cataclysm * * 74 10/29/97 4:59p Peter * fixed csim/non-debug stupidity * * 73 10/29/97 2:45p Peter * C version of Taco's packing code * * 72 10/23/97 5:28p Peter * sli fifo thing * * 71 10/17/97 3:15p Peter * grSstVidMode thingee * * 70 10/14/97 2:44p Peter * moved close flag set * * 69 10/09/97 8:02p Dow * State Monster 1st Cut * ** */ #include #include #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #endif #if (GLIDE_PLATFORM & GLIDE_OS_MACOS) #define __MACERRORS__ #include #endif #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #ifdef HAL_CSIM #include static FxU32 lostcontext_csim; #elif HSIM #include #endif #endif /* (GLIDE_PLATFORM & GLIDE_SST_SIM) */ #ifdef DRI_BUILD #include #endif #define kPageBoundarySlop 0x1000UL #define kPageBoundaryMask (kPageBoundarySlop - 1) /* Some forward declarations */ #ifdef FX_GLIDE_NAPALM static void _grSstSetColumnsOfNWidth(FxU32 width); #endif /* FX_GLIDE_NAPALM */ /* Init hw */ ResEntry _resTable[] = { {GR_RESOLUTION_320x200, 320, 200}, /* 0x0 */ {GR_RESOLUTION_320x240, 320, 240}, /* 0x1 */ {GR_RESOLUTION_400x256, 400, 256}, /* 0x2 */ {GR_RESOLUTION_512x384, 512, 384}, /* 0x3 */ {GR_RESOLUTION_640x200, 640, 200}, /* 0x4 */ {GR_RESOLUTION_640x350, 640, 350}, /* 0x5 */ {GR_RESOLUTION_640x400, 640, 400}, /* 0x6 */ {GR_RESOLUTION_640x480, 640, 480}, /* 0x7 */ {GR_RESOLUTION_800x600, 800, 600}, /* 0x8 */ {GR_RESOLUTION_960x720, 960, 720}, /* 0x9 */ {GR_RESOLUTION_856x480, 856, 480}, /* 0xa */ {GR_RESOLUTION_512x256, 512, 256}, /* 0xb */ {GR_RESOLUTION_1024x768, 1024, 768}, /* 0xC */ {GR_RESOLUTION_1280x1024, 1280, 1024}, /* 0xD */ {GR_RESOLUTION_1600x1200, 1600, 1200}, /* 0xE */ {GR_RESOLUTION_400x300, 400, 300}, /* 0xF */ {GR_RESOLUTION_1152x864, 1152, 864}, /* 0x10 */ {GR_RESOLUTION_1280x960, 1280, 960}, /* 0x11 */ {GR_RESOLUTION_1600x1024, 1600, 1024}, /* 0x12 */ {GR_RESOLUTION_1792x1344, 1792, 1344}, /* 0x13 */ {GR_RESOLUTION_1856x1392, 1856, 1392}, /* 0x14 */ {GR_RESOLUTION_1920x1440, 1920, 1440}, /* 0x15 */ {GR_RESOLUTION_2048x1536, 2048, 1536}, /* 0x16 */ {GR_RESOLUTION_2048x2048, 2048, 2048} /* 0x17 */ }; /* --------------------------------------------- This function both sets and documents the expected default state for any rendering context ..taco - separated out in preparation for multiple contexts ---------------------------------------------*/ void assertDefaultState( void ) { GR_DCL_GC; GrTexInfo textureinfo = { GR_LOD_LOG2_1, GR_LOD_LOG2_1, GR_ASPECT_LOG2_1x1, GR_TEXFMT_8BIT, 0 }; #if FX_GLIDE_NAPALM if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); } #endif /* Just set this once. */ gc->state.shadow.fbzColorPath = SST_PARMADJUST; grDisable(GR_ALLOW_MIPMAP_DITHER); grSstOrigin(gc->state.origin); grAlphaBlendFunction(GR_BLEND_ONE , GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO); grAlphaTestFunction(GR_CMP_ALWAYS); grAlphaTestReferenceValue(0); grChromakeyMode(GR_CHROMAKEY_DISABLE); grChromaRangeMode( GR_CHROMAKEY_DISABLE ); grTexChromaMode( GR_TMU0, GR_TEXCHROMA_DISABLE_EXT ); grConstantColorValue((FxU32) ~0); #if FX_GLIDE_NAPALM if(IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { /* Make sure 2PPC stuff is in a known state. */ gc->state.shadow.combineMode = SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK; _grTex2ppc(FXFALSE); grColorCombineExt(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); grTexColorCombineExt(GR_TMU0, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXFALSE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); grTexColorCombineExt(GR_TMU1, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXFALSE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); grAlphaCombineExt(GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); grTexAlphaCombineExt(GR_TMU0, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXFALSE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); grTexAlphaCombineExt(GR_TMU1, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXFALSE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_OP_ADD, GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_OP_ADD); grColorMaskExt(FXTRUE, FXTRUE, FXTRUE, FXTRUE); grStencilMask(0); gc->state.tbufferMask = 0xff/*0xf*/; /* KoolSmoky - enable 8 tbuffers for 4 chip config */ } #endif grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_ITERATED, FXFALSE); grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE); grColorMask(FXTRUE, FXFALSE); grCullMode(GR_CULL_DISABLE); grDepthBiasLevel(0); grDepthMask(FXFALSE); grDepthBufferMode(GR_DEPTHBUFFER_DISABLE); grDepthBufferFunction(GR_CMP_LESS); grDepthBiasLevel(0); grDitherMode(GR_DITHER_2x2); grFogMode(GR_FOG_DISABLE); grFogColorValue(0x00000000); /* ** initialize default state for viewport and grVertexLayout */ grCoordinateSpace(GR_WINDOW_COORDS); grViewport(0, 0, gc->state.screen_width, gc->state.screen_height ); switch (gc->num_tmu) { case 2: grTexClampMode(GR_TMU1, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP); grTexDetailControl(GR_TMU1, 0, 1, 1.0F); grTexFilterMode(GR_TMU1, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED); grTexLodBiasValue(GR_TMU1, 0.5F); grTexMipMapMode(GR_TMU1, GR_MIPMAP_DISABLE, FXFALSE); grTexCombine(GR_TMU1, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); /* Intentional fallthrough */ /* ** napalm glide place its fifo at low address 0, to prevent tmu read ** from fifo, we initialize the tmu base address to its min address */ if ((IS_NAPALM(gc->bInfo->pciInfo.deviceID)) && (!gc->windowed)) { grTexSource(GR_TMU1, grTexMinAddress(GR_TMU1), GR_MIPMAPLEVELMASK_BOTH, &textureinfo); } case 1: grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP); grTexDetailControl(GR_TMU0, 0, 1, 1.0F); grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED); grTexLodBiasValue(GR_TMU0, 0.5F); grTexMipMapMode(GR_TMU0, GR_MIPMAP_DISABLE, FXFALSE); grTexCombine(GR_TMU0, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); if ((IS_NAPALM(gc->bInfo->pciInfo.deviceID)) && (!gc->windowed)) { grTexSource(GR_TMU0, grTexMinAddress(GR_TMU0), GR_MIPMAPLEVELMASK_BOTH, &textureinfo); } } grLfbConstantAlpha(0xFF); grLfbConstantDepth(0); gc->triSetupProc = CUR_TRI_PROC(FXTRUE, (gc->state.cull_mode != GR_CULL_DISABLE)); /* Napalm-specific initialization kruft */ if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grSstSetColumnsOfNWidth(8); /* 8 is default for now */ } gc->state.mode2ppc = FXFALSE; gc->state.mode2ppcTMU = 0xFFFFFFFF; } /* assertDefaultState */ #ifndef DRI_BUILD static void clearBuffers( GrGC *gc ) { /* Get rid of crap in the buffers. */ grClipWindow(0, 0, gc->state.screen_width, gc->state.screen_height); if ( gc->state.num_buffers > 1 ) { grBufferClear( 0, 0, 0UL ); grBufferSwap( 1 ); grBufferClear( 0, 0, 0xFFFFFFFFUL ); grBufferSwap( 1 ); grBufferClear( 0, 0, 0xFFFFFFFFUL ); grBufferSwap( 1 ); grRenderBuffer( GR_BUFFER_BACKBUFFER ); } else { grBufferClear( 0, 0, 0xFFFFFFFFUL ); grRenderBuffer( GR_BUFFER_FRONTBUFFER ); } } /* clearBuffers */ #else /* defined(DRI_BUILD) */ static void clearBuffers( GrGC *gc ) { /* Get rid of crap in the buffers. */ grClipWindow(0, 0, gc->state.screen_width, gc->state.screen_height); if ( gc->state.num_buffers > 1 ) { grBufferClear( 0, 0, 0UL ); grDRIBufferSwap( 1 ); grBufferClear( 0, 0, 0xFFFFFFFFUL ); grDRIBufferSwap( 1 ); grBufferClear( 0, 0, 0xFFFFFFFFUL ); grDRIBufferSwap( 1 ); grRenderBuffer( GR_BUFFER_BACKBUFFER ); } else { grBufferClear( 0, 0, 0xFFFFFFFFUL ); grRenderBuffer( GR_BUFFER_FRONTBUFFER ); } } /* clearBuffers */ #endif /* defined(DRI_BUILD) */ static void doSplash( void ) { GR_DCL_GC; /* The splash screen wants a swapped Y origin, which doesn't * work in all SLI configs. */ if(_GlideRoot.environment.sliBandHeightForce) return; if (_GlideRoot.environment.noSplash == 0) { #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) { FxBool didLoad; if (gc->pluginInfo.moduleHandle == NULL) gc->pluginInfo.moduleHandle = LoadLibrary("3dfxspl3.dll"); didLoad = (gc->pluginInfo.moduleHandle != NULL); if (didLoad) { gc->pluginInfo.initProc = (GrSplashInitProc)GetProcAddress(gc->pluginInfo.moduleHandle, "_fxSplashInit@24"); gc->pluginInfo.shutdownProc = (GrSplashShutdownProc)GetProcAddress(gc->pluginInfo.moduleHandle, "_fxSplashShutdown@0"); gc->pluginInfo.splashProc = (GrSplashProc)GetProcAddress(gc->pluginInfo.moduleHandle, "_fxSplash@20"); gc->pluginInfo.plugProc = (GrSplashPlugProc)GetProcAddress(gc->pluginInfo.moduleHandle, "_fxSplashPlug@16"); didLoad = ((gc->pluginInfo.initProc != NULL) && (gc->pluginInfo.splashProc != NULL) && (gc->pluginInfo.plugProc != NULL) && (gc->pluginInfo.shutdownProc != NULL)); if (didLoad) { GrState glideState; /* Protect ourselves from the splash screen */ grGlideGetState(&glideState); { didLoad = (*gc->pluginInfo.initProc)(gc->grHwnd, gc->state.screen_width, gc->state.screen_height, gc->grColBuf, gc->grAuxBuf, gc->state.color_format); if (!didLoad) (*gc->pluginInfo.shutdownProc)(); } grGlideSetState((const void*)&glideState); } if (!didLoad) FreeLibrary(gc->pluginInfo.moduleHandle); } /* Clear all the info if we could not load for some reason */ if (!didLoad) memset(&gc->pluginInfo, 0, sizeof(gc->pluginInfo)); } #else { FxBool didLoad; gc->pluginInfo.initProc = fxSplashInit; gc->pluginInfo.shutdownProc = fxSplashShutdown; gc->pluginInfo.splashProc = fxSplash; gc->pluginInfo.plugProc = fxSplashPlug; didLoad = ((gc->pluginInfo.initProc != NULL) && (gc->pluginInfo.splashProc != NULL) && (gc->pluginInfo.plugProc != NULL) && (gc->pluginInfo.shutdownProc != NULL)); if (didLoad) { GrState glideState; /* Protect ourselves from the splash screen */ grGlideGetState(&glideState); { didLoad = (*gc->pluginInfo.initProc)(gc->grHwnd, gc->state.screen_width, gc->state.screen_height, gc->grColBuf, gc->grAuxBuf, gc->state.color_format); if (!didLoad) (*gc->pluginInfo.shutdownProc)(); } grGlideSetState((const void*)&glideState); } /* Clear all the info if we could not load for some reason */ if (!didLoad) memset(&gc->pluginInfo, 0, sizeof(gc->pluginInfo)); } #endif /* (GLIDE_PLATFORM & GLIDE_OS_WIN32) */ grSplash(0.0f, 0.0f, (float)gc->state.screen_width, (float)gc->state.screen_height, 0); } _GlideRoot.environment.noSplash = 1; } /* doSplash */ /*---------------------------------------------------- Return a GC to reset state ...taco - separated out as a first pass since this will be common function per context ----------------------------------------------------*/ void initGC ( GrGC *gc ) { #define FN_NAME "initGC" FxI32 t = 0; GDBG_INFO(95, FN_NAME"(0x%X)\n", gc); #if _FIFODUMP gc->myLevel = 0; /* KoolSmoky */ #endif /* Setup the indices of the logical buffers */ #ifdef DRI_BUILD gc->curBuffer = (gc->grColBuf > 1) ? 1 : 0; gc->frontBuffer = 0; #else /* defined(DRI_BUILD) */ gc->curBuffer = 0; gc->frontBuffer = ((gc->grColBuf > 1) ? 1 : 0); #endif /* defined(DRI_BUILD) */ gc->backBuffer = (gc->grColBuf > 2) ? 2 : gc->curBuffer; for (t = 0; t < MAX_BUFF_PENDING; t++) { gc->bufferSwaps[t] = 0xffffffff; } gc->bufferSwaps[0] = ((FxU32) gc->cmdTransportInfo.fifoPtr - (FxU32) gc->cmdTransportInfo.fifoStart); gc->swapsPending = 1; gc->lockPtrs[GR_LFB_READ_ONLY] = (FxU32)-1; gc->lockPtrs[GR_LFB_WRITE_ONLY] = (FxU32)-1; /* initialize command packet headers for state restore buffer */ gc->state.shadow.pkt4Hdr_0 = 0x1 << 11 | /* note, don't send chromarange to tmu... */ ( SR_MASK_0 << SSTCP_PKT4_MASK_SHIFT ) | SSTCP_REGBASE_FROM_ADDR( SR_ADDR_0 ) | SSTCP_PKT4; gc->state.shadow.pkt4Hdr_1 = ( SR_MASK_1 << SSTCP_PKT4_MASK_SHIFT ) | SSTCP_REGBASE_FROM_ADDR( SR_ADDR_1 ) | SSTCP_PKT4; gc->state.shadow.pkt1Hdr_2 = ( SR_WORDS_2 << SSTCP_PKT1_NWORDS_SHIFT ) | SSTCP_INC | SSTCP_REGBASE_FROM_ADDR( SR_ADDR_2 ) | SSTCP_PKT1; gc->state.shadow.pkt4Hdr_3 = ( SR_MASK_3 << SSTCP_PKT4_MASK_SHIFT ) | SSTCP_REGBASE_FROM_ADDR( SR_ADDR_3 ) | SSTCP_PKT4; for( t = 0; t < 32; t++ ) { gc->state.shadow.paletteRow[t].pkt1Hdr_P = ( SR_WORDS_P << SSTCP_PKT1_NWORDS_SHIFT ) | SSTCP_INC | SSTCP_REGBASE_FROM_ADDR( SR_ADDR_P ) | SSTCP_PKT1; } /* Initialize the read/write registers to all 0 */ gc->state.shadow.fbzColorPath = 0; gc->state.shadow.fogMode = 0; gc->state.shadow.alphaMode = 0; gc->state.shadow.fbzMode = 0; gc->state.shadow.lfbMode = 0; gc->state.shadow.clipLeftRight = 0; gc->state.shadow.clipBottomTop = 0; gc->state.shadow.fogColor = 0; gc->state.shadow.zaColor = 0; gc->state.shadow.chromaKey = 0; gc->state.shadow.stipple = 0; gc->state.shadow.color0 = 0; gc->state.shadow.color1 = 0; /* for fog coords and prepare for Napalm */ gc->state.depth_range = 65535.f; /* NB: This loop has to setup the packet headers for *ALL* of the * tmu persistent state. F*ck this up at your own peril because * someone who cares about running glide in a window will come and * kill you as you sit in your cube. */ #if defined( USE_PACKET_FIFO ) for (t = 0; t < GLIDE_NUM_TMU; t ++) { gc->state.shadow.tmuState[t].texPkt4Hdr_0 = (( SR_MASK_4 << SSTCP_PKT4_MASK_SHIFT ) | FIFO_REG((0x02UL << t), textureMode) | SSTCP_PKT4); gc->state.shadow.tmuState[t].textureMode = 0x00000000; gc->state.shadow.tmuState[t].tLOD = 0x00000000; gc->state.shadow.tmuState[t].tDetail = 0x00000000; gc->state.shadow.tmuState[t].texBaseAddr = 0x00000000; gc->state.shadow.tmuState[t].texBaseAddr_1 = 0x00000000; gc->state.shadow.tmuState[t].texBaseAddr_2 = 0x00000000; gc->state.shadow.tmuState[t].texBaseAddr_3_8 = 0x00000000; gc->state.shadow.tmuState[t].texPkt4Hdr_1 = ( SR_MASK_5 << SSTCP_PKT4_MASK_SHIFT ) | FIFO_REG((0x02UL << t), chromaKey) | SSTCP_PKT4; gc->state.shadow.tmuState[t].texPkt1Hdr_2 = ( SR_WORDS_6 << SSTCP_PKT1_NWORDS_SHIFT ) | SSTCP_INC | FIFO_REG((0x02UL << t), nccTable0) | SSTCP_PKT1; #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { gc->state.shadow.tmuState[t].texPkt4Hdr_3 = ( SR_MASK_7 << SSTCP_PKT4_MASK_SHIFT ) | FIFO_REG((0x02UL << t), combineMode) | SSTCP_PKT4; gc->state.shadow.tmuState[t].combineMode = 0x00000000; } #endif gc->tmuMemInfo[t].prePacket[0] = ((0x01UL << SSTCP_PKT1_NWORDS_SHIFT) | FIFO_REG_WAX(command) | SSTCP_PKT1); gc->tmuMemInfo[t].prePacket[1] = (SSTG_NOP + SSTG_GO); gc->tmuMemInfo[t].postPacket[0] = ((0x01UL << SSTCP_PKT1_NWORDS_SHIFT) | FIFO_REG((0x02UL << t), texBaseAddr) | SSTCP_PKT1); gc->tmuMemInfo[t].postPacket[1] = ~gc->state.shadow.tmuState[t].texBaseAddr; gc->tmuMemInfo[t].postPacket[2] = ((0x01UL << SSTCP_PKT1_NWORDS_SHIFT) | FIFO_REG(BROADCAST_ID, nopCMD) | SSTCP_PKT1); gc->tmuMemInfo[t].postPacket[3] = 0x00UL; gc->tmuMemInfo[t].postPacket[4] = ((0x01UL << SSTCP_PKT1_NWORDS_SHIFT) | FIFO_REG((0x02UL << t), texBaseAddr) | SSTCP_PKT1); gc->tmuMemInfo[t].postPacket[5] = gc->state.shadow.tmuState[t].texBaseAddr; gc->tmuMemInfo[t].postPacket[6] = ((0x01UL << SSTCP_PKT1_NWORDS_SHIFT) | FIFO_REG_WAX(command) | SSTCP_PKT1); gc->tmuMemInfo[t].postPacket[7] = (SSTG_NOP + SSTG_GO); /* This is the signal to flush */ gc->tmuMemInfo[t].flushCount = 1; gc->state.per_tmu[t].mmMode = GR_MIPMAP_NEAREST; gc->state.per_tmu[t].smallLod = GR_LOD_LOG2_1; gc->state.per_tmu[t].largeLod = GR_LOD_LOG2_1; gc->state.per_tmu[t].s_scale = 256.f; gc->state.per_tmu[t].t_scale = 256.f; gc->state.per_tmu[t].evenOdd = GR_MIPMAPLEVELMASK_BOTH; gc->state.per_tmu[t].nccTable = GR_NCCTABLE_NCC0; gc->state.per_tmu[t].texSubLodDither = FXFALSE; } #endif #undef FN_NAME } /* initGC */ /*------------------------------------------------------------------- Function: grSstWinOpen Date: 3/16 Implementor(s): dow, gmt, murali, jdt Mutator: dpc Library: Glide Description: Initialize the selected SST Arguments: hwnd - pointer to a window handle or null. If NULL, then the application window handle will be inferred though the GetActiveWindow() api. resolution - either one of the pre-defined glide resolutions, or GR_RESOLUTION_NONE, in which case the window size is inferred from the size application window refresh - requested fullscreen refresh rate, ignored in a window format - requested ccolor format for glide packed color values origin - location of coordinate origin either upper left or lower left nColBuffers - number of color buffers to attempt to allocate 0 - meaningless 1 - allocate a front buffer only 2 - allocate a front and back buffer 3 - allocate a front, back, aux buffer for triple buffering nAuxBuffers - number of aux buffers to attempt to allocate 0 - no alpha or z buffers 1 - allocate one aux buffer for alpha/depth buffering 2 - allocate one depth and one alpha buffer (unsup) Return: NULL - glide was unable to create a fullscreen context context handle - glide was able to create a context with handle H -------------------------------------------------------------------*/ GR_ENTRY(grSstWinOpen, GrContext_t, ( FxU32 hWnd, GrScreenResolution_t resolution, GrScreenRefresh_t refresh, GrColorFormat_t format, GrOriginLocation_t origin, int nColBuffers, int nAuxBuffers) ) { #define FN_NAME "grSstWinOpen" #define TILE_WIDTH_PXLS 64 #define TILE_HEIGHT_PXLS 32 #define BYTES_PER_PIXEL 2 #define MIN_TEXTURE_STORE 0x200000 #define MIN_FIFO_SIZE 0x10000 #if defined( GLIDE_INIT_HWC ) hwcBoardInfo *bInfo = 0; hwcVidInfo *vInfo = 0; hwcBufferInfo *bufInfo = 0; hwcFifoInfo *fInfo = 0; #elif defined( GLIDE_INIT_HAL ) FxDeviceInfo devInfo; hwcBoardInfo *bInfo = 0; hwcVidInfo *vInfo = 0; hwcBufferInfo *bufInfo = 0; hwcFifoInfo *fInfo = 0; #endif /* defined ( GLIDE_INIT_HAL ) */ struct cmdTransportInfo *gcFifo = 0; GrContext_t retVal = 0; #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) if (!hWnd) hWnd = (FxU32) GetActiveWindow(); if (!hWnd) GrErrorCallback("grSstWinOpen: need to use a valid window handle", FXTRUE); /* GDBG_INFO(80, "Setting hwnd to foreground.\n"); SetForegroundWindow((HWND)hWnd); */ #endif /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) */ /* NB: TLS must be setup before the 'declaration' which grabs the * current gc. This gc is valid for all threads in the fullscreen * context. */ setThreadValue( (FxU32)&_GlideRoot.GCs[_GlideRoot.current_sst] ); { /* Partial Argument Validation */ GR_BEGIN_NOFIFOCHECK_NORET("grSstWinOpen",80); GDBG_INFO_MORE(gc->myLevel, "(rez=%d,ref=%d,cformat=%d,origin=%s,#bufs=%d, #abufs=%d)\n", resolution,refresh,format, origin ? "LL" : "UL", nColBuffers, nAuxBuffers); GR_CHECK_F(FN_NAME, !gc, "no SST selected as current (gc==NULL)"); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { GrPixelFormat_t thePixelFormat = GR_PIXFMT_RGB_565 ; #if 0 /**/ /* All this stuff lets Joe bag-o-donuts force old apps */ /* to render with 32bpp and AA modes. */ /* */ if (_GlideRoot.environment.outputBpp == 32) { /* Force rendering to 32bpp */ if ((_GlideRoot.environment.aaSample == 8) && /* 8xaa */ (gc->chipCount > 2)) thePixelFormat = GR_PIXFMT_AA_8_ARGB_8888 ; else if ((_GlideRoot.environment.aaSample == 4) && (gc->chipCount > 1)) thePixelFormat = GR_PIXFMT_AA_4_ARGB_8888 ; else if (_GlideRoot.environment.aaSample == 2) thePixelFormat = GR_PIXFMT_AA_2_ARGB_8888 ; else thePixelFormat = GR_PIXFMT_ARGB_8888 ; } else { /* default rendering to 16bpp */ if ((_GlideRoot.environment.aaSample == 8) && /* 8xaa */ (gc->chipCount > 2)) thePixelFormat = GR_PIXFMT_AA_8_RGB_565 ; else if ((_GlideRoot.environment.aaSample == 4) && (gc->chipCount > 1)) thePixelFormat = GR_PIXFMT_AA_4_RGB_565 ; else if (_GlideRoot.environment.aaSample == 2) thePixelFormat = GR_PIXFMT_AA_2_RGB_565 ; else thePixelFormat = GR_PIXFMT_RGB_565 ; } #endif return ( grSstWinOpenExt(hWnd, resolution, refresh, format, origin, thePixelFormat, nColBuffers, nAuxBuffers) ); } #endif return ( grSstWinOpenExt(hWnd, resolution, refresh, format, origin, GR_PIXFMT_RGB_565, nColBuffers, nAuxBuffers) ); } #undef FN_NAME } /* grSstWinOpen */ #ifdef FX_GLIDE_NAPALM /*------------------------------------------------------------------- Function: grSstWinOpenExt Date: 3/16 Implementor(s): dow, gmt, murali, jdt Mutator: dpc Library: Glide Description: Initialize the selected SST Arguments: hwnd - pointer to a window handle or null. If NULL, then the application window handle will be inferred though the GetActiveWindow() api. resolution - either one of the pre-defined glide resolutions, or GR_RESOLUTION_NONE, in which case the window size is inferred from the size application window refresh - requested fullscreen refresh rate, ignored in a window format - requested ccolor format for glide packed color values origin - location of coordinate origin either upper left or lower left pixelformat - requested pixel format nColBuffers - number of color buffers to attempt to allocate 0 - meaningless 1 - allocate a front buffer only 2 - allocate a front and back buffer 3 - allocate a front, back, aux buffer for triple buffering nAuxBuffers - number of aux buffers to attempt to allocate 0 - no alpha or z buffers 1 - allocate one aux buffer for alpha/depth buffering 2 - allocate on depth and one alpha buffer (unsup) fsAA - type of full screen AA algorithm Return: NULL - glide was unable to create a fullscreen context context handle - glide was able to create a context with handle H -------------------------------------------------------------------*/ GR_EXT_ENTRY(grSstWinOpenExt, GrContext_t, ( FxU32 hWnd, GrScreenResolution_t resolution, GrScreenRefresh_t refresh, GrColorFormat_t format, GrOriginLocation_t origin, GrPixelFormat_t pixelformat, int nColBuffers, int nAuxBuffers) ) { #define FN_NAME "grSstWinOpenExt" #define TILE_WIDTH_PXLS 64 #define TILE_HEIGHT_PXLS 32 #define BYTES_PER_PIXEL 2 #define MIN_TEXTURE_STORE 0x200000 #define MIN_FIFO_SIZE 0x10000 #if defined( GLIDE_INIT_HWC ) hwcBoardInfo *bInfo = 0; hwcVidInfo *vInfo = 0; hwcBufferInfo *bufInfo = 0; hwcFifoInfo *fInfo = 0; FxU32 hwPixelFormat; #elif defined( GLIDE_INIT_HAL ) FxDeviceInfo devInfo; hwcBoardInfo *bInfo = 0; hwcVidInfo *vInfo = 0; hwcBufferInfo *bufInfo = 0; hwcFifoInfo *fInfo = 0; #endif /* defined ( GLIDE_INIT_HAL ) */ int buffer; struct cmdTransportInfo *gcFifo = 0; GrContext_t retVal = 0; FxU32 tramShift, tmu1Offset; #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) if (!hWnd) hWnd = (FxU32) GetActiveWindow(); if (!hWnd) GrErrorCallback("grSstWinOpen: need to use a valid window handle", FXTRUE); /* GDBG_INFO(80, "Setting hwnd to foreground.\n"); SetForegroundWindow((HWND)hWnd); */ /* Want Windowed Mode */ if (resolution == GR_RESOLUTION_NONE) { extern GrContext_t _grCreateWindowSurface(FxU32 hWnd, GrColorFormat_t format, GrOriginLocation_t origin, GrPixelFormat_t pixelformat, int nAuxBuffer); return _grCreateWindowSurface(hWnd, format, origin, pixelformat, nAuxBuffers); } #endif /* (GLIDE_PLATFORM & GLIDE_OS_UNIX) || defined(__DJGPP__) */ /* NB: TLS must be setup before the 'declaration' which grabs the * current gc. This gc is valid for all threads in the fullscreen * context. */ setThreadValue( (FxU32)&_GlideRoot.GCs[_GlideRoot.current_sst] ); { /* Partial Argument Validation */ GR_BEGIN_NOFIFOCHECK_NORET("grSstWinOpen",80); GDBG_INFO_MORE(gc->myLevel, "(rez=%d,ref=%d,cformat=%d,origin=%s,#bufs=%d, #abufs=%d)\n", resolution,refresh,format, origin ? "LL" : "UL", nColBuffers, nAuxBuffers); GR_CHECK_F(FN_NAME, !gc, "no SST selected as current (gc==NULL)"); /* ** check if the environment variable for triple buffering is on */ if (_GlideRoot.environment.nColorBuffer != -1) { if ((_GlideRoot.environment.nColorBuffer > 0) && (_GlideRoot.environment.nColorBuffer <= 3) ){ nColBuffers = _GlideRoot.environment.nColorBuffer; } } resolution = (((FxU32)resolution) > (sizeof(_resTable) / sizeof(ResEntry))) ? GR_RESOLUTION_640x480 : resolution; #ifdef DRI_BUILD gc->state.screen_width = driInfo.screenWidth; gc->state.screen_height = driInfo.screenHeight; #else /* defined(DRI_BUILD) */ gc->state.screen_width = _resTable[resolution].xres; gc->state.screen_height = _resTable[resolution].yres; GR_CHECK_F( FN_NAME, resolution != _resTable[resolution].resolution, "resolution table compilation incorrect" ); if ( gc->vidTimings ) { gc->state.screen_width = gc->vidTimings->xDimension; gc->state.screen_height = gc->vidTimings->yDimension; } #endif /* defined(DRI_BUILD) */ /* this is a stupid hack but... */ gc->chipCount = 1; /* Set this to 0 by detault */ gc->state.forced32BPP = 0; if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { /* I apologize for this hack: * if glide was previously in a half-mode * gc->chipCount was forced to one. * It should be restored before we try to use it. */ gc->chipCount = gc->bInfo->pciInfo.numChips ; /* All this stuff lets Joe bag-o-donuts force old apps */ /* to render with 32bpp and AA modes. */ /* Bear in mind: it is silly to try to force 16bpp */ /* rendering since we don't want to scale down the */ /* apps Z or W values to fit in a 16 bit depth buffer. */ if (_GlideRoot.environment.outputBpp == 32 || pixelformat == GR_PIXFMT_ARGB_8888) { // App requested 16 bit, but we are giving 32. Need to remember for framebuffer access if (pixelformat == GR_PIXFMT_ARGB_1555 || pixelformat == GR_PIXFMT_AA_2_ARGB_1555 || pixelformat == GR_PIXFMT_AA_4_ARGB_1555 || pixelformat == GR_PIXFMT_AA_8_ARGB_1555) { gc->state.forced32BPP = 15; } else if (pixelformat == GR_PIXFMT_RGB_565 || pixelformat == GR_PIXFMT_AA_2_RGB_565 || pixelformat == GR_PIXFMT_AA_4_RGB_565 || pixelformat == GR_PIXFMT_AA_8_RGB_565) { gc->state.forced32BPP = 16; } if ((_GlideRoot.environment.aaSample == 8) && /* 8xaa */ (gc->chipCount > 2)) { pixelformat = GR_PIXFMT_AA_8_ARGB_8888; } else if ((_GlideRoot.environment.aaSample == 4) && (gc->chipCount > 1)) { pixelformat = GR_PIXFMT_AA_4_ARGB_8888; } else if (_GlideRoot.environment.aaSample == 2) { pixelformat = GR_PIXFMT_AA_2_ARGB_8888; } else { pixelformat = GR_PIXFMT_ARGB_8888; } } else if (_GlideRoot.environment.outputBpp == 15 || pixelformat == GR_PIXFMT_ARGB_1555) { if ((_GlideRoot.environment.aaSample == 8) && /* 8xaa */ (gc->chipCount > 2)) { pixelformat = GR_PIXFMT_AA_8_ARGB_1555; } else if ((_GlideRoot.environment.aaSample == 4) && (gc->chipCount > 1)) { pixelformat = GR_PIXFMT_AA_4_ARGB_1555; } else if (_GlideRoot.environment.aaSample == 2) { pixelformat = GR_PIXFMT_AA_2_ARGB_1555; } else { pixelformat = GR_PIXFMT_ARGB_1555; } } else if (pixelformat == GR_PIXFMT_RGB_565) { if ((_GlideRoot.environment.aaSample == 8) && /* 8xaa */ (gc->chipCount > 2)) { pixelformat = GR_PIXFMT_AA_8_RGB_565; } else if ((_GlideRoot.environment.aaSample == 4) && (gc->chipCount > 1)) { pixelformat = GR_PIXFMT_AA_4_RGB_565; } else if (_GlideRoot.environment.aaSample == 2) { pixelformat = GR_PIXFMT_AA_2_RGB_565; } else { pixelformat = GR_PIXFMT_RGB_565; } } } /* Automagic SLI band height settings *//* magical indeed */ if(gc->state.screen_height >= 768) { gc->sliBandHeight = 5; } else { gc->sliBandHeight = 4; } GDBG_INFO(80,"Default band height: %d\n",gc->sliBandHeight); /* Allow user override (within reason). */ if(_GlideRoot.environment.sliBandHeight != 0) { GDBG_INFO(80,"User set sli band height to: %d\n",_GlideRoot.environment.sliBandHeight); gc->sliBandHeight = _GlideRoot.environment.sliBandHeight; if(gc->sliBandHeight < 1) { GDBG_INFO(80,"Clamping band height to 1.\n"); gc->sliBandHeight = 1; } else if(gc->sliBandHeight > 5) { GDBG_INFO(80,"Clamping band height to 5.\n"); gc->sliBandHeight = 5; } } #ifdef DRI_BUILD /* The DRI knows how the framebuffer should be configured */ if (driInfo.cpp==3 || driInfo.cpp==4) { /* 24 or 32bpp modes */ /* XXX Check for AA flags here too */ pixelformat = GR_PIXFMT_ARGB_8888; } #endif gc->state.origin = origin; gc->grSstRez = resolution; gc->grSstRefresh = refresh; gc->grColBuf = gc->state.num_buffers = nColBuffers; gc->grAuxBuf = nAuxBuffers; gc->fbStride = gc->state.screen_width * BYTES_PER_PIXEL; gc->grHwnd = (int) hWnd; gc->grPixelFormat = (int) pixelformat; gc->chipmask = SST_CHIP_MASK_ALL_CHIPS; switch (pixelformat) { case GR_PIXFMT_RGB_565: gc->grPixelSample = 1; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB565D; break; case GR_PIXFMT_ARGB_1555: gc->grPixelSample = 1; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555D; break; case GR_PIXFMT_ARGB_8888: gc->grPixelSample = 1; gc->grPixelSize = 4; hwPixelFormat = SST_OVERLAY_PIXEL_RGB32U; break; case GR_PIXFMT_AA_2_RGB_565: gc->grPixelSample = 2; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB565U; break; case GR_PIXFMT_AA_2_ARGB_1555: gc->grPixelSample = 2; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555U; break; case GR_PIXFMT_AA_2_ARGB_8888: gc->grPixelSample = 2; gc->grPixelSize = 4; hwPixelFormat = SST_OVERLAY_PIXEL_RGB32U; break; case GR_PIXFMT_AA_4_RGB_565: gc->grPixelSample = 4; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB565U; break; case GR_PIXFMT_AA_4_ARGB_1555: gc->grPixelSample = 4; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555U; break; case GR_PIXFMT_AA_4_ARGB_8888: gc->grPixelSample = 4; gc->grPixelSize = 4; hwPixelFormat = SST_OVERLAY_PIXEL_RGB32U; break; case GR_PIXFMT_AA_8_RGB_565: /* 8xaa */ gc->grPixelSample = 8; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB565U; break; case GR_PIXFMT_AA_8_ARGB_1555: gc->grPixelSample = 8; gc->grPixelSize = 2; hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555U; break; case GR_PIXFMT_AA_8_ARGB_8888: gc->grPixelSample = 8; gc->grPixelSize = 4; hwPixelFormat = SST_OVERLAY_PIXEL_RGB32U; break; default: gc->grPixelSample = 0; GDBG_INFO( gc->myLevel, "Unsupported Pixel Format = %d\n", pixelformat); GrErrorCallback( "grSstWinOpen: unsupported pixel format", FXFALSE ); return 0; break; } #if 0 /* Old Way */ gc->sliCount = gc->chipCount / ((gc->grPixelSample == 4) ? 2 : 1); /* Default for the SLI case... */ gc->grSamplesPerChip = gc->grPixelSample > 1 ? 2 : 1; /* We have two ways to do 2-sample AA when we have more than two chips. We * can either do 2 samples per chip with 2-way (or 4-way) SLI, or we can do * one sample per chip with 1-way (or 2-way) SLI. By default we'll opt for * non-SLI since in theory it has better performance. We have an environment * variable to override this, though. */ if(gc->chipCount == 2 && gc->grPixelSample == 2 && gc->sliCount == 2) { if(!_GlideRoot.environment.forceOldAA) { gc->grSamplesPerChip = 1; gc->sliCount = 1; /* In this mode I think the video filter still works... */ if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB1555U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555D; } else if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB565U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB565D; } } } else if(gc->chipCount == 4 && gc->grPixelSample == 2 && gc->sliCount == 4) { /* This doesn't work yet */ if(0 && !_GlideRoot.environment.forceOldAA) { gc->grSamplesPerChip = 1; gc->sliCount = 2; /* In this mode I think the video filter still works... */ if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB1555U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555D; } else if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB565U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB565D; } } } #else switch( gc->chipCount ) { case 4: switch( gc->grPixelSample ) { case 8: gc->sliCount = 1; gc->grSamplesPerChip = 2; gc->sampleOffsetIndex = 9; break; case 4: gc->sliCount = 1; /*no sli, 1 sample per chip */ gc->grSamplesPerChip = 1; gc->sampleOffsetIndex = 8; break; case 2: if(!_GlideRoot.environment.forceOldAA) { gc->grSamplesPerChip = 1; //2 way SLI, 1 sample per SLI unit gc->sliCount = 2; gc->sampleOffsetIndex = 7; /* In this mode I think the video filter still works... */ if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB1555U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555D; } else if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB565U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB565D; } } else { gc->grSamplesPerChip = 2; /* 4 way SLI, 2 samples per SLI unit */ gc->sliCount = 4; /* doesn't work yet */ gc->sampleOffsetIndex = 7; } break; case 1: gc->sliCount = 4; gc->grSamplesPerChip = 1; gc->sampleOffsetIndex = 0; break; } break; case 2: switch( gc->grPixelSample ) { case 4: gc->sliCount = 1; gc->grSamplesPerChip = 2; gc->sampleOffsetIndex = 3; break; case 2: if(!_GlideRoot.environment.forceOldAA) { gc->sliCount = 1; /* no sli, 1 sample per chip */ gc->grSamplesPerChip = 1; gc->sampleOffsetIndex = 2; if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB1555U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB1555D; } else if(hwPixelFormat == SST_OVERLAY_PIXEL_RGB565U) { hwPixelFormat = SST_OVERLAY_PIXEL_RGB565D; } } else { gc->sliCount = 2; /* 2 samples per SLI pair */ gc->grSamplesPerChip = 2; gc->sampleOffsetIndex = 1; } break; case 1: gc->sliCount = 2; gc->grSamplesPerChip = 1; gc->sampleOffsetIndex = 0; break; } break; case 1: switch( gc->grPixelSample ) { case 2: gc->sliCount = 1; gc->grSamplesPerChip = 2; gc->sampleOffsetIndex = 1; break; case 1: gc->sliCount = 1; gc->grSamplesPerChip = 1; gc->sampleOffsetIndex = 0; break; } break; default: gc->sliCount = 1; gc->grSamplesPerChip = 1; gc->sampleOffsetIndex = 0; break; } #endif /* Yeesh. */ gc->enableSecondaryBuffer = gc->grSamplesPerChip > 1 ? FXTRUE : FXFALSE; /* Precompute which table entries to use for per-chip primary and secondary AA offsets. */ /* Index 0 - No AA * Index 1 - 2-sample AA, 2 samples per chip * Index 2 - 2-sample AA, 1 sample per chip * Index 3 - 4-sample AA, 2 samples per chip * Index 4 - 2-sample AA, 2 samples per chip - correct values * Index 5 - 2-sample AA, 1 sample per chip - correct values * Index 6 - 4-sample AA, 2 samples per chip - correct values */ #if 0 /* adjust offset index for 4 chip cards */ if( gc->chipCount == 4 ) { switch ( gc->grPixelSample ) { case 8: gc->sampleOffsetIndex = 9; break; case 4: gc->sampleOffsetIndex = 8; break; case 2: gc->sampleOffsetIndex = 7; break; } } else { gc->sampleOffsetIndex = gc->grPixelSample-1 + ((gc->grSamplesPerChip == 1) ? 1 : 0); if (!GETENV("FX_GLIDE_AA_SAMPLE", gc->bInfo->RegPath) && gc->sampleOffsetIndex) gc->sampleOffsetIndex+=3; } #else if (!GETENV("FX_GLIDE_AA_SAMPLE", gc->bInfo->RegPath) && gc->sampleOffsetIndex) gc->sampleOffsetIndex+=3; #endif if (gc->sliCount == 0) { GDBG_INFO( gc->myLevel, "Unsupported Pixel Format = %d\n", pixelformat); GDBG_INFO( gc->myLevel, "Number of chips = %d\n", gc->chipCount); GDBG_INFO( gc->myLevel, "Number of pixel sample = %d\n", gc->grPixelSample); GrErrorCallback( "grSstWinOpen: unsupported pixel format", FXFALSE ); return 0; } /* ** 2 pixel per clock rendering will only be enabled if ** 1) we are in 15/16 bpp rendering mode (may not help in high res) ** high res = GR_RESOLUTION_1600x1200 for now ** 2) low resolution in 32 bpp ** low res = 0 for now ( we may never turn it on ) ** In other cases, we still rely on the lodmin = lodmax = 1 to ** minimize the texture access ** ** sli & aa rendering must be disabled in all half modes */ if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { gc->do2ppc = FXFALSE; gc->bInfo->h3analogSli = 0 ; if (gc->grPixelSize <= 2) { switch (gc->grSstRez) { case GR_RESOLUTION_1600x1200: case GR_RESOLUTION_1600x1024: case GR_RESOLUTION_1280x1024: case GR_RESOLUTION_1280x960: case GR_RESOLUTION_1152x864: case GR_RESOLUTION_1024x768: case GR_RESOLUTION_960x720: case GR_RESOLUTION_800x600: case GR_RESOLUTION_856x480: case GR_RESOLUTION_640x480: case GR_RESOLUTION_640x400: case GR_RESOLUTION_640x350: gc->do2ppc = FXTRUE; break; case GR_RESOLUTION_640x200: case GR_RESOLUTION_512x384: case GR_RESOLUTION_512x256: case GR_RESOLUTION_400x300: case GR_RESOLUTION_400x256: case GR_RESOLUTION_320x240: case GR_RESOLUTION_320x200: gc->sliCount = 1 ; gc->chipCount = 1 ; gc->grPixelSample = 1 ; break; case GR_RESOLUTION_2048x2048: case GR_RESOLUTION_2048x1536: case GR_RESOLUTION_1920x1440: case GR_RESOLUTION_1856x1392: case GR_RESOLUTION_1792x1344: default: gc->bInfo->h3analogSli = 1 ; break; } } else if (gc->grPixelSize == 4) { switch (gc->grSstRez) { case GR_RESOLUTION_1280x1024: case GR_RESOLUTION_1280x960: case GR_RESOLUTION_1152x864: case GR_RESOLUTION_1024x768: case GR_RESOLUTION_960x720: case GR_RESOLUTION_800x600: case GR_RESOLUTION_856x480: case GR_RESOLUTION_640x480: case GR_RESOLUTION_640x400: case GR_RESOLUTION_640x350: gc->do2ppc = FXTRUE; break; case GR_RESOLUTION_640x200: case GR_RESOLUTION_512x384: case GR_RESOLUTION_512x256: case GR_RESOLUTION_400x300: case GR_RESOLUTION_400x256: case GR_RESOLUTION_320x240: case GR_RESOLUTION_320x200: gc->sliCount = 1 ; gc->chipCount = 1 ; gc->grPixelSample = 1 ; break; case GR_RESOLUTION_2048x2048: case GR_RESOLUTION_2048x1536: case GR_RESOLUTION_1920x1440: case GR_RESOLUTION_1856x1392: case GR_RESOLUTION_1792x1344: case GR_RESOLUTION_1600x1200: case GR_RESOLUTION_1600x1024: default: gc->bInfo->h3analogSli = 1 ; break; } } /* If we force the env var to 1, always turn 2ppc on. * Otherwise, we only enable 2ppc in certain condition. * FX_GLIDE_2PPC: -1=disable, 1=enable, 0=glide decides * 2ppc is always enabled for now. see gpci.c */ if (_GlideRoot.environment.do2ppc < 0) { gc->do2ppc = FXFALSE; } else if (_GlideRoot.environment.do2ppc) { gc->do2ppc = FXTRUE; } /* * Ditto for analog sli */ if (_GlideRoot.environment.analogSli < 0) { gc->bInfo->h3analogSli = 0; } else if (_GlideRoot.environment.analogSli) { gc->bInfo->h3analogSli = 1; } /* * This seems like bad news to me, but the control * panel applet is supposed to be able to turn off * SLI. */ if (_GlideRoot.environment.forceSingleChip) { gc->sliCount = 1 ; gc->chipCount = 1 ; } } /* enable analog for 8xaa 4 chip cards */ if( gc->chipCount == 4 ) gc->bInfo->h3analogSli = 1 ; GDBG_INFO(80, "%s: sliCount = %d\n", FN_NAME, gc->sliCount); GDBG_INFO(80, "%s: chipCount = %d\n", FN_NAME, gc->chipCount); /* compute tile dimensions */ gc->strideInTiles = ( gc->state.screen_width * (gc->grPixelSize >> 1) + ( TILE_WIDTH_PXLS - 1 ) ) / TILE_WIDTH_PXLS; GDBG_INFO(80, "%s: strideInTiles = 0X%x\n", FN_NAME, gc->strideInTiles); gc->heightInTiles = ( gc->state.screen_height + ( TILE_HEIGHT_PXLS - 1 ) ) / TILE_HEIGHT_PXLS; GDBG_INFO(80, "%s: heightInTiles = 0x%x\n", FN_NAME, gc->heightInTiles); gc->bufferStride = gc->strideInTiles * TILE_WIDTH_PXLS * BYTES_PER_PIXEL; GDBG_INFO(80, "%s: bufferStride = 0x%x\n", FN_NAME, gc->bufferStride); gc->bufSizeInTiles = gc->strideInTiles * gc->heightInTiles; GDBG_INFO(80, "%s: bufSizeInTiles = 0x%x\n", FN_NAME, gc->bufSizeInTiles); gc->bufSize = gc->bufSizeInTiles * TILE_WIDTH_PXLS * TILE_HEIGHT_PXLS * BYTES_PER_PIXEL; GDBG_INFO(80, "%s: bufSize = 0x%x\n", FN_NAME, gc->bufSize); /* Check for enough memory */ #ifdef GLIDE_INIT_HWC #ifdef FX_GLIDE_NAPALM /* We must constrain the sli band height such that Y origin swapping * values work correctly. */ if(gc->sliCount > 1) { FxU32 chipScreenHeight; FxU32 maxBandHeightLog2 = 0; FxU32 sliBandHeightInPixels; FxU32 numBands; // chipScreenHeight = gc->state.screen_height >> (gc->sliCount - 1); chipScreenHeight = gc->state.screen_height/gc->sliCount; /* Find the biggest value that's still * divisible by a power of two. The check * for a non-zero chipScreenHeight is just * in case something bad happens and it starts * out as zero. */ if(!_GlideRoot.environment.sliBandHeightForce) { while(!(chipScreenHeight & 1) && chipScreenHeight) { maxBandHeightLog2++; chipScreenHeight >>= 1; } if(gc->sliBandHeight > maxBandHeightLog2) { gc->sliBandHeight = maxBandHeightLog2; GDBG_INFO(80, "%s: Clamping SLI band height (Log2) to %d\n",FN_NAME, maxBandHeightLog2); } } /* Recompute buffer memory requirements */ sliBandHeightInPixels = 1L << gc->sliBandHeight; // chipScreenHeight = gc->state.screen_height >> (gc->sliCount - 1); chipScreenHeight = gc->state.screen_height / gc->sliCount; GDBG_INFO(80, "%s: SLI band height in pixels: %d\n",FN_NAME, sliBandHeightInPixels); numBands = (chipScreenHeight + (sliBandHeightInPixels - 1)) / sliBandHeightInPixels; GDBG_INFO(80, "%s: SLI bands required: %d\n", FN_NAME, numBands); chipScreenHeight = numBands * sliBandHeightInPixels; GDBG_INFO(80, "%s: SLI chip screen height: %d\n",FN_NAME, chipScreenHeight); gc->heightInTiles = ( chipScreenHeight + ( TILE_HEIGHT_PXLS - 1 ) ) / TILE_HEIGHT_PXLS; GDBG_INFO(80, "%s: SLI heightInTiles = 0x%x\n", FN_NAME, gc->heightInTiles); gc->bufSizeInTiles = gc->strideInTiles * gc->heightInTiles; GDBG_INFO(80, "%s: SLI bufSizeInTiles = 0x%x\n", FN_NAME, gc->bufSizeInTiles); gc->bufSize = gc->bufSizeInTiles * TILE_WIDTH_PXLS * TILE_HEIGHT_PXLS * BYTES_PER_PIXEL; GDBG_INFO(80, "%s: SLI bufSize = 0x%x\n", FN_NAME, gc->bufSize); } #endif if ( ( /* If we are doing 2 or 4 sample AA, then each chip needs twice as many buffers */ #ifdef FX_GLIDE_NAPALM gc->grSamplesPerChip * #endif gc->bufSize * ( gc->grColBuf + gc->grAuxBuf ) + MIN_TEXTURE_STORE + MIN_FIFO_SIZE) > ( gc->bInfo->h3Mem << 20 ) ) { GDBG_INFO( gc->myLevel, "Failed to open for insufficient memory\n" ); GrErrorCallback( "grSstWinOpen: not enough memory for requested buffers", FXFALSE ); return 0; } #endif /* Allocate Color/Aux Buffers, Set Memory Layout */ gcFifo = &gc->cmdTransportInfo; #if defined( USE_PACKET_FIFO ) #if defined( GLIDE_INIT_HWC ) bInfo = gc->bInfo; vInfo = &bInfo->vidInfo; bufInfo = &bInfo->buffInfo; /* If we closed down then the hw may have been un-mapped (on * systems that actually support this) so we need to re-map the * board and re-cache our hw pointers. */ if (!gc->bInfo->isMapped) { if (!hwcMapBoard(bInfo, HWC_BASE_ADDR_MASK)) { GDBG_INFO( gc->myLevel, "Failed to re-map the hw.\n" ); GrErrorCallback( FN_NAME": Failed to re-map the hw.", FXFALSE ); GR_RETURN( FXFALSE ); } if (!hwcInitRegisters(bInfo)) { GDBG_INFO( gc->myLevel, "Failed to re-initialize the hw.\n" ); GrErrorCallback( FN_NAME": Failed to re-initialize the hw.", FXFALSE ); GR_RETURN( FXFALSE ); } } /* Don't assume that because the board was still mapped that these didn't change! */ gc->sstRegs = (SstRegs*)bInfo->regInfo.sstBase; gc->ioRegs = (SstIORegs*)bInfo->regInfo.ioMemBase; gc->cRegs = (SstCRegs*)bInfo->regInfo.cmdAGPBase; gc->lfb_ptr = (FxU32*)bInfo->regInfo.lfbBase; gc->rawLfb = (FxU32*)bInfo->regInfo.rawLfbBase; gc->tex_ptr = (FxU32*)SST_TEX_ADDRESS(bInfo->regInfo.sstBase); #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { if (gc->chipCount) { FxU32 chip ; for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) { gc->slaveSstRegs[chip] = (SstRegs *) bInfo->regInfo.slaveSstBase[chip] ; gc->slaveCRegs[chip] = (SstCRegs *)bInfo->regInfo.slaveCmdBase[chip] ; } } } #endif #ifdef DRI_BUILD vInfo->xRes = driInfo.w; vInfo->yRes = driInfo.h; #else /* defined(DRI_BUILD) */ vInfo->xRes = gc->state.screen_width; vInfo->yRes = gc->state.screen_height; #endif /* defined(DRI_BUILD) */ vInfo->refresh = gc->grSstRefresh; vInfo->tiled = FXTRUE; vInfo->initialized = FXTRUE; bufInfo->enable2ndbuffer = gc->enableSecondaryBuffer; bInfo->h3pixelSize = gc->grPixelSize; bInfo->h3pixelSample = gc->grPixelSample; bInfo->h3nwaySli = gc->sliCount ; bInfo->h3sliBandHeight = 1L << gc->sliBandHeight; /* KCD: hwc buffer allocation needs this */ gc->colTiled = gc->auxTiled = FXTRUE ; /* AJB- grBufferClear needs to know this */ if ( hwcAllocBuffers( bInfo, nColBuffers, nAuxBuffers ) == FXFALSE ) { GDBG_INFO( gc->myLevel, "hwcAllocBuffers failed\n" ); GrErrorCallback(hwcGetErrorString(), FXFALSE); return 0; } for (buffer = 0; buffer < nColBuffers; buffer++) { gc->buffers0[buffer] = bufInfo->colBuffStart0[buffer]; GDBG_INFO(80, "Buffer %d: Start: 0x%x\n", buffer, gc->buffers0[buffer]); gc->lfbBuffers[buffer] = (FxU32)gc->rawLfb + bufInfo->lfbBuffAddr0[buffer]; if (bInfo->buffInfo.enable2ndbuffer) { gc->buffers1[buffer] = bufInfo->colBuffStart1[buffer]; GDBG_INFO(80, "Buffer %d: Start: 0x%x\n", buffer, gc->buffers1[buffer]); } } if (nAuxBuffers != 0) { gc->buffers0[buffer] = bufInfo->auxBuffStart0; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers0[buffer]); gc->lfbBuffers[buffer] = (FxU32)gc->rawLfb + bufInfo->lfbBuffAddr0[buffer]; if (bInfo->buffInfo.enable2ndbuffer) { gc->buffers1[buffer] = bufInfo->auxBuffStart1; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers1[buffer]); } } vInfo->hWnd = gc->grHwnd; vInfo->sRes = gc->grSstRez; vInfo->vRefresh = gc->grSstRefresh; GDBG_INFO(80, "current_sst: %d\n", _GlideRoot.current_sst); if ( hwcInitVideo( bInfo, FXTRUE, gc->vidTimings, hwPixelFormat, FXTRUE ) == FXFALSE ) { GrErrorCallback(hwcGetErrorString(), FXFALSE); GDBG_INFO( gc->myLevel, "hwcInitVideo failed\n" ); return 0; } /* Restore the function specializations if the user is trying to * recover. This only resets the non-null environment. The actual * function specializations are recovered later in the mainline * code path for the open. */ if (gc->open && !gc->contextP) { GrTriSetupProcArchVector* curTriProcs = _GlideRoot.deviceArchProcs.curTriProcs; GrVertexListProc* curVertexListProcs = _GlideRoot.deviceArchProcs.curVertexListProcs; _GlideRoot.deviceArchProcs.curTriProcs = _GlideRoot.deviceArchProcs.nullTriProcs; _GlideRoot.deviceArchProcs.curVertexListProcs = _GlideRoot.deviceArchProcs.nullVertexListProcs; _GlideRoot.deviceArchProcs.nullTriProcs = curTriProcs; _GlideRoot.deviceArchProcs.nullVertexListProcs = curVertexListProcs; } /* This actually gets taken in hwcInitVideo */ gc->contextP = FXTRUE; #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* CSR - Set up flag for display driver to tell us that context was lost */ if ( !gc->open ) /* If we already have a context open, then lets not re-initialize the pointers */ { hwcShareContextData(gc->bInfo, &(gc->lostContext)); gc->cmdTransportInfo.ptrLostContext = &(gc->lostContext); } /* This actually gets taken in hwcInitVideo */ gc->contextP = FXTRUE; *gc->lostContext = FXFALSE; #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ if (_GlideRoot.environment.gammaR != 1.3f && _GlideRoot.environment.gammaG != 1.3f && _GlideRoot.environment.gammaB != 1.3f) { hwcGammaRGB(gc->bInfo, _GlideRoot.environment.gammaR, _GlideRoot.environment.gammaG, _GlideRoot.environment.gammaB); } else { hwcGammaRGB(gc->bInfo, 1.3f, 1.3f, 1.3f); } /* Setup memory configuration */ gc->fbOffset = bInfo->fbOffset; /* ** if the environment variable is on, use the its texture memory size * 2 */ if ((_GlideRoot.environment.tmuMemory != -1) && (gc->fbOffset >= 0x200000)) bInfo->tramSize = _GlideRoot.environment.tmuMemory << 21; GDBG_INFO(80, FN_NAME ": TMUs: %d\n", gc->num_tmu); GDBG_INFO(80, FN_NAME ": Total TMU Memory: 0x%x\n", bInfo->tramSize); GDBG_INFO(80, FN_NAME ": Texture Memory Offset: 0x%x\n",bInfo->tramOffset); /* ** if we only have one TMU or we are using UMA, do similar things */ if ( (gc->num_tmu < 1) || (gc->state.grEnableArgs.texture_uma_mode == GR_MODE_ENABLE) ) { tramShift = 0; tmu1Offset = 0; GDBG_INFO(80, FN_NAME ": UMA ON\n"); } else { tramShift = 1; tmu1Offset = bInfo->tramSize >> 1; GDBG_INFO(80, FN_NAME ": UMA OFF\n"); } switch (gc->num_tmu) { case 2: gc->tmuMemInfo[1].tramOffset = bInfo->tramOffset + tmu1Offset; gc->tmuMemInfo[1].tramSize = (bInfo->tramSize >> tramShift); gc->tmu_state[1].total_mem = gc->tmuMemInfo[1].tramSize; GDBG_INFO(80, FN_NAME ": TMU1: Offset 0x%x, size 0x%x\n", gc->tmuMemInfo[1].tramOffset, gc->tmuMemInfo[1].tramSize); /* NOTE: NO BREAK. THIS IS ON PURPOSE */ case 1: default: gc->tmuMemInfo[0].tramOffset = bInfo->tramOffset; gc->tmuMemInfo[0].tramSize = (bInfo->tramSize >> tramShift); gc->tmu_state[0].total_mem = gc->tmuMemInfo[0].tramSize; GDBG_INFO(80, FN_NAME ": TMU0: Offset 0x%x, size 0x%x\n", gc->tmuMemInfo[0].tramOffset, gc->tmuMemInfo[0].tramSize); break; } /* gc->num_tmu */ gc->tBuffer.bufType = HWC_BUFFER_TEXTUREBUFFER; gc->tBuffer.bufOffset = bInfo->tramOffset; gc->tBuffer.bufSize = bInfo->tramSize; gc->tBuffer.tiled = FXFALSE; gc->tBuffer.bufBPP = 0xffffffff; /* Don't matter to me */ GDBG_INFO(1, "autoBump: 0x%x\n", _GlideRoot.environment.autoBump); /* The logic for this is hosed for PowerPC, where we disable auto-bump even on PCI. */ if (gc->cmdTransportInfo.autoBump = _GlideRoot.environment.autoBump) { if (!hwcInitFifo( bInfo, gc->cmdTransportInfo.autoBump)) { hwcRestoreVideo(bInfo); GrErrorCallback(hwcGetErrorString(), FXFALSE); GDBG_INFO(gc->myLevel, "hwcInitFifo failed\n"); GR_RETURN(FXFALSE); } } else { /* %%KCD - I pass in true because I know this will just fall through to hwcInitFifo() */ #if __POWERPC__ if (!hwcInitAGPFifo(bInfo, FXFALSE)) { #else if (!hwcInitAGPFifo(bInfo, _GlideRoot.environment.forceAutoBump/*FXTRUE*/)) { #endif hwcRestoreVideo(bInfo); GrErrorCallback(hwcGetErrorString(), FXFALSE); GDBG_INFO(gc->myLevel, "hwcInitFifo failed\n"); GR_RETURN(FXFALSE); } /* Check to see where the command fifo was placed since the agp * allocation might have failed for some reason, and fallen back * to using the normal video command fifo. */ gc->cmdTransportInfo.autoBump = ((GR_CAGP_GET(baseSize) & SST_CMDFIFO_DISABLE_HOLES) == 0); GDBG_INFO(gc->myLevel, "autoBump = %i\n", gc->cmdTransportInfo.autoBump); } /* COMMAND FIFO SETUP */ fInfo = &gc->bInfo->fifoInfo; /* Establish physical bounds of cmd fifo from HWC calculation */ gcFifo->fifoOffset = fInfo->fifoStart; gcFifo->fifoSize = fInfo->fifoLength; #elif defined( GLIDE_INIT_HAL ) #if 0 gc->fbOffset = 0x200000; gc->tramOffset = 0x0; gc->tramSize = gc->fbOffset; gc->tmu_state[0].total_mem = gc->tramSize; #else /* gc->fbOffset = (FxU32)fxHalFbiGetMemory((SstRegs*)gc->reg_ptr); */ gc->fbOffset = (FxU32)gc->rawLfb; gc->fbOffset = 0; gc->tmuMemInfo[0].tramOffset = (pixelformat == GR_PIXFMT_ARGB_8888) ? 0x400000 : 0x200000; gc->tmuMemInfo[0].tramSize = (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) ? 0x1600000 : 0x0200000; gc->tmuMemInfo[1].tramOffset = gc->tmuMemInfo[0].tramSize + gc->tmuMemInfo[0].tramOffset; gc->tmuMemInfo[1].tramSize = (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) ? 0x1600000 : 0x0200000; gc->tmu_state[0].total_mem = gc->tmuMemInfo[0].tramSize; gc->tmu_state[1].total_mem = gc->tmuMemInfo[1].tramSize; #endif /* napalm buffer allocation */ #define NAPALM_BUFFER_ALLOC 1 #if NAPALM_BUFFER_ALLOC { bInfo = gc->bInfo; vInfo = &bInfo->vidInfo; bufInfo = &bInfo->buffInfo; vInfo->xRes = gc->state.screen_width; vInfo->yRes = gc->state.screen_height; vInfo->refresh = gc->grSstRefresh; vInfo->tiled = FXFALSE; vInfo->initialized = FXTRUE; gc->colTiled = gc->auxTiled = FXFALSE ; /* AJB- grBufferClear needs to know this */ if (GETENV("SST_FBI_MEM")) { bInfo->h3Mem = atoi(GETENV("SST_FBI_MEM")); } else { bInfo->h3Mem = 32; } bInfo->h3pixelSize = gc->grPixelSize; if (gc->grPixelSample > 1) bInfo->buffInfo.enable2ndbuffer = FXTRUE; if ( hwcAllocBuffers( gc->bInfo, nColBuffers, nAuxBuffers ) == FXFALSE ) { GDBG_INFO( gc->myLevel, "hwcAllocBuffers failed\n" ); GrErrorCallback(hwcGetErrorString(), FXFALSE); return 0; } for ( buffer = 0; buffer < nColBuffers; buffer++ ) { gc->buffers0[buffer] = bufInfo->colBuffStart0[buffer]; GDBG_INFO(80, "Buffer %d: Start: 0x%x\n", buffer, gc->buffers0[buffer]); gc->lfbBuffers[buffer] = (FxU32)gc->rawLfb + bufInfo->lfbBuffAddr0[buffer]; if (bInfo->buffInfo.enable2ndbuffer) { gc->buffers1[buffer] = bufInfo->colBuffStart1[buffer]; GDBG_INFO(80, "Buffer %d: Start: 0x%x\n", buffer, gc->buffers1[buffer]); } } if (nAuxBuffers != 0) { gc->buffers0[buffer] = bufInfo->auxBuffStart0; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers0[buffer]); gc->lfbBuffers[buffer] = (FxU32)gc->rawLfb + bufInfo->lfbBuffAddr0[buffer]; if (bInfo->buffInfo.enable2ndbuffer) { gc->buffers1[buffer] = bufInfo->auxBuffStart1; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers1[buffer]); } } } #else for ( buffer = 0; buffer < nColBuffers; buffer++ ) { gc->buffers0[buffer] = gc->fbOffset + buffer * gc->bufSize; /* XXXjdt: this is never initialized in the old code */ gc->lfbBuffers[buffer] = 0; GDBG_INFO(80, "%s: Buffer %d: 0x%x\n", FN_NAME, buffer, gc->buffers0[buffer]); } if (nAuxBuffers != 0) { gc->buffers0[buffer] = gc->fbOffset + buffer * gc->bufSize; gc->lfbBuffers[buffer] = 0; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers0[buffer]); } #endif if( !fxHalGetDeviceInfo((SstRegs*)gc->reg_ptr, &devInfo) ) { GrErrorCallback(" XXXGetDeviceInfo failed.\n", FXFALSE); GDBG_INFO( gc->myLevel, " XXXGetDeviceInfo failed. (0x%x)\n", gc->reg_ptr ); return 0; } /* COMMAND FIFO SETUP */ #if 0 gcFifo->fifoOffset = gc->fbOffset + ( gc->bufSize * ( gc->grColBuf + gc->grAuxBuf ) ); gcFifo->fifoSize = 0x400000 - gcFifo->fifoOffset + gc->fbOffset; #else gcFifo->fifoOffset = ( gc->bufSize * ( gc->grColBuf + gc->grAuxBuf ) ); gcFifo->fifoSize = 0x20000; #if NAPALM_BUFFER_ALLOC gcFifo->fifoOffset = 0x0; gcFifo->fifoSize = 0x20000; #endif #if NAPALM_BUFFER_ALLOC { gc->fbOffset = bInfo->fbOffset; gc->tmuMemInfo[0].tramOffset = bInfo->tramOffset; gc->tmuMemInfo[0].tramSize = bInfo->tramSize >> 1; gc->tmu_state[0].total_mem = gc->tmuMemInfo[0].tramSize; gc->tmuMemInfo[1].tramOffset = gc->tmuMemInfo[0].tramOffset + gc->tmuMemInfo[0].tramSize; gc->tmuMemInfo[1].tramSize = (bInfo->tramSize >> 1); gc->tmu_state[1].total_mem = gc->tmuMemInfo[1].tramSize; gcFifo->fifoOffset = 0x0; gcFifo->fifoSize = 0x20000; } #endif #endif if ( !fxHalInitCmdFifo((SstRegs *) gc->reg_ptr, 0, /* which fifo - 0 for 3d cmd fifo */ /* v fifoStart - offset from hw base v */ gcFifo->fifoOffset, gcFifo->fifoSize, /* size - in bytes */ FXTRUE, /* directExec */ FXFALSE, /* disableHoles */ FXFALSE) /* agpEnable */ ) { #ifdef GLIDE_INIT_HWC GrErrorCallBack( "fxHalInitCmdFifo failed.\n", FxFALSE ); #endif GDBG_INFO( 0, "Error: fxHalInitCmdFifo failed\n" ); return 0; } if ( !fxHalInitVideo( (SstRegs*) gc->reg_ptr, (resolution == GR_RESOLUTION_NONE) ? GR_RESOLUTION_640x480 : (resolution), refresh, NULL ) ) { #ifdef GLIDE_INIT_HWC GrErrorCallBack( "fxHalInitVideo failed.\n", FxFALSE ); #endif GDBG_INFO( 0, "Error: fxHalInitVideo failed\n" ); GR_RETURN( FXFALSE ); } fxHalInitVideoOverlaySurface( (SstRegs*) gc->reg_ptr, /* SstRegs */ FXTRUE, /* 1=enable Overlay surface*/ FXFALSE, /* 1=enable OS stereo, 0=disable*/ FXFALSE, /* 1=enable horizontal*/ 0, /* horizontal scale factor (ignored if*/ FXFALSE, /* 1=enable vertical scaling,*/ 0, /* vertical scale factor (ignored if not*/ 0, /* duh*/ 1, /* 0=OS linear, 1=tiled*/ SST_OVERLAY_PIXEL_RGB565U, /* pixel format of OS*/ FXFALSE, /* bypass clut for OS?*/ FXFALSE, /* 0=lower 256 CLUT entries,*/ gc->buffers0[gc->curBuffer], /* board address of beginning of OS */ gc->strideInTiles ); /* distance between scanlines of the OS, in*/ #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* ** initialize context checking */ { gc->lostContext = &lostcontext_csim; *gc->lostContext = FXFALSE; gc->contextP = 1; } #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ #endif /* defined( GLIDE_INIT_HAL ) */ #else /* !defined( USE_PACKET_FIFO ) */ gc->fbOffset = (FxU32)gc->rawLfb; gc->fbOffset = 0x0; gc->tmuMemInfo[0].tramOffset = 0x200000; gc->tmuMemInfo[0].tramSize = 0x200000; gc->tmuMemInfo[1].tramOffset = gc->tmuMemInfo[0].tramSize + gc->tmuMemInfo[0].tramOffset; gc->tmuMemInfo[1].tramSize = 0x200000; gc->tmu_state[0].total_mem = gc->tmuMemInfo[0].tramSize; gc->tmu_state[1].total_mem = gc->tmuMemInfo[1].tramSize; { bInfo = gc->bInfo; vInfo = &bInfo->vidInfo; bufInfo = &bInfo->buffInfo; vInfo->xRes = gc->state.screen_width; vInfo->yRes = gc->state.screen_height; vInfo->refresh = gc->grSstRefresh; vInfo->tiled = FXFALSE; vInfo->initialized = FXTRUE; gc->colTiled = gc->auxTiled = FXFALSE ; /* AJB- grBufferClear needs to know this */ if (GETENV("SST_FBI_MEM")) { bInfo->h3Mem = atoi(GETENV("SST_FBI_MEM")); } else { bInfo->h3Mem = 32; } bInfo->h3pixelSize = gc->grPixelSize; bInfo->buffInfo.enable2ndbuffer = FXFALSE; if (gc->grPixelSample > 1) bInfo->buffInfo.enable2ndbuffer = FXTRUE; if ( hwcAllocBuffers( gc->bInfo, nColBuffers, nAuxBuffers ) == FXFALSE ) { GDBG_INFO( gc->myLevel, "hwcAllocBuffers failed\n" ); GrErrorCallback(hwcGetErrorString(), FXFALSE); return 0; } for ( buffer = 0; buffer < nColBuffers; buffer++ ) { gc->buffers0[buffer] = bufInfo->colBuffStart0[buffer]; GDBG_INFO(80, "Buffer %d: Start: 0x%x\n", buffer, gc->buffers0[buffer]); gc->lfbBuffers[buffer] = (FxU32)gc->rawLfb + bufInfo->lfbBuffAddr0[buffer]; if (bInfo->buffInfo.enable2ndbuffer) { gc->buffers1[buffer] = bufInfo->colBuffStart1[buffer]; GDBG_INFO(80, "Buffer %d: Start: 0x%x\n", buffer, gc->buffers1[buffer]); } } if (nAuxBuffers != 0) { gc->buffers0[buffer] = bufInfo->auxBuffStart0; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers0[buffer]); gc->lfbBuffers[buffer] = (FxU32)gc->rawLfb + bufInfo->lfbBuffAddr0[buffer]; if (bInfo->buffInfo.enable2ndbuffer) { gc->buffers1[buffer] = bufInfo->auxBuffStart1; GDBG_INFO(80, "Aux Buffer: Start: 0x%x\n", gc->buffers1[buffer]); } } } if( !fxHalGetDeviceInfo((SstRegs*)gc->reg_ptr, &devInfo) ) { GrErrorCallback(" XXXGetDeviceInfo failed.\n", FXFALSE); GDBG_INFO( gc->myLevel, " XXXGetDeviceInfo failed. (0x%x)\n", gc->reg_ptr ); GR_RETURN( 0 ); } #if 0 /* COMMAND FIFO SETUP */ gcFifo->fifoOffset = gc->fbOffset + ( gc->bufSize * ( gc->grColBuf + gc->grAuxBuf ) ); gcFifo->fifoSize = 0x400000 - gcFifo->fifoOffset + gc->fbOffset; if ( !fxHalInitCmdFifo((SstRegs *) gc->reg_ptr, 0, /* which fifo - 0 for 3d cmd fifo */ /* v fifoStart - offset from hw base v */ gcFifo->fifoOffset, gcFifo->fifoSize, /* size - in bytes */ FXTRUE, /* directExec */ FXFALSE, /* disableHoles */ FXFALSE) /* agpEnable */ ) { #ifdef FX_FAIL_HWC GrErrorCallBack( "fxHalInitCmdFifo failed.\n", FxFALSE ); #endif GDBG_INFO( 0, "Error: fxHalInitCmdFifo failed\n" ); GR_RETURN( 0 ); } #endif if ( !fxHalInitVideo( (SstRegs*) gc->reg_ptr, (resolution == GR_RESOLUTION_NONE) ? GR_RESOLUTION_640x480 : (resolution), refresh, NULL ) ) { GR_RETURN( 0 ); } fxHalInitVideoOverlaySurface( (SstRegs*) gc->reg_ptr, /* SstRegs */ FXTRUE, /* 1=enable Overlay surface*/ FXFALSE, /* 1=enable OS stereo, 0=disable*/ FXFALSE, /* 1=enable horizontal*/ 0, /* horizontal scale factor (ignored if*/ FXFALSE, /* 1=enable vertical scaling,*/ 0, /* vertical scale factor (ignored if not*/ 0, /* duh*/ 1, /* 0=OS linear, 1=tiled*/ SST_OVERLAY_PIXEL_RGB565U, /* pixel format of OS*/ FXFALSE, /* bypass clut for OS?*/ FXFALSE, /* 0=lower 256 CLUT entries,*/ gc->buffers0[gc->curBuffer], /* board address of beginning of OS */ gc->strideInTiles ); /* distance between scanlines of the OS, in*/ _grReCacheFifo(0); #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) /* ** initialize context checking */ { gc->lostContext = &lostcontext_csim; *gc->lostContext = FXFALSE; gc->contextP = 1; } #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ #endif /* !defined( USE_PACKET_FIFO ) */ /* Compute Virtual FIFO address extents */ #ifdef GLIDE_INIT_HWC if (bInfo->fifoInfo.agpFifo) { gcFifo->fifoStart = (FxU32 *) bInfo->fifoInfo.agpVirtAddr; gcFifo->fifoOffset = bInfo->fifoInfo.agpPhysAddr; } else { #else { #endif gcFifo->fifoStart = gc->rawLfb + ( gcFifo->fifoOffset >> 2 ); } gcFifo->fifoEnd = gcFifo->fifoStart + ( gcFifo->fifoSize >> 2 ); /* Adjust room values. ** RoomToEnd needs enough room for the jmp packet since we never ** allow the hw to auto-wrap. RoomToRead needs to be adjusted so that ** we never acutally write onto the read ptr. ** ** fifoRoom is generally the min of roomToEnd and roomToRead, but we ** 'know' here that roomToRead < roomToEnd. */ #if USE_PACKET_FIFO gcFifo->roomToEnd = gcFifo->fifoSize - FIFO_END_ADJUST; gcFifo->fifoRoom = gcFifo->roomToReadPtr = gcFifo->roomToEnd - sizeof( FxU32 ); /* Set initial fifo state. hw read and sw write pointers at * start of the fifo. */ gcFifo->fifoPtr = gcFifo->fifoStart; gcFifo->fifoRead = HW_FIFO_PTR( FXTRUE ); #endif /* USE_PACKET_FIFO */ #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) if ( (void*)gcFifo->fifoPtr != (void*)gcFifo->fifoRead ) { #ifdef GLIDE_INIT_HWC hwcRestoreVideo( bInfo ); #endif GDBG_INFO( gc->myLevel, "Initial fifo state is incorrect\n" ); return 0; } #endif /* GLIDE_PLATFORM & GLIDE_OS_UNIX */ #if __POWERPC__ && PCI_BUMP_N_GRIND enableCopyBackCache((FxU32)gcFifo->fifoStart,gcFifo->fifoSize); #endif if (!gc->cmdTransportInfo.autoBump) { gcFifo->bumpSize = _GlideRoot.environment.bumpSize; gcFifo->lastBump = gcFifo->fifoPtr; gcFifo->bumpPos = gcFifo->fifoPtr + gcFifo->bumpSize; #if __POWERPC__ && PCI_BUMP_N_GRIND gcFifo->fifoJmpHdr[0] = ( SSTCP_PKT0_JMP_LOCAL | ( gcFifo->fifoOffset << ( SSTCP_PKT0_ADDR_SHIFT - 2 ))); #else gcFifo->fifoJmpHdr[0] = ( SSTCP_PKT0_JMP_AGP | ( gcFifo->fifoOffset << ( SSTCP_PKT0_ADDR_SHIFT - 2 ))); gcFifo->fifoJmpHdr[1] = (gcFifo->fifoOffset >> 25); #endif } else { gcFifo->fifoJmpHdr[0] = ( SSTCP_PKT0_JMP_LOCAL | ( gcFifo->fifoOffset << ( SSTCP_PKT0_ADDR_SHIFT - 2 ))); } GDBG_INFO(80, "Command Fifo:\n" "\tfifoStart: 0x%x\n" "\tfifoEnd: 0x%x\n" "\tfifoOffset: 0x%x\n" "\tfifoSize: 0x%x\n" "\tfifoPtr: 0x%x\n", gcFifo->fifoStart, gcFifo->fifoEnd, gcFifo->fifoOffset, gcFifo->fifoSize, gcFifo->fifoPtr ); #ifdef DRI_BUILD _grImportFifo(*driInfo.fifoPtr, *driInfo.fifoRead); #endif /* The hw is now in a usable state from the fifo macros. * * NB: See the comment in fxglide.h for the difference between * these flags. */ gc->open = FXTRUE; /* Setup the procs that we can do w/o any mode knowledge */ gc->archDispatchProcs.texDownloadProcs = _GlideRoot.deviceArchProcs.curTexProcs; gc->archDispatchProcs.drawTrianglesProc = _GlideRoot.deviceArchProcs.curDrawTrisProc; /* Default render procs to window space */ gc->archDispatchProcs.coorModeTriVector = (*_GlideRoot.deviceArchProcs.curTriProcs) + GR_WINDOW_COORDS; gc->archDispatchProcs.drawVertexList = _GlideRoot.deviceArchProcs.curVertexListProcs[GR_WINDOW_COORDS]; /*------------------------------------------------------ GC Init ------------------------------------------------------*/ GDBG_INFO(gc->myLevel, " GC Init\n"); initGC( gc ); gc->orgSW = gc->state.screen_width; gc->orgSH = gc->state.screen_height; /*------------------------------------------------------ 3D State Init ------------------------------------------------------*/ GDBG_INFO( gc->myLevel, " 3D State Init\n"); GDBG_INFO( gc->myLevel, " Setting default register states\n" ); gc->state.shadow.fbzMode = ( SST_ENRECTCLIP | SST_ENZBIAS ); GDBG_INFO( gc->myLevel, " Setting up initial draw buffer state\n" ); REG_GROUP_BEGIN(BROADCAST_ID, leftOverlayBuf, 1, 0x1); REG_GROUP_SET(hw, leftOverlayBuf, gc->buffers0[gc->frontBuffer]); REG_GROUP_END(); REG_GROUP_BEGIN(BROADCAST_ID, swapbufferCMD, 1, 0x1); REG_GROUP_SET(hw, swapbufferCMD, 0x0); REG_GROUP_END(); gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; gc->state.shadow.colBufferStride = gc->strideInTiles | SST_BUFFER_MEMORY_TILED; gc->state.shadow.auxBufferAddr = gc->buffers0[nColBuffers]; gc->state.shadow.auxBufferStride = gc->strideInTiles | SST_BUFFER_MEMORY_TILED; #ifdef GLIDE_INIT_HWC if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( gc->chipmask ); } REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); if (gc->grPixelSample > 1) { if(gc->enableSecondaryBuffer) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->buffers1[nColBuffers] | SST_BUFFER_BASE_SELECT); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); } /* ** setup aaCtrl register */ { _grAAOffsetValue(_GlideRoot.environment.aaXOffset[gc->sampleOffsetIndex], _GlideRoot.environment.aaYOffset[gc->sampleOffsetIndex], 0, gc->chipCount - 1, FXTRUE, gc->enableSecondaryBuffer) ; } } if (gc->sliCount > 1) { _grEnableSliCtrl(); } #else #ifdef HAL_CSIM #if 1 { if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( gc->chipmask ); } { /* ** initialize pci registers for sli/aa */ FxI32 chipIndex; for(chipIndex=0; (FxU32)chipIndexchipCount; chipIndex++) { halCfgStore32(0x3FC, 1, gc->halInfo->boardInfo[chipIndex].pciBusNumber, gc->halInfo->boardInfo[chipIndex].pciDeviceNumber, gc->halInfo->boardInfo[chipIndex].pciFunctionNumber, offsetof(SstPCIConfigRegs, cfgSliLfbCtrl), SST_SLI_LFB_CPU_WRITE_ENABLE | SST_SLI_LFB_DISPATCH_WRITE_ENABLE | SST_SLI_LFB_READ_ENABLE); halCfgStore32(0x3FC, 1, gc->halInfo->boardInfo[chipIndex].pciBusNumber, gc->halInfo->boardInfo[chipIndex].pciDeviceNumber, gc->halInfo->boardInfo[chipIndex].pciFunctionNumber, offsetof(SstPCIConfigRegs, cfgAADepthBufferAperture), 0); halCfgStore32(0x3FC, 1, gc->halInfo->boardInfo[chipIndex].pciBusNumber, gc->halInfo->boardInfo[chipIndex].pciDeviceNumber, gc->halInfo->boardInfo[chipIndex].pciFunctionNumber, offsetof(SstPCIConfigRegs, cfgAALfbCtrl), SST_AA_LFB_CPU_WRITE_ENABLE | SST_AA_LFB_DISPATCH_WRITE_ENABLE | SST_AA_LFB_READ_ENABLE); } } gc->state.shadow.colBufferAddr = gc->buffers0[gc->curBuffer]; gc->state.shadow.colBufferStride = gc->state.screen_width * bInfo->h3pixelSize; gc->state.shadow.auxBufferAddr = gc->buffers0[nColBuffers]; gc->state.shadow.auxBufferStride = gc->state.screen_width * bInfo->h3pixelSize; REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->state.shadow.colBufferAddr); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); if (gc->grPixelSample > 1) { REG_GROUP_BEGIN(BROADCAST_ID, colBufferAddr, 4, 0xf); { REG_GROUP_SET(hw, colBufferAddr, gc->buffers1[gc->curBuffer] | SST_BUFFER_BASE_SELECT); #ifdef DRI_BUILD REG_GROUP_SET(hw, colBufferStride, (!gc->curBuffer) ? driInfo.stride : gc->state.shadow.colBufferStride ); #else REG_GROUP_SET(hw, colBufferStride, gc->state.shadow.colBufferStride ); #endif REG_GROUP_SET(hw, auxBufferAddr, gc->buffers1[nColBuffers] | SST_BUFFER_BASE_SELECT); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); /* ** setup aaCtrl register */ { /* Anti-aliasing default perturbation values */ //8xaa FxU32 defaultXOffset[8];// = {0x7a, 0x2, 0x7c, 0x4}; FxU32 defaultYOffset[8];// = {0x7b, 0x4, 0x3, 0x7d}; _grAAOffsetValue(defaultXOffset, defaultYOffset, 0, gc->chipCount - 1, FXTRUE, FXTRUE); } } } if (gc->sliCount > 1) { _grEnableSliCtrl(); } #endif #endif #endif { /* ** setup default rendermode */ _grRenderMode(pixelformat); } GDBG_INFO( gc->myLevel, " Setting all Glide state\n" ); assertDefaultState(); #ifdef DRI_BUILD if (nColBuffers>1) grRenderBuffer(GR_BUFFER_BACKBUFFER); else grRenderBuffer(GR_BUFFER_FRONTBUFFER); grClipWindow(0, 0, gc->state.screen_width, gc->state.screen_height); #else /* defined(DRI_BUILD) */ clearBuffers( gc ); #endif /* defined(DRI_BUILD) */ gc->state.color_format = format; /* -------------------------------------------------------- Splash Screen --------------------------------------------------------*/ doSplash(); gc->windowed = FXFALSE; _GlideRoot.windowsInit++; /* to avoid race with grSstControl() */ retVal = (GrContext_t)gc; if(_GlideRoot.environment.aaClip == FXTRUE) { if((gc->grPixelSample > 1) && (_GlideRoot.windowsInit == 1)) { grClipWindow(0, 0, gc->state.screen_width, gc->state.screen_height); } } GR_END(); } return retVal; #undef FN_NAME } /* grSstWinOpenExt */ #endif /* NAPALM */ /*------------------------------------------------------------------- Function: grSstWinClose Date: 3/16 Implementor(s): jdt Library: Glide Description: Shut down the selected SST Shutdown has 4 steps 3D Idle the 3D engine must be idled to make sure that there are no commands executing in the transport when the registers are reset GC Reset the GC is flagged as unitialized - (nosup) Command Transport Disable the command transport to the 3D device is put in a state of reset. No further commands may be issued throught the command transport Video Restore video is restored to its pre-open state. Arguments: none Return: none -------------------------------------------------------------------*/ GR_ENTRY(grSstWinClose, FxBool, (GrContext_t context)) { #define FN_NAME "grSstWinClose" GrGC* gc = (GrGC*)context; GDBG_INFO(80, FN_NAME"(0x%X)\n", context); if (!gc) return 0; #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) /* We are in Windowed Mode */ if (gc->windowed) { extern void _grReleaseWindowSurface(GrContext_t ctx); _grReleaseWindowSurface(context); return FXTRUE; } #endif /* If we are OpenGL, we need to release Exclusive mode so other ** OpenGL fullscreen apps can run. If not, we will cause a lot ** of problems. */ /* KoolSmoky - HACK! We skip this for win32 because it crashes. */ #if !(GLIDE_OS & GLIDE_OS_WIN32) if(_GlideRoot.environment.is_opengl == FXTRUE) { hwcRestoreVideo(gc->bInfo); } #endif #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) if (gc->lostContext) { if (*gc->lostContext) { #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) /* KoolSmoky - splashscreen DLL needs to be freed */ if (gc->pluginInfo.moduleHandle) { FreeLibrary(gc->pluginInfo.moduleHandle); gc->pluginInfo.moduleHandle = 0L; } #endif return 0; } } #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ /* NB: The gc that is being closed is the passed gc not the * currently selected gc. This must be setup before the * 'declaration' which grabs the current gc in grFlush. In * addition, it is possible for us to have 'missed' a thread attach * if the current thread came into existance before glide was * explicitly loaded by an application. In this case we have to set * the tls gc explicitly otherwise other whacky-ness (read 'random * crashes' will ensue). */ setThreadValue((FxU32)gc); if ((gc != NULL) && gc->open) grFlush(); /* Make sure that the user specified gc is not whacked */ if ((gc != NULL) && (gc >= _GlideRoot.GCs) && (gc <= _GlideRoot.GCs + MAX_NUM_SST)) { if (gc->open) { #if GLIDE_INIT_HAL /* dpc - 22 may 1997 - FixMe! * We need the equivilant stuff in the hal layer too. */ #else /* !GLIDE_INIT_HAL */ #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) /* KoolSmoky - splashscreen DLL needs to be freed */ if (gc->pluginInfo.moduleHandle) { FreeLibrary(gc->pluginInfo.moduleHandle); gc->pluginInfo.moduleHandle = 0L; } #endif /*-------------------------- 3D Idle --------------------------*/ GDBG_INFO(gc->myLevel, " 3D Idle\n"); /*-------------------------- Command Transport Disable --------------------------*/ GDBG_INFO(gc->myLevel, " Command Transport Disable\n"); #if __POWERPC__ && PCI_BUMP_N_GRIND restoreCacheSettings(); #endif /* Video Restore * * NB: The hwcRestoreVideo in addition to restoring the video also * turns off the command fifo and then releases the hw context * which can unmap the board at the driver level. The next time * we use grSstWinOpen we need to re-map the board etc just to be * safe everywhere. */ GDBG_INFO(gc->myLevel, " Restore Video\n"); #if !(GLIDE_PLATFORM & GLIDE_OS_UNIX) if (!*gc->lostContext) { /* disable SLI and AA */ #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); _grTex2ppc(FXFALSE); if (gc->grPixelSample > 1) { _grAAOffsetValue(_GlideRoot.environment.aaXOffset[0], _GlideRoot.environment.aaYOffset[0], 0, gc->chipCount - 1, FXTRUE, FXFALSE) ; } if (gc->sliCount > 1) _grDisableSliCtrl(); /* Idle the 3D pipe. */ grFinish(); } #endif hwcRestoreVideo(gc->bInfo); } #endif /* !(GLIDE_PLATFORM & GLIDE_OS_UNIX) */ #endif /* !GLIDE_INIT_HAL */ /*-------------------------- GC Reset --------------------------*/ GDBG_INFO(gc->myLevel, " GC Reset\n"); /* These are really two different things. * * hwInitP indicates whether the init code mapping/init sequence * is active for this hw. * * open includes setting up video, command transport, and the * initial glide state. */ //gc->hwInitP = FXFALSE; _grDisplayStats(); } gc->open = FXFALSE; gc->grSstRez = GR_RESOLUTION_NONE; gc->grSstRefresh = GR_REFRESH_NONE; } _GlideRoot.windowsInit--; #if (GLIDE_OS & GLIDE_OS_WIN32) if (_GlideRoot.environment.is_opengl != FXTRUE) { if ((_GlideRoot.OS == OS_WIN32_95) || (_GlideRoot.OS == OS_WIN32_98) || (_GlideRoot.OS == OS_WIN32_ME)) { hwcUnmapMemory9x ( gc->bInfo ); } else { hwcUnmapMemory(); } } #endif return FXTRUE; #undef FN_NAME } /* grSstWinClose */ /*------------------------------------------------------------------- Function: grSetNumPendingBuffers Date: 13-Oct-2000 Implementor(s): mmcclure Description: Allow the application to supply the number of pending buffers Arguments: NumPendingBuffers - Sent to force number of pending buffers Return: -------------------------------------------------------------------*/ GR_DIENTRY(grSetNumPendingBuffers, void, (FxI32 NumPendingBuffers)) { _GlideRoot.environment.swapPendingCount = NumPendingBuffers; } /*------------------------------------------------------------------- Function: grSelectContext Date: 18-Jan-98 Implementor(s): atai, taco Description: Designates a context as current. This selects a named state vector with it's own command transport as the current target for all glide commands. Arguments: context - name of context Return: TRUE - valid context FALSE - invalid context -------------------------------------------------------------------*/ /* NOTE: THIS FUNCTION CAN BE CALLED WHEN THERE IS NO VALID GC */ GR_DIENTRY(grSelectContext, FxBool , (GrContext_t context) ) { #define FN_NAME "grSelectContext" GrGC* gc = (GrGC*)context; FxBool rv = FXFALSE; GDBG_INFO( 80, FN_NAME"(0x%X)\n", context ); /* WTF?!?!?!?!!? - dpc - 31 mar 1999 - I was not aware that apps * could select invalid contexts. They're not supposed to call * grSstWinClose w/ some whacked value, why's this function any * different? */ if ( context == 0 ) { GDBG_INFO( 80, "NULL Context passed\n" ); rv = FXFALSE; } else { setThreadValue( context ); if (gc != NULL) { if (gc->windowed) { /* Setup the procs that we can do w/o any mode knowledge */ gc->archDispatchProcs.texDownloadProcs = _GlideRoot.deviceArchProcs.curTexProcs; gc->archDispatchProcs.drawTrianglesProc = _GlideRoot.deviceArchProcs.curDrawTrisProc; /* Default render procs to window space */ gc->archDispatchProcs.coorModeTriVector = (*_GlideRoot.deviceArchProcs.curTriProcs) + GR_WINDOW_COORDS; gc->archDispatchProcs.drawVertexList = _GlideRoot.deviceArchProcs.curVertexListProcs[GR_WINDOW_COORDS]; gc->contextP = !(*gc->lostContext) ; gc->open = FXTRUE; rv = gc->contextP ; } else { const FxBool oldContextState = gc->contextP; GR_ASSERT((gc >= _GlideRoot.GCs) && (gc <= _GlideRoot.GCs + MAX_NUM_SST)); // Need context checking in XP. Should this effect windowed contexts as well?? #if WINXP_ALT_TAB_FIX hwcQueryContextXP(gc->bInfo); #endif #ifdef GLIDE_INIT_HWC gc->contextP = !(*gc->lostContext) ; #else gc->contextP = 1; #endif rv = gc->contextP; /* We may now need to fiddle w/ the current specialization * vectors. The fifo writing macros are 'smart' (in a dumb * sort of way) about not writing to the fifo, but the * specialized routines in assembly are not. We replace the * base specialization vectors here w/ null (empty that is) * vectors that don't do anything. */ if (!gc->contextP && oldContextState) { GrTriSetupProcArchVector* curTriProcs = _GlideRoot.deviceArchProcs.curTriProcs; GrVertexListProc* curVertexListProcs = _GlideRoot.deviceArchProcs.curVertexListProcs; _GlideRoot.deviceArchProcs.curTriProcs = _GlideRoot.deviceArchProcs.nullTriProcs; _GlideRoot.deviceArchProcs.curVertexListProcs = _GlideRoot.deviceArchProcs.nullVertexListProcs; _GlideRoot.deviceArchProcs.nullTriProcs = curTriProcs; _GlideRoot.deviceArchProcs.nullVertexListProcs = curVertexListProcs; gc->archDispatchProcs.texDownloadProcs = _GlideRoot.deviceArchProcs.nullTexProcs; gc->archDispatchProcs.drawTrianglesProc = _GlideRoot.deviceArchProcs.nullDrawTrisProc; gc->archDispatchProcs.coorModeTriVector = (*_GlideRoot.deviceArchProcs.curTriProcs) + GR_WINDOW_COORDS; gc->archDispatchProcs.drawVertexList = _GlideRoot.deviceArchProcs.curVertexListProcs[GR_WINDOW_COORDS]; } } } } GDBG_INFO(80, "%s() => 0x%x---------------------\n", FN_NAME, rv ); return rv; #undef FN_NAME } /* grSelectConetext */ /*--------------------------------------------------------------------------- ** grStatsResetPerfStats */ void FX_CSTYLE _grSstResetPerfStats(void) { #define FN_NAME "grSstResetPerfStats" GR_BEGIN("grSstResetPerfStats",83,4, 1); GDBG_INFO_MORE(gc->myLevel,"()\n"); GR_SET(BROADCAST_ID, hw, nopCMD, 1); GR_END(); #undef FN_NAME } /* grSstResetPerfStats */ /*--------------------------------------------------------------------------- ** grSstStatus - return contents of status register */ FxU32 FX_CSTYLE _grSstStatus(void) { #define FN_NAME "grSstStatus" FxU32 status; GR_BEGIN_NOFIFOCHECK_RET(FN_NAME"()\n", 83); status = GR_GET(hw->status); #ifdef FX_GLIDE_NAPALM /* */ /* AJB check slave status */ /* */ { FxU32 chip ; if (gc->chipCount) for (chip = 0 ; chip < gc->chipCount - 1 ; chip++) status |= GR_GET(gc->slaveSstRegs[chip]->status) ; } #endif return(status); GR_END(); #undef FN_NAME }/* grSstStatus */ /*--------------------------------------------------------------------------- ** grSstVideoLine - return current video line number */ FxU32 FX_CSTYLE _grSstVideoLine(void) { FxU32 vline = 1; return vline; }/* grSstVideoLine */ /*--------------------------------------------------------------------------- ** grSstVRetrace - return contents of SST_VRETRACE bit of status register; */ FxBool FX_CSTYLE _grSstVRetraceOn(void) { FxU32 status; GR_BEGIN_NOFIFOCHECK_RET("grSstVRetraceOn",83); status = GR_GET(hw->status); return ((status & SST_VRETRACE) == 0); }/* grSstVRetrace */ /*------------------------------------------------------------------- Function: grFlush Date: 09-Jan-98 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_ENTRY(grFlush, void, (void)) { #define FN_NAME "grFlush" GR_BEGIN_NOFIFOCHECK( "grFlush", 80 ); GDBG_INFO_MORE(gc->myLevel,"()\n"); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0x0); GR_CHECK_SIZE(); if ( gc->windowed ) { #ifdef GLIDE_INIT_HWC GDBG_INFO(gc->myLevel + 200, FN_NAME": cmdSize(0x%X)\n", ((FxU32)gc->cmdTransportInfo.fifoPtr - (FxU32)gc->cmdTransportInfo.hwcFifoInfo.cmdBuf.baseAddr)); _FifoFlush(); #endif } else if (!gc->cmdTransportInfo.autoBump) { GR_BUMP_N_GRIND; } GR_END(); #undef FN_NAME } /* grFlush */ /*--------------------------------------------------------------------------- ** grSstIdle/grFinish */ GR_ENTRY(grFinish, void, (void)) #define FN_NAME "grFinish" { FxU32 i = 0 ; GR_BEGIN_NOFIFOCHECK(FN_NAME, 83); GDBG_INFO_MORE(gc->myLevel,"()\n"); grFlush(); if ( gc->windowed ) { #if defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) struct cmdTransportInfo* gcFifo = &gc->cmdTransportInfo; hwcIdleWinFifo(gc->bInfo, &gcFifo->hwcFifoInfo, gcFifo->issuedSerialNumber); #endif /* defined(GLIDE_INIT_HWC) && !(GLIDE_PLATFORM & GLIDE_OS_UNIX) && !defined(__DJGPP__) */ } else { /*while((_grSstStatus() & SST_BUSY) != 0) */ /* Do Nothing */; /* * Napalm should be read as idle three times * before we believe it. */ do { if(_grSstStatus() & SST_BUSY) i = 0; /* Reset counter */ else i++; } while(i < 3); /* while (_grSstStatus() & SST_BUSY) ; while (((_grSstStatus() & SST_BUSY) == 0) && (++i < 3)) ; */ } GR_END(); #undef FN_NAME } /* grSstIdle */ /*--------------------------------------------------------------------------- ** grSstIsBusy - find out if the SST is busy or not */ FxBool FX_CSTYLE _grSstIsBusy(void) { #define FN_NAME "grSstIsBusy" static FxBool nopP = FXTRUE; FxBool idle; FxU32 i = 0 ; GR_BEGIN_NOFIFOCHECK_RET("grSstIsBusy", 80); /* dpc - 22 may 1997 - FixMe! * Seems like the simplest way to do it, but is this really the way * to do it? */ if (nopP) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, nopCMD, 0); GR_CHECK_SIZE(); } if ( gc->windowed ) { #ifdef GLIDE_INIT_HWC _FifoFlush(); #endif idle = 1; } else { /* * Napalm must be read idle three times for us * to believe it. */ while ((idle = ((_grSstStatus() & SST_BUSY) == 0)) && (++i < 3)); idle = !idle; } nopP = idle; GDBG_INFO(84,"grSstIsBusy() => 0x%x\n", !idle); return !idle; #undef FN_NAME }/* grSstIsBusy */ #if defined(GLIDE3) && defined(GLIDE3_ALPHA) /*--------------------------------------------------------------------------- ** guGammaCorrectionRGB - set the gamma correction value */ GR_ENTRY(guGammaCorrectionRGB, void, (float r, float g, float b)) { GR_BEGIN_NOFIFOCHECK("guGammaCorrectionValue",80); GDBG_INFO_MORE(gc->myLevel,"(%g %g %g)\n",r, g, b); #if GLIDE_INIT_HAL fxHalInitGamma(hw, r); #else /* !GLIDE_INIT_HAL */ /* ** Hack for Fifa99! ** Fifa99 calls this routine after they use grGlideShutdown. ** The game crashes here with a null gc. */ if (_GlideRoot.environment.useAppGamma) { if (gc) hwcGammaRGB(gc->bInfo, r, g, b); } else GDBG_INFO(69,"guGammaCorrectionRGB::hwcGammaRGB (%3.3f, %3.3f, %3.3f) call ignored\n", r,g,b); #endif /* !GLIDE_INIT_HAL */ GR_END(); } /* guGammaCorrectionRGB */ /*------------------------------------------------------------------- Function: grLoadGammaTable Date: 05-Jan-97 Implementor(s): atai Description: Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grLoadGammaTable, void, (FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)) { #define FN_NAME "grLoadGammaTable" FxU32 max; GR_BEGIN_NOFIFOCHECK("grLoadGammaTable",80); grGet(GR_GAMMA_TABLE_ENTRIES, 4, (FxI32 *)&max); if (nentries > max) nentries = max; #ifdef GLIDE_INIT_HWC if (_GlideRoot.environment.useAppGamma) hwcGammaTable(gc->bInfo, nentries, red, green, blue); else GDBG_INFO(69, "grLoadGammaTable::hwcGammaRGB call ignored\n"); #endif GR_END(); #undef FN_NAME } /*------------------------------------------------------------------- Function: grGetGammaTable Date: 04-Jan-00 Implementor(s): chuck Description: Arguments: Return: -------------------------------------------------------------------*/ GR_EXT_ENTRY(grGetGammaTable, void, (FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)) { #define FN_NAME "grGetGammaTable" FxU32 max; GR_BEGIN_NOFIFOCHECK("grGetGammaTable",80); grGet(GR_GAMMA_TABLE_ENTRIES, 4, (FxI32 *)&max); if (nentries > max) nentries = max; #ifdef GLIDE_INIT_HWC hwcGetGammaTable(gc->bInfo, nentries, red, green, blue); #endif GR_END(); #undef FN_NAME } #endif #ifndef GLIDE3 /*--------------------------------------------------------------------------- ** grGammaCorrectionValue - set the gamma correction value */ GR_ENTRY(grGammaCorrectionValue, void, (float gamma)) { GR_BEGIN_NOFIFOCHECK("grGammaCorrectionValue",80); GDBG_INFO_MORE(gc->myLevel,"(%g)\n",gamma); #if GLIDE_INIT_HAL fxHalInitGamma(hw, gamma); #else /* !GLIDE_INIT_HAL */ if (_GlideRoot.environment.useAppGamma) hwcGamma(gc->bInfo, gamma, gamma, gamma); else GDBG_INFO(69,"grGammaCorrectionValue::hwcGammaRGB (gamma = %3.3f) call ignored\n", gamma); #endif /* !GLIDE_INIT_HAL */ GR_END(); } /* grGammaCorrectionValue */ #endif /*--------------------------------------------------------------------------- ** grSstOrigin - Set the orgin orientation of the screen. ** ** Returns: ** ** Notes: ** */ GR_STATE_ENTRY(grSstOrigin, void, (GrOriginLocation_t origin)) { #define FN_NAME "grSstOrigin" FxU32 fbzMode; GR_BEGIN_NOFIFOCHECK("grSstOrigin", 83); GDBG_INFO_MORE(gc->myLevel, "(%d)\n", origin); /* Initialize FBZMODE register */ fbzMode = gc->state.shadow.fbzMode; if (origin == GR_ORIGIN_LOWER_LEFT) fbzMode |= SST_YORIGIN; else fbzMode &= ~(SST_YORIGIN); /* dpc - 22 may 1997 - FixMe! * Do we need to do anything here for the HAL? */ #if !GLIDE_INIT_HAL /* dpc - 5 sep 1997 - FixMe! * This is the old way. Is there anything else we * need to do here? * * initOrigin(origin); */ #endif gc->state.shadow.fbzMode = fbzMode; #ifdef FX_GLIDE_NAPALM if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { FxU32 renderMode = gc->state.shadow.renderMode; renderMode &= ~(SST_RM_YORIGIN_TOP); renderMode |= SST_RM_YORIGIN_SELECT; if (origin == GR_ORIGIN_LOWER_LEFT) { /* AJB - According to the Napalm spec this is correct, but the winsim seems to perform the yorigin */ /* subtraction BEFORE the SLI munging */ renderMode |= (((gc->state.screen_height / gc->sliCount) - 1) << SST_RM_YORIGIN_TOP_SHIFT); /* renderMode |= ((gc->state.screen_height - 1) << SST_RM_YORIGIN_TOP_SHIFT); */ } REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 0x1, 0x1); REG_GROUP_SET(hw, renderMode, renderMode); REG_GROUP_END(); gc->state.shadow.renderMode = renderMode; if (gc->sliCount > 1) _grEnableSliCtrl() ; } #endif #undef FN_NAME } /* grSstOrigin */ /* GMT: do we really have users for this??? * CHD: No. * JDT: Huh? If you're talking about grSstOrigin, you're smoking crack. * if you are talking about SstConfigPipeline, it is evil and must * be destroyed. :) * dpc: There is one user that I know of. This 'Nature' demo that Scott just * gave me. * chd: It's a stub now. * (much time elapses) * chd: But WTF is that forward decl down there? * dpc: Its to get rid of the compiler warning for a function that * we only sort of export. */ extern FX_ENTRY void FX_CALL grSstConfigPipeline(GrChipID_t chip, FxU32 reg, FxU32 value); /*--------------------------------------------------------------------------- ** grSstConfigPipeline */ GR_ENTRY(grSstConfigPipeline, void, (GrChipID_t chip, FxU32 reg, FxU32 value)) { } /* grSstConfigPipeline */ #ifdef FX_GLIDE_NAPALM /* ** _grSstSetColumnsOfNWidth ** ** Sets the 'columns of N' width (fka columns of 8). ** */ static void _grSstSetColumnsOfNWidth(FxU32 width) { #define FN_NAME "_grSstSetColumnsOfNWidth" FxU32 bits, /* Bits for the column band control field */ fbzColorPath; /* local shadow of same */ GR_BEGIN_NOFIFOCHECK(FN_NAME, 80); if (_GlideRoot.environment.columnWidth) width = _GlideRoot.environment.columnWidth; GDBG_INFO_MORE(gc->myLevel, "(%d)\n", width); /* Validate Argument ** ** There might be some effed-up algorithm for this, but it escapes ** me at this time. It's not like this is a performance-critical ** routine, anyway. */ switch (width) { case 32: bits = 0x2; break; /* KoolSmoky - don't we need break here? */ case 16: bits = 0x1; break; case 8: bits = 0x0; break; case 4: bits = 0x3; break; default: GDBG_INFO(80, FN_NAME ": Invalid argument %d. Falling back to default\n", width); width = 8; bits = 0x0; break; } fbzColorPath = gc->state.shadow.fbzColorPath; fbzColorPath &= ~SST_TRIANGLE_ITERATOR_COLUMN_BAND_CONTROL; fbzColorPath |= (bits << SST_TRIANGLE_ITERATOR_COLUMN_BAND_CONTROL_SHIFT); REG_GROUP_BEGIN(BROADCAST_ID, fbzColorPath, 0x1, 0x1); REG_GROUP_SET(hw, fbzColorPath, fbzColorPath); REG_GROUP_END(); gc->state.shadow.fbzColorPath = fbzColorPath; #undef FN_NAME } /* _grSstSetColumnsOfNWidth */ /*--------------------------------------------------------------------------- ** _grChipMask */ void _grChipMask(FxU32 mask) { #define FN_NAME "_grChipMask" GR_BEGIN_NOFIFOCHECK("_grChipMask", 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", mask); /* Optimized out redundant changes since changing the chipMask * field causes a pipeline flush! */ if(mask != gc->state.shadow.chipMask) { REG_GROUP_BEGIN(BROADCAST_ID, chipMask, 1, 0x1); REG_GROUP_SET(hw, chipMask, mask); REG_GROUP_END(); gc->state.shadow.chipMask = mask; } #undef FN_NAME } /* _grChipMask */ /*--------------------------------------------------------------------------- ** _grAAOffsetValue ** chipid is 0 based */ void _grAAOffsetValue(FxU32 *xOffset, FxU32 *yOffset, FxU32 minchipid, FxU32 maxchipid, FxBool enablePrimary, FxBool enableSecondary) { #define FN_NAME "_grAAOffsetValue" FxU32 chipIndex, aaCtrl; GR_BEGIN_NOFIFOCHECK("_grAAOffsetValue", 85); GDBG_INFO_MORE(gc->myLevel, "(0x%x,0x%x,%d,%d,%d,%d)\n", xOffset, yOffset, minchipid, maxchipid, enablePrimary, enableSecondary); for (chipIndex = minchipid; chipIndex <= maxchipid; chipIndex++) { _grChipMask( 1 << chipIndex); //8xaa aaCtrl = (xOffset[(chipIndex * 2)%8] << SST_AA_CONTROL_PRIMARY_X_OFFSET_SHIFT) | (yOffset[(chipIndex * 2)%8] << SST_AA_CONTROL_PRIMARY_Y_OFFSET_SHIFT) | (xOffset[(chipIndex * 2 + 1)%8] << SST_AA_CONTROL_SECONDARY_X_OFFSET_SHIFT) | (yOffset[(chipIndex * 2 + 1)%8] << SST_AA_CONTROL_SECONDARY_Y_OFFSET_SHIFT) | ((enableSecondary) ? SST_AA_CONTROL_AA_ENABLE : 0) | ((enablePrimary) ? 0 : SST_AA_CONTROL_AA_DISABLE_FIRST); REG_GROUP_BEGIN(BROADCAST_ID, aaCtrl, 1, 0x1); REG_GROUP_SET(hw, aaCtrl, aaCtrl); REG_GROUP_END(); } _grChipMask( gc->chipmask ); /* Force fogMode to be updated */ INVALIDATE(fogMode); #undef FN_NAME } /* _grAAOffsetValue */ /*--------------------------------------------------------------------------- ** _grEnableSliCtrl */ void _grEnableSliCtrl(void) { #define FN_NAME "_grEnableSliCtrl" FxU32 chipIndex; FxI32 sliChipCountDivisor; FxU32 renderMask; FxU32 scanMask; FxU32 log2chipCount; GR_BEGIN_NOFIFOCHECK("_grEnableSliCtrl", 85); /* ** enable sli mode */ //8xaa if( gc-> chipCount == 2 ) sliChipCountDivisor = (gc->grPixelSample == 4) ? 2 : 1; if( gc-> chipCount == 4 ) sliChipCountDivisor = (gc->grPixelSample == 2) ? 2 : 1; renderMask = (gc->chipCount / sliChipCountDivisor - 1) << gc->sliBandHeight; scanMask = (1 << gc->sliBandHeight) - 1; log2chipCount = 0; while (( 0x1UL << log2chipCount ) != (gc->chipCount / sliChipCountDivisor)) log2chipCount++; for (chipIndex = 0; chipIndex < gc->chipCount; chipIndex++) { FxU32 compareMask ; FxU32 sliCtrl ; /* AJB- When YORIGIN swapping we have to swap the compareMask too-- Otherwise line ownership gets hosed. 'course winsim behaves completely differently, so this might need some fixing on real hardware. */ if (gc->state.shadow.fbzMode & SST_YORIGIN) compareMask = ((gc->chipCount - chipIndex - 1) / sliChipCountDivisor) << gc->sliBandHeight; else compareMask = (chipIndex / sliChipCountDivisor) << gc->sliBandHeight; sliCtrl = ( (renderMask << SST_SLI_CONTROL_RENDER_MASK_SHIFT) | (compareMask << SST_SLI_CONTROL_COMPARE_MASK_SHIFT) | (scanMask << SST_SLI_CONTROL_SCAN_MASK_SHIFT) | (log2chipCount << SST_SLI_CONTROL_LOG2_CHIP_COUNT_SHIFT) | SST_SLI_CONTROL_SLI_ENABLE); _grChipMask( 1 << chipIndex ); REG_GROUP_BEGIN(BROADCAST_ID, sliCtrl, 1, 0x1); REG_GROUP_SET(hw, sliCtrl, sliCtrl); REG_GROUP_END(); } _grChipMask( gc->chipmask ); #undef FN_NAME } /* _grEnableSliCtrl */ /*--------------------------------------------------------------------------- ** _grDisableSliCtrl */ void _grDisableSliCtrl(void) { #define FN_NAME "_grDisableSliCtrl" FxU32 chipIndex; GR_BEGIN_NOFIFOCHECK("_grDisableSliCtrl", 85); /* ** disable sli mode */ for (chipIndex = 0; chipIndex < gc->chipCount; chipIndex++) { FxU32 sliCtrl = 0; _grChipMask( 1 << chipIndex ); REG_GROUP_BEGIN(BROADCAST_ID, sliCtrl, 1, 0x1); REG_GROUP_SET(hw, sliCtrl, sliCtrl); REG_GROUP_END(); } _grChipMask( gc->chipmask ); #undef FN_NAME } /* _grDisableSliCtrl */ /*--------------------------------------------------------------------------- ** _grRenderMode */ void _grRenderMode(FxU32 pixelformat) { #define FN_NAME "_grRenderMode" FxU32 renderMode; GR_BEGIN_NOFIFOCHECK("_grRenderMode", 85); /* ** setup default rendermode */ renderMode = gc->state.shadow.renderMode; renderMode &= ~(SST_RM_3D_MODE); if (_GlideRoot.environment.guardbandclipping) { renderMode |= SST_RM_ENGUARDBAND; } /* Just set this once, since this is an expensive register to write. */ renderMode &= ~(SST_RM_TWO_PIXELS_PER_CLOCK_BAND_SELECTION); renderMode |= (_GlideRoot.environment.band2ppc << SST_RM_TWO_PIXELS_PER_CLOCK_BAND_SELECTION_SHIFT); /* * XXX Memo to Myself XXX * For 4 chip SLI, do different stuff with the * dither rotation bit. Touch the puppet head. */ switch (pixelformat) { case GR_PIXFMT_AA_2_ARGB_1555: case GR_PIXFMT_AA_4_ARGB_1555: case GR_PIXFMT_AA_8_ARGB_1555: /* 8xaa */ renderMode |= SST_RM_DITHER_ROTATION ; case GR_PIXFMT_ARGB_1555: renderMode |= SST_RM_15BPP; break; case GR_PIXFMT_ARGB_8888: case GR_PIXFMT_AA_2_ARGB_8888: case GR_PIXFMT_AA_4_ARGB_8888: case GR_PIXFMT_AA_8_ARGB_8888: /* 8xaa */ renderMode |= SST_RM_32BPP; grColorMaskExt(gc->state.stateArgs.grColorMaskExtArgs.r, gc->state.stateArgs.grColorMaskExtArgs.g, gc->state.stateArgs.grColorMaskExtArgs.b, gc->state.stateArgs.grColorMaskExtArgs.a); break; case GR_PIXFMT_AA_2_RGB_565: case GR_PIXFMT_AA_4_RGB_565: case GR_PIXFMT_AA_8_RGB_565: /* 8xaa */ renderMode |= SST_RM_DITHER_ROTATION ; default: renderMode |= SST_RM_16BPP; break; } REG_GROUP_BEGIN(BROADCAST_ID, renderMode, 0x1, 0x1); REG_GROUP_SET(hw, renderMode, renderMode); REG_GROUP_END(); gc->state.shadow.renderMode = renderMode; #undef FN_NAME } /* _grRenderMode */ #endif /* FX_GLIDE_NAPALM */ glide3x/h5/glide3/src/gsstdef.h0100700000175300010010000001105307725034670015602 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gsstdef.h,v 1.3.4.2 2003/06/05 08:23:54 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ * * 1 1/16/98 4:29p Atai * create glide 3 src * * 4 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 3 5/21/97 6:05a Peter ** */ #ifndef __GSSTDEF_H__ #define __GSSTDEF_H__ #if (GLIDE_PLATFORM & GLIDE_HW_CVG) #include #else #include #endif /*----------------- SST chip layout -----------------------*/ typedef enum { SSTR_STATUS, SSTR_RESERVED0, SSTR_VAX, SSTR_VAY, SSTR_VBX, SSTR_VBY, SSTR_VCX, SSTR_VCY, #ifdef GLIDE_USE_ALT_REGMAP SSTR_R, SSTR_DRDX, SSTR_DRDY, SSTR_G, SSTR_DGDX, SSTR_DGDY, SSTR_B, SSTR_DBDX, SSTR_DBDY, SSTR_Z, SSTR_DZDX, SSTR_DZDY, SSTR_A, SSTR_DADX, SSTR_DADY, SSTR_S, SSTR_DSDX, SSTR_DSDY, SSTR_T, SSTR_DTDX, SSTR_DTDY, SSTR_W, SSTR_DWDX, SSTR_DWDY, #else SSTR_R, SSTR_G, SSTR_B, SSTR_Z, SSTR_A, SSTR_S, SSTR_T, SSTR_W, SSTR_DRDX, SSTR_DGDX, SSTR_DBDX, SSTR_DZDX, SSTR_DADX, SSTR_DSDX, SSTR_DTDX, SSTR_DWDX, SSTR_DRDY, SSTR_DGDY, SSTR_DBDY, SSTR_DZDY, SSTR_DADY, SSTR_DSDY, SSTR_DTDY, SSTR_DWDY, #endif SSTR_TRIANGLECMD, SSTR_RESERVED1, SSTR_FVAX, SSTR_FVAY, SSTR_FVBX, SSTR_FVBY, SSTR_FVCX, SSTR_FVCY, #ifdef GLIDE_USE_ALT_REGMAP SSTR_FR, SSTR_FDRDX, SSTR_FDRDY, SSTR_FG, SSTR_FDGDX, SSTR_FDGDY, SSTR_FB, SSTR_FDBDX, SSTR_FDBDY, SSTR_FZ, SSTR_FDZDX, SSTR_FDZDY, SSTR_FA, SSTR_FDADX, SSTR_FDADY, SSTR_FS, SSTR_FDSDX, SSTR_FDSDY, SSTR_FT, SSTR_FDTDX, SSTR_FDTDY, SSTR_FW, SSTR_FDWDX, SSTR_FDWDY, #else SSTR_FR, SSTR_FG, SSTR_FB, SSTR_FZ, SSTR_FA, SSTR_FS, SSTR_FT, SSTR_FW, SSTR_FDRDX, SSTR_FDGDX, SSTR_FDBDX, SSTR_FDZDX, SSTR_FDADX, SSTR_FDSDX, SSTR_FDTDX, SSTR_FDWDX, SSTR_FDRDY, SSTR_FDGDY, SSTR_FDBDY, SSTR_FDZDY, SSTR_FDADY, SSTR_FDSDY, SSTR_FDTDY, SSTR_FDWDY, #endif SSTR_FTRIANGLECMD, SSTR_FBZCOLORPATH, SSTR_FOGMODE, SSTR_ALPHAMODE, SSTR_FBZMODE, SSTR_LFBMODE, SSTR_CLIPLEFTRIGHT, SSTR_CLIPBOTTOMTOP, SSTR_NOPCMD, SSTR_FASTFILLCMD, SSTR_SWAPBUFFERCMD, SSTR_FOGCOLOR, SSTR_ZACOLOR, SSTR_CHROMAKEY, SSTR_RESERVED2, SSTR_RESERVED3, SSTR_STIPPLE, SSTR_C0, SSTR_C1, SSTR_FBIPIXELSIN, SSTR_FBICHROMAFAIL, SSTR_FBIZFUNCFAIL, SSTR_FBIAFUNCFAIL, SSTR_FBIPIXELSOUT, SSTR_FOGTABLE, SSTR_RESERVED8 = SSTR_FOGTABLE + 32, SSTR_FBIINIT4 = SSTR_RESERVED8 + 8, SSTR_VRETRACE, SSTR_BACKPORCH, SSTR_VIDEODIMENSIONS, SSTR_FBIINIT0, SSTR_FBIINIT1, SSTR_FBIINIT2, SSTR_FBIINIT3, SSTR_HSYNC, SSTR_VSYNC, SSTR_CLUTDATA, SSTR_DACDATA, SSTR_MAX_RGB_DELTA, SSTR_RESERVED51, SSTR_TEXTUREMODE = SSTR_RESERVED51 + 51, SSTR_TLOD, SSTR_TDETAIL, SSTR_TEXBASEADDR, SSTR_TEXBASEADDR1, SSTR_TEXBASEADDR2, SSTR_TEXBASEADDR38, SSTR_TEXINIT0, SSTR_TEXINIT1, SSTR_NCCTABLE0, SSTR_NCCTABLE1 = SSTR_NCCTABLE0 + 12, SSTR_END_OF_REGISTER_SET } GrSstRegister; #endif /* __GSSTDEF_H__ */ glide3x/h5/glide3/src/gstrip.c0100700000175300010010000001660707725034670015460 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gstrip.c,v 1.3.4.2 2003/06/05 08:23:54 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 14 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 13 6/03/99 12:14p Kcd ** PowerPC still needs some C code when C triangle setup is disabled. ** ** 12 4/16/99 2:58p Kcd ** Hack to use more general (but slower) SETF() macro. ** ** 11 12/03/98 11:26p Dow ** ** 10 10/16/98 1:24p Peter ** c trisetup fixes ** ** 9 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 8 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 6 3/21/98 11:31a Atai ** added GR_TRIANGLE_STRIP_CONTINUE and GR_TRIANGLE_FAN_CONTINUE ** ** 5 2/24/98 6:00p Atai ** use 0 offset for vertex data ** ** 4 2/03/98 3:40p Atai ** remove aa strip/fan and code clean up ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 19 12/12/97 12:43p Atai * move i and dateElem into the set up loop * * 17 12/08/97 10:38a Atai * added grDrawVertexArrayLinear() * * 16 11/21/97 6:05p Atai * use one datalist (tsuDataList) in glide3 * * 15 11/06/97 6:10p Atai * update GrState size * rename grDrawArray to grDrawVertexArray * update _grDrawPoint and _grDrawVertexList * * 14 11/04/97 6:35p Atai * 1. sync with data structure changes * 2. break up aa triangle routine * * 13 11/04/97 4:57p Atai * use byte offset * * 12 11/03/97 3:43p Peter * h3/cvg cataclysm * * 11 10/17/97 2:11p Atai * added grContinueArray. We only support non aa mode for now. * * 10 10/16/97 1:50p Atai * fix drawarray bugs * * 9 10/14/97 6:16p Atai * reverse triangle order in _grAADrawVertexList * * 8 10/14/97 5:41p Atai * added _grAADrawVertexList() * * 7 10/14/97 4:57p Dow * Clamping * * 6 10/09/97 8:02p Dow * State Monster 1st Cut * * 5 10/08/97 11:32a Peter * pre-computed packet headers for packet 3 * * 4 9/29/97 1:26p Dow * Fixed packed color strips/fans * * 3 9/26/97 10:24a Dow * Fixed state effage in Glide3 parameter data * * 2 9/23/97 2:35p Dow * One less loop * * 1 9/23/97 2:04p Dow * DD code for strips ** */ #if SET_BSWAP #define SLOW_SETF 1 #endif #ifdef GLIDE3 #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #if HAL_CSIM #include #else #include #endif #endif #if GLIDE_USE_C_TRISETUP || __POWERPC__ /*------------------------------------------------------------------- Function: _grDrawVertexList Date: 18-Sep-97 Implementor(s): dow Description: Sends a triangle strip to CVG. Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grDrawVertexList(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers) { #define FN_NAME "_grDrawVertexList" #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP /* ** simplified code */ FxU32 vSize; FxI32 stride = mode; GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(type = 0x%x, count = %d, pointers = 0x%x)\n", type, count, pointers); GR_FLUSH_STATE(); vSize = gc->state.vData.vSize; if (stride == 0) stride = gc->state.vData.vStride; /* Draw the first (or possibly only) set. This is necessary because the packet is 3_BDDDDDD, and in the next set, the packet is 3_DDDDDD */ /* ** We try to make tstrip code simple to read. We combine the original code ** into a single loop by adding an extra packet type assignment at the end of the loop. ** Also, the debugging code are removed temporarily. */ if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { while (count > 0) { FxI32 k, vcount = count >= 15 ? 15 : count; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); TRI_STRIP_BEGIN(type, vcount, vSize, pktype); /* ** If we use a while loop, the compiler will increment vNum and store the value back ** to the memory at every loop. In a for loop, vNum data are kept in a register. ** After the loop complete, the vNum data are written back to memory. */ for (k = 0; k < vcount; k++) { FxI32 i; FxU32 dataElem; float *vPtr; vPtr = pointers; if (mode) vPtr = *(float **)vPtr; (float *)pointers += stride; TRI_SETF(FARRAY(vPtr, 0)); dataElem = 0; TRI_SETF(FARRAY(vPtr, 4)); i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(vPtr, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } TRI_END; GR_CHECK_SIZE(); count -= 15; pktype = SSTCP_PKT3_DDDDDD; } } else { /* * first cut of clip space coordinate code, no optimization. */ float oow; while (count > 0) { FxI32 k, vcount = count >= 15 ? 15 : count; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); TRI_STRIP_BEGIN(type, vcount, vSize, pktype); for (k = 0; k < vcount; k++) { float *vPtr; vPtr = pointers; if (mode) vPtr = *(float **)vPtr; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset); /* x, y */ TRI_SETF(FARRAY(vPtr, 0) *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox); TRI_SETF(FARRAY(vPtr, 4) *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy); (float *)pointers += stride; TRI_VP_SETFS(vPtr, oow); } TRI_END; GR_CHECK_SIZE(); count -= 15; pktype = SSTCP_PKT3_DDDDDD; } } #endif #undef FN_NAME } /* _grDrawVertexList */ #endif #endif glide3x/h5/glide3/src/gstrip_ppc.c0100700000175300010010000002266407725034670016322 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gstrip_ppc.c,v 1.3 2000/11/15 23:32:53 joseph Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 1 7/30/99 1:12p Kcd ** Optimized strip setup for PowerPC. ** ** 14 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 13 6/03/99 12:14p Kcd ** PowerPC still needs some C code when C triangle setup is disabled. ** ** 12 4/16/99 2:58p Kcd ** Hack to use more general (but slower) SETF() macro. ** ** 11 12/03/98 11:26p Dow ** Code 'cleanup' heheh ** ** 10 10/16/98 1:24p Peter ** c trisetup fixes ** ** 9 6/09/98 11:59a Atai ** 1. update glide header ** 2. fix cull mode ** 3. fix tri stats ** ** 8 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 6 3/21/98 11:31a Atai ** added GR_TRIANGLE_STRIP_CONTINUE and GR_TRIANGLE_FAN_CONTINUE ** ** 5 2/24/98 6:00p Atai ** use 0 offset for vertex data ** ** 4 2/03/98 3:40p Atai ** remove aa strip/fan and code clean up ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 19 12/12/97 12:43p Atai * move i and dateElem into the set up loop * * 17 12/08/97 10:38a Atai * added grDrawVertexArrayLinear() * * 16 11/21/97 6:05p Atai * use one datalist (tsuDataList) in glide3 * * 15 11/06/97 6:10p Atai * update GrState size * rename grDrawArray to grDrawVertexArray * update _grDrawPoint and _grDrawVertexList * * 14 11/04/97 6:35p Atai * 1. sync with data structure changes * 2. break up aa triangle routine * * 13 11/04/97 4:57p Atai * use byte offset * * 12 11/03/97 3:43p Peter * h3/cvg cataclysm * * 11 10/17/97 2:11p Atai * added grContinueArray. We only support non aa mode for now. * * 10 10/16/97 1:50p Atai * fix drawarray bugs * * 9 10/14/97 6:16p Atai * reverse triangle order in _grAADrawVertexList * * 8 10/14/97 5:41p Atai * added _grAADrawVertexList() * * 7 10/14/97 4:57p Dow * Clamping * * 6 10/09/97 8:02p Dow * State Monster 1st Cut * * 5 10/08/97 11:32a Peter * pre-computed packet headers for packet 3 * * 4 9/29/97 1:26p Dow * Fixed packed color strips/fans * * 3 9/26/97 10:24a Dow * Fixed state effage in Glide3 parameter data * * 2 9/23/97 2:35p Dow * One less loop * * 1 9/23/97 2:04p Dow * DD code for strips ** */ #if SET_BSWAP #define SLOW_SETF 1 #endif #ifdef GLIDE3 #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if (GLIDE_PLATFORM & GLIDE_SST_SIM) #if HAL_CSIM #include #else #include #endif #endif #if GLIDE_USE_C_TRISETUP || __POWERPC__ /*------------------------------------------------------------------- Function: _grDrawVertexList Date: 18-Sep-97 Implementor(s): dow Description: Sends a triangle strip to CVG. Arguments: Return: -------------------------------------------------------------------*/ void FX_CSTYLE _grDrawVertexList(FxU32 pktype, FxU32 type, FxI32 mode, FxI32 count, void *pointers) { #define FN_NAME "_grDrawVertexList" #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP /* ** simplified code */ FxU32 vSize; FxI32 stride = mode; GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(type = 0x%x, count = %d, pointers = 0x%x)\n", type, count, pointers); GR_FLUSH_STATE(); vSize = gc->state.vData.vSize; if (stride == 0) stride = gc->state.vData.vStride; /* Draw the first (or possibly only) set. This is necessary because the packet is 3_BDDDDDD, and in the next set, the packet is 3_DDDDDD */ /* ** We try to make tstrip code simple to read. We combine the original code ** into a single loop by adding an extra packet type assignment at the end of the loop. ** Also, the debugging code are removed temporarily. */ if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { while (count > 0) { FxI32 k, vcount = count >= 15 ? 15 : count; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); { union { FxU32 buffer[2]; double buffer_double; } buff; const int *dataList; FxI32 i; float *vPtr; FxU32 *tPackPtr = gc->cmdTransportInfo.fifoPtr; const FxU32 packetVal = (((type) << SSTCP_PKT3_SMODE_SHIFT) | ((vcount) << SSTCP_PKT3_NUMVERTEX_SHIFT) | (pktype) | gc->cmdTransportInfo.cullStripHdr); TRI_ASSERT_DECL(vcount, vSize, packetVal); k = vcount; if((FxU32)tPackPtr & 7) { SET(*tPackPtr++, packetVal); goto vertex_end_empty; } else { SET(buff.buffer[0], packetVal); goto vertex_end_half; } /* ** If we use a while loop, the compiler will increment vNum and store the value back ** to the memory at every loop. In a for loop, vNum data are kept in a register. ** After the loop complete, the vNum data are written back to memory. */ vertex_begin_empty: vPtr = pointers; if(mode) vPtr = *(float **)vPtr; SETF(buff.buffer[0],vPtr[0]); SETF(buff.buffer[1],vPtr[1]); (float *)pointers += stride; dataList = gc->tsuDataList; *(double *)tPackPtr = *(double *)&buff.buffer[0]; tPackPtr += 2; goto vertex_loop_empty; vertex_begin_half: vPtr = pointers; if(mode) vPtr = *(float **)vPtr; SETF(buff.buffer[1],vPtr[0]); (float *)pointers += stride; dataList = gc->tsuDataList; *(double *)tPackPtr = *(double *)&buff.buffer[0]; tPackPtr += 2; SETF(buff.buffer[0],vPtr[1]); goto vertex_loop_half; vertex_loop_empty: i = *dataList++; if(i == GR_DLIST_END) { goto vertex_end_empty; } SETF(buff.buffer[0],FARRAY(vPtr,i)); vertex_loop_half: i = *dataList++; if(i == GR_DLIST_END) { goto vertex_end_half; } SETF(buff.buffer[1],FARRAY(vPtr,i)); *(double *)tPackPtr = *(double *)&buff.buffer[0]; tPackPtr += 2; goto vertex_loop_empty; vertex_end_empty: k--; if(k >= 0) { goto vertex_begin_empty; } goto vertex_end; vertex_end_half: k--; if(k >= 0) { goto vertex_begin_half; } *tPackPtr++ = buff.buffer[0]; vertex_end: /* TRI_ASSERT(); */ gc->cmdTransportInfo.fifoRoom -= ((FxU32)tPackPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); gc->cmdTransportInfo.fifoPtr = tPackPtr; GDBG_INFO(gc->myLevel + 200, "\tTriEnd: (0x%X : 0x%X)\n", tPackPtr, gc->cmdTransportInfo.fifoRoom); FIFO_ASSERT(); /* GR_CHECK_SIZE(); */ count -= 15; pktype = SSTCP_PKT3_DDDDDD; } } } else { /* * first cut of clip space coordinate code, no optimization. */ float oow; while (count > 0) { FxI32 k, vcount = count >= 15 ? 15 : count; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); TRI_STRIP_BEGIN(type, vcount, vSize, pktype); for (k = 0; k < vcount; k++) { float *vPtr; vPtr = pointers; if (mode) vPtr = *(float **)vPtr; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset); /* x, y */ TRI_SETF(FARRAY(vPtr, 0) *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox); TRI_SETF(FARRAY(vPtr, 4) *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy); (float *)pointers += stride; TRI_VP_SETFS(vPtr, oow); } TRI_END; GR_CHECK_SIZE(); count -= 15; pktype = SSTCP_PKT3_DDDDDD; } } #endif #undef FN_NAME } /* _grDrawVertexList */ #endif #endif glide3x/h5/glide3/src/gtex.c0100700000175300010010000040021707725034670015111 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gtex.c,v 1.3.4.6 2003/08/21 08:49:55 dborca Exp $ ** $Log: ** 39 3dfx 1.34.1.0.1.211/14/00 Jonny Cochrane Implement multisample LOD ** Dithering for 2x and 4x FSAA modes ** 38 3dfx 1.34.1.0.1.110/11/00 Brent Forced check in to enforce ** branching. ** 37 3dfx 1.34.1.0.1.007/11/00 Adam Briggs fixed a state management ** bug where using the constant color extension was inadvertently turning on ** chroma range substitution ** 36 3dfx 1.34.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 35 3dfx 1.34 04/25/00 Kenneth Dyke Fixed non-compressed -> ** compressed texture chip bug workaround code. ** 34 3dfx 1.33 04/11/00 Kenneth Dyke Fixed debug assertion ** failure in grTexMultibaseAddress(). ** 33 3dfx 1.32 04/04/00 Kenneth Dyke Fixed addressing for large ** tiled textures. ** 32 3dfx 1.31 03/31/00 Kenneth Dyke Make sure immediate updates ** in 2PPC mode update both real TMU hardware shadows. ** 31 3dfx 1.30 03/23/00 Kenneth Dyke Make sure we maintain the ** same state across all chips. ** 30 3dfx 1.29 03/19/00 Kenneth Dyke Don't set renderMode each ** time we change 2ppc state. ** Don't defer TMU state updates unless we really have to. ** 29 3dfx 1.28 03/16/00 Kenneth Dyke User-adjustable LOD bias ** value. ** 28 3dfx 1.27 03/11/00 Kenneth Dyke Removed hack to disable ** palettized textures in 2PPC mode. ** Added some texture combine debuggng stuff. ** 27 3dfx 1.26 03/07/00 Kenneth Dyke Minor refinement to ** compressed texture nop workaround. ** 26 3dfx 1.25 03/07/00 Kenneth Dyke Workaround for weird ** compressed texture quirk. ** 25 3dfx 1.24 02/22/00 Kenneth Dyke Track palettized texture ** usage. ** 24 3dfx 1.23 02/02/00 Kenneth Dyke Fixed per-TMU constant ** color values to not interfere with texture chroma keying. ** 23 3dfx 1.22 02/02/00 Kenneth Dyke Fix parameter setup issue ** with 2PPC modes. ** 22 3dfx 1.21 02/01/00 Kenneth Dyke Added code to detect when ** TMU0 is in passthrough mode and to enabled 2PPC in that case. (Remap TMU1 ** to TMU0). ** 21 3dfx 1.20 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 20 3dfx 1.19 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 19 3dfx 1.18 01/30/00 Adam Briggs changed ** grConstantColorValueExt back to a GR_EXT_ENTRY ** 18 3dfx 1.17 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 17 3dfx 1.16 01/23/00 Adam Briggs set & recognize the SSTTYPE ** var for Voodoo4 ** 16 3dfx 1.15 01/18/00 Kenneth Dyke Fix for 26-bit texture ** addresses. ** 15 3dfx 1.14 01/16/00 Kenneth Dyke Changes to enforce proper ** combine extension usage. ** 14 3dfx 1.13 11/30/99 Kenneth Dyke Fixed incorrect LOD ** settings for inactive TMUs. ** 13 3dfx 1.12 10/26/99 Larry warner Turn off mipmap level size ** debug check ** if we're in windowed mode, to enable the ** napalm mustpass.bat conform test to run. ** 12 3dfx 1.11 10/25/99 Anthony tai disable 2ppc in turning off ** combine ext ** 11 3dfx 1.10 10/25/99 Anthony tai fixed wrong tex state ** 10 3dfx 1.9 10/25/99 Anthony tai fixed 2ppc state and b_mode ** init value ** 9 3dfx 1.8 10/15/99 Anthony tai move 2ppc setting to state ** validation ** 8 3dfx 1.7 10/14/99 Anthony tai fixed localTMUstate ** 7 3dfx 1.6 10/06/99 Anthony tai disable 2ppc if tmu1 is ** specified ** 6 3dfx 1.5 09/30/99 Adam Briggs fixed ** grConstantColorValueExt ** 5 3dfx 1.4 09/30/99 Anthony tai fixed grTexAlphaCombineExt, ** local tmu should not be set for other texture ** 4 3dfx 1.3 09/22/99 Adam Briggs Added ** grConstantColorValueExt... not yet tested. ** 3 3dfx 1.2 09/17/99 Adam Briggs Supported TEXTUREBUFFEREXT ** for Napalm 32bpp and AA modes. ** 2 3dfx 1.1 09/17/99 Anthony tai fixed 2ppc and tmumask for ** texture color/alpha combine extension ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 67 8/05/99 5:03p Larryw ** FXT1 format works now. ** ** 66 7/30/99 3:52p Atai ** make csim happy ** ** 65 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 64 7/27/99 2:39p Atai ** added 12 nopCMD going from 2ppc to 1ppc ** ** 63 7/22/99 8:14p Larryw ** Texture format byte-depth improvements ** ** 62 7/18/99 11:11a Atai ** added 2 pixel per clock ** ** 61 7/16/99 10:59a Atai ** remove un-supported mode ** fixed tcc, tac problem ** ** 60 7/14/99 6:23p Larryw ** Remove obsolete G3_LOD_TRANSLATE() macro ** Define _grMipMapOffset[][] at compile time ** Fix 2k texture address-finding ** ** 59 7/14/99 5:03p Larryw ** Removed some #if 0 code (no functional changes) ** ** 58 7/12/99 6:27p Larryw ** Cleaner handling of tBig variable ** Filled in _grMipMapOffset[][] for 512+ sizes ** Fixed problems with grTexMipMapMode() ** ** 57 7/07/99 6:52p Larryw ** * 2k texture support ** * Reversed order of LOD tables ** * Added 512,1024, and 2048-sized entries in tables ** * Nullified G3_LOD_TRANSLATE() ** * Created _g3LodXlat() for where tLOD register is read/written ** * Misc cosmetic changes. ** ** 56 6/29/99 7:19p Atai ** remove argument for enabling SST_CM_USE_COMBINE_MODE ** ** 54 6/27/99 12:44p Atai ** fixed CC and TCC ** ** 53 6/24/99 7:14p Atai ** added COMBINE extension and 2 buffers per chip ** ** 52 6/14/99 5:16p Larryw ** Added 32-bit texture format support. ** ** 51 6/13/99 4:56p Atai ** added code for TCC and TAC, not working yet ** ** 50 5/19/99 3:55p Denis ** ** 49 5/19/99 12:45p Denis ** First check in of the TEXTUREBUFFER extension. ** Contains both the texture color buffer and texture aux. buffer ** extensions ** that allows to specify a piece of texture memory as a rendering target ** and/or a piece of texture memory as the aux. buffer. ** ** Probably a non conventional check in, in the sense that the API ** isn't entirely frozen / specified yet. To ease whoever's job it will be ** to complete the extension, I've added a tbext comment ** everywhere I made a modification. These should go away ** once the API is frozen. ** ** ** 48 4/10/99 1:24p Atai ** fixed code to compile in packet fifo mode ** ** 47 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 46 3/24/99 6:17p Peter ** reduce nop flush for chain downloads ** ** 45 3/12/99 2:23p Dow ** fixed debug messages ** ** 44 3/05/99 10:34p Peter ** removed extraneous nops ** ** 43 3/02/99 2:08p Peter ** 2d nop flushes pixels (although 3d nop should too) ** ** 42 2/24/99 4:51p Peter ** the rest of tiled texturing ** ** 41 2/19/99 10:15a Peter ** multi-base sourcing ** ** 40 2/18/99 5:57p Peter ** sub-page tiled texture sourcing ** ** 39 2/10/99 2:34p Peter ** removed whacked debugging code ** ** 38 2/02/99 4:41p Peter ** more tiled cleanup(one more coming), 16 byte texture alignmnet ** ** 37 1/28/99 4:28p Atai ** fixed non-square texture bug ** ** 36 1/25/99 6:35p Peter ** tiled texture cleanup ** ** 35 1/14/99 7:48p Peter ** cleanedup bytes per texel stuff ** ** 34 1/14/99 4:02p Peter ** fixed internal computation of tiled textures ** ** 33 12/14/98 6:19p Dow ** Fixed for current surface extension spec ** ** 32 12/09/98 6:25p Atai ** grTexCombine did the right thing for the un-used TMU. Initialize the ** 2nd TMU value to take care of "set FX_GLIDE_NUM_TMU=1" ** ** 31 12/09/98 5:10p Dow ** Fixed debugging ** ** 30 12/09/98 4:28p Dow ** Fixed debug build ** ** 29 12/09/98 2:02p Atai ** Added _grTexForceLod back. Set tLOD min = max = 8 for the 2nd TMU by ** default for Avenger to increase single texturing tri fillrate. ** ** 28 12/03/98 11:26p Dow ** ** 27 11/30/98 6:57p Peter ** windowed texture effage ** ** 26 11/21/98 10:19a Atai ** fixed test37 grChromaRangeModeExt error and rename functions ** ** 25 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 24 11/09/98 5:07p Dow ** Texturing from tiled rendered surfaces works now ** ** 23 10/13/98 5:27p Peter ** 6666 format hack ** ** 22 9/30/98 12:59p Atai ** use texchromakey and texchromarange shadow state ** ** 21 8/31/98 5:54p Jdt ** Fix Mipmapping bug in grTexSource, fix grTexNCCTable ** ** 20 8/12/98 4:25p Peter ** fixed sense of trilinear fixup ** ** 19 7/18/98 3:42p Jdt ** Fix texture size checking bug ** ** 18 7/18/98 10:42a Dow ** Replaced effed-up nest of steaming pile of macros ** ** 17 7/18/98 12:30a Jdt ** Changes to reflect new shadow register structure. ** ** 16 7/17/98 10:44a Atai ** fixed grTexNCCTable and clip coords st with aspect ratio ** ** 15 7/16/98 8:19a Jdt ** fxcmd.h ** ** 14 6/24/98 10:55a Peter ** gary's trilinear hell bug ** ** 13 6/22/98 3:35p Peter ** concatenation this way is evil ** ** 12 5/29/98 11:45a Atai ** 1.added _EXT for extension #defines. ** 2. change GR_TEXBASE_* values ** 3. Remove GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB ** ** 11 5/15/98 4:02p Atai ** fogCoord and texchroma extension for Banshee ** ** 10 5/08/98 1:40p Peter ** merged Anthony's palette of Taco changes ** ** 9 5/07/98 4:13p Peter ** lbe texture thing ** ** 8 5/05/98 2:22p Peter ** merged chroma stuff ** ** 7 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 5 4/22/98 4:57p Peter ** glide2x merge ** ** 4 1/30/98 2:41p Atai ** fix texchroma prototype ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 2 1/18/98 12:03p Atai ** sync to rev 17 spec * * 1 1/16/98 4:29p Atai * create glide 3 src * * 32 1/13/98 12:42p Atai * fixed grtexinfo, grVertexLayout, and draw triangle * * 31 1/09/98 6:48p Atai * grTexInfo, GR_LOD_* and GR_ASPECT_* * * 30 1/08/98 7:09p Peter * real hw stuff modulo makefile change * * 29 1/08/98 4:58p Atai * tex table broadcast, grVertexLayout enable/disable, stq, and some * defines * * 28 1/07/98 10:22a Peter * lod dithering env var * * 27 1/05/98 6:06p Atai * glide extension stuff * * 26 12/18/97 10:52a Atai * fixed grGet(GR_VIDEO_POS) * * 25 12/17/97 4:45p Peter * groundwork for CrybabyGlide * * 24 12/11/97 4:15p Peter * fixed assertions * * 23 12/05/97 4:26p Peter * watcom warnings * * 22 11/20/97 6:57p Dow * baseaddress for banshee * * 21 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 20 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 19 11/03/97 3:43p Peter * h3/cvg cataclysm * * 18 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 17 9/05/97 12:31p Peter * more reg write grouping * * 16 7/08/97 2:48p Peter * started playing w/ h3 sim * * 15 6/06/97 10:47a Peter * texture downloading, fixed 640x480 dimension, changed cvg dep to be the * same as sst1 * * 14 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 13 5/21/97 6:05a Peter * * 12 3/04/97 9:08p Dow * * 11 3/03/97 10:58a Jdt * Fixe for 2-pass trilinear * * 10 12/23/96 1:37p Dow * chagnes for multiplatform glide ** */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #ifndef GLIDE_INIT_HWC #include "minihwc.h" #endif static GrLOD_t g3LodXlat_base[2] = { GR_LOD_LOG2_256, GR_LOD_LOG2_2048 }; #define _g3LodXlat(someLOD, tBig) \ (g3LodXlat_base[tBig] - someLOD) /*------------------------------------------------------------------- Function: _grTexCalcBaseAddressTiled Date: 12-Dec-98 Implementor(s): dow Description: Arguments: start_address: This is the actual physical address of largeLOD. largLOD: This is the largest LOD in the chain aspect: The aspect ratio of the mipmaplevels in the chain fmt: The texture format evenOdd: Bitmask specifiying presence of even & odd mipmap levels. Return: the Value to be placed into the baseAddress register. -------------------------------------------------------------------*/ FxI32 _grTexCalcBaseAddressTiled(GrChipID_t tmu, FxU32 start_address, GrAspectRatio_t aspect, GrLOD_t largeLod, GrTextureFormat_t fmt, FxU32 evenOdd) { #define FN_NAME "_grTexCalcBaseAddressTiled" FxU32 byteOffset, offsetX, offsetY; FxI32 baseAddress = start_address; GrLOD_t maxPossibleLod = GR_LOD_LOG2_256; /* But see below for Napalm */ GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 88); GDBG_INFO_MORE(gc->myLevel, "(%d, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X)\n", tmu, start_address, aspect, largeLod, fmt, evenOdd); /* texBaseAddr gets the address of the largest mipmap level that the * hw is capable of handling (256 for Banshee & Voodoo 3; 2048 for * Napalm) even if some of the larger levels don't exist. Now, * we'll basically calculate the offset (from the beginning) of the * largest mipmap level, and subtract that from start_address to * calculate the baseAdress. * * Capiche? * * Check for Napalm-ness and use that level if applicable. Capisce? * * As it turns out, even on Napalm texBaseAddr *always* points at * the 256x256 mipmap level. %%KCD */ byteOffset = _grTexCalcMipmapLevelOffsetTiled(tmu, largeLod, maxPossibleLod, aspect, fmt, evenOdd, &offsetX, &offsetY); /* _grTexCalcMipmapLevelOffsetTiled returns a byte offset from the * current location back to the start of the biggest level. However, * if we are in tiled texture mode then we actually need to compute * a tiled offset. */ { const struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; const FxU32 tileOffsetY = (offsetY >> HWC_TILE_HEIGHT_SHIFT), tileOffsetX = (offsetX >> HWC_TILE_WIDTH_SHIFT), tileSlopY = (offsetY & (HWC_TILE_HEIGHT - 0x01UL)), tileSlopX = (offsetX & (HWC_TILE_WIDTH - 0x01UL)); /* Count the # of whole page lines we're offsettting */ baseAddress -= (((tileOffsetY * memInfo->texStrideTiles) + tileOffsetX) << (HWC_TILE_HEIGHT_SHIFT + HWC_TILE_WIDTH_SHIFT)); /* If there is a fractional # of tiles then we round back an * entire tile in the dimension of the slop, and then compute the * offset within this tile. ick! */ if (tileSlopX != 0x00UL) { baseAddress -= (0x01UL << (HWC_TILE_HEIGHT_SHIFT + HWC_TILE_WIDTH_SHIFT)); baseAddress += ((0x01UL << HWC_TILE_WIDTH_SHIFT) - tileSlopX); } if (tileSlopY != 0x00UL) { baseAddress -= (memInfo->texStrideTiles << (HWC_TILE_HEIGHT_SHIFT + HWC_TILE_WIDTH_SHIFT)); baseAddress += (((0x01UL << HWC_TILE_HEIGHT_SHIFT) - tileSlopY) << HWC_TILE_WIDTH_SHIFT); } } GR_RETURN(baseAddress); #undef FN_NAME } /* _grTexCalcBaseAddressTiled */ FxU32 _grTexCalcMipmapLevelOffsetTiled(GrChipID_t tmu, GrLOD_t lod, GrLOD_t largeLOD, GrAspectRatio_t aspect, GrTextureFormat_t fmt, FxU32 evenOdd, FxU32 *tileXreturn, FxU32 *tileYreturn) { #define FN_NAME "_grTexCalcMipmapLevelOffsetTiled" const FxU32 texelSize = _grBitsPerTexel[fmt]; FxU32 byteOffset = 0, tileX = 0, tileY = 0; FxI32 direction; GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 90); GR_CHECK_F(FN_NAME, texelSize == 0, "invalid texture format"); GR_CHECK_TMU(FN_NAME, tmu); GR_ASSERT(gc->tmuMemInfo[tmu].texTiled); /* Tiled textures look like this (for big textures) +--------------+-------+ | | | | | 1024 | | | | | +---*---+ | 2048 |512| | <- 256-1 (see below for rest) | +---+---+ | | | | | | | | | | ->| |<- Stride +--------------+ Tiled Textures look like this (for non-big textures): baseAddress regardless of anything else. | V +--------+----*-------------+ | |128 | | | 256 |____| | | |64|-| <-32-1 | +--------+------------------+ |<----------Stride--------->| Expanded View of 32-1: (pretend they're square--this is just intended to demonstrate the layout) +-------------+-------+-------------+ | | 16 | | | | | | | 32 +---+---+ | |8 | | +---+ | |4| | |2 | |1 +-------------+---------------------+ |<-----------------------------stride much bigger than width --------->| */ /* We are either summing up the offsets all the way from the smallest * mipmap in the chain, or we are finding the offset from a given mipmap * level to the one that's used as the base hardware pointer. */ if(lod <= largeLOD) direction = 1; else direction = -1; /* LOOK AT THE PICTURE!!!!! * We're trying to work our way from the upper-left-hand corner of * largeLOD to the upper-left-hand corner of the 256 LOD. */ { const FxU32 texStrideBytes = gc->tmuMemInfo[tmu].texStrideBytes; GrLOD_t level; level = lod; while (level != largeLOD) { switch (level) { case GR_LOD_LOG2_2048: if(direction > 0) { /* Do nothing, in theory should never get here. */ } else { /* Offset by width of 2048 LOD */ if(evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileX -= WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_2048); } level--; } break; case GR_LOD_LOG2_1024: /* Offset by height of 1024 LOD */ if(direction > 0) { /* Offset by width of 2048 LOD */ if(evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileX += WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_2048); } level++; } else { if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY -= HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_1024); } level--; } break; case GR_LOD_LOG2_512: if(direction > 0) { /* Offset by height of 1024 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_1024); } level++; } else { /* Offset by width of 512 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileX -= WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_512); } level--; } break; case GR_LOD_LOG2_256: if(direction > 0) { /* Offset the width of the 512 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileX += WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_512); } level++; } else { /* Do nothing. In theory should never get here. */ } break; case GR_LOD_LOG2_128: /* Offset the width of the 256 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileX += WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_256); } level++; break; case GR_LOD_LOG2_64: /* Offset the height of the 128 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_128); } level++; break; case GR_LOD_LOG2_32: /* Offset the width of the 64 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileX += WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_64); } level++; break; case GR_LOD_LOG2_16: /* Offset the width of the 32 LOD */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileX += WIDTH_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_32); } level++; break; case GR_LOD_LOG2_8: { switch(fmt) { case GR_TEXFMT_ARGB_CMP_FXT1: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileY += HEIGHT_BY_ASPECT_LOD_FXT1(aspect, GR_LOD_LOG2_16); } break; case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileY += HEIGHT_BY_ASPECT_LOD_DXT(aspect, GR_LOD_LOG2_16); } break; default: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileY += HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_16); } break; } } level++; break; case GR_LOD_LOG2_4: { switch(fmt) { case GR_TEXFMT_ARGB_CMP_FXT1: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD_FXT1(aspect, GR_LOD_LOG2_8); } break; case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD_DXT(aspect, GR_LOD_LOG2_8); } break; default: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_8); } break; } } level++; break; case GR_LOD_LOG2_2: { switch(fmt) { case GR_TEXFMT_ARGB_CMP_FXT1: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileY += HEIGHT_BY_ASPECT_LOD_FXT1(aspect, GR_LOD_LOG2_4); } break; case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileY += HEIGHT_BY_ASPECT_LOD_DXT(aspect, GR_LOD_LOG2_4); } break; default: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_ODD) { tileY += HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_4); } break; } } level++; break; case GR_LOD_LOG2_1: { switch(fmt) { case GR_TEXFMT_ARGB_CMP_FXT1: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD_FXT1(aspect, GR_LOD_LOG2_2); } break; case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD_DXT(aspect, GR_LOD_LOG2_2); } break; default: /* For these, we offset the LOD height * texture stride */ if (evenOdd & GR_MIPMAPLEVELMASK_EVEN) { tileY += HEIGHT_BY_ASPECT_LOD(aspect, GR_LOD_LOG2_2); } break; } } level++; break; } } if(tileXreturn) { *tileXreturn = (tileX * texelSize)>>3; *tileYreturn = tileY; } /* The ">>3" is here to to convert from bits to bytes: */ byteOffset = (((tileX * texelSize)>>3) + (tileY * texStrideBytes)); } return byteOffset; #undef FN_NAME } /* _grTexCalcMipmapLevelOffsetTiled */ #if GLIDE_CHECK_TRILINEAR /* !! TACO - Come back to this code on Avenger */ /* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must be called after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. * * FixMe: This should eventually get merged in w/ the texture * statemonster. When/If that ever happens. */ static void _grTexCheckTriLinear(GrChipID_t tmu) { #define FN_NAME "_grTexCheckTriLinear" GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(0x%X)\n", tmu); #if (GLIDE_NUM_TMU > 2) #error "(GLIDE_NUM_TMU > 2): Write this code" #endif /* NB: The factor mask needs to include the factor bits as * well as the reverse bit so that we can differentiate * between the lodfrac and the (1 - lodfrac) case. */ #define SST_TC_FACTOR_MASK (SST_TC_MSELECT | SST_TC_REVERSE_BLEND) #define SST_MIPMAP_LEVEL_MASK (SST_LOD_ODD | SST_LOD_TSPLIT) /* Is this tmu on? */ if (!gc->tmuLodDisable[tmu]) { const struct PerTmuState* tmu0 = gc->state.per_tmu; const struct PerTmuState* tmu1 = gc->state.per_tmu + 1; const struct PerTmuState* curTmu = gc->state.per_tmu + tmu; const struct PerTmuState* otherTmu = gc->state.per_tmu + !tmu; /* This is the 'tricky' state where we have to manage the states * of teh tmu's together to get the correct effect. Within this * state there are two sub-states: two-pass trilinear and single * pass using both tmu's w/ split levels. * * Case 1 - TMU set for lod blending and has both even/odd levels */ if ((curTmu->textureMode & SST_TRILINEAR) && (curTmu->evenOdd == 3)) { /* Check the 'other' tmu to see if it is active, if not then we * are doing two pass trilinear so check that we have the * correct even/odd things set based on the factor where one * pass will use GR_COMBINE_FACTOR_LOD_FRACTION and the other * will use (1 - GR_COMBINE_FACTOR_LOD_FRACTION). */ if (gc->tmuLodDisable[!tmu]) { /* NB: In this case the rgb/alpha factors need to match so * checking for only one of them is fine. */ const FxU32 levelMask = (((curTmu->textureMode & SST_TC_FACTOR_MASK) == SST_TC_MLODFRAC) ? SST_LOD_ODD : 0); GDBG_INFO(gc->myLevel, FN_NAME": Two-pass trilinear fixup (0x%X) : tLOD : (0x%X : 0x%X)\n", tmu, curTmu->tLOD, ((curTmu->tLOD & ~SST_MIPMAP_LEVEL_MASK) | levelMask)); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(eChipTMU0, SST_TMU(hw, 0), tLOD, ((curTmu->tLOD & ~SST_MIPMAP_LEVEL_MASK) | levelMask)); GR_CHECK_SIZE(); } else { /* One pass trilinear * * Make sure that the tmu's have the levels split across the * two tmu's. There are basically three cases based on what * the user might have already set on the other tmu. */ if (((tmu0->textureMode & SST_TC_BLEND) == SST_TC_BLEND) && ((tmu1->textureMode & SST_TC_REPLACE) == SST_TC_REPLACE)) { FxU32 evenOdd[GLIDE_NUM_TMU]; FxU32* curEvenOdd = evenOdd + tmu; { FxU32 i; for(i = 0; i < GLIDE_NUM_TMU; i++) { evenOdd[i] = gc->state.shadow[i].tLOD & SST_LOD_ODD; } } /* 1 - The other tmu already has the even levels. */ if ((otherTmu->evenOdd == GR_MIPMAPLEVELMASK_EVEN) && (curTmu->evenOdd != GR_MIPMAPLEVELMASK_ODD)) { *curEvenOdd = SST_LOD_ODD; goto __tmuRegUpdate; } /* 2 - The other tmu already has the odd levels. */ if ((otherTmu->evenOdd == GR_MIPMAPLEVELMASK_ODD) && (curTmu->evenOdd != GR_MIPMAPLEVELMASK_EVEN)) { *curEvenOdd = 0; goto __tmuRegUpdate; } /* 3 - The other tmu already has both the levels. If the * downstream tmu's factor is lodFrac then the upstream tmu * needs to be (1 - lodFrac) and vice-versa. */ if (otherTmu->evenOdd == GR_MIPMAPLEVELMASK_BOTH) { evenOdd[0] = (((tmu0->textureMode & SST_TC_FACTOR_MASK) == SST_TC_MLODFRAC) ? SST_LOD_ODD : 0); evenOdd[1] = ~evenOdd[0] & SST_LOD_ODD; goto __tmuRegUpdate; } /* Do the register updates */ if (0) { __tmuRegUpdate: GDBG_INFO(gc->myLevel, FN_NAME": Tri-linear fixup (0x%X : 0x%X) : (0x%X : 0x%X)\n", tmu0->tLOD, tmu1->tLOD, ((tmu0->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[0]), ((tmu1->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[1])); GR_SET_EXPECTED_SIZE((sizeof(FxU32) << 1), 2); { GR_SET(eChipTMU0, SST_TMU(hw, 0), tLOD, ((tmu0->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[0])); GR_SET(eChipTMU1, SST_TMU(hw, 1), tLOD, ((tmu1->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[1])); } GR_CHECK_SIZE(); } } } } } GR_END(); #undef FN_NAME } /* _grTexCheckTriLinear*/ #endif /* GLIDE_CHECK_TRILINEAR */ void _grTex2ppc(FxBool enable) { #define FN_NAME "_grTex2ppc" #ifdef FX_GLIDE_NAPALM /* ** enable combineMode[29] ** control the band in renderMode[24:22] ** make tmu 1 state the same as tmu0 */ FxU32 combineMode; FxU32 tmu0cMode; FxU32 tmu1cMode; FxU32 tmu0cMode_tmuShadow; FxU32 tmu1cMode_tmuShadow; FxBool oldstate; GR_BEGIN_NOFIFOCHECK("_grTex2ppc",88); combineMode = gc->state.shadow.combineMode; oldstate = (combineMode & SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK) ? FXTRUE : FXFALSE; GDBG_INFO(gc->myLevel, FN_NAME ": changing 2ppc mode to: %s\n", enable ? "FXTRUE" : "FXFALSE"); if (enable == oldstate) return; gc->state.mode2ppc = enable; /* Make sure that all TMU registers are restored if 2PPC mode is being switched off. */ if(!enable) { INVALIDATE_TMU(GR_TMU0, textureMode); INVALIDATE_TMU(GR_TMU0, texBaseAddr); INVALIDATE_TMU(GR_TMU0, texchroma); INVALIDATE_TMU(GR_TMU1, textureMode); INVALIDATE_TMU(GR_TMU1, texBaseAddr); INVALIDATE_TMU(GR_TMU1, texchroma); } tmu0cMode = gc->state.shadow.tmuState[0].combineMode; tmu1cMode = gc->state.shadow.tmuState[1].combineMode; tmu0cMode_tmuShadow = gc->state.tmuShadow[0].combineMode; tmu1cMode_tmuShadow = gc->state.tmuShadow[1].combineMode; combineMode &= ~(SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK); tmu0cMode &= ~(SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK); tmu1cMode &= ~(SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK); tmu0cMode_tmuShadow &= ~(SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK); tmu1cMode_tmuShadow &= ~(SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK); combineMode |= ((enable) ? SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK : 0); tmu0cMode |= ((enable) ? SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK : 0); tmu1cMode |= ((enable) ? SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK : 0); tmu0cMode_tmuShadow |= ((enable) ? SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK : 0); tmu1cMode_tmuShadow |= ((enable) ? SST_CM_ENABLE_TWO_PIXELS_PER_CLOCK : 0); /* ** Need to flush the tmu pipeline going from 2ppc to 1ppc ** by sending 12 nopCMD */ if (!enable) { FxU32 i; GR_SET_EXPECTED_SIZE(sizeof(FxU32)*12, 12); for (i = 0; i < 12; i++) { GR_SET(eChipTMU0 | eChipTMU1, hw, nopCMD, 0); } GR_CHECK_SIZE(); } /* set combine mode */ REG_GROUP_BEGIN(BROADCAST_ID, combineMode, 1, 0x1); { REG_GROUP_SET(hw, combineMode, combineMode); #if DEBUG_2PPC GDBG_PRINTF("FBI combineMode: %08lx\n",combineMode); #endif } REG_GROUP_END(); REG_GROUP_BEGIN(eChipTMU0, combineMode, 1, 0x1); { REG_GROUP_SET(SST_TMU(hw, 0), combineMode, tmu0cMode); #if DEBUG_2PPC GDBG_PRINTF("TMU0 combineMode: %08lx 2ppc=%d\n",tmu0cMode,enable); #endif } REG_GROUP_END(); REG_GROUP_BEGIN(eChipTMU1, combineMode, 1, 0x1); { REG_GROUP_SET(SST_TMU(hw, 1), combineMode, tmu1cMode); #if DEBUG_2PPC GDBG_PRINTF("TMU1 combineMode: %08lx 2ppc=%d\n",tmu1cMode,enable); #endif } REG_GROUP_END(); gc->state.shadow.combineMode = combineMode; gc->state.shadow.tmuState[0].combineMode = tmu0cMode; gc->state.shadow.tmuState[1].combineMode = tmu1cMode; gc->state.tmuShadow[0].combineMode = tmu0cMode_tmuShadow; gc->state.tmuShadow[1].combineMode = tmu1cMode_tmuShadow; GR_END(); #endif #undef FN_NAME } /* _grTex2ppc */ /*--------------------------------------------------------------------------- ** grTexClampMode */ GR_ENTRY(grTexClampMode, void, (GrChipID_t tmu, GrTextureClampMode_t s_clamp_mode, GrTextureClampMode_t t_clamp_mode)) { #define FN_NAME "grTexClampMode" FxU32 texturemode, tLod, clampMode =(((s_clamp_mode == GR_TEXTURECLAMP_CLAMP) ? SST_TCLAMPS : 0) | ((t_clamp_mode == GR_TEXTURECLAMP_CLAMP) ? SST_TCLAMPT : 0)), mirrorMode =(((s_clamp_mode == GR_TEXTURECLAMP_MIRROR_EXT) ? SST_TMIRRORS : 0) | ((t_clamp_mode == GR_TEXTURECLAMP_MIRROR_EXT) ? SST_TMIRRORT : 0)); GR_BEGIN_NOFIFOCHECK("grTexClampMode",88); GDBG_INFO_MORE(gc->myLevel,"(%d, %d,%d)\n",tmu,s_clamp_mode,t_clamp_mode); GR_CHECK_TMU(FN_NAME, tmu); /* ** Assuming Banshee family has max tmu size of 2 */ texturemode = gc->state.tmuShadow[tmu].textureMode; texturemode &= ~(SST_TCLAMPS | SST_TCLAMPT); texturemode |= clampMode; tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_TMIRRORS | SST_TMIRRORT); /* disable mirror */ if (mirrorMode) tLod |= mirrorMode; gc->state.tmuShadow[tmu].textureMode = texturemode; gc->state.tmuShadow[tmu].tLOD = tLod; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].textureMode = texturemode; gc->state.shadow.tmuState[tmu].tLOD = tLod; _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), textureMode, 2, 0x3); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[tmu].textureMode); REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); } REG_GROUP_END(); _grChipMask(gc->chipmask); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); } else { INVALIDATE_TMU(tmu, textureMode); } GR_END(); #undef FN_NAME } /* grTexClampMode */ /*--------------------------------------------------------------------------- ** grTexCombine */ GR_ENTRY(grTexCombine, void, (GrChipID_t tmu, GrCombineFunction_t rgb_function, GrCombineFactor_t rgb_factor, GrCombineFunction_t alpha_function, GrCombineFactor_t alpha_factor, FxBool rgb_invert, FxBool alpha_invert)) { #define FN_NAME "grTexCombine" FxU32 texturemode; FxU32 tLod; FxU32 tmuMask; FxBool localColorP = FXFALSE; FxBool localAlphaP = FXFALSE; GR_BEGIN_NOFIFOCHECK("grTexCombine",88); GDBG_INFO_MORE(gc->myLevel,"(%d, %d,%d, %d,%d, %d,%d)\n", tmu, rgb_function, rgb_factor, alpha_function, alpha_factor, rgb_invert, alpha_invert); GR_CHECK_TMU(FN_NAME, tmu); GR_CHECK_W(FN_NAME, rgb_function < GR_COMBINE_FUNCTION_ZERO || rgb_function > GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA, "unsupported texture color combine function"); GR_CHECK_W(FN_NAME, alpha_function < GR_COMBINE_FUNCTION_ZERO || alpha_function > GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA, "unsupported texture alpha combine function"); GR_CHECK_W(FN_NAME, (rgb_factor & 0x7) < GR_COMBINE_FACTOR_ZERO || (rgb_factor & 0x7) > GR_COMBINE_FACTOR_LOD_FRACTION || rgb_factor > GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION, "unsupported texture color combine scale factor"); GR_CHECK_W(FN_NAME, (alpha_factor & 0x7) < GR_COMBINE_FACTOR_ZERO || (alpha_factor & 0x7) > GR_COMBINE_FACTOR_LOD_FRACTION || alpha_factor > GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION, "unsupported texture alpha combine scale factor"); #if DEBUG_2PPC GDBG_PRINTF("grTexCombine(tmu=%d,rgbfunc=%x,rgbfact=%x,afunc=%x,afact=%x,ri=%d,ai=%d)\n", tmu,rgb_function,rgb_factor,alpha_function,alpha_factor,rgb_invert,alpha_invert); #endif #ifdef FX_GLIDE_NAPALM { /* ** turn off combine mode if necessary */ FxU32 combineMode = gc->state.tmuShadow[tmu].combineMode; FxU32 isCombineExt = (combineMode & SST_CM_USE_COMBINE_MODE); if (isCombineExt) { SstRegs* tmuHw = SST_TMU(hw, tmu); /* It appears that some of the combineMode bits still take effect */ /* even if SST_CM_USE_COMBINE_MODE is cleared. Thus, to make sure */ /* that things work right with old style combine modes, we clear */ /* all of the combine mode bits to zero. */ combineMode &= ~( SST_CM_USE_COMBINE_MODE | SST_CM_TC_OTHERSELECT | SST_CM_TC_LOCALSELECT | SST_CM_TC_MSELECT_7 | SST_CM_TC_INVERT_OTHER | SST_CM_TC_INVERT_LOCAL | SST_CM_TC_INVERT_ADD_LOCAL | SST_CM_TC_OUTSHIFT | SST_CM_TCA_OTHERSELECT | SST_CM_TCA_LOCALSELECT | SST_CM_TCA_INVERT_OTHER | SST_CM_TCA_INVERT_LOCAL | SST_CM_TCA_INVERT_ADD_LOCAL | SST_CM_TCA_OUTSHIFT | SST_CM_DISABLE_CHROMA_SUBSTITUTION ); INVALIDATE_TMU(tmu, textureMode); gc->state.tmuShadow[tmu].combineMode = combineMode; } } #endif /* tmuMask tells grColorCombineFunction what to turn off an on if the ccFunc requires texture mapping */ texturemode = gc->state.tmuShadow[tmu].textureMode; texturemode &= ~(SST_TCOMBINE | SST_TACOMBINE); tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_LOD_ODD); gc->state.tcc_requires_constant_color[tmu] = FXFALSE; gc->state.tac_requires_constant_color[tmu] = FXFALSE; gc->state.combineExtsInUse &= ~(STATE_USING_TCC|STATE_USING_TAC); tmuMask = GR_TMUMASK_TMU0 << tmu; gc->state.tmuMaskShadow &= ~tmuMask; gc->state.tmuColorPassthrough &= ~tmuMask; gc->state.tmuAlphaPassthrough &= ~tmuMask; /* Check for obvious passthrough case */ if((rgb_function == GR_COMBINE_FUNCTION_SCALE_OTHER) && (rgb_factor == GR_COMBINE_FACTOR_ONE) && (alpha_function == GR_COMBINE_FUNCTION_SCALE_OTHER) && (alpha_factor == GR_COMBINE_FACTOR_ONE)) { gc->state.tmuColorPassthrough |= tmuMask; gc->state.tmuAlphaPassthrough |= tmuMask; } /* setup scale factor bits */ texturemode |= (rgb_factor & 0x7) << SST_TC_MSELECT_SHIFT; if (!(rgb_factor & 0x8)) texturemode |= SST_TC_REVERSE_BLEND; if (((rgb_factor & 0x7) == GR_COMBINE_FACTOR_LOCAL) || ((rgb_factor & 0x7) == GR_COMBINE_FACTOR_LOCAL_ALPHA)) gc->state.tmuMaskShadow |= tmuMask; texturemode |= (alpha_factor & 0x7) << SST_TCA_MSELECT_SHIFT; if (!(alpha_factor & 0x8)) texturemode |= SST_TCA_REVERSE_BLEND; if (((alpha_factor & 0x7) == GR_COMBINE_FACTOR_LOCAL) || ((alpha_factor & 0x7) == GR_COMBINE_FACTOR_LOCAL_ALPHA)) gc->state.tmuMaskShadow |= tmuMask; /* setup invert output bits */ if (rgb_invert) texturemode |= SST_TC_INVERT_OUTPUT; if (alpha_invert) texturemode |= SST_TCA_INVERT_OUTPUT; /* setup core color combine unit bits */ switch (rgb_function) { case GR_COMBINE_FUNCTION_ZERO: texturemode |= SST_TC_ZERO_OTHER; localColorP = FXTRUE; break; case GR_COMBINE_FUNCTION_LOCAL: texturemode |= SST_TC_ZERO_OTHER | SST_TC_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; localColorP = FXTRUE; break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: texturemode |= SST_TC_ZERO_OTHER | SST_TC_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; localColorP = FXTRUE; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: texturemode |= SST_TC_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: texturemode |= SST_TC_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: texturemode |= SST_TC_SUB_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: texturemode |= SST_TC_SUB_CLOCAL | SST_TC_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: texturemode |= SST_TC_SUB_CLOCAL | SST_TC_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: texturemode |= SST_TC_ZERO_OTHER | SST_TC_SUB_CLOCAL | SST_TC_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; localColorP = ((rgb_factor & 0x07UL) != GR_COMBINE_FACTOR_OTHER_ALPHA); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: texturemode |= SST_TC_ZERO_OTHER | SST_TC_SUB_CLOCAL | SST_TC_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; localColorP = ((rgb_factor & 0x07UL) != GR_COMBINE_FACTOR_OTHER_ALPHA); break; } switch (alpha_function) { case GR_COMBINE_FUNCTION_ZERO: texturemode |= SST_TCA_ZERO_OTHER; localAlphaP = FXTRUE; break; case GR_COMBINE_FUNCTION_LOCAL: texturemode |= SST_TCA_ZERO_OTHER | SST_TCA_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; localAlphaP = FXTRUE; break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: texturemode |= SST_TCA_ZERO_OTHER | SST_TCA_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; localAlphaP = FXTRUE; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: texturemode |= SST_TCA_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: texturemode |= SST_TCA_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: texturemode |= SST_TCA_SUB_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: texturemode |= SST_TCA_SUB_CLOCAL | SST_TCA_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: texturemode |= SST_TCA_SUB_CLOCAL | SST_TCA_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: texturemode |= SST_TCA_ZERO_OTHER | SST_TCA_SUB_CLOCAL | SST_TCA_ADD_CLOCAL; gc->state.tmuMaskShadow |= tmuMask; localAlphaP = ((alpha_factor & 0x07UL) != GR_COMBINE_FACTOR_OTHER_ALPHA); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: texturemode |= SST_TCA_ZERO_OTHER | SST_TCA_SUB_CLOCAL | SST_TCA_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; localAlphaP = ((alpha_factor & 0x07UL) != GR_COMBINE_FACTOR_OTHER_ALPHA); break; } gc->state.tcc_requires_prev_texture[tmu] = !localColorP; gc->state.tac_requires_prev_texture[tmu] = !localAlphaP; /* Hack to enable TWO-PASS Trilinear */ if (texturemode & SST_TRILINEAR) { if ((texturemode & SST_TC_ZERO_OTHER) && (texturemode & SST_TC_BLEND_LODFRAC) && !(texturemode & SST_TC_REVERSE_BLEND)) { tLod |= SST_LOD_ODD; } } /* Hack to use single pass trilinear in UMA state */ if((texturemode & SST_TRILINEAR) && (gc->state.grEnableArgs.texture_uma_mode == GR_MODE_ENABLE) && (gc->state.per_tmu[tmu].evenOdd == GR_MIPMAPLEVELMASK_BOTH) && (tmu == GR_TMU1)) { tLod |= SST_LOD_ODD; } tLod |= _gr_evenOdd_xlate_table[gc->state.per_tmu[tmu].evenOdd]; /* Update shadows */ INVALIDATE_TMU(tmu, textureMode); gc->state.tmuShadow[tmu].textureMode = texturemode; gc->state.tmuShadow[tmu].tLOD = tLod; /* If the state of a tmu changes from active then make sure that it * is addressing some valid tiny texture so that it does not spend * time thrashing on a large texture access. * * NB: We don't update the shadow here so the other bits in the * register shadow should be unchanged. */ #if GLIDE_CHECK_TRILINEAR /* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must happen after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. */ if (gc->num_tmu > 1) _grTexCheckTriLinear(tmu); #endif /* GLIDE_CHECK_TRILINEAR */ GR_END(); #undef FN_NAME } /* grTexCombine */ #if DEBUG_COMBINEEXT const char *cmbxName[] = { "ZERO ", /* GR_CMBX_ZERO 0x00 */ "TA ", /* GR_CMBX_TEXTURE_ALPHA 0x01 */ "ALCL ", /* GR_CMBX_ALOCAL 0x02 */ "AOTR ", /* GR_CMBX_AOTHER 0x03 */ "B ", /* GR_CMBX_B 0x04 */ "CA ", /* GR_CMBX_CONSTANT_ALPHA 0x05 */ "CC ", /* GR_CMBX_CONSTANT_COLOR 0x06 */ "DFCT ", /* GR_CMBX_DETAIL_FACTOR 0x07 */ "IA ", /* GR_CMBX_ITALPHA 0x08 */ "IRGB ", /* GR_CMBX_ITRGB 0x09 */ "LTA ", /* GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a */ "LTRG ", /* GR_CMBX_LOCAL_TEXTURE_RGB 0x0b */ "LFRC ", /* GR_CMBX_LOD_FRAC 0x0c */ "OTA ", /* GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d */ "OTRG ", /* GR_CMBX_OTHER_TEXTURE_RGB 0x0e */ "TRGB ", /* GR_CMBX_TEXTURE_RGB 0x0f */ "TCA ", /* GR_CMBX_TMU_CALPHA 0x10 */ "TCC " /* GR_CMBX_TMU_CCOLOR 0x11 */ }; const char *funcName[] = { "ZERO ", /* GR_FUNC_MODE_ZERO 0x00 */ "X ", /* GR_FUNC_MODE_X 0x01 */ "1-X ", /* GR_FUNC_MODE_ONE_MINUS_X 0x02 */ "-X ", /* GR_FUNC_MODE_NEGATIVE_X 0x03 */ "X-.5 ", /* GR_FUNC_MODE_X_MINUS_HALF 0x04 */ "1 ", /* GR_FUNC_MODE_ONE 0x05 */ "-.5 " /* GR_FUNC_MODE_MINUS_HALF 0x06 */ }; const char *shiftName[] = { "1X ", "2X ", "4X " }; const char *boolName[] = { "FXFALSE ", "FXTRUE " }; #endif #ifdef FX_GLIDE_NAPALM /*--------------------------------------------------------------------------- ** grTexColorCombineExt */ GR_EXT_ENTRY(grTexColorCombineExt, void, (GrChipID_t tmu, GrTCCUColor_t a, GrCombineMode_t a_mode, GrTCCUColor_t b, GrCombineMode_t b_mode, GrTCCUColor_t c, FxBool c_invert, GrTCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert)) { #define FN_NAME "grTexColorCombineExt" FxU32 texturemode; FxU32 combineMode; FxU32 tLod; FxU32 tmuMask; FxU32 btmuMask = 0; FxU32 localTMU = FXFALSE; FxU32 btermTMU = FXFALSE; GR_BEGIN_NOFIFOCHECK("grTexColorCombineExt",88); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d,%d,%d,%d,%d,%d,%d)\n", tmu, a, a_mode, b, b_mode, c, d, shift, invert); #if DEBUG_2PPC || DEBUG_COMBINEEXT GDBG_PRINTF("grTexColorCombineExt(tmu=%d,a=%s,am=%s,b=%s,bm=%s,c=%s,ci=%s,d=%s,di=%s,s=%s,i=%s)\n", tmu,cmbxName[a],funcName[a_mode], cmbxName[b],funcName[b_mode], cmbxName[c],boolName[c_invert], cmbxName[d],boolName[d_invert], shiftName[shift], boolName[invert]); #endif /* ** a = tc_otherselect ** a_mode = tc_invert_other ** b = tc_localselect ** b_mode = tc_invert_local ** c = (tc_mselect, tc_mselect_7) ** d = (tc_add_clocal, tc_add_alocal) ** shift = tc_outshift ** invert = tc_invert_output */ /* tmuMask tells grColorCombineFunction what to turn off an on if the ccFunc requires texture mapping */ combineMode = gc->state.tmuShadow[tmu].combineMode; texturemode = gc->state.tmuShadow[tmu].textureMode; texturemode &= ~(SST_TCOMBINE); tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_LOD_ODD); /* Mark that grTexColorCombine has been called... */ gc->state.combineExtsInUse |= STATE_USING_TCC; /* Generate mask for this TMU. */ tmuMask = GR_TMUMASK_TMU0 << tmu; /* Clear flag marking this TMU as being in use. */ gc->state.tmuMaskShadow &= ~tmuMask; combineMode &= ~( SST_CM_TC_OTHERSELECT | SST_CM_TC_LOCALSELECT | SST_CM_TC_MSELECT_7 | SST_CM_TC_INVERT_OTHER | SST_CM_TC_INVERT_LOCAL | SST_CM_TC_INVERT_ADD_LOCAL | SST_CM_TC_OUTSHIFT | SST_CM_DISABLE_CHROMA_SUBSTITUTION ); texturemode &= ~( SST_TC_MSELECT | /* part of c */ SST_TC_ADD_CLOCAL | /* part of d */ SST_TC_ADD_ALOCAL | /* part of d */ SST_TC_INVERT_OUTPUT | /* invert */ SST_TC_REVERSE_BLEND | SST_TC_ZERO_OTHER | SST_TC_SUB_CLOCAL ); tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_LOD_ODD); tmuMask = GR_TMUMASK_TMU0 << tmu; gc->state.tmuMaskShadow &= ~tmuMask; gc->state.tcctmuMask &= ~tmuMask; gc->state.tmuColorPassthrough &= ~tmuMask; /* Check for obvious passthrough case. Expand later if something other * than OpenGL ever does this sort of thing. */ if(((a == GR_CMBX_OTHER_TEXTURE_RGB) && (a_mode == GR_FUNC_MODE_X)) && ((b == GR_CMBX_ZERO) && (b_mode == GR_FUNC_MODE_X)) && ((c == GR_CMBX_ZERO) && (c_invert == FXTRUE)) && ((d == GR_CMBX_ZERO) && (d_invert == FXFALSE)) && (shift == 0) && (invert == FXFALSE)) { gc->state.tmuColorPassthrough |= tmuMask; } gc->state.tcc_requires_it_alpha[tmu] = ( (a == GR_CMBX_ITALPHA) | (b == GR_CMBX_ITALPHA) | (c == GR_CMBX_ITALPHA) ); gc->state.tcc_requires_it_rgb[tmu] = ( (a == GR_CMBX_ITRGB) | (b == GR_CMBX_ITRGB) | (c == GR_CMBX_ITRGB) | (d == GR_CMBX_ITRGB) ); gc->state.tcc_requires_prev_texture[tmu] = ( (a == GR_CMBX_OTHER_TEXTURE_RGB) | (a == GR_CMBX_OTHER_TEXTURE_ALPHA) | (b == GR_CMBX_OTHER_TEXTURE_RGB) | (b == GR_CMBX_OTHER_TEXTURE_ALPHA) | (c == GR_CMBX_OTHER_TEXTURE_RGB) | (c == GR_CMBX_OTHER_TEXTURE_ALPHA) ); gc->state.tcc_requires_texture[tmu] = ( (a == GR_CMBX_OTHER_TEXTURE_RGB) | (a == GR_CMBX_LOCAL_TEXTURE_RGB) | (a == GR_CMBX_OTHER_TEXTURE_ALPHA) | (a == GR_CMBX_LOCAL_TEXTURE_ALPHA) | (b == GR_CMBX_OTHER_TEXTURE_RGB) | (b == GR_CMBX_LOCAL_TEXTURE_RGB) | (b == GR_CMBX_OTHER_TEXTURE_ALPHA) | (b == GR_CMBX_LOCAL_TEXTURE_ALPHA) | (c == GR_CMBX_OTHER_TEXTURE_RGB) | (c == GR_CMBX_LOCAL_TEXTURE_RGB) | (c == GR_CMBX_OTHER_TEXTURE_ALPHA) | (c == GR_CMBX_LOCAL_TEXTURE_ALPHA) | (d == GR_CMBX_LOCAL_TEXTURE_ALPHA) ); gc->state.tcc_requires_constant_color[tmu] = FXFALSE; switch (a) { case GR_CMBX_OTHER_TEXTURE_RGB: combineMode |= SST_CM_TC_OTHERSELECT_OTHER_TRGB; localTMU = FXFALSE; break; case GR_CMBX_OTHER_TEXTURE_ALPHA: combineMode |= SST_CM_TC_OTHERSELECT_OTHER_TA; localTMU = FXFALSE; break; case GR_CMBX_LOCAL_TEXTURE_RGB: combineMode |= SST_CM_TC_OTHERSELECT_LOCAL_TRGB; gc->state.tmuMaskShadow |= tmuMask; localTMU = FXTRUE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: combineMode |= SST_CM_TC_OTHERSELECT_LOCAL_TA; gc->state.tmuMaskShadow |= tmuMask; localTMU = FXTRUE; break; case GR_CMBX_ITRGB: combineMode |= SST_CM_TC_OTHERSELECT_IRGB; localTMU = FXTRUE; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_TC_OTHERSELECT_IA; localTMU = FXTRUE; break; case GR_CMBX_TMU_CCOLOR: combineMode |= SST_CM_TC_OTHERSELECT_CR_RGB; gc->state.tcc_requires_constant_color[tmu] = FXTRUE; gc->state.tmuMaskShadow |= tmuMask; localTMU = FXTRUE; break; case GR_CMBX_TMU_CALPHA: combineMode |= SST_CM_TC_OTHERSELECT_CR_A ; gc->state.tcc_requires_constant_color[tmu] = FXTRUE; gc->state.tmuMaskShadow |= tmuMask; localTMU = FXTRUE; break; default: /* output zero if the a term is unknown type */ a_mode = GR_FUNC_MODE_ZERO; localTMU = FXTRUE; break; } switch (b) { case GR_CMBX_LOCAL_TEXTURE_RGB: combineMode |= SST_CM_TC_LOCALSELECT_LOCAL_TRGB; if (b_mode != GR_FUNC_MODE_ZERO) { gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; } btmuMask = tmuMask; btermTMU = FXTRUE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: combineMode |= SST_CM_TC_LOCALSELECT_LOCAL_TA; if (b_mode != GR_FUNC_MODE_ZERO) { gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; } btmuMask = tmuMask; btermTMU = FXTRUE; break; case GR_CMBX_OTHER_TEXTURE_RGB: combineMode |= SST_CM_TC_LOCALSELECT_OTHER_TRGB; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXFALSE; btermTMU = FXFALSE; break; case GR_CMBX_OTHER_TEXTURE_ALPHA: combineMode |= SST_CM_TC_LOCALSELECT_OTHER_TA; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXFALSE; btermTMU = FXFALSE; break; case GR_CMBX_ITRGB: combineMode |= SST_CM_TC_LOCALSELECT_IRGB; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXTRUE; btermTMU = FXTRUE; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_TC_LOCALSELECT_IA; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXTRUE; btermTMU = FXTRUE; break; case GR_CMBX_TMU_CCOLOR: combineMode |= SST_CM_TC_LOCALSELECT_CK_RGB; gc->state.tcc_requires_constant_color[tmu] = FXTRUE; if (b_mode != GR_FUNC_MODE_ZERO) { gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; } btmuMask = tmuMask; btermTMU = FXTRUE; break; case GR_CMBX_TMU_CALPHA: combineMode |= SST_CM_TC_LOCALSELECT_CK_A; gc->state.tcc_requires_constant_color[tmu] = FXTRUE; if (b_mode != GR_FUNC_MODE_ZERO) { gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; } btmuMask = tmuMask; btermTMU = FXTRUE; break; default: /* output zero if the b term is unknown type */ b_mode = GR_FUNC_MODE_ZERO; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXTRUE; btermTMU = FXTRUE; break; } switch (a_mode) { case GR_FUNC_MODE_ZERO: combineMode |= SST_CM_TC_INVERT_OTHER_X; break; case GR_FUNC_MODE_X: combineMode |= SST_CM_TC_INVERT_OTHER_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_TC_INVERT_OTHER_ZERO_MINUS_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_TC_INVERT_OTHER_ONE_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_TC_INVERT_OTHER_X_MINUS_HALF; break; } if (a_mode == GR_FUNC_MODE_ZERO) texturemode |= SST_TC_ZERO_OTHER; switch (b_mode) { case GR_FUNC_MODE_ZERO: combineMode |= SST_CM_TC_INVERT_LOCAL_X; break; case GR_FUNC_MODE_X: combineMode |= SST_CM_TC_INVERT_LOCAL_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_TC_INVERT_LOCAL_ZERO_MINUS_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_TC_INVERT_LOCAL_ONE_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_TC_INVERT_LOCAL_X_MINUS_HALF; break; } if (b_mode != GR_FUNC_MODE_ZERO) texturemode |= SST_TC_SUB_CLOCAL; switch (c) { /* Is this correct??? */ case GR_CMBX_ZERO: texturemode |= SST_TC_MONE; localTMU &= FXTRUE; break; case GR_CMBX_B: texturemode |= SST_TC_MCLOCAL; localTMU &= btermTMU; gc->state.tmuMaskShadow |= btmuMask; break; case GR_CMBX_OTHER_TEXTURE_ALPHA: texturemode |= SST_TC_MAOTHER; localTMU &= FXFALSE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: texturemode |= SST_TC_MALOCAL; gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; break; case GR_CMBX_DETAIL_FACTOR: texturemode |= SST_TC_MLOD; /* ??? */ gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; break; case GR_CMBX_LOD_FRAC: texturemode |= SST_TC_MLODFRAC; /* ??? */ gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXFALSE; break; case GR_CMBX_LOCAL_TEXTURE_RGB: texturemode |= SST_TC_MCMSELECT7; combineMode |= SST_CM_TC_MSELECT_7_LOCAL_TRGB; gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; break; case GR_CMBX_OTHER_TEXTURE_RGB: texturemode |= SST_TC_MCMSELECT7; combineMode |= SST_CM_TC_MSELECT_7_OTHER_TRGB; localTMU &= FXFALSE; break; case GR_CMBX_ITRGB: texturemode |= SST_TC_MCMSELECT7; combineMode |= SST_CM_TC_MSELECT_7_IRGB; localTMU &= FXTRUE; break; case GR_CMBX_ITALPHA: texturemode |= SST_TC_MCMSELECT7; combineMode |= SST_CM_TC_MSELECT_7_IA; localTMU &= FXTRUE; break; case GR_CMBX_TMU_CCOLOR: texturemode |= SST_TC_MCMSELECT7; combineMode |= SST_CM_TC_MSELECT_7_CR_RGB; gc->state.tcc_requires_constant_color[tmu] = FXTRUE; gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; break; case GR_CMBX_TMU_CALPHA: texturemode |= SST_TC_MCMSELECT7; combineMode |= SST_CM_TC_MSELECT_7_CR_A; gc->state.tcc_requires_constant_color[tmu] = FXTRUE; gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; break; } if (!c_invert) texturemode |= SST_TC_REVERSE_BLEND; switch (d) { case GR_CMBX_ZERO: localTMU &= FXTRUE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: texturemode |= SST_TC_ADD_ALOCAL; gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; break; case GR_CMBX_ITRGB: texturemode |= SST_TC_ADD_CLOCAL | SST_TC_ADD_ALOCAL; localTMU &= FXTRUE; break; case GR_CMBX_B: texturemode |= SST_TC_ADD_CLOCAL; localTMU &= btermTMU; gc->state.tmuMaskShadow |= btmuMask; break; } if (d_invert) combineMode |= SST_CM_TC_INVERT_ADD_LOCAL; switch (shift) { case 1: combineMode |= SST_CM_TC_OUTSHIFT_2X; break; case 2: combineMode |= SST_CM_TC_OUTSHIFT_4X; break; case 0: default: combineMode |= SST_CM_TC_OUTSHIFT_1X; break; } if (invert) texturemode |= SST_TC_INVERT_OUTPUT; combineMode |= SST_CM_USE_COMBINE_MODE; /* Hack to enable TWO-PASS Trilinear */ if (texturemode & SST_TRILINEAR) { if ((texturemode & SST_TC_ZERO_OTHER) && (texturemode & SST_TC_BLEND_LODFRAC) && !(texturemode & SST_TC_REVERSE_BLEND)) { tLod |= SST_LOD_ODD; } } /* Hack to use single pass trilinear in UMA state */ if((texturemode & SST_TRILINEAR) && (gc->state.grEnableArgs.texture_uma_mode == GR_MODE_ENABLE) && (gc->state.per_tmu[tmu].evenOdd == GR_MIPMAPLEVELMASK_BOTH) && (tmu == GR_TMU1)) { tLod |= SST_LOD_ODD; } tLod |= _gr_evenOdd_xlate_table[gc->state.per_tmu[tmu].evenOdd]; /* update tmuMask for tac */ if (gc->state.tmuMaskShadow & tmuMask) { gc->state.tcctmuMask |= tmuMask; } if (gc->state.tcc_requires_texture[tmu] || gc->state.tac_requires_texture[tmu]) { gc->state.tmuMaskShadow |= gc->state.tactmuMask | gc->state.tcctmuMask; } if(gc->state.tac_requires_constant_color[tmu] || gc->state.tcc_requires_constant_color[tmu]) combineMode |= SST_CM_DISABLE_CHROMA_SUBSTITUTION; /* * AJB- If we are either turning on or turning off constant color * combining, validateState will need to swap the values in * chromaRange & chromaKey. */ if ((combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION) != (gc->state.tmuShadow[tmu].combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION)) INVALIDATE_TMU(tmu, texchroma) ; /* Update shadows */ INVALIDATE_TMU(tmu, textureMode); gc->state.tmuShadow[tmu].tLOD = tLod; gc->state.tmuShadow[tmu].combineMode = combineMode; gc->state.tmuShadow[tmu].textureMode = texturemode; /* If the state of a tmu changes from active then make sure that it * is addressing some valid tiny texture so that it does not spend * time thrashing on a large texture access. * * NB: We don't update the shadow here so the other bits in the * register shadow should be unchanged. */ #if GLIDE_CHECK_TRILINEAR /* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must happen after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. */ if (gc->num_tmu > 1) _grTexCheckTriLinear(tmu); #endif /* GLIDE_CHECK_TRILINEAR */ GR_END(); #undef FN_NAME } /* grTexColorCombineExt */ /*--------------------------------------------------------------------------- ** grTexAlphaCombineExt */ GR_EXT_ENTRY(grTexAlphaCombineExt, void, (GrChipID_t tmu, GrTACUColor_t a, GrCombineMode_t a_mode, GrTACUColor_t b, GrCombineMode_t b_mode, GrTACUColor_t c, FxBool c_invert, GrTACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert)) { #define FN_NAME "grTexAlphaCombineExt" FxU32 texturemode; FxU32 combineMode; FxU32 tLod; FxU32 tmuMask; FxU32 btmuMask = 0; FxU32 localTMU = FXFALSE; FxU32 btermTMU = FXFALSE; GR_BEGIN_NOFIFOCHECK("grTexAlphaCombineExt",88); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d,%d,%d,%d,%d,%d,%d)\n", tmu, a, a_mode, b, b_mode, c, d, shift, invert); #if DEBUG_2PPC || DEBUG_COMBINEEXT GDBG_PRINTF("grTexAlphaCombineExt(tmu=%d,a=%s,am=%s,b=%s,bm=%s,c=%s,ci=%s,d=%s,di=%s,s=%s,i=%s)\n", tmu,cmbxName[a],funcName[a_mode], cmbxName[b],funcName[b_mode], cmbxName[c],boolName[c_invert], cmbxName[d],boolName[d_invert], shiftName[shift], boolName[invert]); #endif /* ** a = tca_otherselect ** a_mode = tca_invert_other ** b = tca_localselect ** b_mode = tca_invert_local ** c = tca_mselect ** d = (tca_add_clocal, tca_add_alocal) ** shift = tca_outshift ** invert = tca_invert_output */ /* tmuMask tells grColorCombineFunction what to turn off an on if the ccFunc requires texture mapping */ combineMode = gc->state.tmuShadow[tmu].combineMode; texturemode = gc->state.tmuShadow[tmu].textureMode; texturemode &= ~(SST_TACOMBINE); tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_LOD_ODD); gc->state.combineExtsInUse |= STATE_USING_TAC; tmuMask = GR_TMUMASK_TMU0 << tmu; gc->state.tmuMaskShadow &= ~tmuMask; gc->state.tactmuMask &= ~tmuMask; gc->state.tmuAlphaPassthrough &= ~tmuMask; /* Check for obvious passthrough case. Expand later if something other * than OpenGL ever does this sort of thing. */ if(((a == GR_CMBX_OTHER_TEXTURE_ALPHA) && (a_mode == GR_FUNC_MODE_X)) && ((b == GR_CMBX_ZERO) && (b_mode == GR_FUNC_MODE_X)) && ((c == GR_CMBX_ZERO) && (c_invert == FXTRUE)) && ((d == GR_CMBX_ZERO) && (d_invert == FXFALSE)) && (shift == 0) && (invert == FXFALSE)) { gc->state.tmuAlphaPassthrough |= tmuMask; } combineMode &= ~( SST_CM_TCA_OTHERSELECT | SST_CM_TCA_LOCALSELECT | SST_CM_TCA_INVERT_OTHER | SST_CM_TCA_INVERT_LOCAL | SST_CM_TCA_OUTSHIFT | SST_CM_TCA_INVERT_ADD_LOCAL | SST_CM_TCA_OUTSHIFT | SST_CM_DISABLE_CHROMA_SUBSTITUTION ); texturemode &= ~( SST_TCA_MSELECT | /* c */ SST_TCA_ADD_CLOCAL | /* part of d */ SST_TCA_ADD_ALOCAL | /* part of d */ SST_TCA_INVERT_OUTPUT | /* invert */ SST_TCA_REVERSE_BLEND | SST_TCA_ZERO_OTHER | SST_TCA_SUB_CLOCAL ); gc->state.tac_requires_it_alpha[tmu] = ( (a == GR_CMBX_ITALPHA) | (b == GR_CMBX_ITALPHA) | (c == GR_CMBX_ITALPHA) | (d == GR_CMBX_ITALPHA) ); gc->state.tac_requires_prev_texture[tmu] = ( (a == GR_CMBX_OTHER_TEXTURE_ALPHA) | (b == GR_CMBX_OTHER_TEXTURE_ALPHA) | (c == GR_CMBX_OTHER_TEXTURE_ALPHA) ); gc->state.tac_requires_texture[tmu] = ( (a == GR_CMBX_OTHER_TEXTURE_ALPHA) | (a == GR_CMBX_LOCAL_TEXTURE_ALPHA) | (b == GR_CMBX_OTHER_TEXTURE_ALPHA) | (b == GR_CMBX_LOCAL_TEXTURE_ALPHA) | (c == GR_CMBX_OTHER_TEXTURE_ALPHA) | (c == GR_CMBX_LOCAL_TEXTURE_ALPHA) | (d == GR_CMBX_LOCAL_TEXTURE_ALPHA) ); gc->state.tac_requires_constant_color[tmu] = FXFALSE; switch (a) { case GR_CMBX_OTHER_TEXTURE_ALPHA: combineMode |= SST_CM_TCA_OTHERSELECT_OTHER_TA; localTMU = FXFALSE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: combineMode |= SST_CM_TCA_OTHERSELECT_LOCAL_TA; localTMU = FXTRUE; gc->state.tmuMaskShadow |= tmuMask; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_TCA_OTHERSELECT_IA; localTMU = FXTRUE; break; case GR_CMBX_TMU_CALPHA: combineMode |= SST_CM_TCA_OTHERSELECT_CR_A; gc->state.tac_requires_constant_color[tmu] = FXTRUE; localTMU = FXTRUE; break; default: /* output zero if the a term is unknown type */ a_mode = GR_FUNC_MODE_ZERO; localTMU = FXTRUE; break; } switch (b) { case GR_CMBX_LOCAL_TEXTURE_ALPHA: combineMode |= SST_CM_TCA_LOCALSELECT_LOCAL_TA; if (b_mode != GR_FUNC_MODE_ZERO) { gc->state.tmuMaskShadow |= tmuMask; localTMU &= FXTRUE; } btermTMU = FXTRUE; btmuMask = tmuMask; break; case GR_CMBX_OTHER_TEXTURE_ALPHA: combineMode |= SST_CM_TCA_LOCALSELECT_OTHER_TA; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXFALSE; btermTMU = FXFALSE; break; case GR_CMBX_ITALPHA: combineMode |= SST_CM_TCA_LOCALSELECT_IA; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXTRUE; btermTMU = FXTRUE; break; case GR_CMBX_TMU_CALPHA: combineMode |= SST_CM_TCA_LOCALSELECT_CK_A; gc->state.tac_requires_constant_color[tmu] = FXTRUE; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXTRUE; btermTMU = FXTRUE; break; default: /* output zero if the b term is unknown type */ b_mode = GR_FUNC_MODE_ZERO; if (b_mode != GR_FUNC_MODE_ZERO) localTMU &= FXTRUE; btermTMU = FXTRUE; break; } switch (a_mode) { case GR_FUNC_MODE_ZERO: combineMode |= SST_CM_TCA_INVERT_OTHER_X; break; case GR_FUNC_MODE_X: combineMode |= SST_CM_TCA_INVERT_OTHER_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_TCA_INVERT_OTHER_ZERO_MINUS_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_TCA_INVERT_OTHER_ONE_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_TCA_INVERT_OTHER_X_MINUS_HALF; break; } if (a_mode == GR_FUNC_MODE_ZERO) texturemode |= SST_TCA_ZERO_OTHER; switch (b_mode) { case GR_FUNC_MODE_ZERO: combineMode |= SST_CM_TCA_INVERT_LOCAL_X; break; case GR_FUNC_MODE_X: combineMode |= SST_CM_TCA_INVERT_LOCAL_X; break; case GR_FUNC_MODE_NEGATIVE_X: combineMode |= SST_CM_TCA_INVERT_LOCAL_ZERO_MINUS_X; break; case GR_FUNC_MODE_ONE_MINUS_X: combineMode |= SST_CM_TCA_INVERT_LOCAL_ONE_MINUS_X; break; case GR_FUNC_MODE_X_MINUS_HALF: combineMode |= SST_CM_TCA_INVERT_LOCAL_X_MINUS_HALF; break; } if (b_mode != GR_FUNC_MODE_ZERO) texturemode |= SST_TCA_SUB_CLOCAL; switch (c) { case GR_CMBX_ZERO: texturemode |= SST_TCA_MONE; localTMU &= FXTRUE; break; case GR_CMBX_B: texturemode |= SST_TCA_MCLOCAL; localTMU &= btermTMU; gc->state.tmuMaskShadow |= btmuMask; break; case GR_CMBX_OTHER_TEXTURE_ALPHA: texturemode |= SST_TCA_MAOTHER; localTMU &= FXFALSE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: texturemode |= SST_TCA_MALOCAL; localTMU &= FXTRUE; gc->state.tmuMaskShadow |= tmuMask; break; case GR_CMBX_DETAIL_FACTOR: texturemode |= SST_TCA_MLOD; localTMU &= FXTRUE; break; case GR_CMBX_LOD_FRAC: texturemode |= SST_TCA_MLODFRAC; localTMU &= FXFALSE; break; case GR_CMBX_ITALPHA: texturemode |= SST_TCA_MAITER; localTMU &= FXTRUE; break; case GR_CMBX_TMU_CALPHA: texturemode |= SST_TCA_MCR; gc->state.tac_requires_constant_color[tmu] = FXTRUE; localTMU &= FXTRUE; break; } if (!c_invert) texturemode |= SST_TCA_REVERSE_BLEND; switch (d) { case GR_CMBX_ZERO: localTMU &= FXTRUE; break; case GR_CMBX_LOCAL_TEXTURE_ALPHA: texturemode |= SST_TCA_ADD_ALOCAL; localTMU &= FXTRUE; gc->state.tmuMaskShadow |= tmuMask; break; case GR_CMBX_ITALPHA: texturemode |= SST_TCA_ADD_CLOCAL | SST_TCA_ADD_ALOCAL; localTMU &= FXTRUE; break; case GR_CMBX_B: texturemode |= SST_TCA_ADD_CLOCAL; localTMU &= btermTMU; gc->state.tmuMaskShadow |= btmuMask; break; } if (d_invert) combineMode |= SST_CM_TCA_INVERT_ADD_LOCAL; switch (shift) { case 1: combineMode |= SST_CM_TCA_OUTSHIFT_2X; break; case 2: combineMode |= SST_CM_TCA_OUTSHIFT_4X; break; case 0: default: combineMode |= SST_CM_TCA_OUTSHIFT_1X; break; } if (invert) texturemode |= SST_TCA_INVERT_OUTPUT; combineMode |= SST_CM_USE_COMBINE_MODE; /* Hack to enable TWO-PASS Trilinear */ if (texturemode & SST_TRILINEAR) { if ((texturemode & SST_TC_ZERO_OTHER) && (texturemode & SST_TC_BLEND_LODFRAC) && !(texturemode & SST_TC_REVERSE_BLEND)) { tLod |= SST_LOD_ODD; } } /* Hack to use single pass trilinear in UMA state */ if((texturemode & SST_TRILINEAR) && (gc->state.grEnableArgs.texture_uma_mode == GR_MODE_ENABLE) && (gc->state.per_tmu[tmu].evenOdd == GR_MIPMAPLEVELMASK_BOTH) && (tmu == GR_TMU1)) { tLod |= SST_LOD_ODD; } tLod |= _gr_evenOdd_xlate_table[gc->state.per_tmu[tmu].evenOdd]; /* update tmuMask for tac */ if (gc->state.tmuMaskShadow & tmuMask) { gc->state.tactmuMask |= tmuMask; } if (gc->state.tcc_requires_texture[tmu] || gc->state.tac_requires_texture[tmu]) { gc->state.tmuMaskShadow |= gc->state.tactmuMask | gc->state.tcctmuMask; } if(gc->state.tac_requires_constant_color[tmu] || gc->state.tcc_requires_constant_color[tmu]) combineMode |= SST_CM_DISABLE_CHROMA_SUBSTITUTION; /* * AJB- If we are either turning on or turning off constant color * combining, validateState will need to swap the values in * chromaRange & chromaKey. */ if ((combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION) != (gc->state.tmuShadow[tmu].combineMode & SST_CM_DISABLE_CHROMA_SUBSTITUTION)) INVALIDATE_TMU(tmu, texchroma) ; /* Update shadows */ INVALIDATE_TMU(tmu, textureMode); gc->state.tmuShadow[tmu].tLOD = tLod; gc->state.tmuShadow[tmu].combineMode = combineMode; gc->state.tmuShadow[tmu].textureMode = texturemode; #if GLIDE_CHECK_TRILINEAR /* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must happen after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. */ if (gc->num_tmu > 1) _grTexCheckTriLinear(tmu); #endif /* GLIDE_CHECK_TRILINEAR */ GR_END(); #undef FN_NAME } /*--------------------------------------------------------------------------- ** grConstantColorValueExt ** ** A sad, sad story: ** ** Whoever designed this api extension overlooked the fact that there are two ** constant color inputs into the color combiner where here we only set one. ** (actually we set them both to the same thing, but in effect we only set one). */ GR_EXT_ENTRY(grConstantColorValueExt, void, (GrChipID_t tmu, GrColor_t value)) { #define FN_NAME "grConstantColorValueExt" FxU32 ccolor = value ; GR_BEGIN_NOFIFOCHECK("grConstantColorValueExt", 88) ; GDBG_INFO_MORE(gc->myLevel,"(%d,%d)\n", tmu, value) ; _grSwizzleColor(&ccolor) ; INVALIDATE_TMU(tmu, texchroma); gc->state.tmuColor[tmu] = ccolor ; GR_END() ; #undef FN_NAME } #endif /* FX_GLIDE_NAPALM */ /* ** _grTexDetailControl, NOTE: its up to caller to account for bytes */ GR_DDFUNC(_grTexDetailControl, void, (GrChipID_t tmu, FxU32 detail)) { #define FN_NAME "_grTexDetailControl" GR_BEGIN_NOFIFOCHECK("_grTexDetailControl",88); GR_CHECK_TMU("_grTexDetailControl", tmu); INVALIDATE_TMU(tmu, textureMode); gc->state.tmuShadow[tmu].tDetail = detail; GR_END(); #undef FN_NAME } /* _grTexDetailControl */ /*--------------------------------------------------------------------------- ** grTexFilterMode */ GR_ENTRY(grTexFilterMode, void, (GrChipID_t tmu, GrTextureFilterMode_t minfilter, GrTextureFilterMode_t magfilter)) { #define FN_NAME "grTexFilterMode" FxU32 texMode; GR_BEGIN_NOFIFOCHECK("grTexFilterMode",99); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d)\n",tmu,minfilter,magfilter); GR_CHECK_TMU(FN_NAME, tmu); texMode = gc->state.tmuShadow[tmu].textureMode; texMode &= ~(SST_TMINFILTER | SST_TMAGFILTER); texMode |= (minfilter == GR_TEXTUREFILTER_BILINEAR ? SST_TMINFILTER : 0) | (magfilter == GR_TEXTUREFILTER_BILINEAR ? SST_TMAGFILTER : 0); gc->state.tmuShadow[tmu].textureMode = texMode; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].textureMode = texMode; if(gc->state.mode2ppc) { gc->state.shadow.tmuState[1-tmu].textureMode = texMode; } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), textureMode, 1, 0x1); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[tmu].textureMode); } REG_GROUP_END(); _grChipMask( gc->chipmask ); } else { INVALIDATE_TMU(tmu, textureMode); } GR_END(); #undef FN_NAME } /* grTexFilterMode */ /*--------------------------------------------------------------------------- ** grTexLodBiasValue */ GR_ENTRY(grTexLodBiasValue, void, (GrChipID_t tmu, float fvalue)) { #define FN_NAME "grTexLodBiasValue" FxU32 tLod; FxI32 lodBias; GR_BEGIN_NOFIFOCHECK("grTexLodBiasValue",88); GDBG_INFO_MORE(gc->myLevel,"(%d,%g)\n",tmu,fvalue); GR_CHECK_TMU(FN_NAME, tmu); tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_LODBIAS); lodBias = _grTexFloatLODToFixedLOD(fvalue); /* Sign extend it. */ lodBias = ((lodBias << (32-6)) >> (32-6)); lodBias += _GlideRoot.environment.lodBias; if(lodBias > 0x1f) lodBias = 0x1f; else if(lodBias < -0x20) lodBias = -0x20; /* Mask it back off. */ lodBias &= 0x3f; tLod |= lodBias << SST_LODBIAS_SHIFT; gc->state.tmuShadow[tmu].tLOD = tLod; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].tLOD = tLod; _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), tLOD, 1, 0x1); { REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); } REG_GROUP_END(); _grChipMask( gc->chipmask ); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu,gc->state.shadow.tmuState[tmu].tLOD); } else { INVALIDATE_TMU(tmu, textureMode); } GR_END(); #undef FN_NAME } /* grTexLodBiasValue */ /*------------------------------------------------------------------- Function: grTexMipMapMode Date: 6/2 Implementor(s): GaryMcT, Jdt Library: glide Description: Sets the mip map mode for the specified TMU "Ex" because glide's grTexMipMapMode is inadequate for low level texture memory management Arguments: tmu - tmu to update mmMode - mipmap mode One of: GR_MIPMAP_DISABLE GR_MIPMAP_NEAREST GR_MIPMAP_NEAREST_DITHER lodBlend - enable lodBlending FXTRUE - enabled FXFALSE - disabled Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexMipMapMode, void, (GrChipID_t tmu, GrMipMapMode_t mmMode, FxBool lodBlend)) { #define FN_NAME "grTexMipMapMode" FxU32 tLod, texMode; FxBool tBig = FXFALSE; GR_BEGIN_NOFIFOCHECK("grTexMipMapMode",88); GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d)\n",tmu,mmMode,lodBlend); GR_CHECK_TMU(FN_NAME, tmu); /*-------------------------------------------------------------- Get Current tLod and texMode register values --------------------------------------------------------------*/ tLod = gc->state.tmuShadow[tmu].tLOD; texMode = gc->state.tmuShadow[tmu].textureMode; /*-------------------------------------------------------------- Do we want big (>256) textures or not? --------------------------------------------------------------*/ #ifdef FX_GLIDE_NAPALM if ((IS_NAPALM(gc->bInfo->pciInfo.deviceID)) && (tLod & SST_TBIG)) { tBig = FXTRUE; } #endif /*-------------------------------------------------------------- Clear LODMIN, LODMAX and LODDITHER --------------------------------------------------------------*/ tLod &= ~(SST_LODMIN | SST_LODMAX | SST_LOD_ODD); texMode &= ~(SST_TLODDITHER | SST_TRILINEAR); /*-------------------------------------------------------------- Encode Mipmap Mode Bits --------------------------------------------------------------*/ switch (mmMode) { case GR_MIPMAP_DISABLE: /*---------------------------------------------------------- To disable mipmapping set the min and max lods to the same value ----------------------------------------------------------*/ tLod |= SST_TLOD_MINMAX_INT(gc->state.per_tmu[tmu].largeLod, gc->state.per_tmu[tmu].largeLod); break; case GR_MIPMAP_NEAREST_DITHER: if (gc->state.allowLODdither) texMode |= SST_TLODDITHER; /* intentional fall-through to set lodmin and lodmax values */ case GR_MIPMAP_NEAREST: /*---------------------------------------------------------- Set LODMIN and LODMAX in the tLod register to the actual min and max LODs of the current texture. ----------------------------------------------------------*/ tLod |= SST_TLOD_MINMAX_INT(gc->state.per_tmu[tmu].largeLod, gc->state.per_tmu[tmu].smallLod); if(_GlideRoot.environment.texSubLodDither && !lodBlend) gc->state.per_tmu[tmu].texSubLodDither = FXTRUE; break; default: GrErrorCallback("grTexMipMapMode: invalid mode passed", FXFALSE); break; } gc->state.per_tmu[tmu].mmMode = mmMode; /* Force LOD dithering if the user asked for it. * * NB: There is a performance hit for this, but it does * look better. */ texMode |= _GlideRoot.environment.texLodDither; /*-------------------------------------------------------------- Fix trilinear and evenOdd bits - This is a bit of a hack to make two pass trilinear work with full textures. The assumption here is that the only reason you would ever set up Multiply by LODFRAC w/o REVERSE BLEND is for the ODD pass of trilinear. --------------------------------------------------------------*/ if (lodBlend) { /* If we're doing trilinear for real then nuke the lod dithering * at the same time because it just looks bad. */ texMode = ((texMode & ~SST_TLODDITHER) | SST_TRILINEAR); if ((texMode & SST_TC_ZERO_OTHER) && (texMode & SST_TC_BLEND_LODFRAC) && !(texMode & SST_TC_REVERSE_BLEND)) { tLod |= SST_LOD_ODD; } } tLod |= _gr_evenOdd_xlate_table[gc->state.per_tmu[tmu].evenOdd]; /*-------------------------------------------------------------- Write State To Hardware and Update Glide Shadow State --------------------------------------------------------------*/ gc->state.tmuShadow[tmu].tLOD = tLod; gc->state.tmuShadow[tmu].textureMode = texMode; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].textureMode = texMode; gc->state.shadow.tmuState[tmu].tLOD = tLod; if(gc->state.mode2ppc) { gc->state.shadow.tmuState[1-tmu].textureMode = texMode; gc->state.shadow.tmuState[1-tmu].tLOD = tLod; } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), textureMode, 2, 0x3); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[tmu].textureMode); REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); } REG_GROUP_END(); _grChipMask( gc->chipmask ); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); } else { INVALIDATE_TMU(tmu, textureMode); } #if GLIDE_CHECK_TRILINEAR /* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must happen after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. */ if (gc->num_tmu > 1) _grTexCheckTriLinear(tmu); #endif /* GLIDE_CHECK_TRILINEAR */ GR_END(); #undef FN_NAME } /* grTexMipMapMode */ /*------------------------------------------------------------------- Function: grTexMinAddress Date: 6/2 Implementor(s): GaryMcT, Jdt Library: glide Description: Returns address of start of texture ram for a TMU Arguments: tmu Return: integer texture base address, this pointer is not to be dereferenced by the application, it is on to be used by grTexDownload(), and grTExDownloadLevel() -------------------------------------------------------------------*/ /*------------------------------------------------------------------- Function: grTexNCCTable Date: 6/3 Implementor(s): jdt Library: glide Description: select one of the two NCC tables Arguments: tmu - which tmu table - which table to select One of: GR_TEXTABLE_NCC0 GR_TEXTABLE_NCC1 GR_TEXTABLE_PALETTE Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexNCCTable, void, (GrNCCTable_t table)) { #define FN_NAME "grTexNCCTable" FxU32 texMode; FxI32 i; GR_BEGIN("grTexNCCTable",88,4*GLIDE_NUM_TMU, GLIDE_NUM_TMU); GDBG_INFO_MORE(gc->myLevel,"\n"); GR_CHECK_F(myName, table > GR_TEXTABLE_PALETTE, "invalid ncc table specified"); for(i = 0; i < gc->num_tmu; i++) { /* Update local state */ gc->state.per_tmu[i].nccTable = table; /* Grab shadow texMode, update TexMode, update shadow/real register */ texMode = gc->state.tmuShadow[i].textureMode; texMode &= ~(SST_TNCCSELECT); if (table == GR_TEXTABLE_NCC1) texMode |= SST_TNCCSELECT; else texMode &= ~(SST_TNCCSELECT); gc->state.tmuShadow[i].textureMode = texMode; /* Update real shadows and update hardware immediately if we can. */ /* This is a special case, we always update the tables on both TMUs */ /* So we don't care whether or not we're in 2PPC mode. */ { SstRegs* tmuHw = SST_TMU(hw, i); gc->state.shadow.tmuState[i].textureMode = texMode; _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << i), textureMode, 1, 0x1); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[i].textureMode); } REG_GROUP_END(); _grChipMask( gc->chipmask ); } } GR_END(); #undef FN_NAME } /* grTexNCCTable */ /*------------------------------------------------------------------- Function: grTexSource Date: 6/2 Implementor(s): GaryMcT, Jdt Library: glide Description: Sets up the current texture for texture mapping on the specified TMU. Arguments: tmu - which tmu startAddress - texture start address evenOdd - which set of mipmap levels have been downloaded for the selected texture One of: GR_MIPMAPLEVELMASK_EVEN GR_MIPMAPLEVELMASK_ODD GR_MIPMAPLEVELMASK_BOTH info - pointer to GrTexInfo structure containing texture dimensions Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexSource, void, (GrChipID_t tmu, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info)) { #define FN_NAME "grTexSource" FxU32 baseAddress, texMode, tLod; FxBool tBig = FXFALSE, doNOP = FXFALSE; GR_BEGIN_NOFIFOCHECK("grTexSource", 88); GDBG_INFO_MORE(gc->myLevel, "(%d, 0x%X, 0x%X, [%d:%d %d %d 0x%X])\n", tmu, startAddress, evenOdd, info->smallLodLog2, info->largeLodLog2, info->aspectRatioLog2, info->format, info->data); GR_CHECK_TMU(FN_NAME, tmu); GR_CHECK_COMPATABILITY(FN_NAME, startAddress >= gc->tmu_state[tmu].total_mem, "invalid startAddress"); GR_CHECK_COMPATABILITY(FN_NAME, (gc->windowed ? FXFALSE : (startAddress + _grTexTextureMemRequired(info->smallLodLog2, info->largeLodLog2, info->aspectRatioLog2, info->format, evenOdd, FXTRUE, FXFALSE) > gc->tmu_state[tmu].total_mem)), "insufficient texture ram at startAddress"); GR_CHECK_F(FN_NAME, evenOdd > 0x3 || evenOdd == 0, "evenOdd mask invalid"); GR_CHECK_F(FN_NAME, !info, "invalid info pointer"); #ifdef FX_GLIDE_NAPALM /*-------------------------------------------------------------- Do we want big (>256) textures or not? --------------------------------------------------------------*/ if ((IS_NAPALM(gc->bInfo->pciInfo.deviceID)) && (info->largeLodLog2 > GR_LOD_LOG2_256)) { tBig = FXTRUE; } #endif /*------------------------------------------------------------- Update Texture Unit State -------------------------------------------------------------*/ gc->state.per_tmu[tmu].smallLod = _g3LodXlat(info->smallLodLog2, tBig); gc->state.per_tmu[tmu].largeLod = _g3LodXlat(info->largeLodLog2, tBig); gc->state.per_tmu[tmu].evenOdd = evenOdd; /* Calculate Base Address * texBaseAddr gets the address of the largest mipmap level that the * hw is capable of handling (256 in the current sst1 core * derivatives) even if some of the larger levels don't exist. Now, * we'll basically calculate the offset (from the beginning) of the * largest mipmap level, and subtract that from start_address to * calculate the baseAdress. * * Capiche? */ { const struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; if (memInfo->texTiled) { const FxI32 baseAddressAdj = _grTexCalcBaseAddressTiled(tmu, startAddress, info->aspectRatioLog2, info->largeLodLog2, info->format, evenOdd); baseAddress = memInfo->tramOffset + baseAddressAdj; baseAddress = SST_TEXTURE_MUNGE_ADDRESS(baseAddress); baseAddress |= SST_TEXTURE_IS_TILED; baseAddress |= (memInfo->texStrideTiles << SST_TEXTURE_TILESTRIDE_SHIFT); GR_CHECK_F(FN_NAME, (gc->windowed && (startAddress != 0)), "Surface extension only supports startAddress 0\n"); } else { baseAddress = (FxI32)_grTexCalcBaseAddress(startAddress, info->largeLodLog2, G3_ASPECT_TRANSLATE(info->aspectRatioLog2), info->format, evenOdd); baseAddress += memInfo->tramOffset; baseAddress = SST_TEXTURE_MUNGE_ADDRESS(baseAddress); } } /*------------------------------------------------------------- Update Texture Mode -------------------------------------------------------------*/ { GrTextureFormat_t format = info->format; FxU32 oldTexMode; oldTexMode = texMode = gc->state.tmuShadow[tmu].textureMode; texMode &= ~SST_TFORMAT; #ifdef FX_GLIDE_NAPALM texMode &= ~SST_COMPRESSED_TEXTURES; #endif #if 0 if ((format == GR_TEXFMT_P_8) || (format == GR_TEXFMT_YIQ_422) || (format == GR_TEXFMT_AYIQ_8422) || (format == GR_TEXFMT_AP_88)) { gc->state.palletizedTexture[tmu] = FXTRUE; } else { gc->state.palletizedTexture[tmu] = FXFALSE; } #endif /* Adjust texture format to match the current texture table type */ #ifdef FX_GLIDE_NAPALM /* Glide uses a different value than the HW's textureMode reg */ switch(format) { case GR_TEXFMT_P_8: format = ((gc->state.tex_table == GR_TEXTABLE_PALETTE_6666_EXT) ? GR_TEXFMT_P_8_RGBA : GR_TEXFMT_P_8); break; case GR_TEXFMT_ARGB_8888: format = (SST_ARGB8888 >> SST_TFORMAT_SHIFT); break; case GR_TEXFMT_ARGB_CMP_FXT1: format = (SST_3DFX_COMPRESSED >> SST_TFORMAT_SHIFT); texMode |= SST_COMPRESSED_TEXTURES; break; case GR_TEXFMT_ARGB_CMP_DXT1: format = (SST_DXT1 >> SST_TFORMAT_SHIFT); texMode |= SST_COMPRESSED_TEXTURES; break; case GR_TEXFMT_ARGB_CMP_DXT2: format = (SST_DXT2 >> SST_TFORMAT_SHIFT); texMode |= SST_COMPRESSED_TEXTURES; break; case GR_TEXFMT_ARGB_CMP_DXT3: format = (SST_DXT3 >> SST_TFORMAT_SHIFT); texMode |= SST_COMPRESSED_TEXTURES; break; case GR_TEXFMT_ARGB_CMP_DXT4: format = (SST_DXT4 >> SST_TFORMAT_SHIFT); texMode |= SST_COMPRESSED_TEXTURES; break; case GR_TEXFMT_ARGB_CMP_DXT5: format = (SST_DXT5 >> SST_TFORMAT_SHIFT); texMode |= SST_COMPRESSED_TEXTURES; break; } #else if (format == GR_TEXFMT_P_8) { format = ((gc->state.tex_table == GR_TEXTABLE_PALETTE_6666_EXT) ? GR_TEXFMT_P_8_RGBA : GR_TEXFMT_P_8); } #endif /* There seems to be a minor hardware bug when switching from a * non-compressed texture to a compressed one. We have to idle * the TMUs when this transition happens. */ if((texMode ^ oldTexMode) & SST_COMPRESSED_TEXTURES & texMode) { doNOP = FXTRUE; } texMode |= (SST_TPERSP_ST | SST_TCLAMPW | (format << SST_TFORMAT_SHIFT)); } /*------------------------------------------------------------- Compute TLOD (keep LODBIAS intact) -------------------------------------------------------------*/ { const FxU32 smallLOD = _g3LodXlat(info->smallLodLog2, tBig), largeLOD = _g3LodXlat(info->largeLodLog2, tBig), aspectRatio = G3_ASPECT_TRANSLATE(info->aspectRatioLog2); tLod = gc->state.tmuShadow[tmu].tLOD; tLod &= ~(SST_LODMIN | SST_LODMAX | SST_LOD_ASPECT | SST_LOD_TSPLIT | SST_LOD_ODD | SST_LOD_S_IS_WIDER); #ifdef FX_GLIDE_NAPALM if (tBig) { tLod |= SST_TBIG; } else { tLod &= ~SST_TBIG; } #endif if (gc->state.per_tmu[tmu].mmMode == GR_MIPMAP_DISABLE ) tLod |= SST_TLOD_MINMAX_INT(largeLOD, largeLOD); else tLod |= SST_TLOD_MINMAX_INT(largeLOD, smallLOD); tLod |= _gr_evenOdd_xlate_table[evenOdd]; tLod |= _gr_aspect_xlate_table[aspectRatio]; } /* update shadows */ gc->state.tmuShadow[tmu].textureMode = texMode; gc->state.tmuShadow[tmu].tLOD = tLod; gc->state.tmuShadow[tmu].texBaseAddr = baseAddress; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].textureMode = texMode; gc->state.shadow.tmuState[tmu].tLOD = tLod; gc->state.shadow.tmuState[tmu].texBaseAddr = baseAddress; /* If in 2PPC, then update both "real" TMU register shadows. */ if(gc->state.mode2ppc) { gc->state.shadow.tmuState[1-tmu].textureMode = texMode; gc->state.shadow.tmuState[1-tmu].tLOD = tLod; gc->state.shadow.tmuState[1-tmu].texBaseAddr = baseAddress; } if(doNOP) { GR_SET_EXPECTED_SIZE(sizeof(FxU32)*1, 1); GR_SET(eChipTMU0 | eChipTMU1, hw, nopCMD, 0); GR_CHECK_SIZE(); } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02UL << tmu), textureMode, 3, 0x0B); { REG_GROUP_SET(tmuHw, textureMode, gc->state.shadow.tmuState[tmu].textureMode); REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); REG_GROUP_SET(tmuHw, texBaseAddr, gc->state.shadow.tmuState[tmu].texBaseAddr); } REG_GROUP_END(); _grChipMask( gc->chipmask ); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); } else { INVALIDATE_TMU(tmu, textureMode); INVALIDATE_TMU(tmu, texBaseAddr); } /* Synch flush data w/ new state */ gc->tmuMemInfo[tmu].postPacket[1] = ~baseAddress; gc->tmuMemInfo[tmu].postPacket[5] = baseAddress; #if GLIDE_CHECK_TRILINEAR /* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must happen after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. */ if (gc->num_tmu > 1) _grTexCheckTriLinear(tmu); #endif /* GLIDE_CHECK_TRILINEAR */ /* ** Update s and t scale for clip coordinates */ switch (info->aspectRatioLog2) { case GR_ASPECT_LOG2_8x1: gc->state.per_tmu[tmu].s_scale = 256.f; gc->state.per_tmu[tmu].t_scale = 32.f; break; case GR_ASPECT_LOG2_4x1: gc->state.per_tmu[tmu].s_scale = 256.f; gc->state.per_tmu[tmu].t_scale = 64.f; break; case GR_ASPECT_LOG2_2x1: gc->state.per_tmu[tmu].s_scale = 256.f; gc->state.per_tmu[tmu].t_scale = 128.f; break; case GR_ASPECT_LOG2_1x1: gc->state.per_tmu[tmu].s_scale = 256.f; gc->state.per_tmu[tmu].t_scale = 256.f; break; case GR_ASPECT_LOG2_1x2: gc->state.per_tmu[tmu].s_scale = 128.f; gc->state.per_tmu[tmu].t_scale = 256.f; break; case GR_ASPECT_LOG2_1x4: gc->state.per_tmu[tmu].s_scale = 64.f; gc->state.per_tmu[tmu].t_scale = 256.f; break; case GR_ASPECT_LOG2_1x8: gc->state.per_tmu[tmu].s_scale = 32.f; gc->state.per_tmu[tmu].t_scale = 256.f; break; } GR_END(); #undef FN_NAME } /* grTexSource */ /*------------------------------------------------------------------- Function: grTexMultibase Date: 11/4/96 Implementor(s): gmt Library: Glide Description: Enable multiple base addresses for texturing. Arguments: tmu - which tmu enable - flag which enables/disables multibase Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexMultibase, void, (GrChipID_t tmu, FxBool enable)) { #define FN_NAME "grTexMultibase" FxU32 tLod; GR_BEGIN_NOFIFOCHECK("grTexMultibase",88); GDBG_INFO_MORE(gc->myLevel,"(%d,%d)\n",tmu,enable); GR_CHECK_TMU(FN_NAME,tmu); tLod = gc->state.tmuShadow[tmu].tLOD; if (enable) tLod |= SST_TMULTIBASEADDR; else tLod &= ~SST_TMULTIBASEADDR; /*-------------------------------------------------------------- Write State To Hardware and Update Glide Shadow State --------------------------------------------------------------*/ gc->state.tmuShadow[tmu].tLOD = tLod; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].tLOD = tLod; _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), tLOD, 1, 0x1); { REG_GROUP_SET(tmuHw, tLOD, gc->state.shadow.tmuState[tmu].tLOD); } REG_GROUP_END(); _grChipMask( gc->chipmask ); if(gc->state.per_tmu[tmu].texSubLodDither) g3LodBiasPerChip(tmu, gc->state.shadow.tmuState[tmu].tLOD); } else { INVALIDATE_TMU(tmu, textureMode); } GR_END(); #undef FN_NAME } /* grTexMultibase */ /*------------------------------------------------------------------- Function: grTexMultibaseAddress Date: 11/4/96 Implementor(s): gmt Library: Glide Description: Set the base address for a particular set of mipmaps Arguments: tmu - which tmu range - range of lods that are based at this starting address One of: GR_TEXBASE_2048 \ These are not valid GR_TEXBASE_1024 \ for Banshee or GR_TEXBASE_512 / Voodoo3. They are GR_TEXBASE_256_TO_1 / valid for Napalm. GR_TEXBASE_256 GR_TEXBASE_128 GR_TEXBASE_64 GR_TEXBASE_32_TO_1 startAddress - start address that data was downloaded to hardware with using grTexDownload/Level info - pointer to GrTexInfo structure containing texture dimensions Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexMultibaseAddress, void, (GrChipID_t tmu, GrTexBaseRange_t range, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info)) { #define FN_NAME "grTexMultibaseAddress" GrTexBaseRange_t maxPossibleLodRange = GR_TEXBASE_256; /* But see below for Napalm */ GR_BEGIN_NOFIFOCHECK("grTexMultibaseAddress", 88); GDBG_INFO_MORE(gc->myLevel,"(%d, 0x%X, 0x%X)\n", tmu, range, startAddress); GR_CHECK_TMU(FN_NAME, tmu); if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { maxPossibleLodRange = GR_TEXBASE_2048; } GR_CHECK_F(FN_NAME, range > maxPossibleLodRange, "invalid range"); GR_CHECK_F(FN_NAME, startAddress >= gc->tmu_state[tmu].total_mem, "invalid startAddress"); GR_CHECK_F(FN_NAME, evenOdd > 0x3, "evenOdd mask invalid"); GR_CHECK_F(FN_NAME, info == NULL, "invalid info pointer"); /* Write relevant registers out to hardware and shadows */ { GrLOD_t largeLevelLod; FxU32 baseAddrRegIndex, *addrRegShadow, *addrRegShadowHW, *addrRegShadowHWAlt; switch (range) { case GR_TEXBASE_256: largeLevelLod = GR_LOD_LOG2_256; baseAddrRegIndex = (offsetof(SstRegs, texBaseAddr) >> 2UL); addrRegShadow = &gc->state.tmuShadow[tmu].texBaseAddr; addrRegShadowHW = &gc->state.shadow.tmuState[tmu].texBaseAddr; addrRegShadowHWAlt = &gc->state.shadow.tmuState[1-tmu].texBaseAddr; break; case GR_TEXBASE_128: largeLevelLod = GR_LOD_LOG2_128; baseAddrRegIndex = (offsetof(SstRegs, texBaseAddr1) >> 2UL); addrRegShadow = &gc->state.tmuShadow[tmu].texBaseAddr_1; addrRegShadowHW = &gc->state.shadow.tmuState[tmu].texBaseAddr_1; addrRegShadowHWAlt = &gc->state.shadow.tmuState[1-tmu].texBaseAddr_1; break; case GR_TEXBASE_64: largeLevelLod = GR_LOD_LOG2_64; baseAddrRegIndex = (offsetof(SstRegs, texBaseAddr2) >> 2UL); addrRegShadow = &gc->state.tmuShadow[tmu].texBaseAddr_2; addrRegShadowHW = &gc->state.shadow.tmuState[tmu].texBaseAddr_2; addrRegShadowHWAlt = &gc->state.shadow.tmuState[1-tmu].texBaseAddr_2; break; case GR_TEXBASE_32_TO_1: largeLevelLod = GR_LOD_LOG2_32; baseAddrRegIndex = (offsetof(SstRegs, texBaseAddr38) >> 2UL); addrRegShadow = &gc->state.tmuShadow[tmu].texBaseAddr_3_8; addrRegShadowHW = &gc->state.shadow.tmuState[tmu].texBaseAddr_3_8; addrRegShadowHWAlt = &gc->state.shadow.tmuState[1-tmu].texBaseAddr_3_8; break; } { const struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; const FifoChipField tmuChip = (FifoChipField)(0x02UL << tmu); const FxU32 baseAddress = (memInfo->tramOffset + _grTexCalcBaseAddress(startAddress, largeLevelLod, G3_ASPECT_TRANSLATE(info->aspectRatioLog2), info->format, evenOdd)) & SST_TEXTURE_ADDRESS; *addrRegShadow = baseAddress; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); *addrRegShadowHW = baseAddress; if(gc->state.mode2ppc) { *addrRegShadowHWAlt = baseAddress; } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET_INDEX(tmuChip, tmuHw, baseAddrRegIndex, baseAddress); GR_CHECK_SIZE(); _grChipMask( gc->chipmask ); } else { INVALIDATE_TMU(tmu, texBaseAddr); } /* Synch flush data w/ new state */ if (addrRegShadow == &gc->state.tmuShadow[tmu].texBaseAddr) { gc->tmuMemInfo[tmu].postPacket[1] = ~baseAddress; gc->tmuMemInfo[tmu].postPacket[5] = baseAddress; } } } GR_END(); #undef FN_NAME } /* grTexMultibaseAddress */ /*------------------------------------------------------------------- Function: grTexChromaMode Date: 17-Dec-97 Implementor(s): atai Description: Draw triangles Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grTexChromaMode, void , (GrChipID_t tmu, GrChromakeyMode_t mode) ) { #define FN_NAME "grTexChromaMode" GrColor_t chromaRange; GR_BEGIN_NOFIFOCHECK(FN_NAME"\n", 85); chromaRange = gc->state.tmuShadow[tmu].texchromaRange; chromaRange &= ~(SST_ENCHROMARANGE | SST_ENCHROMAKEY_TMU | SST_ENCOLORSUBSTITUTION); switch (mode) { case GR_TEXCHROMA_ENABLE_EXT: /* ** substitude with black */ chromaRange |= (SST_ENCHROMARANGE | SST_ENCHROMAKEY_TMU); break; #if 0 /* ** disable in Glide3 */ case GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB: chromaRange |= (SST_ENCHROMARANGE | SST_ENCHROMAKEY_TMU | SST_ENCOLORSUBSTITUTION); break; #endif case GR_TEXCHROMA_DISABLE_EXT: break; } gc->state.tmuShadow[tmu].texchromaRange = chromaRange; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].texchromaRange = chromaRange; if(gc->state.mode2ppc) { gc->state.shadow.tmuState[1-tmu].texchromaRange = chromaRange; } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), chromaRange, 1, 0x1); { REG_GROUP_SET(tmuHw, chromaRange, gc->state.shadow.tmuState[tmu].texchromaRange); } REG_GROUP_END(); _grChipMask( gc->chipmask ); } else { INVALIDATE_TMU(tmu, texchroma); } #undef FN_NAME } /* grTexChromaMode */ /*------------------------------------------------------------------- Function: grTexChromaRange Date: 17-Dec-97 Implementor(s): atai Description: Draw triangles Arguments: Return: -------------------------------------------------------------------*/ GR_DIENTRY(grTexChromaRange, void , (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode) ) { #define FN_NAME "grTexChromaRange" GrColor_t minColor = min; GrColor_t maxColor = max; FxU32 chromaRange; GR_BEGIN_NOFIFOCHECK("grTexChromaRange",85); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", tmu); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", min); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", max); GDBG_INFO_MORE(gc->myLevel, "(0x%x)\n", mode); _grSwizzleColor(&minColor); _grSwizzleColor(&maxColor); minColor = minColor & 0x00ffffff; maxColor = maxColor & 0x00ffffff; chromaRange = gc->state.tmuShadow[tmu].texchromaRange; chromaRange &= (BIT(31) | /* bit 31 is not used, keep it zero */ SST_ENCHROMARANGE | SST_ENCHROMAKEY_TMU | SST_ENCOLORSUBSTITUTION); chromaRange = chromaRange | maxColor | (mode << 24); #if 0 /* ** fbiInit7 bit(19) = 1 enable texture chromarange ** It was enabled by default */ fbiInit7 = GR_GET(hw->fbiInit7); fbiInit7 = fbiInit7 | SST_TMU_CHROMA_REG_WR_EN; GR_SET(BROADCAST_ID, hw, fbiInit7, fbiInit7); #endif gc->state.tmuShadow[tmu].texchromaKey = minColor; gc->state.tmuShadow[tmu].texchromaRange = chromaRange; /* Update real shadows and update hardware immediately if we can. */ if(!gc->state.mode2ppc || (tmu == gc->state.mode2ppcTMU)) { SstRegs* tmuHw = SST_TMU(hw, tmu); gc->state.shadow.tmuState[tmu].texchromaKey = minColor; gc->state.shadow.tmuState[tmu].texchromaRange = chromaRange; if(gc->state.mode2ppc) { gc->state.shadow.tmuState[1-tmu].texchromaKey = minColor; gc->state.shadow.tmuState[1-tmu].texchromaRange = chromaRange; } _grChipMask( SST_CHIP_MASK_ALL_CHIPS ); REG_GROUP_BEGIN((0x02 << tmu), chromaKey, 2, 0x3); { REG_GROUP_SET(tmuHw, chromaKey, gc->state.shadow.tmuState[tmu].texchromaKey); REG_GROUP_SET(tmuHw, chromaRange, gc->state.shadow.tmuState[tmu].texchromaRange); } REG_GROUP_END(); _grChipMask( gc->chipmask ); } else { INVALIDATE_TMU(tmu, texchroma); } GR_END(); #undef FN_NAME } /* grTexChromaRange */ /* ** _grTexForceLod ** ** Forces tLOD to a specific LOD level. This is useful only for ** debugging purposes. GMT: obsolete, please remove ** AYT: added it back for Averger. */ void _grTexForceLod(GrChipID_t tmu, int value) { #define FN_NAME "_grTexForceLod" GR_DCL_GC; GR_DCL_HW; FxU32 tLod = gc->state.tmuShadow[tmu].tLOD; FxBool tBig = FXFALSE; #ifdef FX_GLIDE_NAPALM if ((IS_NAPALM(gc->bInfo->pciInfo.deviceID)) && (tLod & SST_TBIG)) { tBig = FXTRUE; } #endif value = _g3LodXlat(value, tBig); tLod &= ~(SST_LODMIN | SST_LODMAX); tLod |= SST_TLOD_MINMAX_INT(value,value); INVALIDATE_TMU(tmu, textureMode); gc->state.tmuShadow[tmu].tLOD = tLod; #undef FN_NAME } /* _grTexForceLod */ /* tbext */ /*------------------------------------------------------------------- Function: grTextureBuffer Date: Implementor(s): DA. Library: glide Description: Arguments: Return: none -------------------------------------------------------------------*/ GR_DIENTRY(grTextureBuffer, void, (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask )) { /* ** This assumes: ** frame buffer in Tiled memory ** texture in linear memory ** What about Napalm which offers 16 & 32 bits frame buffer formats? */ #define FN_NAME "grTextureBuffer" FxU32 add = 0, offset = 0; int width = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0], height = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; FxU32 dwBytesPerPixel ; FxU32 stride ; GR_BEGIN_NOFIFOCHECK("grTextureBuffer", 88); GR_CHECK_F(myName, ((_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Banshee) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo3) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo4)), "grTextureBuffer not supported."); dwBytesPerPixel = gc->grPixelSize ; // If the format is not the same as FB format, we're in trouble. stride = width * dwBytesPerPixel ; #ifdef FX_GLIDE_NAPALM /* * AJB- Last I checked we couldn't render to an FXT1 surface... * if (format == GR_TEXFMT_ARGB_CMP_FXT1 || format == GR_TEXFMT_ARGB_CMP_DXT1) { width = _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0]; height = _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; } else if (format >= GR_TEXFMT_ARGB_CMP_DXT2 && format <= GR_TEXFMT_ARGB_CMP_DXT5) { width = _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0]; height = _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; } else { width = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0], height = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; } stride = width * dwBytesPerPixel; */ GR_CHECK_F(myName, (((gc->grPixelSize == 4) && (format != GR_TEXFMT_ARGB_8888)) || ((gc->grPixelSize == 2) && ((format != GR_TEXFMT_RGB_565) && (format != GR_TEXFMT_ARGB_1555)))), "format incompatible with rendermode"); #endif /* Planning ahead... ** For Napalm & later: we need to check that the format is one ** of the supported rendering formats. If it is and if it is different ** than the current rendering format then we throw en exception. ** Let me explain: we could, but I don't thing we'd want to, change ** the rendering format to the target format. This would be easy. ** The hard part would be restoring it to the 'default' rendering format. */ /* not testing thisLOD > largeLOD...*/ if ( thisLOD == largeLOD ) offset = 0; else offset = _grTexTextureMemRequired( thisLOD+1, largeLOD, aspectRatio, format, odd_even_mask, FXTRUE, FXFALSE ); /* How do we deal with UMA? The tmu only makes sense when the UMA is not turned on. Or could I use mminfo->tmu_base_address for all cases? if ( UMA ) { add = gc->tmuMemInfo[0].tramOffset + startAddress + offset; } else */ add = gc->tmuMemInfo[tmu].tramOffset + startAddress + offset; if ( gc->state.shadow.fbzMode & SST_YORIGIN ) { add -= ( gc->state.screen_height - height ) * width * dwBytesPerPixel; } gc->textureBuffer.init = FXTRUE; gc->textureBuffer.addr = add; gc->textureBuffer.stride = stride; gc->textureBuffer.width = width; gc->textureBuffer.height = height; gc->curBuffer = 0xffffffff; if ( gc->textureBuffer.on && gc->textureBuffer.prevState.valid ) { INVALIDATE(fbzMode); grClipWindow(0, 0, gc->textureBuffer.width, gc->textureBuffer.height); _grValidateClipState(0, 0, gc->textureBuffer.width, gc->textureBuffer.height); } else gc->textureBuffer.prevState.valid = FXFALSE; GR_END(); #undef FN_NAME } /* grTextureBuffer */ /* tbext */ /*------------------------------------------------------------------- Function: grTextureAuxBuffer Date: Implementor(s): DA. Library: glide Description: Arguments: Return: none -------------------------------------------------------------------*/ GR_DIENTRY(grTextureAuxBuffer, void, (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask )) { #define FN_NAME "grTextureAuxBuffer" FxU32 add = 0, offset = 0; int width = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0], height = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; FxU32 dwBytesPerPixel ; FxU32 stride ; GR_BEGIN_NOFIFOCHECK("grTextureAuxBuffer", 88); GR_CHECK_F(myName, ((_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Banshee) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo3) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo4)), "grTextureBuffer not supported."); dwBytesPerPixel = gc->grPixelSize ; // If the format is not the same as FB format, we're in trouble. stride = width * dwBytesPerPixel ; #ifdef FX_GLIDE_NAPALM /* * AJB- Using FXT1 for an aux buffer looks like it would be a mistake to me as well. * if (format == GR_TEXFMT_ARGB_CMP_FXT1 || format == GR_TEXFMT_ARGB_CMP_DXT1) { width = _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0]; height = _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; } else if (format >= GR_TEXFMT_ARGB_CMP_DXT2 && format <= GR_TEXFMT_ARGB_CMP_DXT5) { width = _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0]; height = _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; } else { width = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][0], height = _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLOD][1]; } stride = width * dwBytesPerPixel; */ GR_CHECK_F(myName, (((gc->grPixelSize == 4) && (format != GR_TEXFMT_ARGB_8888)) || ((gc->grPixelSize == 2) && ((format != GR_TEXFMT_RGB_565) && (format != GR_TEXFMT_ARGB_1555)))), "format incompatible with rendermode"); #endif /* not testing thisLOD > largeLOD...*/ if ( thisLOD == largeLOD ) offset = 0; else offset = _grTexTextureMemRequired( thisLOD+1, largeLOD, aspectRatio, format, odd_even_mask, FXTRUE, FXFALSE ); /* How do we deal with UMA? The tmu only makes sense when the UMA is not turned on. Or could I use mminfo->tmu_base_address for all cases? if ( UMA ) { add = gc->tmuMemInfo[0].tramOffset + startAddress + offset; } else */ add = gc->tmuMemInfo[tmu].tramOffset + startAddress + offset; if ( gc->state.shadow.fbzMode & SST_YORIGIN ) { add -= ( gc->state.screen_height - height ) * width * dwBytesPerPixel; } gc->textureAuxBuffer.init = FXTRUE; gc->textureAuxBuffer.addr = add; gc->textureAuxBuffer.stride = stride; gc->textureAuxBuffer.width = width; gc->textureAuxBuffer.height = height; GR_END(); #undef FN_NAME } /* grTextureAuxBuffer */ GR_DIENTRY(grAuxBuffer, void, (GrBuffer_t buffer )) { #define FN_NAME "grAuxBuffer" GR_BEGIN_NOFIFOCHECK("grAuxBuffer", 88); GR_CHECK_F(myName, ((_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Banshee) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo3) && (_GlideRoot.hwConfig.SSTs[_GlideRoot.current_sst].type != GR_SSTTYPE_Voodoo4)), "grAuxBuffer not supported."); switch( buffer ){ case GR_BUFFER_AUXBUFFER: gc->state.shadow.auxBufferAddr = gc->buffers0[gc->grColBuf]; /* gc->grColBuf is the # of buffer, aux buffer included, and ** it is assumed that the grColBuf th buffer is the aux buffer. ** What happens when we have more than 1 aux buffers? ** Like a Z buffer and an alpha buffer? */ /* gc->strideInTiles may have been changed during the texturebuffer.on mode? No? */ gc->state.shadow.auxBufferStride = gc->strideInTiles | SST_BUFFER_MEMORY_TILED; gc->textureAuxBuffer.on = FXFALSE; break; case GR_BUFFER_TEXTUREAUXBUFFER_EXT: GR_CHECK_F(myName, !gc->textureAuxBuffer.init, "You need to call grTextureAuxBuffer once before calling grAuxBuffer with GR_BUFFER_TEXTUREAUXBUFFER_EXT" ); gc->state.shadow.auxBufferAddr = gc->textureAuxBuffer.addr; gc->state.shadow.auxBufferStride = gc->textureAuxBuffer.stride; gc->textureAuxBuffer.on = FXTRUE; break; } /* Reset the registers ** Note that this is not going thru the glide state monster / validate mechanism */ REG_GROUP_BEGIN(BROADCAST_ID, auxBufferAddr, 2, 0x3); { REG_GROUP_SET(hw, auxBufferAddr, gc->state.shadow.auxBufferAddr); REG_GROUP_SET(hw, auxBufferStride, gc->state.shadow.auxBufferStride); } REG_GROUP_END(); GR_END(); #undef FN_NAME } /* grAuxBuffer */ #if 0 /* KoolSmoky - don't need this anymore */ /*------------------------------------------------------------------- Function: _g3LodXlat Date: 1-Jul-99 Implementor(s): LEW Description: Translate LOD value between software's sense to hardware's sense. Arguments: someLod: A GrLOD_t index to be translated (subtracted from GR_LOD_LOG2_2048 if we're using big textures, or from GR_LOD_LOG2_256 if we're not.) tBig: Boolean telling us whether big textures are to be used. Use the SST_TBIG bit from the tLOD register for this. NB: SST_TBIG didn't exist before Napalm, so if we are on Banshee or Voodoo3 then we know for sure that tBig is false. Return: The translated LOD index. -------------------------------------------------------------------*/ GrLOD_t _g3LodXlat(const GrLOD_t someLOD, const FxBool tBig) { #define FN_NAME "_g3LodXlat" if (tBig) { return GR_LOD_LOG2_2048 - someLOD; } else { return GR_LOD_LOG2_256 - someLOD; } #undef FN_NAME } /* _g3LodXlat */ #endif /*------------------------------------------------------------------- Function: _g3LodBiasPerChip Date: 14-Nov-2000 Implementor: Jonny Cochrane Description: Sub sample LOD Dithering. Called if TMU is in texSubLodDither state. 2chip x2fsaa - no sli, 1 sample per chip 2chip x4fsaa - no sli, 2 samples per chip 4chip x2fsaa - 2 way sli, 1 sample per sli unit 4chip x4fsaa - no sli, 1 sample per chip 4chip x8fsaa - no sli, 2 samples per chip Arguments: tmu: TMU to set. tLod: tLOD to modify. Return: None -------------------------------------------------------------------*/ void g3LodBiasPerChip(GrChipID_t tmu, FxU32 tLod) { #define FN_NAME "g3LodBiasPerChip" FxU32 newtLod ; FxI32 oldLodBias, newLodBias; unsigned int i; unsigned int idx, iTexLodDither; static FxI32 chipLodBias[2][2][4] = /* 4.2 format for tLod register * 2chip x2fsaa - no sli, 1 sample per chip * 2chip x4fsaa - no sli, 2 samples per chip * 4chip x2fsaa - 2 way sli, 1 sample per sli unit * 0.00, 0.50, 0.00, 0.50 - the last 2 are used only when 4chip * {0x00, 0x02, 0x00, 0x02}, * 4chip x4fsaa - no sli, 1 sample per chip * 4chip x8fsaa - no sli, 2 samples per chip * 0.00, 0.25, 0.50, 0.75 - 4 chip * {0x00, 0x01, 0x02, 0x03} * if mipmap dithering is enabled * we will use different tLod registers. */ { { {0x00<sliCount == gc->chipCount) || (gc->windowed) ) return; /* sign extend it. */ oldLodBias = (((tLod & SST_LODBIAS) << (32-6-SST_LODBIAS_SHIFT)) >> (32-6-SST_LODBIAS_SHIFT)); /* unmask lodbias */ tLod &= ~(SST_LODBIAS); idx = ((gc->chipCount - gc->sliCount) > 2); iTexLodDither = (_GlideRoot.environment.texLodDither == 1); for (i = 0; i < gc->chipCount; i++) { /* don't need to modify lodbias if 0 */ if(chipLodBias[iTexLodDither][idx][i] != 0) { newLodBias = oldLodBias + chipLodBias[iTexLodDither][idx][i]; if(newLodBias > (0x1f<chipmask ); GR_END(); #undef FN_NAME } #if 0 /* KoolSmoky - don't need this anymore */ /*------------------------------------------------------------------- Function: MultitextureAndTrilinear Date: 4-Nov-2000 Implementor: Jonny Cochrane Description: Determines if we are multitexturing and NOT trilinear filtering. so that we can do sub sample lod dithering which gives an almost trilinear result. mipmap dithering (lod dithering) is passed through, see g3LodBiasPerChip Arguments: None Return: tmuMask of the TMUs that can do it -------------------------------------------------------------------*/ GrChipID_t MultitextureAndTrilinear(void) { #define FN_NAME "MultitextureAndTrilinear" GR_DCL_GC; GrChipID_t retval = FXBIT(0x4); /* KoolSmoky - we can only do this if we are running in; * 2chip x2fsaa - no sli, 1 sample per chip * 2chip x4fsaa - no sli, 2 samples per chip * 4chip x2fsaa - 2 way sli, 1 sample per sli unit * 4chip x4fsaa - no sli, 1 sample per chip * 4chip x8fsaa - no sli, 2 samples per chip * ...and with FX_GLIDE_LOD_SUBSAMPLE_DITHER=1 */ if( (_GlideRoot.environment.texSubLodDither != 1) || (gc->sliCount == gc->chipCount) || (gc->windowed) ) return retval; #if 0 #if 0 /* Jonny Cochrane's method */ if(_GlideRoot.environment.texLodDither) return 0; if( (gc->state.per_tmu[0].evenOdd == 3) && //both even and odd (gc->state.per_tmu[1].evenOdd == 3) && //both even and odd (gc->state.tmuShadow[0].textureMode & (SST_TMINFILTER | SST_TMAGFILTER)) && //and bilinear for mag and min filter (gc->state.tmuShadow[1].textureMode & (SST_TMINFILTER | SST_TMAGFILTER)) ) //and bilinear for mag and min filter retval |= (GR_TMUMASK_TMU0 | GR_TMUMASK_TMU1); #else /* Colourless's method if bilinear filtering is required */ if( (gc->state.per_tmu[0].evenOdd == 3) && //both even and odd (gc->state.tmuShadow[0].textureMode & (SST_TMINFILTER | SST_TMAGFILTER)) && //and bilinear for mag and min filter !(gc->state.tmuShadow[0].textureMode & (SST_TRILINEAR | SST_TLODDITHER)) ) //and not mipmap dithering or trilinear retval |= GR_TMUMASK_TMU0; if( (gc->state.per_tmu[1].evenOdd == 3) && //both even and odd (gc->state.tmuShadow[1].textureMode & (SST_TMINFILTER | SST_TMAGFILTER)) && //and bilinear for mag and min filter !(gc->state.tmuShadow[1].textureMode & (SST_TRILINEAR | SST_TLODDITHER)) ) //and not mipmap dithering or trilinear retval |= GR_TMUMASK_TMU1; #endif #else #if 0 /* Colourless's method */ if( (gc->state.per_tmu[0].evenOdd == 3) && //both even and odd !(gc->state.tmuShadow[0].textureMode & (SST_TRILINEAR | SST_TLODDITHER)) ) //and not trilinear and not dither mode retval |= GR_TMUMASK_TMU0; if( (gc->state.per_tmu[1].evenOdd == 3) && //both even and odd !(gc->state.tmuShadow[1].textureMode & (SST_TRILINEAR | SST_TLODDITHER)) && //and not trilinear and not dither mode !(gc->state.tmuShadow[0].textureMode & SST_TRILINEAR) ) retval |= GR_TMUMASK_TMU1; #else /* KoolSmoky - we will allow mip dithering. */ if( !(gc->state.tmuShadow[1].textureMode & SST_TRILINEAR) && !(gc->state.tmuShadow[0].textureMode & SST_TRILINEAR) ) { //not single or two pass trilinear if(gc->state.per_tmu[0].evenOdd == 3) //both even and odd retval |= GR_TMUMASK_TMU0; if(gc->state.per_tmu[1].evenOdd == 3) //both even and odd retval |= GR_TMUMASK_TMU1; } #endif #endif return retval; } #endif glide3x/h5/glide3/src/gtexdl.c0100700000175300010010000012671307725034670015437 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gtexdl.c,v 1.3.4.7 2003/08/21 08:49:55 dborca Exp $ ** $Log: ** 11 3dfx 1.8.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 10 3dfx 1.8.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 9 3dfx 1.8 04/04/00 Kenneth Dyke Fixed addressing for large ** tiled textures. ** 8 3dfx 1.7 01/31/00 Adam Briggs changed the IS_NAPALM macro ** to cooperate with the display driver version of the same ** 7 3dfx 1.6 01/31/00 Adam Briggs Changed all device ID magic ** numbers to use those defined in fxhal.h & added IS_NAPALM macro to test ** against device ID range ** 6 3dfx 1.5 01/19/00 Kenneth Dyke Fixed texture memory sanity ** check bug. ** 5 3dfx 1.4 10/27/99 Stephane Huaulme keeping the Mac compiler ** happy... ** 4 3dfx 1.3 10/26/99 Larry warner Turn off mipmap level size ** debug check ** if we're in windowed mode, to enable the ** napalm mustpass.bat conform test to run. ** 3 3dfx 1.2 10/21/99 Larry warner Added 4-bit and 32-bit ** download code for tiled memory. ** 2 3dfx 1.1 09/22/99 Larry warner Created download procedures ** for FXT1 format. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 58 8/25/99 8:45p Larryw ** Don't bother with 16-byte alignment magic for FXT1. ** ** 57 8/19/99 7:55p Larryw ** Backed out my last change. ** ** 56 8/18/99 3:20p Larryw ** FXT1 refinements. ** ** 55 8/05/99 5:03p Larryw ** FXT1 format works now. ** ** 54 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 53 7/22/99 8:14p Larryw ** Texture format byte-depth improvements ** ** 52 7/14/99 6:23p Larryw ** Remove obsolete G3_LOD_TRANSLATE() macro ** Define _grMipMapOffset[][] at compile time ** Fix 2k texture address-finding ** ** 51 7/07/99 6:52p Larryw ** * 2k texture support ** * Reversed order of LOD tables ** * Added 512,1024, and 2048-sized entries in tables ** * Nullified G3_LOD_TRANSLATE() ** * Created _g3LodXlat() for where tLOD register is read/written ** * Misc cosmetic changes. ** ** 50 6/14/99 5:16p Larryw ** Added 32-bit texture format support. ** ** 49 6/03/99 5:23p Russp ** Add in some ifdef'd code to allow variable texture alignment ** ** 48 4/16/99 9:01a Dow ** Fixed bogus 11th arg to GDBG_INFO_MORE ** ** 47 4/04/99 8:51p Atai ** Partial check-in for alt-tab issue. set FX_GLIDE_ALT_TAB=1 to build ** glide3x with hwcQueryContext built into GR_BEGIN_NOFIFOCHECK. It works ** with DEBUG glide only. In the non-debug glide, we can still see the ** desktop corruption. ** ** 46 3/24/99 6:17p Peter ** reduce nop flush for chain downloads ** ** 45 3/05/99 10:34p Peter ** removed extraneous nops ** ** 44 3/02/99 3:20p Atai ** added 2d nop before texture download to maintain cache coherency ** ** 43 3/02/99 2:08p Peter ** 2d nop flushes pixels (although 3d nop should too) ** ** 42 2/24/99 4:51p Peter ** the rest of tiled texturing ** ** 41 2/19/99 10:25a Atai ** check invalid textable with GR_TEXTABLE_PALETTE_6666_EXT ** ** 40 2/18/99 6:00p Peter ** sub alignment linear textures ** ** 39 2/10/99 3:08p Peter ** i swear I will never cut and paste code again, for as long as I live ** ** 38 2/10/99 2:34p Peter ** corrected alignment textures within an alignment unit ** ** 37 2/04/99 5:17p Peter ** fixed my eff-ed alignment for small lod levels (1x1) ** ** 36 2/02/99 4:36p Peter ** download through lfb rather than texture port ** ** 35 1/25/99 6:35p Peter ** tiled texture cleanup ** ** 34 1/14/99 7:48p Peter ** cleanedup bytes per texel stuff ** ** 33 12/14/98 6:19p Dow ** Fixed for current surface extension spec ** ** 32 12/03/98 11:26p Dow ** ** 31 11/30/98 6:57p Peter ** windowed texture effage ** ** 30 11/15/98 3:21a Atai ** first attempt to make 2 tmus work in H4 glide3x full screen mode, just ** in time check-in for comdex demo. warning: the code is not completed ** yet. ** ** 29 10/13/98 5:27p Peter ** 6666 format hack ** ** 28 10/12/98 9:51a Peter ** dynamic 3DNow!(tm) ** ** 27 10/09/98 2:44p Atai ** fixed 6666 palette ** ** 26 9/24/98 11:17a Dow ** AMD 3DNow! (tm) mods ** ** 25 9/11/98 2:09p Peter ** removed debugging code ** ** 24 9/11/98 1:44p Peter ** texture mask fixes ** ** 23 9/09/98 12:56p Atai ** relaxed 2mb texture address constraint for uma devices ** ** 22 9/04/98 3:32p Peter ** reversed the sense of the active bytes in small downloads ** ** 21 8/27/98 10:05p Peter ** fixed state effage ** ** 20 8/27/98 9:54p Peter ** flush old texels when replacing small lod levels ** ** 19 8/27/98 1:55p Peter ** download problem w/ widths smaller than dword ** ** 18 8/03/98 6:41a Jdt ** moved stats into GC from global location ** ** 17 7/18/98 3:43p Jdt ** Fix texture download state saving bug. Remove convert and download ** RLE. ** ** 16 7/18/98 12:31a Jdt ** Changes to reflect new shadow register structure. ** Added shadowing of palette/ncc table downloads. ** ** 15 7/17/98 2:07p Jdt ** Remove pointless SST_SEQ_8_DOWWNLD bit ** ** 14 7/16/98 8:19a Jdt ** fxcmd.h ** ** 13 6/08/98 12:47p Atai ** added return value for grTexDownloadMipmapLevelPartial ** ** 12 6/05/98 7:51p Atai ** return FxBool for grTexDownloadMipMapLevelPartial ** ** 11 5/29/98 11:45a Atai ** 1.added _EXT for extension #defines. ** 2. change GR_TEXBASE_* values ** 3. Remove GR_TEXCHROMA_ENABLE_SUBSTITUTE_RGB ** ** 10 5/08/98 1:40p Peter ** merged Anthony's palette of Taco changes ** ** 9 5/05/98 3:01p Peter ** packet chipfield vs direct register chipfield ** ** 8 4/30/98 5:01p Peter ** first pass glide3 merge ** ** 7 4/30/98 10:34a Peter ** merged w/ cvg again ** ** 6 4/29/98 2:32p Peter ** fixed texture palette broadcast ** ** 5 4/22/98 4:57p Peter ** glide2x merge ** ** 4 2/02/98 12:21p Atai ** fixed palette broadcasts in _grTexDownloadNccTable and ** _grTexDownloadPalette ** ** 3 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress ** ** 2 1/18/98 12:03p Atai ** sync to rev 17 spec * * 1 1/16/98 4:29p Atai * create glide 3 src * * 54 1/09/98 6:48p Atai * grTexInfo, GR_LOD_* and GR_ASPECT_* * * 53 1/08/98 7:09p Peter * real hw stuff modulo makefile change * * 52 1/08/98 4:58p Atai * tex table broadcast, grVertexLayout enable/disable, stq, and some * defines * * 51 1/08/98 11:06a Dow * Set palette downloads to broadcast. * * 50 12/11/97 4:15p Peter * fixed assertions * * 49 12/09/97 12:20p Peter * mac glide port * * 48 12/05/97 4:26p Peter * watcom warnings * * 47 12/02/97 9:48a Dow * Got rid of Texelfx rev 0 warning * * 46 11/21/97 1:03p Peter * small texture download problem * * 45 11/20/97 6:57p Dow * Texture Downloads for Banshee * * 44 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 43 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 42 11/14/97 12:09a Peter * comdex thing and some other stuff * * 41 11/12/97 11:16a Peter * cleaned up assertions * * 40 11/05/97 1:50p Peter * fixed partial palette downloads * * 39 11/03/97 3:43p Peter * h3/cvg cataclysm * * 38 10/08/97 11:33a Peter * reg group for palette download * * 37 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 36 9/04/97 3:32p Peter * starting grouping serial reg writes * * 35 8/18/97 3:52p Peter * pre-hw arrival fixes/cleanup * * 34 7/26/97 5:18p Peter * fixed macro effage * * 33 7/08/97 2:49p Peter * started playing w/ h3 sim * * 32 7/02/97 12:28p Peter * removed spurious NOP, tex dl * * 31 6/30/97 3:22p Peter * cmd fifo sanity * ** */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" /*--------------------------------------------------------------------------- ** _grTexDownloadNccTable ** ** Downloads an ncctable to the specified _physical_ TMU(s). This ** function is called internally by Glide and should not be executed ** by an application. */ GR_DDFUNC(_grTexDownloadNccTable, void, (GrChipID_t tmu, FxU32 which, const GuNccTable *table, int start, int end)) { #define FN_NAME "_grTexDownloadNccTable" GR_BEGIN_NOFIFOCHECK(FN_NAME,89); GDBG_INFO_MORE(gc->myLevel,"(%d,%d, 0x%x, %d,%d)\n",tmu,which,table,start,end); GR_ASSERT(start==0); GR_ASSERT(end==11); /* check for null pointer */ if (table == NULL) return; gc->stats.palDownloads++; gc->stats.palBytes += (end-start+1)<<2; if (gc->tmu_state[tmu].ncc_table[which] != table) { SstRegs* texHW; int i; #ifdef GLIDE_POINTCAST_PALETTE texHW = SST_TMU(hw,tmu); #else texHW = SST_CHIP(hw, 0x06UL); #endif if (which == 0) { #ifdef GLIDE_POINTCAST_PALETTE REG_GROUP_BEGIN((0x02UL << tmu), nccTable0, 12, 0x0FFF); #else REG_GROUP_BEGIN(0x06UL, nccTable0, 12, 0x0FFF); #endif for (i = 0; i < 12; i++) { gc->state.shadow.tmuState[tmu].nccTable0[i] = table->packed_data[i]; REG_GROUP_SET(texHW, nccTable0[i], table->packed_data[i]); } REG_GROUP_END(); } else { #ifdef GLIDE_POINTCAST_PALETTE REG_GROUP_BEGIN((0x02UL << tmu), nccTable1, 12, 0x0FFF); #else REG_GROUP_BEGIN(0x06UL, nccTable1, 12, 0x0FFF); #endif for (i = 0; i < 12; i++) { gc->state.shadow.tmuState[tmu].nccTable1[i] = table->packed_data[i]; REG_GROUP_SET(texHW, nccTable1[i], table->packed_data[i]); } REG_GROUP_END(); } gc->tmu_state[tmu].ncc_table[which] = table; } GR_END(); #undef FN_NAME } /* _grTexDownloadNccTable */ /*------------------------------------------------------------------- Function: _grTexDownloadPalette Date: 6/9 Implementor(s): jdt Library: Glide Description: Private function to download a palette to the specified tmu Arguments: tmu - which tmu to download the palette to pal - the pallete data start - beginning index to download end - ending index to download Return: none -------------------------------------------------------------------*/ GR_DDFUNC(_grTexDownloadPalette, void, (GrChipID_t tmu, GrTexTable_t type, GuTexPalette *pal, int start, int end)) { #define FN_NAME "_grTexDownloadPalette" GR_BEGIN_NOFIFOCHECK(FN_NAME, 89); GDBG_INFO_MORE(gc->myLevel,"(%d,0x%x, %d,%d)\n",tmu,pal,start,end); GR_CHECK_F(FN_NAME, pal == NULL, "pal invalid"); GR_CHECK_F(FN_NAME, start < 0, "invalid start index"); GR_CHECK_F(FN_NAME, end > 255, "invalid end index"); /* NOTE: ** ** This code broadcasts the palette because in the future, we will ** only support one global texture palette no matter how many TMUs ** there are. This is fallout from the fact that future hardware ** has a unified memory architecture. ** ** Source licensees (meaning arcade or LBE vendors that) require the ** one palette/tmu mode should define GLIDE_POINTCAST_PALETTE on ** the command line for this file. Understand, however, that this ** will not work on future hardware. */ #ifdef GLIDE_POINTCAST_PALETTE /* ** FURTHER NOTE: ** There is a sublety (nice way of saying BUG) here. ** If TMU0 is specified, then the palette will be broadcast to all ** TMUS. So, if the user downloads TMU1's palette, then TMU0's ** palette, TMU0's palette will be on *both* TMUs. This is a ** pretty strong indicator that no one is using separate palettes ** on different TMUs. */ hw = SST_TMU(hw,tmu); #else hw = SST_CHIP(hw,0xE); #endif gc->stats.palDownloads++; gc->stats.palBytes += ((end - start + 1) << 2); /* We divide the writes into 3 chunks trying to group things into * complete 8 word grouped packets to fit the nccTable palette * format: stuff before the 8 word alignment, aligned writes, and * stuff after the 8 word alignment to the end. The slop regions * are one packet apiece. */ { #ifdef GLIDE_POINTCAST_PALETTE const FifoChipField chipId = (FifoChipField)(0x02UL << tmu); #else const FifoChipField chipId = (FifoChipField)0x06UL; #endif const int endSlop = (end & ~0x07); const int startSlop = MIN(((start + 8) & ~0x07) - 1, end); int i = start; if (type == GR_TEXTABLE_PALETTE) { /* Is the start of the palette range unaligned or is the end of * the range less than a completely aligned range? */ if (((start & 0x07) != 0) || (end < ((start + 8) & ~0x07))) { const FxI32 slopCount = startSlop - start + 1; GR_ASSERT((slopCount > 0) && (slopCount <= 8)); REG_GROUP_BEGIN(chipId, nccTable0[4 + (start & 0x07)], slopCount, (0xFF >> (8 - slopCount))); while(i < start + slopCount) { FxU32 entry; entry = 0x80000000 | ((i & 0xFE) << 23) | (pal->data[i] & 0xFFFFFF); gc->state.shadow.paletteRow[i>>3].data[i&7] = entry; REG_GROUP_SET(hw, nccTable0[4 + (i & 0x07)], entry ); i++; } REG_GROUP_END(); } /* Do all of the aligned palette ranges. */ while(i < endSlop) { const int endIndex = i + 8; REG_GROUP_BEGIN(chipId, nccTable0[4], 8, 0xFF); while(i < endIndex) { FxU32 entry; entry = 0x80000000 | ((i & 0xFE) << 23) | (pal->data[i] & 0xFFFFFF); gc->state.shadow.paletteRow[i>>3].data[i&7] = entry; REG_GROUP_SET(hw, nccTable0[4 + (i & 0x07)], entry ); i++; } REG_GROUP_END(); } /* Do we have any more slop at the end of the range? */ if (i <= end) { const FxU32 slopCount = end - endSlop + 1; REG_GROUP_BEGIN(chipId, nccTable0[4], slopCount, (0xFF >> (8 - slopCount))); while(i <= end) { FxU32 entry; entry = 0x80000000 | ((i & 0xFE) << 23) | (pal->data[i] & 0xFFFFFF); gc->state.shadow.paletteRow[i>>3].data[i&7] = entry; REG_GROUP_SET(hw, nccTable0[4 + (i & 0x07)], entry ); i++; } REG_GROUP_END(); } } else { /* Is the start of the palette range unaligned or is the end of * the range less than a completely aligned range? */ if (((start & 0x07) != 0) || (end < ((start + 8) & ~0x07))) { const FxI32 slopCount = startSlop - start + 1; GR_ASSERT((slopCount > 0) && (slopCount <= 8)); REG_GROUP_BEGIN(chipId, nccTable0[4 + (start & 0x07)], slopCount, (0xFF >> (8 - slopCount))); while(i < start + slopCount) { FxU32 p1, p2, p3, p4, entry; p1 = p2 = pal->data[i]; p1 &= 0xfc000000; p2 &= 0x00fc0000; p1 >>= 8; p2 >>= 6; p3 = p4 = pal->data[i]; p3 &= 0x0000fc00; p4 &= 0x000000fc; p3 >>= 4; p4 >>= 2; p1 |= p2; p3 |= p4; p1 |= p3; entry = (0x80000000UL | ((i & 0xFEUL) << 23) | p1); gc->state.shadow.paletteRow[i>>3].data[i&7] = entry; REG_GROUP_SET(hw, nccTable0[4 + (i & 0x07)], entry); i++; } REG_GROUP_END(); } /* Do all of the aligned palette ranges. */ while(i < endSlop) { const int endIndex = i + 8; REG_GROUP_BEGIN(chipId, nccTable0[4], 8, 0xFF); while(i < endIndex) { FxU32 p1, p2, p3, p4; p1 = p2 = pal->data[i]; p1 &= 0xfc000000; p2 &= 0x00fc0000; p1 >>= 8; p2 >>= 6; p3 = p4 = pal->data[i]; p3 &= 0x0000fc00; p4 &= 0x000000fc; p3 >>= 4; p4 >>= 2; p1 |= p2; p3 |= p4; p1 |= p3; REG_GROUP_SET(hw, nccTable0[4 + (i & 0x07)], (0x80000000 | ((i & 0xFE) << 23) | p1)); i++; } REG_GROUP_END(); } /* Do we have any more slop at the end of the range? */ if (i <= end) { const FxU32 slopCount = end - endSlop + 1; REG_GROUP_BEGIN(chipId, nccTable0[4], slopCount, (0xFF >> (8 - slopCount))); while(i <= end) { FxU32 p1, p2, p3, p4, entry; p1 = p2 = pal->data[i]; p1 &= 0xfc000000; p2 &= 0x00fc0000; p1 >>= 8; p2 >>= 6; p3 = p4 = pal->data[i]; p3 &= 0x0000fc00; p4 &= 0x000000fc; p3 >>= 4; p4 >>= 2; p1 |= p2; p3 |= p4; p1 |= p3; entry = (0x80000000UL | ((i & 0xFE) << 23) | p1); gc->state.shadow.paletteRow[i>>3].data[i&7] = entry; REG_GROUP_SET(hw, nccTable0[4 + (i & 0x07)], entry); i++; } REG_GROUP_END(); } } } /* NB: If we're changing table types and the currently selected texture is * a palettized texture then we need to change the texture format * behind the user's back to match the table type. */ if (type != gc->state.tex_table) { FxI32 i; for(i = 0; i < gc->num_tmu; i++) { const FxU32 texFmt = (gc->state.shadow.tmuState[i].textureMode & SST_TFORMAT), newTexMode = (gc->state.shadow.tmuState[i].textureMode ^ ((GR_TEXFMT_P_8 ^ GR_TEXFMT_P_8_RGBA) << SST_TFORMAT_SHIFT)); if ((texFmt == (GR_TEXFMT_P_8 << SST_TFORMAT_SHIFT)) || (texFmt == (GR_TEXFMT_P_8_RGBA << SST_TFORMAT_SHIFT))) { GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET((0x02UL << i), SST_TMU(hw, i), textureMode, newTexMode); GR_CHECK_SIZE(); gc->state.shadow.tmuState[i].textureMode = newTexMode; } } } GR_END(); #undef FN_NAME } /* _grTexDownloadPalette */ /*------------------------------------------------------------------- Function: grTexDownloadTable Date: 6/3 Implementor(s): jdt, GaryMcT Library: glide Description: download look up table data to a tmu Arguments: tmu - which tmu type - what type of table to download One of: GR_TEXTABLE_NCC0 GR_TEXTABLE_NCC1 GR_TEXTABLE_PALETTE void *data - pointer to table data Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexDownloadTable, void, (GrTexTable_t type, void *data)) { GR_BEGIN_NOFIFOCHECK("grTexDownloadTable",89); GDBG_INFO_MORE(gc->myLevel,"(%d,0x%x)\n",type,data); GR_CHECK_F(myName, type > GR_TEXTABLE_PALETTE_6666_EXT, "invalid table specified"); GR_CHECK_F(myName, !data, "invalid data pointer"); switch(type) { case GR_TEXTABLE_PALETTE: case GR_TEXTABLE_PALETTE_6666_EXT: _grTexDownloadPalette(GR_TMU0, type, (GuTexPalette *)data, 0, 255); break; default: /* Type is an ncc table */ _grTexDownloadNccTable(GR_TMU0, type, (GuNccTable*)data, 0, 11); break; } /* NB: Set the current palette type after we do the download because * the palette download code may need to know that there is a table * type change and do something hoopti. */ gc->state.tex_table = type; GR_END(); } /* grTexDownloadTable */ /*------------------------------------------------------------------- Function: grTexDownloadMipMapLevelPartialTiled Date: 10-Dec-98 Implementor(s): dow Description: Downloads a mipmap level to the specified tmu at the given texture start address--taking into account that the memory is tiled and the stride of that tiled memory may be much greater than the width of any given mipmap level. Arguments: tmu - which tmu startAddress - starting address for texture download, this should be some value between grTexMinAddress() and grTexMaxAddress() thisLod - lod constant that describes the mipmap level to be downloaded largeLod - largest level of detail in complete mipmap to be downloaded at startAddress of which level to be downloaded is a part aspectRatio - aspect ratio of this mipmap format - format of mipmap image data evenOdd - which set of mipmap levels have been downloaded for the selected texture One of: GR_MIPMAPLEVELMASK_EVEN GR_MIPMAPLEVELMASK_ODD GR_MIPMAPLEVELMASK_BOTH data - pointer to mipmap data Return: FXTRUE; -------------------------------------------------------------------*/ FxBool _grTexDownloadMipMapLevelPartialTiled(GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data, int t, int maxT) { #define FN_NAME "_grTexDownloadMipMapLevelPartialTiled" GR_BEGIN_NOFIFOCHECK_RET(FN_NAME"\n", 89); GR_CHECK_TMU(FN_NAME, tmu); GR_ASSERT(gc->tmuMemInfo[tmu].texTiled); { const struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; const FxU32 texelSize = _grBitsPerTexel[format], texStrideBytes = memInfo->texStrideBytes; FxU32 maxS = 0; FxU32 texOffset = 0x00UL; switch(format) { case GR_TEXFMT_ARGB_CMP_FXT1: maxS = WIDTH_BY_ASPECT_LOD_FXT1(aspectRatio, thisLod); break; case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: maxS = WIDTH_BY_ASPECT_LOD_DXT(aspectRatio, thisLod); break; default: maxS = WIDTH_BY_ASPECT_LOD(aspectRatio, thisLod); break; } if (thisLod < largeLod) { texOffset = _grTexCalcMipmapLevelOffsetTiled(tmu, thisLod, largeLod, aspectRatio, format, evenOdd, NULL, NULL); } texOffset += memInfo->tramLfbAddr; GR_CHECK_F(FN_NAME, texelSize == 0, "invalid texture format"); switch(texelSize) { case 4: /* 4-bit textures */ { switch(maxS) { case 4: /* XXX need to test! */ { const FxU16 *src16 = (const FxU16*)data; src16++; for(; t <= maxT; t+=4) { FxU32 texAddress = texOffset + t * texStrideBytes, s; LINEAR_WRITE_BEGIN(2, SSTCP_PKT5_LFB, texAddress, 0x00UL, 0x00UL); for (s = 0; s < 2; s++) { LINEAR_WRITE_SET(texAddress, (FxU32)(*src16)); texAddress++; src16 += 4; } LINEAR_WRITE_END(); } } break; case 8: { const FxU32 *src32 = (const FxU32*)data; texOffset += (t * texStrideBytes); for (; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, SSTCP_PKT5_LFB, texOffset, 0x0UL, 0x0UL); LINEAR_WRITE_SET(texOffset, *src32); LINEAR_WRITE_END(); src32++; texOffset += texStrideBytes; } } break; default: { const FxU32 *src32 = (const FxU32*)data; for (; t <= maxT; t++) { FxU32 texAddress = texOffset + t * texStrideBytes, s; LINEAR_WRITE_BEGIN((maxS >> 3), SSTCP_PKT5_LFB, texAddress, 0x0UL, 0x0UL); for (s = 0; s < maxS; s+=8) { LINEAR_WRITE_SET(texAddress, *src32); texAddress +=4; src32++; } LINEAR_WRITE_END(); } } break; } } break; case 8: /* 8-bit textures */ { const FxU8 *src8 = (const FxU8*)data; switch(maxS) { case 1: texOffset += (t * texStrideBytes); for (; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, SSTCP_PKT5_LFB, texOffset, 0x0UL, 0x0UL); LINEAR_WRITE_SET(((FxU32*)texOffset), *src8); LINEAR_WRITE_END(); src8 += 1; texOffset += texStrideBytes; } break; case 2: texOffset += (t * texStrideBytes); for (; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, SSTCP_PKT5_LFB, texOffset, 0x0UL, 0x0UL); LINEAR_WRITE_SET(((FxU32*)texOffset), *(const FxU16*)src8); LINEAR_WRITE_END(); src8 += 2; texOffset += texStrideBytes; } break; default: for (; t <= maxT; t++) { FxU32 texAddress = (texOffset + t * texStrideBytes), s; LINEAR_WRITE_BEGIN((maxS >> 2), SSTCP_PKT5_LFB, texAddress, 0x0UL, 0x0UL); for (s = 0; s < maxS; s += 4) { LINEAR_WRITE_SET(((FxU32*)texAddress), *(const FxU32*)src8); src8 += 4; texAddress += 4; } LINEAR_WRITE_END(); } break; } } break; case 16: /* 16-bit textures */ { const FxU16 *src16 = (const FxU16*)data; switch(maxS) { case 1: texOffset += (t * texStrideBytes); for(; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, SSTCP_PKT5_LFB, texOffset, 0x00UL, 0x00UL); LINEAR_WRITE_SET_16(texOffset, *src16); LINEAR_WRITE_END(); src16 += 1; texOffset += texStrideBytes; } break; case 2: texOffset += (t * texStrideBytes); for(; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, SSTCP_PKT5_LFB, texOffset, 0x00UL, 0x00UL); LINEAR_WRITE_SET_16(texOffset, *(const FxU32*)src16); LINEAR_WRITE_END(); src16 += 2; texOffset += texStrideBytes; } break; default: for (; t <= maxT; t++) { FxU32 texAddress = texOffset + t * texStrideBytes, s; LINEAR_WRITE_BEGIN((maxS >> 1), SSTCP_PKT5_LFB, texAddress, 0x0UL, 0x0UL); for (s = 0; s < maxS; s += 4) { LINEAR_WRITE_SET_16(texAddress + 0, *(const FxU32*)(src16 + 0)); LINEAR_WRITE_SET_16(texAddress + 4, *(const FxU32*)(src16 + 2)); src16 += 4; texAddress += 8; } LINEAR_WRITE_END(); } break; } } break; case 32: /* 32-bit textures */ { const FxU32 *src32 = (const FxU32*)data; switch(maxS) { case 1: texOffset += (t * texStrideBytes); for(; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, SSTCP_PKT5_LFB, texOffset, 0x00UL, 0x00UL); LINEAR_WRITE_SET(texOffset, *src32); LINEAR_WRITE_END(); src32 += 1; texOffset += texStrideBytes; } break; default: for (; t <= maxT; t++) { FxU32 texAddress = texOffset + t * texStrideBytes, s; LINEAR_WRITE_BEGIN(maxS, SSTCP_PKT5_LFB, texAddress, 0x0UL, 0x0UL); for(s = 0; s < maxS; s += 1) { LINEAR_WRITE_SET(texAddress, *src32); src32 += 1; texAddress += 4; } LINEAR_WRITE_END(); } break; } } break; default: /* Undefined texture format */ GR_ASSERT(texelSize); break; } } return FXTRUE; #undef FN_NAME } /* _grTexDownloadMipMapLevelPartialTiled */ /*------------------------------------------------------------------- Function: grTexDownloadMipMapLevelPartial Date: 6/2 Implementor(s): GaryMcT, Jdt Library: glide Description: Downloads a mipmap level to the specified tmu at the given texture start address Arguments: tmu - which tmu startAddress - starting address for texture download, this should be some value between grTexMinAddress() and grTexMaxAddress() thisLod - lod constant that describes the mipmap level to be downloaded largeLod - largest level of detail in complete mipmap to be downloaded at startAddress of which level to be downloaded is a part aspectRatio - aspect ratio of this mipmap format - format of mipmap image data evenOdd - which set of mipmap levels have been downloaded for the selected texture One of: GR_MIPMAPLEVELMASK_EVEN GR_MIPMAPLEVELMASK_ODD GR_MIPMAPLEVELMASK_BOTH data - pointer to mipmap data Return: none -------------------------------------------------------------------*/ GR_ENTRY(grTexDownloadMipMapLevelPartial, FxBool, (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data, int t, int max_t)) { #define FN_NAME "grTexDownloadMipMapLevelPartial" GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 89); GDBG_INFO_MORE(gc->myLevel,"(%d,0x%x, %d,%d,%d, %d,%d 0x%x, %d,%d)\n", tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, t, max_t); /* Sanity checking */ { GR_CHECK_TMU(FN_NAME, tmu); GR_CHECK_F(FN_NAME, (gc->windowed ? FXFALSE : (startAddress + _grTexTextureMemRequired(thisLod, largeLod, aspectRatio, format, evenOdd, FXTRUE, FXFALSE) > gc->tmu_state[tmu].total_mem)), "insufficient texture ram at startAddress"); GR_CHECK_F(FN_NAME, startAddress & SST_TEXTURE_ALIGN_MASK, "unaligned startAddress"); GR_CHECK_F(FN_NAME, _grBitsPerTexel[format] == 0, "invalid texture format"); if (!IS_NAPALM(gc->bInfo->pciInfo.deviceID)) { /* * Sanity checks for Banshee and Voodoo3 */ GR_CHECK_F(FN_NAME, thisLod > GR_LOD_LOG2_256, "thisLod invalid"); GR_CHECK_F(FN_NAME, largeLod > GR_LOD_LOG2_256, "largeLod invalid"); GR_CHECK_F(FN_NAME, (_grBitsPerTexel[format] == 4), "this hardware doesn't support 4-bit textures"); GR_CHECK_F(FN_NAME, (_grBitsPerTexel[format] == 32), "this hardware doesn't support 32-bit textures"); } else { /* * Sanity checks for Napalm */ GR_CHECK_F(FN_NAME, thisLod > GR_LOD_LOG2_2048, "thisLod invalid"); GR_CHECK_F(FN_NAME, largeLod > GR_LOD_LOG2_2048, "largeLod invalid"); } GR_CHECK_F(FN_NAME, thisLod > largeLod, "thisLod may not be larger than largeLod"); GR_CHECK_F(FN_NAME, ((aspectRatio > GR_ASPECT_LOG2_8x1) || (aspectRatio < GR_ASPECT_LOG2_1x8)), "aspectRatio invalid"); GR_CHECK_F(FN_NAME, evenOdd > 0x3 || evenOdd == 0, "evenOdd mask invalid"); GR_CHECK_F(FN_NAME, !data, "invalid data pointer"); #ifdef FX_GLIDE_NAPALM switch(format) { case GR_TEXFMT_ARGB_CMP_FXT1: GR_CHECK_F(FN_NAME, max_t >= _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)] [thisLod][1], "invalid end row for fxt1, dxt1"); break; case GR_TEXFMT_ARGB_CMP_DXT1: case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: GR_CHECK_F(FN_NAME, max_t >= _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)] [thisLod][1], "invalid end row for dxt2,3,4,5"); break; default: GR_CHECK_F(FN_NAME, max_t >= _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][1], "invalid end row"); break; } #else GR_CHECK_F(FN_NAME, max_t >= _grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][1], "invalid end row"); #endif /* FX_GLIDE_NAPALM */ #ifdef GLIDE_TEST_TEXTURE_ALIGNMENT /* always check texture alignment */ INTERNAL_CHECK(FN_NAME, startAddress & SST_TEXTURE_ALIGN_MASK, "unaligned startAddress", FXTRUE); #endif } /* Skip this level entirely if not in odd/even mask */ if (!(evenOdd & (thisLod & 0x1 ? GR_MIPMAPLEVELMASK_ODD : GR_MIPMAPLEVELMASK_EVEN))) goto all_done; { struct GrTmuMemInfo* memInfo = gc->tmuMemInfo + tmu; /* Part1 of the texel cache coherency stuff for avenger. According * to the docs, the 3d nopCmd should do this all, but it does not * work as advertised. But wait, there's more after the download... * * Force a pixel flush which should force all of the * texture downloads to flush from internal fifos etc. */ GR_TEX_FLUSH_PRE(memInfo); if (memInfo->texTiled) { _grTexDownloadMipMapLevelPartialTiled(tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, t, max_t); } else { FxU32 baseAddress; /* Compute physical start address for the download. */ { FxU32 texOffset = 0x00UL; /* We need to do some magic to pack the small levels and have a * properly aligned baseAddr. If the current level is not going * to start on an alignment boundary when working backwards in * the chain we need to offset it into the block so that it is * addressable with an aligned baseAddr. */ { GrLOD_t minLod = thisLod; /* * We can safely skip this part if we're in FXT1-land * because the minimum level size is 16 bytes (8x4x1/2) * which matches the alignment restriction. */ /* KoolSmoky - same for DXT2,3,4,5 were the minimum level * size is 16 bytes (4x4x1) which also matches the alignment * restriction. * same for DXT1 ((4x4x1/2)x2) minimum level size is 16 bytes */ if(format != GR_TEXFMT_ARGB_CMP_FXT1 && format != GR_TEXFMT_ARGB_CMP_DXT1 && format != GR_TEXFMT_ARGB_CMP_DXT2 && format != GR_TEXFMT_ARGB_CMP_DXT3 && format != GR_TEXFMT_ARGB_CMP_DXT4 && format != GR_TEXFMT_ARGB_CMP_DXT5 ) { const FxU32 aspectIndex = ((aspectRatio < GR_ASPECT_LOG2_1x1) ? -aspectRatio : aspectRatio), lodIndex = ((thisLod == GR_LOD_LOG2_256) ? GR_LOD_LOG2_256 : thisLod + 1), formatMult = _grBitsPerTexel[format]; FxU32 levelSize = (_grMipMapHostSize[aspectIndex][lodIndex] * formatMult)>>3; /* Cvt from bits to bytes */ GR_CHECK_F(FN_NAME, formatMult == 0, "invalid texture format"); if (levelSize < SST_TEXTURE_ALIGN) { GrLOD_t maxLod = lodIndex; /* Find the smallest level that naturally starts on an * alignment boundary. If this is larger than the current * mipmap chain's large lod then this we have to compute the * offset within this alignment unit. * * NB: This could be a table lookup, but I'm writing the * obvious code right now so that there aren't any * mystic #'s being pulled out of the recesses of my * colon. */ while(maxLod < GR_LOD_LOG2_256) { levelSize = (_grMipMapHostSize[aspectIndex][maxLod] * formatMult)>>3; // bits to bytes convertion if (levelSize >= SST_TEXTURE_ALIGN) break; // check on the Even/Odd mask to see if the mip-map affects this TMU if((maxLod & 1) ? (evenOdd & GR_MIPMAPLEVELMASK_ODD) : (evenOdd & GR_MIPMAPLEVELMASK_EVEN)) texOffset += levelSize; maxLod++; } /* maxLod is the index of the smallest level of this aspect * ratio that takes up at least a full alignment unit. We * reset the small lod to this so that we can compute the * offset for the 'large' levels in the mipmap chain. */ GR_ASSERT(maxLod != GR_LOD_LOG2_256); minLod = maxLod - 1; } } if (minLod < largeLod) { texOffset += _grTexTextureMemRequired(minLod + 1, largeLod, aspectRatio, format, evenOdd, FXFALSE, FXFALSE); } } /* Compute physical start address for the download. * * NB: This is going directly to the 2d lfb space rather than * through the texture port so we have to add in the actual hw * offset that the texture 'surface' starts at. */ baseAddress = (memInfo->tramOffset + startAddress + texOffset); } /* Do the download */ { const FxU32 bitsPerTexel = _grBitsPerTexel[format]; FxU32 width, formatSel, widthSel, max_s; /* * Interpretations: * formatSel: Chooses among 4, 8, 16, and 32-bit download procedures. * We want formatSel == log2(bitsPerTexel >> 2). * max_s: The width, measured in 32-bit units. */ switch(format) { case GR_TEXFMT_ARGB_CMP_FXT1: /* Minimum size for 4-bit compressed format mipmaps is 8x4. FXT1 */ formatSel = 0; width = _grMipMapHostWHCmp4Bit[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][0]; max_s = widthSel = (width >> 3); break; case GR_TEXFMT_ARGB_CMP_DXT1: /* Minimum size for DXT1 mipmaps is 8x4 (two 4x4 mipmaps side by side). */ formatSel = 0; width = _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][0]; max_s = widthSel = (width >> 3); break; case GR_TEXFMT_ARGB_CMP_DXT2: case GR_TEXFMT_ARGB_CMP_DXT3: case GR_TEXFMT_ARGB_CMP_DXT4: case GR_TEXFMT_ARGB_CMP_DXT5: /* Minimum size for 8-bit compressed format mipmaps is 4x4. DXT2,3,4,5 */ formatSel = 1; width = _grMipMapHostWHDXT[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][0]; widthSel = ((width == 8) ? 3 : (width >> 1)); max_s = (width >> 2); break; default: width =_grMipMapHostWH[G3_ASPECT_TRANSLATE(aspectRatio)][thisLod][0]; /* For 8,16,32-bit formats */ switch(bitsPerTexel) { case 32: formatSel = 3; max_s = widthSel = width; break; case 8: formatSel = 1; widthSel = ((width == 8) ? 3 : (width >> 1)); max_s = (width >> 2); break; /*case 4: GR_TEXFMT_ARGB_CMP_FXT1, GR_TEXFMT_ARGB_CMP_DXT1 are the only 4-bit format break;*/ case 16: default: formatSel = 2; max_s = widthSel = (width >> 1); break; } break; } if (max_s <= 0) max_s = 1; if (widthSel > 3) widthSel = 4; gc->stats.texBytes += max_s * (max_t - t + 1) * 4; (*((*gc->archDispatchProcs.texDownloadProcs)[formatSel][widthSel])) (gc, baseAddress, max_s, t, max_t, data); } } /* If this is a small lod level in a texture replacing texels that * are already loaded then it may be necessary to flush the old * texels from memory before any other rendering operation using * this texture is issued. Unconditionally flush these old texels * just in case rather than being too clever. * * The reason that we need to flush here even though we're not * going through the texture port is because it is perfectly * legal to source once and download over and over again. (See * chd for a funny SpecOps story). * * NB: The documented nop does not currently work on banshee which * is why we do the ~texBaseAddr crap along w/ the 2d nop. */ GR_TEX_FLUSH_POST(memInfo); } all_done: gc->stats.texDownloads++; return FXTRUE; #undef FN_NAME } /* grTexDownloadMipmapLevelPartial */ glide3x/h5/glide3/src/gthread.c0100700000175300010010000001066307725034670015562 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVE ** ** ** ** $Revision: 1.3.4.5 $ ** $Date: 2003/08/04 12:45:47 $ ** */ /* NOTE: This file is compiled to naught if we aren't running under Win32 */ #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #if defined( __WIN32__ ) #if (GLIDE_PLATFORM & GLIDE_OS_WIN32) #include #endif static CRITICAL_SECTION criticalSectionObject; static DWORD tlsIndex; static FxBool threadInit; static FxBool criticalSectionInit; void initThreadStorage( void ) { if ( !threadInit ) { threadInit = 1; _GlideRoot.tlsIndex = TlsAlloc(); } if ((_GlideRoot.OS == OS_WIN32_95) || (_GlideRoot.OS == OS_WIN32_98) || (_GlideRoot.OS == OS_WIN32_ME)) { _GlideRoot.tlsOffset = W95_TLS_INDEX_TO_OFFSET(_GlideRoot.tlsIndex); } else { _GlideRoot.tlsOffset = WNT_TLS_INDEX_TO_OFFSET(_GlideRoot.tlsIndex); } } /* initThreadStorage */ void setThreadValue( FxU32 value ) { GR_CHECK_F( "setThreadValue", !threadInit, "Thread storage not initialized\n" ); TlsSetValue( _GlideRoot.tlsIndex, (void*)value ); } #ifdef __GNUC__ FxU32 getThreadValueSLOW (void) { GR_CHECK_F( "getThreadValue", !threadInit, "Thread storage not initialized\n" ); return getThreadValueFast(); } #else #pragma warning (4:4035) /* No return value */ FxU32 getThreadValueSLOW( void ) { GR_CHECK_F( "getThreadValue", !threadInit, "Thread storage not initialized\n" ); #if 0 return (FxU32)TlsGetValue( _GlideRoot.tlsIndex ); #elif 1 __GR_GET_TLSC_VALUE(); #else __asm { mov esi, DWORD PTR fs:[WNT_TEB_PTR] add esi, DWORD PTR _GlideRoot.tlsOffset mov eax, DWORD PTR [esi] } #endif } #endif void freeThreadStorage( void ) { if( threadInit ) { TlsFree(_GlideRoot.tlsIndex); threadInit = 0; } } void initCriticalSection( void ) { if ( !criticalSectionInit ) { criticalSectionInit = 1; InitializeCriticalSection( &criticalSectionObject ); } } void beginCriticalSection( void ) { GR_CHECK_F( "beginCriticalSection", !criticalSectionInit, "Critical section not initialized\n" ); EnterCriticalSection( &criticalSectionObject ); } void endCriticalSection( void ) { GR_CHECK_F( "endCriticalSection", !criticalSectionInit, "Critical section not initialized\n" ); LeaveCriticalSection( &criticalSectionObject ); } #elif defined(macintosh) FxU32 _threadValueMacOS; void initThreadStorage(void) { } void setThreadValue( FxU32 value ) { _threadValueMacOS = value; } FxU32 getThreadValueSLOW( void ) { return _threadValueMacOS; } void freeThreadStorage( void ) { } void initCriticalSection(void) { } void beginCriticalSection(void) { } void endCriticalSection(void) { } #elif (GLIDE_PLATFORM & GLIDE_OS_UNIX) FxU32 threadValueLinux; void initThreadStorage(void) { } void setThreadValue( FxU32 value ) { threadValueLinux = value; } FxU32 getThreadValueSLOW( void ) { return threadValueLinux; } void initCriticalSection(void) { } void beginCriticalSection(void) { } void endCriticalSection(void) { } #elif defined(__DJGPP__) FxU32 threadValueDJGPP; void initThreadStorage(void) { } void setThreadValue( FxU32 value ) { threadValueDJGPP = value; } FxU32 getThreadValueSLOW( void ) { return threadValueDJGPP; } void initCriticalSection(void) { } void beginCriticalSection(void) { } void endCriticalSection(void) { } #else /* defined(__DJGPP__) */ # error "No thread synchronization/storage functions defined for this OS" #endif glide3x/h5/glide3/src/gu.c0100700000175300010010000002556107725034670014562 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gu.c,v 1.3.4.2 2003/06/05 08:23:54 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 8 7/18/98 12:31a Jdt ** Removed GUColorCombineFunction. ** ** 7 6/23/98 9:40a Peter ** fixed build ** ** 6 6/22/98 7:57p Jdt ** ** 5 6/22/98 5:42p Russp ** removed #include "fxinline.h" ** ** 3 1/30/98 4:27p Atai ** gufog* prototype ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 14 12/18/97 2:13p Peter * fogTable cataclysm * * 13 5/27/97 1:16p Peter * Basic cvg, w/o cmd fifo stuff. * * 12 5/21/97 6:05a Peter * * 11 3/09/97 10:31a Dow * Added GR_DIENTRY for di glide functions * * 10 3/05/97 9:36p Jdt * Added guEncodeRLE16 * * 9 12/23/96 1:37p Dow * chagnes for multiplatform glide ** */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #if (GLIDE_PLATFORM & GLIDE_HW_H3) #include "fxinline.h" #endif /* (GLIDE_PLATFORM & GLIDE_HW_H3) */ #if ( (GLIDE_PLATFORM & GLIDE_SST_HW) && (GLIDE_PLATFORM & GLIDE_HW_SST1) ) #include #endif /*--------------------------------------------------------------------------- ** guAlphaSource */ GR_DIENTRY(guAlphaSource, void, ( GrAlphaSource_t mode )) { GDBG_INFO(99,"guAlphaSource(%d)\n",mode); switch ( mode ) { case GR_ALPHASOURCE_CC_ALPHA: grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE, FXFALSE ); break; case GR_ALPHASOURCE_ITERATED_ALPHA: grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE ); break; case GR_ALPHASOURCE_TEXTURE_ALPHA: grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE ); break; case GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA: grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE ); break; default: GR_CHECK_F("grAlphaSource", 1, "unknown alpha source mode"); break; } /* xxx not needed at the moment, should update grFogxxx _grVerifyNeedForITAlpha(); */ } /* guAlphaSource */ /*--------------------------------------------------------------------------- ** guEndianSwapWords */ GR_DIENTRY(guEndianSwapWords, FxU32, ( FxU32 value )) { return ( ( value & 0xFFFF0000 ) >> 16 ) | ( value << 16 ); } /*--------------------------------------------------------------------------- ** guEndianSwapBytes */ GR_DIENTRY(guEndianSwapBytes, FxU16, ( FxU16 value )) { return ( ( value & 0xFF00 ) >> 8 ) | ( value << 8 ); } /*--------------------------------------------------------------------------- ** guFogTableIndexToW */ GR_DIENTRY(guFogTableIndexToW, float, ( int i )) { return (float)pow(2.0,3.0+(double)(i>>2)) / (8-(i&3)); } /*--------------------------------------------------------------------------- ** guFogGenerateExp */ GR_DIENTRY(guFogGenerateExp, void, ( GrFog_t *fogtable, float density )) { int i; float f; float scale; float dp; GDBG_INFO(99,"guFogGenerateExp(0x%x,%g)\n",fogtable,density); dp = density * guFogTableIndexToW( kInternalFogTableEntryCount - 1 ); scale = 1.0F / ( 1.0F - ( float ) exp( -dp ) ); for ( i = 0; i < kInternalFogTableEntryCount; i++ ) { dp = density * guFogTableIndexToW( i ); f = ( 1.0F - ( float ) exp( -dp ) ) * scale; if ( f > 1.0F ) f = 1.0F; else if ( f < 0.0F ) f = 0.0F; f *= 255.0F; fogtable[i] = ( GrFog_t ) f; } } /* guFogGenerateExp */ /*--------------------------------------------------------------------------- ** guFogGenerateExp2 */ GR_DIENTRY(guFogGenerateExp2, void, ( GrFog_t *fogtable, float density )) { int i; float f; float scale; float dp; GDBG_INFO(99,"guFogGenerateExp2(0x%x,%g)\n",fogtable,density); dp = density * guFogTableIndexToW( kInternalFogTableEntryCount - 1 ); scale = 1.0F / ( 1.0F - ( float ) exp( -( dp * dp ) ) ); for ( i = 0; i < kInternalFogTableEntryCount; i++ ) { dp = density * guFogTableIndexToW( i ); f = ( 1.0F - ( float ) exp( -( dp * dp ) ) ) * scale; if ( f > 1.0F ) f = 1.0F; else if ( f < 0.0F ) f = 0.0F; f *= 255.0F; fogtable[i] = ( GrFog_t ) f; } } /* guFogGenerateExp2 */ /*--------------------------------------------------------------------------- ** guFogGenerateLinear */ GR_DIENTRY(guFogGenerateLinear, void, ( GrFog_t *fogtable, float nearZ, float farZ )) { int i; float world_w; float f; GDBG_INFO(99,"guFogGenerateLinear(0x%x,%g,%g)\n",fogtable,nearZ,farZ); for ( i = 0; i < kInternalFogTableEntryCount; i++ ) { world_w = guFogTableIndexToW( i ); if ( world_w > 65535.0F ) world_w = 65535.0F; f = ( world_w - nearZ ) / ( farZ - nearZ ); if ( f > 1.0F ) f = 1.0F; else if ( f < 0.0F ) f = 0.0F; f *= 255.0F; fogtable[i] = ( GrFog_t ) f; } } /* guFogGenerateLinear */ /* ** setlevel */ static void setlevel( FxU16 *data, FxU16 color, int width, int height ) { int s, t; for ( t = 0; t < height; t++ ) { for ( s = 0; s < width; s++ ) { *data = color; data++; } } } /* setlevel */ /*--------------------------------------------------------------------------- ** guTexCreateColorMipMap */ GR_DIENTRY(guTexCreateColorMipMap, FxU16 *, ( void )) { FxU32 memrequired; FxU16 *data; FxU16 *start; GDBG_INFO(99,"guTexCreateColorMipMap()\n"); memrequired = 2 * ( 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2 + 1 * 1 ); start = data = malloc( memrequired ); if ( !data ) return 0; setlevel( data, 0xF800, 256, 256 ); setlevel( data += 256*256, 0x07e0, 128, 128 ); setlevel( data += 128*128, 0x001F, 64, 64 ); setlevel( data += 64*64, 0xFFFF, 32, 32); setlevel( data += 32*32, 0x0000, 16, 16 ); setlevel( data += 16*16, 0xF800, 8, 8); setlevel( data += 8*8, 0x07e0, 4, 4 ); setlevel( data += 4*4, 0x001f, 2, 2 ); setlevel( data += 2*2, 0xFFFF, 1, 1 ); return start; } /* guTexCreateColoMipMap */ /* GMT: this code used to be in the code above but I removed it for readability, the first section was case(1) the second section was a replacement for the simple 32-bit copy loop */ #if 0 /* GMT: from what I can tell its not bad to perform unaligned DWORD loads on a P5, so we use the case 2) all the time in fact, its twice as fast as doing aligned short copies */ if ((dstX ^ (((FxU32)src)>>1)) & 1) { /* case 1) a simple 16-bit copy loop */ for (x=0; x < w; x++) { GR_SET16(lfbPtr[x], ((FxU16 *)src)[x]); } } #endif #if 0 /* GMT: I tried to unroll the loop but for some reason the code scheduling was such that it was slower I think it had to do with the way the 2 mov instructions paired Perhaps they were unaligned in the cache? */ FxU32 a,b; FxU32 *s = (FxU32 *)src; FxU32 *d = lfbPtr; while (d < &lfbPtr[w-1]) { a = s[0]; b = s[1]; GR_SET(d[0], a); GR_SET(d[1], b); s += 2; d += 2; } if (w & 1) { GR_SET(d[0], s[0]); } #endif /*------------------------------------------------------------------- Function: guEncodeRle Date: 3/5/96 Implementor(s): jdt Library: Glide Utilities Description: Encode an RGB565 image into RLE16 format Arguments: dst - destination rle image data ( NULL for bytecount only ) src - source rgb565 image data width - width of source data height - height of source data Return: number of bytes in encoded rle image -------------------------------------------------------------------*/ GR_ENTRY( guEncodeRLE16, int, ( void *dst, void *src, FxU32 width, FxU32 height )) { int byteCount = 0; int sourceImageSizeInWords; FxU16 *srcPixels; FxU32 *dstPixels; sourceImageSizeInWords = width * height; srcPixels = src; if ( dst ) { dstPixels = dst; while( sourceImageSizeInWords-- ) { short length = 1; short color = *srcPixels; int lookAhead = 1; while( (sourceImageSizeInWords-length)&& (color == srcPixels[lookAhead]) ) { length++; lookAhead++; } *dstPixels = ((((FxU32)length)<<16) | ((FxU32)color)); dstPixels++; byteCount+=4; srcPixels+=length; sourceImageSizeInWords-=length; } } else { while( sourceImageSizeInWords-- ) { short length = 1; short color = *srcPixels; int lookAhead = 1; while( (sourceImageSizeInWords-length)&& (color == srcPixels[lookAhead]) ) { length++; lookAhead++; } byteCount+=4; srcPixels+=length; sourceImageSizeInWords-=length; } } return byteCount; } glide3x/h5/glide3/src/gxdraw.c0100700000175300010010000011567007725034670015444 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gxdraw.c,v 1.3.4.3 2003/07/07 23:29:06 koolsmoky Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 15 8/16/99 11:18a Adamb ** Merged in V3_OEM_100 fixes ** ** 14 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 13 6/03/99 12:13p Kcd ** Modified to allow me to use parts of this file when assembly triangle ** setup is being used. ** ** 12 3/02/99 2:08p Peter ** 2kx2k check for c 'setup' ** ** 11 2/18/99 4:12p Kcd ** Fixed (lack of) return value from C triangle setup. ** Fixed non-portable array initializer. ** ** 10 1/06/99 11:30a Peter ** cleanup trinalge dispatch code ** ** 9 12/03/98 11:26p Dow ** ** 8 7/01/98 8:40a Jdt ** remvoed gc arg from trisetup funcs ** ** 7 8/03/98 6:42a Jdt ** move stats, pool.ftemp* into GC from global location ** ** 6 7/16/98 8:19a Jdt ** fxcmd.h ** ** 4 4/22/98 4:57p Peter ** glide2x merge ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 60 12/01/97 6:13p Peter * non-packet3 tsu triangles ooz vs z * * 59 11/21/97 3:20p Peter * direct writes tsu registers * * 58 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 57 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 56 11/12/97 9:54p Peter * fixed all the effage from new config * * 55 11/03/97 4:38p Peter * yapc fix * * 54 11/01/97 10:01a Peter * tri dispatch stuff * * 53 10/29/97 2:45p Peter * C version of Taco's packing code * * 52 10/27/97 5:59p Peter * removed some debugging code * * 51 10/21/97 3:22p Peter * hand pack rgb * * 50 10/19/97 12:51p Peter * no tsu happiness * * 49 10/19/97 10:59a Peter * fixed p1 tsu writes * * 48 10/17/97 3:15p Peter * removed unused addr field from datalist * * 47 10/17/97 10:15a Peter * packed rgb state cleanup * * 46 10/16/97 5:33p Peter * argb != rgba * * 45 10/16/97 3:40p Peter * packed rgb * * 44 10/16/97 10:31a Peter * fixed hoopti tsu-subtractor unsorted * * 43 10/15/97 5:53p Peter * hoopti tri compare code * * 42 10/10/97 4:33p Peter * non-packet3 tsu triangles * * 41 10/08/97 5:19p Peter * optinally clamp only texture params * * 40 10/08/97 11:32a Peter * pre-computed packet headers for packet 3 * * 39 9/20/97 4:42p Peter * tri_setf fixup/big fifo * * 38 9/16/97 2:50p Peter * fixed watcom unhappiness w/ static initializers * * 37 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 36 9/10/97 10:13p Peter * fifo logic from GaryT, non-normalized fp first cut * * 35 9/03/97 2:11p Peter * start gdbg_info cleanup, fixed zero area no-tsu triangle effage * * 34 9/01/97 3:19p Peter * no-tsu w from vertex not tmuvtx * * 33 8/31/97 4:06p Peter * no tsu fix * * 32 8/31/97 12:04p Peter * hacked no-tsu code * * 31 7/25/97 11:40a Peter * removed dHalf, change field name to match real use for cvg * * 30 6/30/97 3:22p Peter * cmd fifo sanity * * 29 6/24/97 4:02p Peter * proper cmd fifo placement * * 28 6/23/97 4:43p Peter * cleaned up #defines etc for a nicer tree ** */ #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #ifdef GDBG_INFO_ON /* Some debugging information */ static char *indexNames[] = { "GR_VERTEX_X_OFFSET", /* 0 */ "GR_VERTEX_Y_OFFSET", /* 1 */ "GR_VERTEX_Z_OFFSET", /* 2 */ "GR_VERTEX_R_OFFSET", /* 3 */ "GR_VERTEX_G_OFFSET", /* 4 */ "GR_VERTEX_B_OFFSET", /* 5 */ "GR_VERTEX_OOZ_OFFSET", /* 6 */ "GR_VERTEX_A_OFFSET", /* 7 */ "GR_VERTEX_OOW_OFFSET", /* 8 */ "GR_VERTEX_SOW_TMU0_OFFSET", /* 9 */ "GR_VERTEX_TOW_TMU0_OFFSET", /* 10 */ "GR_VERTEX_OOW_TMU0_OFFSET", /* 11 */ "GR_VERTEX_SOW_TMU1_OFFSET", /* 12 */ "GR_VERTEX_TOW_TMU1_OFFSET", /* 13 */ "GR_VERTEX_OOW_TMU1_OFFSET" /* 14 */ }; #endif /* GDBG_INFO_ON */ #if GLIDE_USE_C_TRISETUP static FxI32 _grTriCull(const void* a, const void* b, const void* c) { #define FN_NAME "_grCullTri" GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X, 0x%X, 0x%X)\n", a, b, c); { const FxI32 xindex = (gc->state.vData.vertexInfo.offset >> 2), yindex = xindex + 1; const float *fa = (const float*)a + xindex, *fb = (const float*)b + xindex, *fc = (const float*)c + xindex; const float dxAB = fa[xindex] - fb[xindex], dxBC = fb[xindex] - fc[xindex], dyAB = fa[yindex] - fb[yindex], dyBC = fb[yindex] - fc[yindex], area = dxAB * dyBC - dxBC * dyAB; { const FxI32 j = *(FxI32*)&area; const FxU32 culltest = (gc->state.cull_mode << 31UL); /* Zero-area triangles are BAD!! */ if ((j & 0x7FFFFFFF) == 0) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", (fa[0]), (fa[1]), (fb[0]), (fb[1]), (fc[0]), (fc[1]), area, gc->state.cull_mode, culltest); return 0; } /* Backface culling, use sign bit as test */ if ((gc->state.cull_mode != GR_CULL_DISABLE) && (((FxI32)(j ^ culltest)) >= 0)) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", (fa[0]), (fa[1]), (fb[0]), (fb[1]), (fc[0]), (fc[1]), area, gc->state.cull_mode, culltest); return -1; } } return 1; } GR_END(); #undef FN_NAME } static FxI32 internal_trisetup(const char* FN_NAME, const FxBool cullP, const FxBool validStateP, const void* a, const void* b, const void* c) { GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X, 0x%X, 0x%X)\n", a, b, c); /* Check to see if the state has to be flushed */ if (!validStateP) GR_FLUSH_STATE(); /* Pass the current culling mode? */ if (cullP) { const FxI32 cullVal = _grTriCull(a, b, c); if (cullVal <= 0) return cullVal; } /* Validate parameter coordinates */ { const FxI32 xindex = (gc->state.vData.vertexInfo.offset >> 2), yindex = xindex + 1; const float *fa = (const float*)a + xindex, *fb = (const float*)b + xindex, *fc = (const float*)c + xindex; const float aX = fa[xindex], aY = fa[yindex], bX = fb[xindex], bY = fb[yindex], cX = fc[xindex], cY = fc[yindex]; #define kDimThreshX 2048.0f #define kDimThreshY 2048.0f GR_ASSERT((fabs(aX) < kDimThreshX) && (fabs(aY) < kDimThreshY)); GR_ASSERT((fabs(bX) < kDimThreshX) && (fabs(bY) < kDimThreshY)); GR_ASSERT((fabs(cX) < kDimThreshX) && (fabs(cY) < kDimThreshY)); #undef kDimThreshX #undef kDimThreshY } /* Send triangle parameters */ #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP { FxU32 dataElem, i; GR_SET_EXPECTED_SIZE(gc->curTriSize, 1); TRI_STRIP_BEGIN(kSetupStrip, 3, gc->curVertexSize, SSTCP_PKT3_BDDBDD); { TRI_SETF(FARRAY(a, 0)); TRI_SETF(FARRAY(a, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } TRI_SETF(FARRAY(b, 0)); TRI_SETF(FARRAY(b, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(b, i)); dataElem++; i = gc->tsuDataList[dataElem]; } TRI_SETF(FARRAY(c, 0)); TRI_SETF(FARRAY(c, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; while (i != GR_DLIST_END) { TRI_SETF(FARRAY(c, i)); dataElem++; i = gc->tsuDataList[dataElem]; } TRI_END; GR_CHECK_SIZE(); } } #else { GR_DCL_HW; int vectorIndex; FxU32 sMode = (gc->cmdTransportInfo.paramMask >> SSTCP_PKT3_PMASK_SHIFT); FxU32 paramMask = (sMode & 0xFF); FxU32 paramCount; const float* vectorArray[3]; vectorArray[0] = (const float *)a; vectorArray[1] = (const float *)b; vectorArray[2] = (const float *)c; /* Convert packet 3 paramMask into sMode format */ sMode = (paramMask | ((sMode & 0xF000) << 4)); { const FxBool hasColor = ((sMode & 0x01) != 0); const FxBool hasAlpha = ((sMode & 0x02) != 0); const FxBool hasZ = ((sMode & 0x04) != 0); const FxBool hasWb = ((sMode & 0x08) != 0); const FxBool hasW0 = ((sMode & 0x10) != 0); const FxBool hasST0 = ((sMode & 0x20) != 0); const FxBool hasW1 = ((sMode & 0x40) != 0); const FxBool hasST1 = ((sMode & 0x80) != 0); /* We always send vertex XY */ paramCount = 2; paramMask = 0x03; /* Build parameter data for reg group packet */ #if GLIDE_PACKED_RGB if (hasColor || hasAlpha) { paramCount += 1; paramMask |= 0x04; } #else /* !GLIDE_PACKED_RGB */ if (hasColor) { paramCount += 3; paramMask |= 0x38; } if (hasAlpha) { paramCount += 1; paramMask |= 0x40; } #endif /* !GLIDE_PACKED_RGB */ if (hasZ) { paramCount += 1; paramMask |= 0x80; } if (hasWb) { paramCount += 1; paramMask |= 0x100; } if (hasW0) { paramCount += 1; paramMask |= 0x200; } if (hasST0) { paramCount += 2; paramMask |= 0xC00; } if (hasW1) { paramCount += 1; paramMask |= 0x1000; } if (hasST1) { paramCount += 2; paramMask |= 0x6000; } /* Set mode once for teh whole triangle */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, sSetupMode, sMode); GR_CHECK_SIZE(); for(vectorIndex = 0; vectorIndex < sizeof(vectorArray) / sizeof(float*); vectorIndex++) { FxU32 dataElem, i; const float* a = (const float *)vectorArray[vectorIndex]; REG_GROUP_BEGIN(BROADCAST_ID, sVx, paramCount, paramMask); { REG_GROUP_SETF(hw, sVx, FARRAY(a, 0)); REG_GROUP_SETF(hw, sVy, FARRAY(a, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; if (hasColor) { REG_GROUP_SETF(hw, sRed, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sGreen, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sBlue, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasAlpha) { REG_GROUP_SETF(hw, sAlpha, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasZ) { REG_GROUP_SETF(hw, sVz, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasWb) { REG_GROUP_SETF(hw, sOowfbi, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU0 */ if (hasW0) { REG_GROUP_SETF(hw, sOow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST0) { REG_GROUP_SETF(hw, sSow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU1 */ if (hasW1) { REG_GROUP_SETF(hw, sOow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST1) { REG_GROUP_SETF(hw, sSow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } REG_GROUP_END(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); if (vectorIndex == 0) { GR_SET(BROADCAST_ID, hw, sBeginTriCMD, 0); } else { GR_SET(BROADCAST_ID, hw, sDrawTriCMD, 0); } GR_CHECK_SIZE(); } } } #endif GR_END(); return FXTRUE; } FxI32 FX_CALL _trisetup_Default_win_cull_invalid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_cull_invalid" #ifdef FAST_C_CLIP AMG_GR_BEGIN_NOFIFOCHECK(); GR_FLUSH_STATE(); cullVal=_grTriCull(a,b,c); if(cullVal <= 0) return cullVal; /* Send triangle parameters */ #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP { FxU32 dataElem,i,i2,nextfifo; unsigned long *casta,*castb,*castc,lenght,Loop; FxU32* tPackPtr; FxU32 packetVal; AMG_GR_SET_EXPECTED_SIZE(gc->curTriSize, 1); AMG_TRI_STRIP_BEGIN(tPackPtr,packetVal); i=gc->curVertexParam; Loop=i-2; i2=i+i; lenght=i-2; nextfifo=6+lenght+lenght; // lenght of vertex params *2 AMG_TRISETXYNOADD(((unsigned long*)a),0); AMG_TRISETXYNOADD(((unsigned long*)b),i); AMG_TRISETXYNOADD(((unsigned long*)c),i2); dataElem=0; i+=2; i2+=2; casta=(unsigned long*)a; castb=(unsigned long*)b; castc=(unsigned long*)c; while(Loop!=0) { AMG_TRISETPARAMNOADD(casta[gc->tsuDataListByte[dataElem]],2); AMG_TRISETPARAMNOADD(castb[gc->tsuDataListByte[dataElem]],i); AMG_TRISETPARAMNOADD(castc[gc->tsuDataListByte[dataElem]],i2); AMG_TRIFIFOADD dataElem++; Loop--; } AMG_TRIFIFOADDVALUE(nextfifo) AMG_TRI_END(tPackPtr) } #else { GR_DCL_HW; int vectorIndex; FxU32 sMode = (gc->cmdTransportInfo.paramMask >> SSTCP_PKT3_PMASK_SHIFT); FxU32 paramMask = (sMode & 0xFF); FxU32 paramCount; const float* vectorArray[3]; vectorArray[0] = (const float *)a; vectorArray[1] = (const float *)b; vectorArray[2] = (const float *)c; /* Convert packet 3 paramMask into sMode format */ sMode = (paramMask | ((sMode & 0xF000) << 4)); { const FxBool hasColor = ((sMode & 0x01) != 0); const FxBool hasAlpha = ((sMode & 0x02) != 0); const FxBool hasZ = ((sMode & 0x04) != 0); const FxBool hasWb = ((sMode & 0x08) != 0); const FxBool hasW0 = ((sMode & 0x10) != 0); const FxBool hasST0 = ((sMode & 0x20) != 0); const FxBool hasW1 = ((sMode & 0x40) != 0); const FxBool hasST1 = ((sMode & 0x80) != 0); /* We always send vertex XY */ paramCount = 2; paramMask = 0x03; /* Build parameter data for reg group packet */ #if GLIDE_PACKED_RGB if (hasColor || hasAlpha) { paramCount += 1; paramMask |= 0x04; } #else /* !GLIDE_PACKED_RGB */ if (hasColor) { paramCount += 3; paramMask |= 0x38; } if (hasAlpha) { paramCount += 1; paramMask |= 0x40; } #endif /* !GLIDE_PACKED_RGB */ if (hasZ) { paramCount += 1; paramMask |= 0x80; } if (hasWb) { paramCount += 1; paramMask |= 0x100; } if (hasW0) { paramCount += 1; paramMask |= 0x200; } if (hasST0) { paramCount += 2; paramMask |= 0xC00; } if (hasW1) { paramCount += 1; paramMask |= 0x1000; } if (hasST1) { paramCount += 2; paramMask |= 0x6000; } /* Set mode once for teh whole triangle */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, sSetupMode, sMode); GR_CHECK_SIZE(); for(vectorIndex = 0; vectorIndex < sizeof(vectorArray) / sizeof(float*); vectorIndex++) { FxU32 dataElem, i; const float* a = (const float *)vectorArray[vectorIndex]; REG_GROUP_BEGIN(BROADCAST_ID, sVx, paramCount, paramMask); { REG_GROUP_SETF(hw, sVx, FARRAY(a, 0)); REG_GROUP_SETF(hw, sVy, FARRAY(a, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; if (hasColor) { REG_GROUP_SETF(hw, sRed, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sGreen, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sBlue, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasAlpha) { REG_GROUP_SETF(hw, sAlpha, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasZ) { REG_GROUP_SETF(hw, sVz, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasWb) { REG_GROUP_SETF(hw, sOowfbi, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU0 */ if (hasW0) { REG_GROUP_SETF(hw, sOow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST0) { REG_GROUP_SETF(hw, sSow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU1 */ if (hasW1) { REG_GROUP_SETF(hw, sOow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST1) { REG_GROUP_SETF(hw, sSow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } REG_GROUP_END(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); if (vectorIndex == 0) { GR_SET(BROADCAST_ID, hw, sBeginTriCMD, 0); } else { GR_SET(BROADCAST_ID, hw, sDrawTriCMD, 0); } GR_CHECK_SIZE(); } } } #endif GR_END(); return FXTRUE; #else /* !FAST_C_CLIP */ return internal_trisetup(FN_NAME, FXTRUE, FXFALSE, a, b, c); #endif /* !FAST_C_CLIP */ #undef FN_NAME } FxI32 FX_CALL _trisetup_Default_win_cull_valid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_cull_valid" #ifdef FAST_C_CLIP AMG_GR_BEGIN_NOFIFOCHECK(); cullVal=_grTriCull(a,b,c); if(cullVal <= 0) return cullVal; #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP { FxU32 dataElem,i,i2,nextfifo; unsigned long *casta,*castb,*castc,lenght,Loop; FxU32* tPackPtr; FxU32 packetVal; AMG_GR_SET_EXPECTED_SIZE(gc->curTriSize, 1); AMG_TRI_STRIP_BEGIN(tPackPtr,packetVal); i=gc->curVertexParam; Loop=i-2; i2=i+i; lenght=i-2; nextfifo=6+lenght+lenght; // lenght of vertex params *2 AMG_TRISETXYNOADD(((unsigned long*)a),0); AMG_TRISETXYNOADD(((unsigned long*)b),i); AMG_TRISETXYNOADD(((unsigned long*)c),i2); dataElem=0; i+=2; i2+=2; casta=(unsigned long*)a; castb=(unsigned long*)b; castc=(unsigned long*)c; while(Loop!=0) { AMG_TRISETPARAMNOADD(casta[gc->tsuDataListByte[dataElem]],2); AMG_TRISETPARAMNOADD(castb[gc->tsuDataListByte[dataElem]],i); AMG_TRISETPARAMNOADD(castc[gc->tsuDataListByte[dataElem]],i2); AMG_TRIFIFOADD dataElem++; Loop--; } AMG_TRIFIFOADDVALUE(nextfifo) AMG_TRI_END(tPackPtr) } #else { GR_DCL_HW; int vectorIndex; FxU32 sMode = (gc->cmdTransportInfo.paramMask >> SSTCP_PKT3_PMASK_SHIFT); FxU32 paramMask = (sMode & 0xFF); FxU32 paramCount; const float* vectorArray[3]; vectorArray[0] = (const float *)a; vectorArray[1] = (const float *)b; vectorArray[2] = (const float *)c; /* Convert packet 3 paramMask into sMode format */ sMode = (paramMask | ((sMode & 0xF000) << 4)); { const FxBool hasColor = ((sMode & 0x01) != 0); const FxBool hasAlpha = ((sMode & 0x02) != 0); const FxBool hasZ = ((sMode & 0x04) != 0); const FxBool hasWb = ((sMode & 0x08) != 0); const FxBool hasW0 = ((sMode & 0x10) != 0); const FxBool hasST0 = ((sMode & 0x20) != 0); const FxBool hasW1 = ((sMode & 0x40) != 0); const FxBool hasST1 = ((sMode & 0x80) != 0); /* We always send vertex XY */ paramCount = 2; paramMask = 0x03; /* Build parameter data for reg group packet */ #if GLIDE_PACKED_RGB if (hasColor || hasAlpha) { paramCount += 1; paramMask |= 0x04; } #else /* !GLIDE_PACKED_RGB */ if (hasColor) { paramCount += 3; paramMask |= 0x38; } if (hasAlpha) { paramCount += 1; paramMask |= 0x40; } #endif /* !GLIDE_PACKED_RGB */ if (hasZ) { paramCount += 1; paramMask |= 0x80; } if (hasWb) { paramCount += 1; paramMask |= 0x100; } if (hasW0) { paramCount += 1; paramMask |= 0x200; } if (hasST0) { paramCount += 2; paramMask |= 0xC00; } if (hasW1) { paramCount += 1; paramMask |= 0x1000; } if (hasST1) { paramCount += 2; paramMask |= 0x6000; } /* Set mode once for teh whole triangle */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, sSetupMode, sMode); GR_CHECK_SIZE(); for(vectorIndex = 0; vectorIndex < sizeof(vectorArray) / sizeof(float*); vectorIndex++) { FxU32 dataElem, i; const float* a = (const float *)vectorArray[vectorIndex]; REG_GROUP_BEGIN(BROADCAST_ID, sVx, paramCount, paramMask); { REG_GROUP_SETF(hw, sVx, FARRAY(a, 0)); REG_GROUP_SETF(hw, sVy, FARRAY(a, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; if (hasColor) { REG_GROUP_SETF(hw, sRed, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sGreen, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sBlue, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasAlpha) { REG_GROUP_SETF(hw, sAlpha, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasZ) { REG_GROUP_SETF(hw, sVz, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasWb) { REG_GROUP_SETF(hw, sOowfbi, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU0 */ if (hasW0) { REG_GROUP_SETF(hw, sOow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST0) { REG_GROUP_SETF(hw, sSow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU1 */ if (hasW1) { REG_GROUP_SETF(hw, sOow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST1) { REG_GROUP_SETF(hw, sSow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } REG_GROUP_END(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); if (vectorIndex == 0) { GR_SET(BROADCAST_ID, hw, sBeginTriCMD, 0); } else { GR_SET(BROADCAST_ID, hw, sDrawTriCMD, 0); } GR_CHECK_SIZE(); } } } #endif GR_END(); return FXTRUE; #else /* !FAST_C_CLIP */ return internal_trisetup(FN_NAME, FXTRUE, FXTRUE, a, b, c); #endif /* !FAST_C_CLIP */ #undef FN_NAME } FxI32 FX_CALL _trisetup_Default_win_nocull_invalid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_nocull_invalid" #ifdef FAST_C_CLIP AMG_GR_BEGIN_NOFIFOCHECK(); /* Pass the current culling mode? */ GR_FLUSH_STATE(); /* Send triangle parameters */ #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP { FxU32 dataElem,i,i2,nextfifo; unsigned long *casta,*castb,*castc,lenght,Loop; FxU32* tPackPtr; FxU32 packetVal; AMG_GR_SET_EXPECTED_SIZE(gc->curTriSize, 1); AMG_TRI_STRIP_BEGIN(tPackPtr,packetVal); i=gc->curVertexParam; Loop=i-2; i2=i+i; lenght=i-2; nextfifo=6+lenght+lenght; // lenght of vertex params *2 AMG_TRISETXYNOADD(((unsigned long*)a),0); AMG_TRISETXYNOADD(((unsigned long*)b),i); AMG_TRISETXYNOADD(((unsigned long*)c),i2); dataElem=0; i+=2; i2+=2; casta=(unsigned long*)a; castb=(unsigned long*)b; castc=(unsigned long*)c; while(Loop!=0) { AMG_TRISETPARAMNOADD(casta[gc->tsuDataListByte[dataElem]],2); AMG_TRISETPARAMNOADD(castb[gc->tsuDataListByte[dataElem]],i); AMG_TRISETPARAMNOADD(castc[gc->tsuDataListByte[dataElem]],i2); AMG_TRIFIFOADD dataElem++; Loop--; } AMG_TRIFIFOADDVALUE(nextfifo) AMG_TRI_END(tPackPtr) } #else { GR_DCL_HW; int vectorIndex; FxU32 sMode = (gc->cmdTransportInfo.paramMask >> SSTCP_PKT3_PMASK_SHIFT); FxU32 paramMask = (sMode & 0xFF); FxU32 paramCount; const float* vectorArray[3]; vectorArray[0] = (const float *)a; vectorArray[1] = (const float *)b; vectorArray[2] = (const float *)c; /* Convert packet 3 paramMask into sMode format */ sMode = (paramMask | ((sMode & 0xF000) << 4)); { const FxBool hasColor = ((sMode & 0x01) != 0); const FxBool hasAlpha = ((sMode & 0x02) != 0); const FxBool hasZ = ((sMode & 0x04) != 0); const FxBool hasWb = ((sMode & 0x08) != 0); const FxBool hasW0 = ((sMode & 0x10) != 0); const FxBool hasST0 = ((sMode & 0x20) != 0); const FxBool hasW1 = ((sMode & 0x40) != 0); const FxBool hasST1 = ((sMode & 0x80) != 0); /* We always send vertex XY */ paramCount = 2; paramMask = 0x03; /* Build parameter data for reg group packet */ #if GLIDE_PACKED_RGB if (hasColor || hasAlpha) { paramCount += 1; paramMask |= 0x04; } #else /* !GLIDE_PACKED_RGB */ if (hasColor) { paramCount += 3; paramMask |= 0x38; } if (hasAlpha) { paramCount += 1; paramMask |= 0x40; } #endif /* !GLIDE_PACKED_RGB */ if (hasZ) { paramCount += 1; paramMask |= 0x80; } if (hasWb) { paramCount += 1; paramMask |= 0x100; } if (hasW0) { paramCount += 1; paramMask |= 0x200; } if (hasST0) { paramCount += 2; paramMask |= 0xC00; } if (hasW1) { paramCount += 1; paramMask |= 0x1000; } if (hasST1) { paramCount += 2; paramMask |= 0x6000; } /* Set mode once for teh whole triangle */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, sSetupMode, sMode); GR_CHECK_SIZE(); for(vectorIndex = 0; vectorIndex < sizeof(vectorArray) / sizeof(float*); vectorIndex++) { FxU32 dataElem, i; const float* a = (const float *)vectorArray[vectorIndex]; REG_GROUP_BEGIN(BROADCAST_ID, sVx, paramCount, paramMask); { REG_GROUP_SETF(hw, sVx, FARRAY(a, 0)); REG_GROUP_SETF(hw, sVy, FARRAY(a, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; if (hasColor) { REG_GROUP_SETF(hw, sRed, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sGreen, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sBlue, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasAlpha) { REG_GROUP_SETF(hw, sAlpha, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasZ) { REG_GROUP_SETF(hw, sVz, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasWb) { REG_GROUP_SETF(hw, sOowfbi, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU0 */ if (hasW0) { REG_GROUP_SETF(hw, sOow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST0) { REG_GROUP_SETF(hw, sSow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU1 */ if (hasW1) { REG_GROUP_SETF(hw, sOow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST1) { REG_GROUP_SETF(hw, sSow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } REG_GROUP_END(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); if (vectorIndex == 0) { GR_SET(BROADCAST_ID, hw, sBeginTriCMD, 0); } else { GR_SET(BROADCAST_ID, hw, sDrawTriCMD, 0); } GR_CHECK_SIZE(); } } } #endif GR_END(); return FXTRUE; #else /* !FAST_C_CLIP */ return internal_trisetup(FN_NAME, FXFALSE, FXFALSE, a, b, c); #endif /* !FAST_C_CLIP */ #undef FN_NAME } FxI32 FX_CALL _trisetup_Default_win_nocull_valid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_nocull_valid" #ifdef FAST_C_CLIP AMG_GR_BEGIN_NOFIFOCHECK(); /* Send triangle parameters */ #if GLIDE_HW_TRI_SETUP && GLIDE_PACKET3_TRI_SETUP { FxU32 dataElem,i,i2,nextfifo; unsigned long *casta,*castb,*castc,lenght,Loop; FxU32* tPackPtr; FxU32 packetVal; AMG_GR_SET_EXPECTED_SIZE(gc->curTriSize, 1); AMG_TRI_STRIP_BEGIN(tPackPtr,packetVal); i=gc->curVertexParam; Loop=i-2; i2=i+i; lenght=i-2; nextfifo=6+lenght+lenght; // lenght of vertex params *2 AMG_TRISETXYNOADD(((unsigned long*)a),0); AMG_TRISETXYNOADD(((unsigned long*)b),i); AMG_TRISETXYNOADD(((unsigned long*)c),i2); dataElem=0; i+=2; i2+=2; casta=(unsigned long*)a; castb=(unsigned long*)b; castc=(unsigned long*)c; while(Loop!=0) { AMG_TRISETPARAMNOADD(casta[gc->tsuDataListByte[dataElem]],2); AMG_TRISETPARAMNOADD(castb[gc->tsuDataListByte[dataElem]],i); AMG_TRISETPARAMNOADD(castc[gc->tsuDataListByte[dataElem]],i2); AMG_TRIFIFOADD dataElem++; Loop--; } AMG_TRIFIFOADDVALUE(nextfifo) AMG_TRI_END(tPackPtr) } #else { GR_DCL_HW; int vectorIndex; FxU32 sMode = (gc->cmdTransportInfo.paramMask >> SSTCP_PKT3_PMASK_SHIFT); FxU32 paramMask = (sMode & 0xFF); FxU32 paramCount; const float* vectorArray[3]; vectorArray[0] = (const float *)a; vectorArray[1] = (const float *)b; vectorArray[2] = (const float *)c; /* Convert packet 3 paramMask into sMode format */ sMode = (paramMask | ((sMode & 0xF000) << 4)); { const FxBool hasColor = ((sMode & 0x01) != 0); const FxBool hasAlpha = ((sMode & 0x02) != 0); const FxBool hasZ = ((sMode & 0x04) != 0); const FxBool hasWb = ((sMode & 0x08) != 0); const FxBool hasW0 = ((sMode & 0x10) != 0); const FxBool hasST0 = ((sMode & 0x20) != 0); const FxBool hasW1 = ((sMode & 0x40) != 0); const FxBool hasST1 = ((sMode & 0x80) != 0); /* We always send vertex XY */ paramCount = 2; paramMask = 0x03; /* Build parameter data for reg group packet */ #if GLIDE_PACKED_RGB if (hasColor || hasAlpha) { paramCount += 1; paramMask |= 0x04; } #else /* !GLIDE_PACKED_RGB */ if (hasColor) { paramCount += 3; paramMask |= 0x38; } if (hasAlpha) { paramCount += 1; paramMask |= 0x40; } #endif /* !GLIDE_PACKED_RGB */ if (hasZ) { paramCount += 1; paramMask |= 0x80; } if (hasWb) { paramCount += 1; paramMask |= 0x100; } if (hasW0) { paramCount += 1; paramMask |= 0x200; } if (hasST0) { paramCount += 2; paramMask |= 0xC00; } if (hasW1) { paramCount += 1; paramMask |= 0x1000; } if (hasST1) { paramCount += 2; paramMask |= 0x6000; } /* Set mode once for teh whole triangle */ GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(BROADCAST_ID, hw, sSetupMode, sMode); GR_CHECK_SIZE(); for(vectorIndex = 0; vectorIndex < sizeof(vectorArray) / sizeof(float*); vectorIndex++) { FxU32 dataElem, i; const float* a = (const float *)vectorArray[vectorIndex]; REG_GROUP_BEGIN(BROADCAST_ID, sVx, paramCount, paramMask); { REG_GROUP_SETF(hw, sVx, FARRAY(a, 0)); REG_GROUP_SETF(hw, sVy, FARRAY(a, sizeof(float))); dataElem = 0; i = gc->tsuDataList[dataElem]; if (hasColor) { REG_GROUP_SETF(hw, sRed, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sGreen, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sBlue, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasAlpha) { REG_GROUP_SETF(hw, sAlpha, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasZ) { REG_GROUP_SETF(hw, sVz, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasWb) { REG_GROUP_SETF(hw, sOowfbi, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU0 */ if (hasW0) { REG_GROUP_SETF(hw, sOow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST0) { REG_GROUP_SETF(hw, sSow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow0, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } /* TMU1 */ if (hasW1) { REG_GROUP_SETF(hw, sOow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } if (hasST1) { REG_GROUP_SETF(hw, sSow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; REG_GROUP_SETF(hw, sTow1, FARRAY(a, i)); dataElem++; i = gc->tsuDataList[dataElem]; } } REG_GROUP_END(); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); if (vectorIndex == 0) { GR_SET(BROADCAST_ID, hw, sBeginTriCMD, 0); } else { GR_SET(BROADCAST_ID, hw, sDrawTriCMD, 0); } GR_CHECK_SIZE(); } } } #endif GR_END(); return FXTRUE; #else /* !FAST_C_CLIP */ return internal_trisetup(FN_NAME, FXFALSE, FXTRUE, a, b, c); #endif /* !FAST_C_CLIP */ #undef FN_NAME } #endif FxI32 FX_CALL _vptrisetup_cull(const void* a, const void* b, const void* c) { #define FN_NAME "_vptrisetup_cull" float *vlist[3]; GR_BEGIN_NOFIFOCHECK_RET(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X, 0x%X, 0x%X)\n", a, b, c); vlist[0] = (float *)a; vlist[1] = (float *)b; vlist[2] = (float *)c; (*gc->archDispatchProcs.drawTrianglesProc)(GR_VTX_PTR_ARRAY, 3, vlist); GR_END(); return 1; #undef FN_NAME } glide3x/h5/glide3/src/gxdraw_ppc.c0100700000175300010010000003320707725034670016301 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/gxdraw_ppc.c,v 1.3 2000/11/15 23:32:53 joseph Exp $ ** $Log: ** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 1 7/30/99 1:12p Kcd ** Optimized trisetup for PowerPC (C). ** ** 14 7/14/99 9:39a Atai ** direct register write for glide3x ** test04 can do 4 sample aa (2 chips) ** ** 13 6/03/99 12:13p Kcd ** Modified to allow me to use parts of this file when assembly triangle ** setup is being used. ** ** 12 3/02/99 2:08p Peter ** 2kx2k check for c 'setup' ** ** 11 2/18/99 4:12p Kcd ** Fixed (lack of) return value from C triangle setup. ** Fixed non-portable array initializer. ** ** 10 1/06/99 11:30a Peter ** cleanup trinalge dispatch code ** ** 9 12/03/98 11:26p Dow ** ** 8 7/01/98 8:40a Jdt ** remvoed gc arg from trisetup funcs ** ** 7 8/03/98 6:42a Jdt ** move stats, pool.ftemp* into GC from global location ** ** 6 7/16/98 8:19a Jdt ** fxcmd.h ** ** 4 4/22/98 4:57p Peter ** glide2x merge ** ** 3 1/26/98 11:30a Atai ** update to new glide.h ** ** 2 1/22/98 10:35a Atai ** 1. introduce GLIDE_VERSION, g3\glide.h, g3\glideutl.h, g2\glide.h, ** g2\glideutl.h ** 2. fixed grChromaRange, grSstOrigin, and grGetProcAddress * * 1 1/16/98 4:29p Atai * create glide 3 src * * 60 12/01/97 6:13p Peter * non-packet3 tsu triangles ooz vs z * * 59 11/21/97 3:20p Peter * direct writes tsu registers * * 58 11/18/97 4:36p Peter * chipfield stuff cleanup and w/ direct writes * * 57 11/17/97 4:55p Peter * watcom warnings/chipfield stuff * * 56 11/12/97 9:54p Peter * fixed all the effage from new config * * 55 11/03/97 4:38p Peter * yapc fix * * 54 11/01/97 10:01a Peter * tri dispatch stuff * * 53 10/29/97 2:45p Peter * C version of Taco's packing code * * 52 10/27/97 5:59p Peter * removed some debugging code * * 51 10/21/97 3:22p Peter * hand pack rgb * * 50 10/19/97 12:51p Peter * no tsu happiness * * 49 10/19/97 10:59a Peter * fixed p1 tsu writes * * 48 10/17/97 3:15p Peter * removed unused addr field from datalist * * 47 10/17/97 10:15a Peter * packed rgb state cleanup * * 46 10/16/97 5:33p Peter * argb != rgba * * 45 10/16/97 3:40p Peter * packed rgb * * 44 10/16/97 10:31a Peter * fixed hoopti tsu-subtractor unsorted * * 43 10/15/97 5:53p Peter * hoopti tri compare code * * 42 10/10/97 4:33p Peter * non-packet3 tsu triangles * * 41 10/08/97 5:19p Peter * optinally clamp only texture params * * 40 10/08/97 11:32a Peter * pre-computed packet headers for packet 3 * * 39 9/20/97 4:42p Peter * tri_setf fixup/big fifo * * 38 9/16/97 2:50p Peter * fixed watcom unhappiness w/ static initializers * * 37 9/15/97 7:31p Peter * more cmdfifo cleanup, fixed normal buffer clear, banner in the right * place, lfb's are on, Hmmmm.. probably more * * 36 9/10/97 10:13p Peter * fifo logic from GaryT, non-normalized fp first cut * * 35 9/03/97 2:11p Peter * start gdbg_info cleanup, fixed zero area no-tsu triangle effage * * 34 9/01/97 3:19p Peter * no-tsu w from vertex not tmuvtx * * 33 8/31/97 4:06p Peter * no tsu fix * * 32 8/31/97 12:04p Peter * hacked no-tsu code * * 31 7/25/97 11:40a Peter * removed dHalf, change field name to match real use for cvg * * 30 6/30/97 3:22p Peter * cmd fifo sanity * * 29 6/24/97 4:02p Peter * proper cmd fifo placement * * 28 6/23/97 4:43p Peter * cleaned up #defines etc for a nicer tree ** */ #include <3dfx.h> #include #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #ifdef GDBG_INFO_ON /* Some debugging information */ static char *indexNames[] = { "GR_VERTEX_X_OFFSET", /* 0 */ "GR_VERTEX_Y_OFFSET", /* 1 */ "GR_VERTEX_Z_OFFSET", /* 2 */ "GR_VERTEX_R_OFFSET", /* 3 */ "GR_VERTEX_G_OFFSET", /* 4 */ "GR_VERTEX_B_OFFSET", /* 5 */ "GR_VERTEX_OOZ_OFFSET", /* 6 */ "GR_VERTEX_A_OFFSET", /* 7 */ "GR_VERTEX_OOW_OFFSET", /* 8 */ "GR_VERTEX_SOW_TMU0_OFFSET", /* 9 */ "GR_VERTEX_TOW_TMU0_OFFSET", /* 10 */ "GR_VERTEX_OOW_TMU0_OFFSET", /* 11 */ "GR_VERTEX_SOW_TMU1_OFFSET", /* 12 */ "GR_VERTEX_TOW_TMU1_OFFSET", /* 13 */ "GR_VERTEX_OOW_TMU1_OFFSET" /* 14 */ }; #endif /* GDBG_INFO_ON */ #if GLIDE_USE_C_TRISETUP inline FxI32 _grTriCull(const void* a, const void* b, const void* c) { #define FN_NAME "_grCullTri" GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X, 0x%X, 0x%X)\n", a, b, c); { const FxI32 xindex = (gc->state.vData.vertexInfo.offset >> 2), yindex = xindex + 1; const float *fa = (const float*)a + xindex, *fb = (const float*)b + xindex, *fc = (const float*)c + xindex; const float dxAB = fa[xindex] - fb[xindex], dxBC = fb[xindex] - fc[xindex], dyAB = fa[yindex] - fb[yindex], dyBC = fb[yindex] - fc[yindex], area = dxAB * dyBC - dxBC * dyAB; { const FxI32 j = *(FxI32*)&area; const FxU32 culltest = (gc->state.cull_mode << 31UL); /* Zero-area triangles are BAD!! */ if ((j & 0x7FFFFFFF) == 0) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", (fa[0]), (fa[1]), (fb[0]), (fb[1]), (fc[0]), (fc[1]), area, gc->state.cull_mode, culltest); return 0; } /* Backface culling, use sign bit as test */ if ((gc->state.cull_mode != GR_CULL_DISABLE) && (((FxI32)(j ^ culltest)) >= 0)) { GDBG_INFO(291, FN_NAME": Culling (%g %g) (%g %g) (%g %g) : (%g : 0x%X : 0x%X)\n", (fa[0]), (fa[1]), (fb[0]), (fb[1]), (fc[0]), (fc[1]), area, gc->state.cull_mode, culltest); return -1; } } return 1; } GR_END(); #undef FN_NAME } inline FxI32 internal_trisetup(const char* FN_NAME, const FxBool cullP, const FxBool validStateP, const void* a, const void* b, const void* c) { GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X, 0x%X, 0x%X)\n", a, b, c); /* Check to see if the state has to be flushed */ if (!validStateP) GR_FLUSH_STATE(); /* Pass the current culling mode? */ if (cullP) { const FxI32 cullVal = _grTriCull(a, b, c); if (cullVal <= 0) return cullVal; } /* Validate parameter coordinates */ { const FxI32 xindex = (gc->state.vData.vertexInfo.offset >> 2), yindex = xindex + 1; const float *fa = (const float*)a + xindex, *fb = (const float*)b + xindex, *fc = (const float*)c + xindex; const float aX = fa[xindex], aY = fa[yindex], bX = fb[xindex], bY = fb[yindex], cX = fc[xindex], cY = fc[yindex]; #define kDimThreshX 2048.0f #define kDimThreshY 2048.0f GR_ASSERT((fabs(aX) < kDimThreshX) && (fabs(aY) < kDimThreshY)); GR_ASSERT((fabs(bX) < kDimThreshX) && (fabs(bY) < kDimThreshY)); GR_ASSERT((fabs(cX) < kDimThreshX) && (fabs(cY) < kDimThreshY)); #undef kDimThreshX #undef kDimThreshY } /* Send triangle parameters */ { FxU32 dataElem; const void *vectorArray[3]; vectorArray[0] = a; vectorArray[1] = b; vectorArray[2] = c; GR_SET_EXPECTED_SIZE(gc->curTriSize, 1); if(gc->contextP) { union { FxU32 buffer[2]; double buffer_double; } buff; const float *vector = vectorArray[0]; const int *dataList; int vectorIndex = 0; FxU32 *tPackPtr = gc->cmdTransportInfo.fifoPtr; const FxU32 packetVal = (((kSetupStrip) << SSTCP_PKT3_SMODE_SHIFT) | /* [27:22] */ ((3) << SSTCP_PKT3_NUMVERTEX_SHIFT) | /* [9:6] */ (SSTCP_PKT3_BDDBDD) | /* command [5:3] */ gc->cmdTransportInfo.cullStripHdr); TRI_ASSERT_DECL(3, gc->curVertexSize, packetVal); if((FxU32)tPackPtr & 7) { /* Destination not 8-byte aligned, so write the packet header directly to the command fifo. */ SET(*tPackPtr++, packetVal); goto vertex_begin_empty; } else { /* Destination is aligned, so store packet header to buffer */ SET(buff.buffer[0], packetVal); goto vertex_begin_half; } /* Buffer is empty, so store X and Y and then flush it to memory. */ vertex_begin_empty: SETF(buff.buffer[0],vector[0]); SETF(buff.buffer[1],vector[1]); *(double *)tPackPtr = *(double *)&buff.buffer[0]; tPackPtr += 2; dataList = gc->tsuDataList; goto vertex_loop_empty; /* Buffer is 1/2 full, so store X into 2nd half and flush it to memory. */ vertex_begin_half: SETF(buff.buffer[1],vector[0]); *(double *)tPackPtr = *(double *)&buff.buffer[0]; tPackPtr += 2; SETF(buff.buffer[0],vector[1]); dataList = gc->tsuDataList; goto vertex_loop_half; /* Buffer is empty, next item goes into entry 0. */ vertex_loop_empty: dataElem = *dataList++; if(dataElem == GR_DLIST_END) goto vertex_end_empty; SETF(buff.buffer[0],FARRAY(vector,dataElem)); /* Buffer is half-full, next item goes into entry 1, then flush. */ vertex_loop_half: dataElem = *dataList++; if(dataElem == GR_DLIST_END) goto vertex_end_half; SETF(buff.buffer[1],FARRAY(vector,dataElem)); *(double *)tPackPtr = *(double *)&buff.buffer[0]; tPackPtr += 2; goto vertex_loop_empty; /* Buffer is empty, increment to next vector and continue. */ vertex_end_empty: vectorIndex++; if(vectorIndex < sizeof(vectorArray) / sizeof(float *)) { vector = vectorArray[vectorIndex]; goto vertex_begin_empty; } goto vertex_end; /* Buffer is 1/2 full, increment to next vector and continue to unaligned read. */ vertex_end_half: vectorIndex++; if(vectorIndex < sizeof(vectorArray) / sizeof(float *)) { vector = vectorArray[vectorIndex]; goto vertex_begin_half; } /* Buffer is 1/2 full, must flush entry */ *tPackPtr++ = buff.buffer[0]; vertex_end: /* TRI_ASSERT(); */ gc->cmdTransportInfo.fifoRoom -= ((FxU32)tPackPtr - (FxU32)gc->cmdTransportInfo.fifoPtr); gc->cmdTransportInfo.fifoPtr = tPackPtr; GDBG_INFO(gc->myLevel + 200, "\tTriEnd: (0x%X : 0x%X)\n", tPackPtr, gc->cmdTransportInfo.fifoRoom); FIFO_ASSERT(); \ /* GR_CHECK_SIZE(); */ } } GR_END(); return FXTRUE; } FxI32 FX_CALL _trisetup_Default_win_cull_invalid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_cull_invalid" return internal_trisetup(FN_NAME, FXTRUE, FXFALSE, a, b, c); #undef FN_NAME } FxI32 FX_CALL _trisetup_Default_win_cull_valid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_cull_valid" return internal_trisetup(FN_NAME, FXTRUE, FXTRUE, a, b, c); #undef FN_NAME } FxI32 FX_CALL _trisetup_Default_win_nocull_invalid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_nocull_invalid" return internal_trisetup(FN_NAME, FXFALSE, FXFALSE, a, b, c); #undef FN_NAME } FxI32 FX_CALL _trisetup_Default_win_nocull_valid(const void* a, const void* b, const void* c) { #define FN_NAME "_trisetup_Default_win_nocull_valid" return internal_trisetup(FN_NAME, FXFALSE, FXTRUE, a, b, c); #undef FN_NAME } #endif FxI32 FX_CALL _vptrisetup_cull(const void* a, const void* b, const void* c) { #define FN_NAME "_vptrisetup_cull" float *vlist[3]; GR_BEGIN_NOFIFOCHECK(FN_NAME, 85); GDBG_INFO_MORE(gc->myLevel, "(0x%X, 0x%X, 0x%X)\n", a, b, c); vlist[0] = (float *)a; vlist[1] = (float *)b; vlist[2] = (float *)c; (*gc->archDispatchProcs.drawTrianglesProc)(GR_VTX_PTR_ARRAY, 3, vlist); GR_END(); return 1; #undef FN_NAME } glide3x/h5/glide3/src/macglide3.h0100700000175300010010000000534107725034670015776 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED */ #ifndef _MAC_GLIDE_H_ #define _MAC_GLIDE_H_ /* Hack */ #define __stdcall /* Glide Global options */ //#define CVG 1 #define GLIDE_LIB 1 #define GLIDE_PLUG 1 #define GLIDE3 1 #define GLIDE3_ALPHA 1 #define GLIDE3_VERTEX_LAYOUT 1 #define HWC_GDX_INIT 1 #define HWC_ACCESS_GDX 1 #define PCI_BUMP_N_GRIND 1 #define FIFO_WRITE_64 0 //#define GLIDE_HW_H3 1 //#define HWC_EXT_INIT 1 #define H3 1 #define H4 1 /* Glide Platform Options */ #define SET_BSWAP 1 #define SET_SWIZZLEHACK 0 #define HAL_HW 1 #define INIT_DOS 1 #define HAS_CONSOLE_IO 1 /* Glide Debugging options */ #define DEBUG 0 #if DEBUG #define GLIDE_DEBUG 1 #define GDBG_INFO_ON 1 #define GLIDE_USE_DEBUG_FIFO 0 //#define FIFO_ASSERT_FULL 0 #define GLIDE_SANITY_SIZE 1 #define GLIDE_SANITY_ASSERT 1 #ifdef __MWERKS__ #pragma global_optimizer off #pragma scheduling off #pragma traceback on #endif #else /* !DEBUG */ #ifdef __MWERKS__ #pragma global_optimizer on #pragma optimization_level 4 #pragma peephole on #pragma scheduling 750 #pragma traceback off #pragma side_effects off #pragma optimize_for_size off #endif #endif /* !DEBUG */ #define GLIDE_USE_C_TRISETUP 1 #define GLIDE_FP_CLAMP 0 #define GLIDE_FP_CLAMP_TEX 0 /* Glide HW Options */ #define GLIDE_CHIP_BROADCAST 1 #define GLIDE_HW_TRI_SETUP 1 #define GLIDE_PACKET3_TRI_SETUP 1 #define GLIDE_TRI_CULLING 1 #define GLIDE_PACKED_RGB 1 #define GLIDE_DISPATCH_SETUP 0 #define GLIDE_BLIT_CLEAR 1 #define USE_PACKET_FIFO 1 #define GLIDE_INIT_HWC 1 #define GLIDE_DEFAULT_GAMMA 1.3f #ifndef __VERSION_REZ__ #include #endif #endif /* _MAC_GLIDE_H_ */ glide3x/h5/glide3/src/makefile.autoconf.am0100700000175300010010000002164107725034670017707 0ustar johndoeNone## ## THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ## PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ## TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ## INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ## DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ## THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ## EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ## FULL TEXT OF THE NON-WARRANTY PROVISIONS. ## ## USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ## RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ## TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ## AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ## SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ## THE UNITED STATES. ## ## COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ## ## $Revision: 1.10.2.5 $ ## $Date: 2003/08/22 05:29:59 $ ## # # First, we define the flags. First, the variable flags, # and then the fixed local ones. # if FX_GLIDE_PACKET_FIFO CMDXPORTDEFS = -DGLIDE_PACKET3_TRI_SETUP=1 \ -DUSE_PACKET_FIFO=1 \ -DGLIDE_HW_TRI_SETUP=1 else CMDXPORTDEFS = -DGLIDE_HW_TRI_SETUP=1 \ -DGLIDE_PACKET3_TRI_SETUP=0 endif if FX_CHRIS_DENIS_ANTHONY_HACK FX_CHRIS_DENIS_ANTHONY_HACK_VDEFS = -DCHRIS_DENIS_ANTHONY_HACK=1 endif if FX_GLIDE_ALT_TAB FX_GLIDE_ALT_TAB_VDEFS = -DGLIDE_ALT_TAB endif if FX_GLIDE_DIRECT_WRITE FX_GLIDE_DIRECT_WRITE_VDEFS = -DDIRECT_IO=1 endif if FX_GLIDE_H5 FX_GLIDE_H5_VDEFS = -DFX_GLIDE_NAPALM=1 -DFX_GLIDE_H5_CSIM=1 endif if GL_AMD3D GL_AMD3D_VDEFS = -DGL_AMD3D endif if GL_SSE GL_SSE_VDEFS = -DGL_SSE endif if GL_MMX GL_MMX_VDEFS = -DGL_MMX endif if GL_SSE2 GL_SSE2_VDEFS = -DGL_SSE2 endif if DRI_BUILD DRI_BUILD_VDEFS = -DDRI_BUILD endif if HAL_HW if HAL_CSIM HAL_HW_CSIM_VDEFS = -DHOOPTI_LAB_LFB_BYPASS=1 endif endif if FX_GLIDE_SW_SETUP FX_GLIDE_SW_SETUP_VDEFS = -DGLIDE_HW_TRI_SETUP=0 -DGLIDE_TRI_CULLING=1 endif if FX_GLIDE_NO_FIFO FX_GLIDE_NO_FIFO_VDEFS = -DUSE_PACKET_FIFO=1 \ -DGLIDE_USE_DEBUG_FIFO=1 \ -DFIFO_ASSERT_FULL=1 \ -DASSERT_FAULT=0 \ -DGLIDE_SANITY_SIZE=1 endif if FX_GLIDE_NO_PLUG else FX_GLIDE_NO_PLUG_VDEFS = -DGLIDE_PLUG endif if FX_GLIDE_NO_SPLASH else FX_GLIDE_NO_SPLASH_VDEFS = -DGLIDE_SPLASH endif if GLIDE_SANITY_ALL GLIDE_SANITY_ALL_VDEFS = -DGLIDE_SANITY_SIZE -DGLIDE_SANITY_ASSERT endif if GLIDE_SANITY_SIZE GLIDE_SANITY_SIZE_VDEFS = -DGLIDE_SANITY_SIZE -DGLIDE_SANITY_ASSERT endif if FX_DLL_BUILD else FX_DLL_BUILD_VDEFS = -DFX_STATIC_BUILD endif if HAL_CSIM HAL_CSIM_VDEFS = -DHAL_CSIM=1 \ -DGLIDE_INIT_HAL \ -DHOOPTI_LAB_LFB_BYPASS=1 else HAL_CSIM_VDEFS = -DGLIDE_INIT_HWC endif if HAL_HW HAL_HW_VDEFS = -DHAL_HW=1 endif if FX_GLIDE_HW_CULL FX_GLIDE_HW_CULL_VDEFS = -DGLIDE_TRI_CULLING=1 endif if FX_GLIDE_CTRISETUP FX_GLIDE_CTRISETUP_VDEFS = -DGLIDE_USE_C_TRISETUP else FX_GLIDE_CTRISETUP_VDEFS = -DGLIDE_PACKED_RGB=0 -DGLIDE_TRI_CULLING=1 endif VDEFS = $(FX_CHRIS_DENIS_ANTHONY_HACK_VDEFS) \ $(FX_GLIDE_ALT_TAB_VDEFS) \ $(FX_GLIDE_DIRECT_WRITE_VDEFS) \ $(FX_GLIDE_H5_VDEFS) \ $(GL_AMD3D_VDEFS) \ $(GL_SSE_VDEFS) \ $(GL_MMX_VDEFS) \ $(GL_SSE2_VDEFS) \ $(DRI_BUILD_VDEFS) \ $(HAL_HW_CSIM_VDEFS) \ $(FX_GLIDE_SW_SETUP_VDEFS) \ $(FX_GLIDE_NO_FIFO_VDEFS) \ $(FX_GLIDE_NO_PLUG_VDEFS) \ $(FX_GLIDE_NO_SPLASH_VDEFS) \ $(GLIDE_SANITY_ALL_VDEFS) \ $(GLIDE_SANITY_SIZE_VDEFS) \ $(FX_DLL_BUILD_VDEFS) \ $(GLIDE_DEBUG_VDEFS) \ $(HAL_CSIM_VDEFS) \ $(HAL_HW_VDEFS) \ $(FX_GLIDE_HW_CULL_VDEFS) \ $(FX_GLIDE_CTRISETUP_VDEFS) LDEFS = -DGLIDE_LIB -DGLIDE3 -DGLIDE3_ALPHA -DH3 $(CMDXPORTDEFS) # # Now, we define the includes, first the variable ones, # and then the fixed ones. # if HAL_CSIM HAL_CSIM_INCLUDES = -I@top_srcdir@/@FX_GLIDE_HW@/csim endif VINCLUDES = $(HAL_CSIM_INCLUDES) # # Nothing for CPPFLAGS or OPTS here. # # # Special rules for assembly files. # Here beginneth the assembly cheap cheat (tm). # Some kind soul to fix this, pleaaase!!! # xdraw2_def.o xdraw2_def.lo: xdraw2.asm xdraw2.inc fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -o $*.o $< $(CP) $*.o $*.lo xdraw3_def.o xdraw3_def.lo: xdraw3.asm fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -o $*.o $< $(CP) $*.o $*.lo xdraw2_3dnow.o xdraw2_3dnow.lo: xdraw2.asm xdraw2.inc fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_AMD3D -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo xdraw3_3dnow.o xdraw3_3dnow.lo: xdraw3.asm fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_AMD3D -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo xtexdl_3dnow.o xtexdl_3dnow.lo: xtexdl.asm fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_AMD3D -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo xdraw2_sse.o xdraw2_sse.lo: xdraw2.asm xdraw2.inc fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_SSE -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo xdraw3_sse.o xdraw3_sse.lo: xdraw3.asm fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_SSE -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo xtexdl_mmx.o xtexdl_mmx.lo: xtexdl.asm fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_MMX -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo xtexdl_sse2.o xtexdl_sse2.lo: xtexdl.asm fxgasm.h nasm -I@top_srcdir@/@FX_GLIDE_HW@/glide3/src -O2 -felf -D__linux__ -DGL_SSE2 -DUSE_PACKET_FIFO=1 -o $*.o $< $(CP) $*.o $*.lo # # Library definitions. # if FX_GLIDE_CTRISETUP FX_GLIDE_CTRISETUP_SRC = gxdraw.c else FX_GLIDE_CTRISETUP_SRC = xdraw2_def.s xdraw3_def.s if GL_AMD3D FX_GLIDE_CTRISETUP_SRC += xdraw2_3dnow.s xdraw3_3dnow.s xtexdl_3dnow.s endif if GL_SSE FX_GLIDE_CTRISETUP_SRC += xdraw2_sse.s xdraw3_sse.s endif if GL_MMX FX_GLIDE_CTRISETUP_SRC += xtexdl_mmx.s endif if GL_SSE2 FX_GLIDE_CTRISETUP_SRC += xtexdl_sse2.s endif endif VGLIDE_SRC=$(FX_GLIDE_CTRISETUP_SRC) WHOLE_LIBS = $(top_builddir)/swlibs/fxmisc/libfxmisc.la \ $(top_builddir)/swlibs/newpci/pcilib/libfxpci.la \ $(top_builddir)/swlibs/$(TEXTURE_UTILITIES_DIR)/lib/libtexus.la \ $(top_builddir)/@FX_GLIDE_HW@/minihwc/libminihwc.la LINK_LIBS = -L/usr/X11R6/lib -lX11 -lXext -lXxf86dga -lXxf86vm -lm CLEANFILES = fxinline.h fxgasm.h fxbldno.h noinst_PROGRAMS = fxgasm fxbldno include_HEADERS = g3ext.h glide.h glideutl.h glidesys.h noinst_HEADERS = fxcmd.h fxsplash.h \ gsfctabl.h macglide3.h \ rcver.h fxglide.h \ gsfc.h gsstdef.h \ qmodes.h tv.h \ fxgasm.h fxinline.h fxbldno.h fxgasm_SOURCES = fxgasm.c fxgasm_LDADD = gthread.lo fxgasm_DEPENDENCIES = gthread.lo fxbldno_SOURCES = fxbldno.c lib_LTLIBRARIES = libglide3.la libglide3_la_SOURCES = fxinline.h fxgasm.h fxbldno.h \ gsplash.c g3df.c gu.c gthread.c \ gpci.c diglide.c disst.c ditex.c \ gbanner.c gerror.c gaa.c gdraw.c \ gglide.c distate.c gstrip.c distrip.c \ diget.c glfb.c gsst.c gtex.c gtexdl.c \ fifo.c cpuid.c xtexdl_def.c $(VGLIDE_SRC) libglide3_la_LDFLAGS = -version-info 13:1:10 libglide3_la_LIBADD = $(WHOLE_LIBS) $(LINK_LIBS) #--------------------------------------------------------------------------# # special rules for making fxgasm.h, fxinclude.h, fxbldno.h # fxgasm.h: fxgasm ./fxgasm -hex > fxgasm.h fxinline.h: fxgasm ./fxgasm -inline > fxinline.h fxbldno.h: fxbldno ./fxbldno > fxbldno.h #--------------------------------------------------------------------------# # special rules for using fxgasm.h, fxinclude.h # diget.o diget.lo gdraw.o gdraw.lo gglide.o gglide.lo gu.o gu.lo: fxinline.h xdraw2_def.o xdraw3_def.o xtexdl_def.o: fxinline.h xdraw2_def.lo xdraw3_def.lo xtexdl_def.lo: fxinline.h xdraw2_3dnow.o xdraw3_3dnow.o xtexdl_3dnow.o: fxgasm.h xdraw2_3dnow.lo xdraw3_3dnow.lo xtexdl_3dnow.lo: fxgasm.h #--------------------------------------------------------------------------# # special rules for using fxbldno.h # rcver.h: fxbldno.h diget.o diget.lo diglide.o diglide.lo gglide.o gglide.lo: rcver.h xdraw2_def.o xdraw3_def.o xtexdl_def.o: fxinline.h xdraw2_def.lo xdraw3_def.lo xtexdl_def.lo: fxinline.h xdraw2_3dnow.o xdraw3_3dnow.o xtexdl_3dnow.o: fxgasm.h xdraw2_3dnow.lo xdraw3_3dnow.lo xtexdl_3dnow.lo: fxgasm.h glide3x/h5/glide3/src/ppcdraw2.inc0100700000175300010010000002405407725034670016214 0ustar johndoeNone; ; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ; ; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ; THE UNITED STATES. ; ; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ; ; Start of triangle setup ; at this point, registers look like this: ; ; r28 - vertex A ; r29 - vertex B ; r30 - vertex C ; r31 - gc ; First step, check for fifo room. lwz r6,curTriSize(r31) ; get triangle data size lwz r0,fifoRoom(r31) ; get fifo room lwz r7,fifoPtr(r31) ; get fifo pointer addi r6,r6,4 ; add in packet header size cmpw cr1,r0,r6 ; is there enough room? (set CR1) li r10,-4 ; keep r10 around as -4 bge+ cr1,@gotFifoRoom ; use CR1 li r4,0 ; XXX - FIXME!!! li r5,0 addi r3,r6,0 bl ._grCommandTransportMakeRoom lwz r7,fifoPtr(r31) ; reload fifo pointer li r10,-4 ; reload r10 align 3 @gotFifoRoom: rlwinm. r0,r7,0,27,31 ; check FIFO alignment... (set CR0) lwz r6,triPacketHdr(r31) ; get packet header addi r8,r7,4 ; bump fifo pointer to next longword (r7 is current, r8 is next) rlwinm r9,r8,0,27,31 ; calc alignment for NEXT write (which would be X of vertex A) ori r6,r6,$00c0 ; fix up packet header bne+ @skipAlignPacketHeader ; skip cache effage (use CR0) dcbz r0,r7 ; clear new cache line dcbf r7,r10 ; flush previous cache line @skipAlignPacketHeader: stwbrx r6,r0,r7 ; store packet header cmplwi cr1,r9,$0000 ; check alignment for write X (set CR1) addi r7,r8,4 ; bump fifo pointer to next longword (r8 is now the current one) lwz r3,0(r28) ; load X value for vertex A rlwinm. r0,r7,0,27,31 ; check alignment for next write (Y) (set CR0) bne+ cr1,@skipAlignAX ; skip cache effage (use CR1) dcbz r0,r8 ; clear dcbf r8,r10 ; flush @skipAlignAX: stwbrx r3,r0,r8 ; store X addi r8,r7,4 ; r7 is current, r8 is next lwz r3,4(r28) ; load Y value rlwinm r9,r8,0,27,31 ; calc alignment mask for next write bne+ @skipAlignAY ; skip cache effage (use CR0) dcbz r0,r7 ; clear dcbf r7,r10 ; flush @skipAlignAY: stwbrx r3,r0,r7 ; store Y value cmplwi r9,$0000 ; check alignment for param 0 (or next vertex X) (set CR0) lwz r4,tsuDataList(r31) ; get first data item index directly addi r11,r31,tsuDataList ; get pointer to data list (1st entry) addi r7,r8,0 ; get dest in correct register b @dataLoopAEntry @dataLoopAStart: lwzx r6,r4,r28 ; load data item addi r7,r8,4 ; r7 is next destination lwzu r4,4(r11) ; load next index value bne+ @dataLoopAWrite ; skip cache effage (use CR0) dcbz r0,r8 ; clear dcbf r8,r10 ; flush @dataLoopAWrite: stwbrx r6,r0,r8 ; store data rlwinm. r0,r7,0,27,31 ; check alignment for next write (using cr0) @dataLoopAEntry: cmplwi cr1,r4,$0000 ; end of list? (set CR1) addi r8,r7,0 ; update pointer to next write bne+ cr1, @dataLoopAStart ; (use CR1) ; Now do vertex B ; ; relevant registers: ; ; r3 - temp vertex data ; r4 - temp index value ; r5 - XXX ; r6 - temp data storage ; r7 - alternat FIFO pointer (out of date) ; r8 - current FIFO pointer ; r9 - scratch pad for condition register calcs ; r10 - constant -4 for cache flushes ; r11 - pointer to data list ; cr0 - whether or not to do cache stuff on next write ; cr1 - trash lwz r3,0(r29) ; load X addi r7,r8,4 ; calc destination for Y rlwinm r9,r7,0,27,31 ; calc alignment mask for Y cmplwi cr1,r9,$0000 ; calc cr1 for Y write (set CR1) bne+ @skipAlignBX ; skip cache effage (use CR0) dcbz r0,r8 ; clear dcbf r8,r10 ; flush @skipAlignBX: stwbrx r3,r0,r8 ; store X addi r8,r7,4 ; r7 is current, r8 is next lwz r3,4(r29) ; load Y value rlwinm r9,r8,0,27,31 ; calc alignment mask for next write bne+ cr1,@skipAlignBY ; skip cache effage (use CR1) dcbz r0,r7 ; clear dcbf r7,r10 ; flush @skipAlignBY: stwbrx r3,r0,r7 ; store Y value cmplwi r9,$0000 ; check alignment for param 0 or next vertex X (set CR0) lwz r4,tsuDataList(r31) ; get first data item index directly addi r11,r31,tsuDataList ; get pointer to data list (1st entry) addi r7,r8,0 ; get dest in correct register b @dataLoopBEntry @dataLoopBStart: lwzx r6,r4,r29 ; load data item addi r7,r8,4 ; r7 is next destination lwzu r4,4(r11) ; load next index value bne+ @dataLoopBWrite ; skip cache effage (use CR0) dcbz r0,r8 ; clear dcbf r8,r10 ; flush @dataLoopBWrite: stwbrx r6,r0,r8 ; store data rlwinm. r0,r7,0,27,31 ; check alignment for next write (set CR0) @dataLoopBEntry: cmplwi cr1,r4,$0000 ; end of list? (set CR1) addi r8,r7,0 ; update pointer to next write bne+ cr1, @dataLoopBStart ; (use CR1) ; Now at last we do vertex C lwz r3,0(r30) ; load X addi r7,r8,4 ; calc destination for Y rlwinm r9,r7,0,27,31 ; calc alignment mask for Y cmplwi cr1,r9,$0000 ; calc cr1 for Y write (set CR1) bne+ @skipAlignCX ; skip cache effage (use CR0) dcbz r0,r8 ; clear dcbf r8,r10 ; flush @skipAlignCX: stwbrx r3,r0,r8 ; store X addi r8,r7,4 ; r7 is current, r8 is next lwz r3,4(r30) ; load Y value rlwinm r9,r8,0,27,31 ; calc alignment mask for next write bne+ cr1,@skipAlignCY ; skip cache effage (use CR1) dcbz r0,r7 ; clear dcbf r7,r10 ; flush @skipAlignCY: stwbrx r3,r0,r7 ; store Y value cmplwi r9,$0000 ; check alignment for param 0 or next vertex X (set CR0) lwz r4,tsuDataList(r31) ; get first data item index directly addi r11,r31,tsuDataList ; get pointer to data list (1st entry) addi r7,r8,0 ; get dest in correct register b @dataLoopCEntry @dataLoopCStart: lwzx r6,r4,r30 ; load data item addi r7,r8,4 ; r7 is next destination lwzu r4,4(r11) ; load next index value bne+ @dataLoopCWrite ; skip cache effage (use CR0) dcbz r0,r8 ; clear dcbf r8,r10 ; flush @dataLoopCWrite: stwbrx r6,r0,r8 ; store data rlwinm. r0,r7,0,27,31 ; check alignment for next write (set CR0) @dataLoopCEntry: cmplwi cr1,r4,$0000 ; end of list? (set CR1) addi r8,r7,0 ; update pointer to next write bne+ cr1, @dataLoopCStart ; (use CR1) ; WHEW! Okay, now update FIFO pointer & fifo data availability before we go. lwz r4,fifoPtr(r31) ; get original fifo pointer lwz r0,fifoRoom(r31) ; get fifo free subf r4,r4,r8 ; calc amount used subf r0,r4,r0 ; calc new amount free stw r0,fifoRoom(r31) ; save free stw r8,fifoPtr(r31) ; save new fifo pointer ; Final cleanup code begins here. Return FXTRUE. li r3,1 lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr glide3x/h5/glide3/src/ppcdraw2.s0100700000175300010010000002137507725034670015710 0ustar johndoeNone; ; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ; ; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ; THE UNITED STATES. ; ; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ; MACRO MakeFunction &fnName EXPORT &fnName[DS] EXPORT .&fnName[PR] TC &fnName[TC], &fnName[DS] CSECT &fnName[DS] DC.L .&fnName[PR] DC.L TOC[tc0] CSECT .&fnName[PR] FUNCTION .&fnName[PR] ENDM INCLUDE 'PPCInline.inc' ; ====================================================================== ; external global variables ; ====================================================================== import _threadValueMacOS import ._grCommandTransportMakeRoom import ._grValidateState toc tc _threadValueMacOS[TC], _threadValueMacOS IF 1 linkageArea: set 24 ; constant comes from the PowerPC Runtime Architecture Document CalleesParams: set 32 ; always leave space for GPR's 3-10 CalleesLocalVars: set 0 ; ClickHandler doesn't have any numGPRs: set 7 ; num volitile GPR's (GPR's 13-31) numFPRs: set 9 ; num volitile FPR's (FPR's 14-31) spaceToSave: set linkageArea + CalleesParams + CalleesLocalVars + 4*numGPRs + 8*numFPRs MakeFunction _trisetup_Default_win_cull_invalid _trisetup_Default_win_cull_invalid_begin: mflr r7 ; Get return address in volatile register lwz r0,invalid(r6) ; load state flag stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) cmplwi r0,$0000 ; check state flag (sets cr0) lwz r0,cull_mode(r6) ; load cull mode addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) cmplwi cr1,r0,$0000 ; check culling mode (sets cr1) stw r7,8(sp) addi r31,r6,0 stwu sp,-128(sp) beq+ @noValidate ; check valid state flag (via cr0), predict branch to true bl ._grValidateState nop lwz r0,cull_mode(r31) ; reload cull mode into r0 ; 1 cycle stall cmplwi cr1,r0,$0000 ; redo cull check since cr1 could have been trashed align 3 @noValidate: beq- cr1,@noCull ; check for culling being disabled, predict as not taken lfs fp4,4(29) ; load bY rlwinm r6,r0,31,0,0 ; get cull mode in top bit lfs fp0,4(r28) ; load aY lfs fp5,0(r29) ; load bX lfs fp1,0(r30) ; load cX fsubs fp0,fp0,fp4 ; fp0 = dyAB lfs fp3,0(r28) ; load aX fsubs fp1,fp5,fp1 ; fp1 = dxBC lfs fp2,4(r30) ; load cY fsubs fp3,fp3,fp5 ; fp3 = dxAB fsubs fp2,fp4,fp2 ; fp2 = dyBC fmuls fp0,fp1,fp0 ; fp0 = dxBC * dyAB ; 2 cycle stall fmsubs fp0,fp3,fp2,fp0 ; fp0 = dxAB * dyBC - dxBC * dyAB ; 2 cycle stall stfs fp0,-32(sp) ; 1 cycle stall lwz r7,-32(sp) ; 1 cycle stall rlwinm. r0,r7,0,1,31 ; check for zero area bne+ @nonZeroArea ; okay so far... li r3,$0000 @culledReturn: lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr align 3 ; allign branch target doubleword address @nonZeroArea: xor. r0,r7,r6 ; check culling blt @noCull li r3,-1 b @culledReturn align 3 @noCull: INCLUDE 'ppcdraw2.inc' _trisetup_Default_win_cull_invalid_end: MakeFunction _trisetup_Default_win_nocull_invalid _trisetup_Default_win_nocull_invalid_begin: mflr r7 ; Get return address in volatile register lwz r0,invalid(r6) ; load state flag stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) cmplwi r0,$0000 ; check state flag (sets cr0) addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) stw r7,8(sp) addi r31,r6,0 stwu sp,-128(sp) beq+ @noValidate ; check valid state flag (via cr0), predict branch to true bl ._grValidateState nop ; 1 cycle stall align 3 @noValidate: INCLUDE 'ppcdraw2.inc' _trisetup_Default_win_nocull_invalid_end: MakeFunction _trisetup_Default_win_cull_valid _trisetup_Default_win_cull_valid_begin: mflr r7 ; Get return address in volatile register lwz r0,cull_mode(r6) ; load cull mode stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) cmplwi cr1,r0,$0000 ; check culling mode (sets cr1) addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) stw r7,8(sp) addi r31,r6,0 stwu sp,-128(sp) beq- cr1,@noCull ; check for culling being disabled, predict as not taken lfs fp4,4(29) ; load bY rlwinm r6,r0,31,0,0 ; get cull mode in top bit lfs fp0,4(r28) ; load aY lfs fp5,0(r29) ; load bX lfs fp1,0(r30) ; load cX fsubs fp0,fp0,fp4 ; fp0 = dyAB lfs fp3,0(r28) ; load aX fsubs fp1,fp5,fp1 ; fp1 = dxBC lfs fp2,4(r30) ; load cY fsubs fp3,fp3,fp5 ; fp3 = dxAB fsubs fp2,fp4,fp2 ; fp2 = dyBC fmuls fp0,fp1,fp0 ; fp0 = dxBC * dyAB ; 2 cycle stall fmsubs fp0,fp3,fp2,fp0 ; fp0 = dxAB * dyBC - dxBC * dyAB ; 2 cycle stall stfs fp0,-32(sp) ; 1 cycle stall lwz r7,-32(sp) ; 1 cycle stall rlwinm. r0,r7,0,1,31 ; check for zero area bne+ @nonZeroArea ; okay so far... li r3,$0000 @culledReturn: lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr align 3 ; allign branch target doubleword address @nonZeroArea: xor. r0,r7,r6 ; check culling blt @noCull li r3,-1 b @culledReturn align 3 @noCull: INCLUDE 'ppcdraw2.inc' _trisetup_Default_win_cull_valid_end: MakeFunction _trisetup_Default_win_nocull_valid _trisetup_Default_win_nocull_valid_begin: mflr r7 ; Get return address in volatile register stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) addi r31,r6,0 stw r7,8(sp) stwu sp,-128(sp) INCLUDE 'ppcdraw2.inc' _trisetup_Default_win_nocull_valid_end: ENDIF IF 1 ; About 3 clock cycles of stalls in the code below, waiting for loads. (But ; about 12 clocks that could be used for something else) MakeFunction grDrawTriangle lwz r6,_threadValueMacOS[TC](RTOC) ; Get pointer to thread value lwz r6,0(r6) ; get thread value (gc) addis r7,r6,1 ; add 64K lwz r12,triSetupProc(r7) ; load triangle dispatch vector lwz r7,0(r12) ; grab function pointer lwz rtoc,4(r12) ; load new TOC mtctr r7 ; move to ctr bctr ; jump to triangle setup function ENDIFglide3x/h5/glide3/src/qmodes.h0100700000175300010010000003070207725034670015435 0ustar johndoeNone/* $Header: /cvsroot/glide/glide3x/h5/glide3/src/qmodes.h,v 1.3.4.2 2003/06/05 08:23:55 koolsmoky Exp $ */ /* ** ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** File name: qmodes.h ** ** Description: Structures, macros, etc to support query mode. ** ** $Revision: 1.3.4.2 $ ** $Date: 2003/06/05 08:23:55 $ ** ** $History: qmodes.h $ ** ** ***************** Version 21 ***************** ** User: Stb_rbissell Date: 5/14/99 Time: 9:47p ** Updated in $/devel/h3/win95/dx/dd16 ** tvout and dfp changes ** ** ***************** Version 20 ***************** ** User: Stuartb Date: 2/25/99 Time: 12:48p ** Updated in $/devel/h3/Win95/dx/dd16 ** Added FPFLAG_CAPABLE. ** ** ***************** Version 19 ***************** ** User: Stuartb Date: 2/18/99 Time: 2:54p ** Updated in $/devel/h3/Win95/dx/dd16 ** Added xlcd FPFLAGS for filter mode setting. ** ** ***************** Version 18 ***************** ** User: Andrew Date: 2/11/99 Time: 11:17a ** Updated in $/devel/h3/Win95/dx/dd16 ** Added AGP Cap Query ** ** ***************** Version 17 ***************** ** User: Stuartb Date: 1/21/99 Time: 11:18a ** Updated in $/devel/h3/Win95/dx/dd16 ** Added FPFLAG_SETRES and FPFLAG_SETREFR for app code. Removed ** broadcastMonitorChange calls. ** ** ***************** Version 16 ***************** ** User: Stuartb Date: 1/12/99 Time: 2:27p ** Updated in $/devel/h3/Win95/dx/dd16 ** Added QUERY_ANALOG_MONITOR & modified QUERY_LCDCTRL. ** ** ***************** Version 15 ***************** ** User: Stuartb Date: 1/08/99 Time: 3:34p ** Updated in $/devel/h3/Win95/dx/dd16 ** Added QUERY_LCDCTRL for control panel flat panel ops. ** ** ***************** Version 14 ***************** ** User: Bob Date: 1/05/99 Time: 5:57p ** Updated in $/devel/h3/WinNT/src/Video/Displays/H3 ** BIOS version reporting to Control Panel applet. ** ** Shared qmodes.h with Win9x and the rest of the universe. ** ** ***************** Version 13 ***************** ** User: Bob Date: 1/05/99 Time: 5:14p ** Updated in $/devel/h3/Win95/dx/dd16 ** Altered nesting of header files so that tv.h is not inside qmodes.h. ** ** This is a sharing issue with NT. ** ** ***************** Version 12 ***************** ** User: Larryw Date: 1/05/99 Time: 4:36p ** Updated in $/devel/swtools/3DfxV2ps ** Changed QUERY[GS]ETDESKTOPGAMMA back to QUERY[GS]ETGAMMA. ** ** ***************** Version 11 ***************** ** User: Larryw Date: 1/05/99 Time: 3:45p ** Updated in $/devel/swtools/3DfxV2ps ** Put MAX_BIOS_VERSION_STRING in; changed some Gamma query values ** ** ***************** Version 10 ***************** ** User: Andrew Date: 1/05/99 Time: 10:50a ** Updated in $/devel/h3/Win95/dx/dd16 ** Added new function to get the bios version string ** ** ***************** Version 9 ***************** ** User: Michael Date: 12/29/98 Time: 2:37p ** Updated in $/devel/h3/Win95/dx/dd16 ** Implement the 3Dfx/STB unified header. ** ** 8 10/10/98 5:21p Hsohel ** ** 7 10/10/98 4:52p Hsohel ** ** 6 10/10/98 3:36p Hsohel ** ** 5 10/09/98 3:54p Hsohel ** ** 4 7/13/98 5:26p Andrew ** Changed to support a gamma table ** ** 3 7/11/98 8:16a Andrew ** Added gamma correction ** ** 2 5/12/98 9:35a Andrew ** Added some minor changes for valid modes ** ** 1 4/22/98 2:47p Andrew ** Query Modes Protocol Information ** ** */ #ifndef _QMODES_H_ #define _QMODES_H_ #define CARD_TABLESIZEMASK 0xFF80 #define CARD_TABLEMODSIZE 0x50 /* The QUERYMODES ESC Code */ #define QUERYESCMODE (0x8001) #define TDFXACK (0x3DF0) #define TDFXERR (0xFFFF) // General Queries #define QUERYVERSION (0x0000) // Mode Queries #define QUERYNUMMODES (0x0001) #define QUERYMODES (0x0002) #define QUERYDEVNODE (0x0003) // Virtual Desktop Queries #define QUERYMAXFREEMEM (0x100) #define QUERYSETVIRTUALSIZE (0x101) #define QUERYGETSTARTADDR (0x102) #define QUERYSETSTARTADDR (0x103) // Gamma Queries #define QUERYGETGAMMA (0x200) #define QUERYSETGAMMA (0x201) #define QUERYGETGLIDEGAMMA (0x202) #define QUERYSETGLIDEGAMMA (0x203) // BIOS Version #define QUERYGETBIOSVERSION (0x280) // AGP Query #define QUERYGETAGPCAPS (0x2A0) // TVOUT Queries // see ..\inc\tv.h uses 0x300 -> 0x38f approx. // LCD CONTROL #define QUERY_LCDCTRL (0x3a0) // ANALOG MONITOR ON/OFF override #define QUERY_ANALOG_MONITOR (0x3b0) /* ** Protocol: ** ** Call will be of the form ** ExtEscape(hdc, QUERYESCMODE, sizeof(QIN), &Qin, sizeof(Output), &Output); ** Escape(hdc, QUERYESCMODE, sizeof(QIN), &Qin, &Output); ** */ /* ** Standard Input Structure ** */ typedef struct qin { DWORD dwSubFunc; // Subfunction } QIN, FAR * LPQIN, * PQIN; /* ** ** ** INPUT: qin.dwSubFunc = QUERYVERSION ** OUTPUT: Driver Major & Minor Version */ typedef struct qversion { DWORD dwMajor; DWORD dwMinor; } QVERSION, FAR * LPQVERSION, * PQVERSION; #define QUERYMODE_MAJOR 0x00000000 #define QUERYMODE_MINOR 0x00009999 /* ** Call this function first to know how many modes to allow ** the following structure for ** ** INPUT: qin.dwSubFunc = QUERYNUMMODES ** OUTPUT: Number of modes */ typedef struct qnummode { DWORD dwNum; } QNUMMODE, FAR * LPQNUMMODE, * PQNUMODE; /* ** This is the mode information. You will need to allocate ** # modes * QMODE structures that the Driver will fill in. ** ** INPUT: qin.dwSubFunc = QUERYMODES ** OUTPUT: #Modes * QMODE */ typedef struct qmode { DWORD dwX; DWORD dwY; DWORD dwBpp; DWORD dwRef; DWORD dwValid; // This will be a field of flags } QMODE, FAR * LPQMODE, * PQMODE; #define QUERY_MODE_VALID (0x000000001L) #define QUERY_TV_MODE (0x000000002L) /* ** This is Devnode that the driver is using ** ** INPUT: qin.dwSubFunc = QUERYDEVNODE ** OUTPUT: dwDevNode */ typedef struct qdevnode { DWORD dwDevNode; // Monitor Device Node DWORD dwValidDefGamma; // 1 ==> bGamma is valid; 0 ==> Invalid BYTE bGamma; // Monitor Default Gamma } QDEVNODE, FAR * LPQDEVNODE, * PQDEVNODE; #define QUERY_MONITOR_GAMMA_VALID (0x00000001L) /* ** This is maximum free memory available for Virtual Desktop Usage in ** this mode ** ** INPUT: qin.dwSubFunc = QUERYMAXFREEMEM ** OUTPUT: Maximum Free Memory */ typedef struct qmaxfree { DWORD dwSubFunc; // Should be set to QUERYSETVIRTUALSIZE DWORD dwMaxFree; // Free Memory Available for Virtual Desktop DWORD dwMaxX; // Maximum Free X ==> min(dwMaxFree/Y, MaxHardwareX) DWORD dwMaxY; // Maximum Free Y ==> min(dwMaxFree/(X*BPP), MaxHardwareY) } QMAXFREE, FAR * LPQMAXFREE, * PQMAXFREE; /* ** This is used to set the Virtual Desktop Size ** ** INPUT: qsetvsize.dwSubFunc = QUERYSETVIRTUALSIZE ** OUTPUT: None */ typedef struct qsetvsize { DWORD dwSubFunc; // Should be set to QUERYSETVIRTUALSIZE DWORD dwX; // X Size in Pixels (X * BPP * Y <= MaxMemSize) DWORD dwY; // Y Size in Lines } QSETVSIZE, FAR * LPQSETVSIZE, * PQSETVSIZE; /* ** This is used to get the Virtual Desktop Start Address ** ** INPUT: qin.dwSubFunc = QUERYGETSTARTADDR ** OUTPUT: QGetStartAddr */ typedef struct qgetstartaddr { DWORD dwX; // X Location in Pixels DWORD dwY; // Y Location in Lines } QGETSTARTADDR, FAR * LPQGETSTARTADDR, * PQGETSTARTADDR; /* ** This is used to move the Virtual Desktop Start Address ** ** INPUT: qsetstartaddr.dwSubFunc = QUERYSETSTARTADDR ** OUTPUT: None */ typedef struct qsetstartaddr { DWORD dwSubFunc; // Should be set to QUERYSETSTARTADDR DWORD dwX; // X Location in Pixels (Note: Start Addr = X * BPP + Y * Display Pitch) DWORD dwY; // Y Location in Lines } QSETSTARTADDR, FAR * LPQSETSTARTADDR, * PQSETSTARTADDR; /* ** This is used to get the gamma values currently in use ** ** INPUT: qin.dwSubFunc = QUERYGETGAMMA ** OUTPUT: QGETGAMMA */ typedef struct qgetgamma { DWORD dwRed; // Red Gamma * 100 DWORD dwGreen; // Green Gamma * 100 DWORD dwBlue; // Blue Gamma * 100 DWORD GammaTable[256]; // Gamma Table Defined as 0x00BBGGRR } QGETGAMMA, FAR * LPQGETGAMMA, * PQGETGAMMA; /* ** This is used to set the Gamma Value ** ** INPUT: qSetGamma.dwSubFunc = QUERYSETSTARTADDR ** OUTPUT: None */ typedef struct qsetgamma { DWORD dwSubFunc; // Should be set to QUERYSETGAMMA DWORD dwRed; // Red Gamma * 100 DWORD dwGreen; // Green Gamma * 100 DWORD dwBlue; // Blue Gamma * 100 DWORD GammaTable[256]; // Gamma Table Defined as 0x00BBGGRR } QSETGAMMA, FAR * LPQSETGAMMA, * PQSETGAMMA; #define MAX_BIOS_VERSION_STRING (32) /* ** This is used to get the BIOS version ** ** INPUT: qin.dwSubFunc = QUERYGETBIOSVERSION ** OUTPUT: QGETBIOSVERSION */ typedef struct qgetbiosversion { BYTE bBIOSVersion[MAX_BIOS_VERSION_STRING]; } QGETBIOSVERSION, FAR * LPQGETBIOSVERSION, * PQGETBIOSVERSION; /* ** This is used to get the AGP Caps ** ** INPUT: qin.dwSubFunc = QUERYGETAGPCAPS ** OUTPUT: QGETAGPCAPS */ // These are also defined in h3g.h #define IS_AGP_CARD (0x00000001L) //Card has AGP capabilities #define IS_GART_AVAILABLE (0x00000002L) //VMM Gart Functions are present #define IS_AGP_READY (IS_AGP_CARD|IS_GART_AVAILABLE) //We can do AGP Functions on this card typedef struct qgetagpcaps { DWORD dwAGPCaps; } QGETAGPCAPS, FAR * LPQGETAGPCAPS, * PQGETAGPCAPS; /* HWCEXT_LCDCTRL * * Enables or disables flat panel monitor and also returns current status as * given in IN-OUT struct below: * */ // CAUTION: this is mirrored in h3g.h!!! typedef struct { DWORD dwSubFunc; // Should be set to QGETSET_LCDCTRL DWORD maxWidth; // out DWORD maxHeight; // out DWORD refreshRate; // out DWORD fpFlags; // in - out } QGETSET_LCDCTRL; #define FPFLAG_ENABLED BIT(0) // is currently enabled (OUT) #define FPFLAG_PRESENT BIT(1) // panel & controller connected (OUT) #define FPFLAG_PRESENT_AT_BOOT BIT(2) // panel & controller connected // at boot time (OUT) #define FPFLAG_ENABLE BIT(3) // try to enable panel (IN) #define FPFLAG_DISABLE BIT(4) // try to disable panel (IN) #define FPFLAG_GET_DIMS BIT(5) // read the EDID to get panel's // physical dimensions (IN) #define FPFLAG_SETRES BIT(6) // current desktop resolution too hi // (OUT) #define FPFLAG_SETREFR BIT(7) // current refresh rate wrong (OUT) // filter bits // 00 bilinear 01 gausian // 10 crisp 11 extra crisp #define FPFLAG_FILTER_SOFT BIT(8) // use these 2 bits together (IN) #define FPFLAG_FILTER_HARD BIT(9) #define FPFLAG_CAPABLE BIT(10) // board has controller & BIOS typedef struct { DWORD dwSubFunc; // Should be set to QUERY_ANALOG_MONITOR DWORD monitorStatus; DWORD monitorControl; } QGETSET_MONITOR_CTL; #define ENABLE_MONITOR BIT(0) #define DISABLE_MONITOR BIT(1) #define MONITOR_IS_ENABLED BIT(2) #ifdef WINNT int QueryMode(PDEV *, LPQIN lpQIN, LPVOID lpOutput); #else int QueryMode(LPQIN lpQIN, LPVOID lpOutput); #endif #endif glide3x/h5/glide3/src/rcver.h0100700000175300010010000000620107725034670015263 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONL ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGH ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DF ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT T ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS I ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FA ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS O ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Log: ** */ #include "fxbldno.h" #define MANVERSION 3 #define MANREVISION 10 #define MINVERSION 00 //#define BUILD_NUMBER 3001 /* hmm, must be at least 674 for the 3dfx OpenGL ICD to work correctly */ #define VERSIONSTR "3.10.00." BUILD_NUMBER_STR #define CONTACTSTR "The Glide Open Source Project http://glide.sourceforge.net/" #if defined(__WIN32__) #define _TRADEMARK_ "(tm)" #define _REGISTERED_ "\256" #define _COPYRIGHT_ "\251" #elif defined(macintosh) #define _TRADEMARK_ "\252" #define _REGISTERED_ "\250" #define _COPYRIGHT_ "\251" #else #define _TRADEMARK_ "(tm)" #define _REGISTERED_ "(R)" #define _COPYRIGHT_ "(C)" #endif #ifdef SST1 # define HWSTR "Voodoo Graphics" _REGISTERED_ # ifdef NT_BUILD # define PRODNAME "Glide" _REGISTERED_ " for Voodoo Graphics" _COPYRIGHT_ " & Windows" _REGISTERED_ " NT" # else # define PRODNAME "Glide" _REGISTERED_ " for Voodoo Graphics" _COPYRIGHT_ " & Windows" _REGISTERED_ " 95/98" # endif /* NT_BUILD */ #elif defined(SST96) # define HWSTR " Voodoo Rush" _REGISTERED_ "" # ifdef NT_BUILD # define PRODNAME "Glide" _REGISTERED_ " for Voodoo Rush" _COPYRIGHT_ " & Windows" _REGISTERED_ " NT" # else # define PRODNAME "Glide" _REGISTERED_ " for Voodoo Rush" _COPYRIGHT_ " & Windows" _REGISTERED_ " 95/98" # endif /* NT_BUILD */ #elif defined(CVG) || defined(VOODOO2) # define HWSTR " Voodoo^2" _REGISTERED_ "" # ifdef NT_BUILD # define PRODNAME "Glide" _REGISTERED_ " for Voodoo^2" _COPYRIGHT_ " & Windows" _REGISTERED_ " NT" # else # define PRODNAME "Glide" _REGISTERED_ " for Voodoo^2" _COPYRIGHT_ " & Windows" _REGISTERED_ " 95/98" # endif /* NT_BUILD */ #elif defined(H3) || defined(H5) # define HWSTR " Voodoo Banshee" _REGISTERED_ ", Velocity" _TRADEMARK_ " 100/200, Voodoo3" _REGISTERED_ ", Voodoo4" _REGISTERED_ ", & Voodoo5" _REGISTERED_ # define PRODNAME "Glide" _REGISTERED_ " for Voodoo Banshee" _REGISTERED_ ", Velocity" _TRADEMARK_ "100/200, Voodoo3" _REGISTERED_ " , Voodoo4" _REGISTERED_ ", & Voodoo5" _REGISTERED_ "; Windows" _REGISTERED_ " 95/98/Me/NT4/2000/XP" #else # define HWSTR "Some Hoopti Chip" _REGISTERED_ "" #endif glide3x/h5/glide3/src/tv.h0100700000175300010010000005560307725034670014605 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Revision: 1.3.4.2 $ ** $Date: 2003/06/05 08:23:55 $ ** $Log: ** 4 3dfx 1.1.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 3 3dfx 1.1.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 2 3dfx 1.1 09/24/99 Mark McMahon Fixed PRS 7906: ** Incorrect memory size reported by control panel in SLI mode ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ // // 1 17/09/99 15:29 Mmcmahon // Voodoo2 Windows 98 control panel. ** ** 12 5/14/99 9:43p Stb_rbissell ** tvout and dfp changes ** ** 11 3/31/99 1:38p Pratt ** added define for TV composite (Stuart did it but forgot to check in ** before he left) ** ** 10 3/02/99 4:20p Stuartb ** Removed obsolete TV_STANDARD_XXX defines. ** ** 9 2/16/99 3:47p Stuartb ** Added some BIOS_XXXX tvout & LCD defines. ** ** 8 2/13/99 6:45p Stuartb ** First cut at PAL_M, PAL_N, PAL_NC support in tvout. ** ** 7 99/01/26 11:51 Larryw ** Bringing the other tv.h's into sync with the changes made to ** $/devel/h3/Win95/dx/inc/tv.h (including QUERYENABLETV). ** ** 2 1/14/99 3:50p Stuartb ** Added #define QUERYENABLETV. ** ** 1 9/10/98 2:55p Stuartb ** Interface file for TVOUT. ** ** 2 7/11/98 8:18a Andrew ** changed some comments ** ** 1 5/12/98 9:34a Andrew ** First attempt at TV out interface ** */ #ifndef _TV_H_ #define _TV_H_ #ifdef VDDONLY #define FAR #endif // TVOut Queries #define QUERYTVAVAIL (0x300) // Returns Status Determined at Boot #define QUERYTVSENSE (0x301) // Performs a Sense on the available connectors // Individual Queries on Capabilities #define QUERYGETPICCAP (0x321) // Get Individual Picture Control Capability #define QUERYGETFILTERCAP (0x322) // Get Individual Filter Control Capability #define QUERYGETPOSCAP (0x323) // Get Individual Position Control Capability #define QUERYGETSIZECAP (0x324) // Get Individual Size Control Capability #define QUERYGETSPECIALCAP (0x325) // Get Individual Special Control Capability // Get Current Settings #define QUERYGETSTANDARD (0x340) // Get Current Standard Setting #define QUERYGETPICCONTROL (0x341) // Get Individual Picture Control Setting #define QUERYGETFILTERCONTROL (0x342) // Get Individual Filter Control Setting #define QUERYGETPOSCONTROL (0x343) // Get Position Control Setting #define QUERYGETSIZECONTROL (0x344) // Get Size Control Setting #define QUERYGETSPECIAL (0x345) // Get Individual Special Control Setting #define QUERYGETCONSTATUS (0x346) // Get Connector Status #define QUERYGETOVERRIDE (0x347) // Get Connector autosense override // Set Settings #define QUERYSETSTANDARD (0x360) // Set Current Standard Setting #define QUERYSETPICCONTROL (0x361) // Set Individual Picture Control Setting #define QUERYSETFILTERCONTROL (0x362) // Set Individual Filter Control Setting #define QUERYSETPOSCONTROL (0x363) // Set Individual Position Control Setting #define QUERYSETSIZECONTROL (0x364) // Set Individual Size Control Setting #define QUERYSSETSPECIAL (0x365) // Set Individual Special Control Setting #define QUERYSETCONSTATUS (0x366) // Set Connector Status #define QUERYSETOVERRIDE (0x367) // Set Connector autosense override // Registery Updates #define QUERYCOMMITREG (0x380) // This should be called after the user hits ok #define QUERYREFRESH (0x381) // This should be called if the user hits cancel // Enable/Disable TV-Out #define QUERYDISABLETV (0x500) // Disable TV-Out and switch CRT On #define QUERYENABLETV (0x501) // This just enables mode selection #define QUERYTVOUTPUT (0x502) // is tv output on, or off? /* ** Call this function first to know how if a TV Encoder is ** available and what general functionality it provides ** ** INPUT: qin.dwSubFunc = QUERYTVAVAIL ** OUTPUT: TVSTATUS */ typedef struct tvcon { DWORD dwType; // Type of the Connector DWORD dwStatus; // Connector Status } TVCON, FAR * LPTVCON, * PTVCON; // To be used in the Type Field of TVCON #define TV_TYPE_SVIDEO (0x00000001L) #define TV_TYPE_COMPOSITE (0x00000002L) #define TV_TYPE_SCART (0x00000004L) #define TV_TYPE_UNKNOWN (0x00000008L) // for broken bt868 rev d // To be used in the Status Field of TVCON #define TV_PRESENT (0x00000001L) // Did sense determine TV on connector ? #define TV_CONNECTOR_ENABLED (0x00000002L) // Is Connector Currently Enabled ? #define MAX_CONNECTORS (0x000000004L) // This structure defines what we are capable of typedef struct qtvstatus { DWORD dwEncoder; // Did I2C Query find a TV Encoder DWORD dwStandard; // Bit Map of Standard's Supported DWORD dwPicControl; // Bit Map of Picture Controls DWORD dwFilterControl; // Bit Map of Filter Controls DWORD dwPosControl; // Bit Map of Position Controls DWORD dwSizeControl; // Bit Map of Size Controls DWORD dwSpecial; // Bit Map of Special Controls DWORD dwNumSimultaneous; // How many outputs can you support at the same time? DWORD dwNumConnectors; // How many connectors does the Encoder support TVCON TVCon[MAX_CONNECTORS]; // TV Connector Status BYTE szName[10]; // Name of the Encoder } QTVSTATUS, FAR * LPQTVSTATUS, * PTVSTATUS; // To be used in TVStatus.dwEncoder #define TV_ENCODER_PRESENT (0x00000001L) // To be used in TVStatus.dwPicControl #define TV_BRIGHTNESS (0x00000001) #define TV_CONTRAST (0x00000002) #define TV_GAMMA (0x00000004) #define TV_HUE (0x00000008) #define TV_SATURATION (0x00000010) #define TV_SHARPNESS (0x00000020) // To be used in TVStatus.dwFilter #define TV_FLICKER (0x10000001) #define TV_CHROMA (0x10000002) #define TV_LUMA (0x10000004) // To be used in TVStatus.dwPosControl #define TV_HORIZONTAL (0x00000001) #define TV_VERTICAL (0x00000002) // To be used in TVStatus.dwSizeControl #define TV_UNDERSCAN (0x00000001) #define TV_OVERSCAN (0x00000002) #define TV_ADJUST_UNDERSCAN (0x00000004) #define TV_ADJUST_OVERSCAN (0x00000008) // To be used in TVStatus.dwSpecial #define TV_CLOSED_CAPTION (0x00000001) #define TV_MACROVISION (0x00000002) #define TV_LCDPANEL (0x00000004) /* Flat panel out */ // To be used in TVSetSpec.dwCap for miscellaneous features #define TV_SETSPECIAL_CCAPTION (0x00000001) #define TV_SETSPECIAL_MACROVISION (0x00000002) #define TV_SETSPECIAL_LCDPANEL (0x00000004) /* Flat panel out */ #define TV_SETSPECIAL_WR_LCDREG (0x00000005) /* For debug */ #define TV_SETSPECIAL_RD_LCDREG (0x00000006) /* For debug */ #define MAX_SPECIAL_DATA 512 /* ** Call this function to request the Driver to perform ** a sense on every connector ** ** INPUT: qin.dwSubFunc = QUERYTVSENSE ** OUTPUT: TVCONSTATUS */ typedef struct tvconstatus { DWORD dwNumConnectors; // How many connectors does the Encoder support TVCON TVCon[MAX_CONNECTORS]; // TV Connector Status } TVCONSTATUS, FAR * LPTVCONSTATUS, * PTVCONSTATUS; /**************************************************************************** ** ** Get Capabilities ** ****************************************************************************/ typedef struct qind { DWORD dwSubFunc; // Sub Function DWORD dwCap; // Capability of Interest } QIND, FAR * LPQIND, * PQIND; /* ** Call this function to request the Driver to ** report individual Picture Capability ** ** INPUT: qind.dwSubFunc = QUERYGETPICCAP ** qind.dwCap = TV_BRIGHTNESS | ** TV_CONTRAST | ** TV_GAMMA | ** TV_HUE | ** TV_SATURATION | ** TV_SHARPNESS ** OUTPUT: TVCAPDATA */ typedef struct tvcapdata { DWORD dwCap; // Capability of Interest DWORD dwNumSteps; // Number of Steps Supported by Hardware } TVCAPDATA, FAR * LPTVCAPDATA, * PTVCAPDATA; /* ** Call this function to request the Driver to ** report all Position Capability ** ** INPUT: qin.dwSubFunc = QUERYGETPOSITIONCAP ** OUTPUT: TVPOSCAP ** Note this is a good match for Chrontel but unknown now to do this on Brooktree */ typedef struct tvposcap { DWORD dwMaxLeft; // Maximum Left Position in Hardware Units DWORD dwMaxRight; // Maximum Right Position in Hardware Units DWORD dwHorGranularity; // Size of Movement in Pixels DWORD dwMaxTop; // Maximum Top Position in Hardware Units DWORD dwMaxBottom; // Maximum Bottom Position in Hardware Units DWORD dwVGAGranularity; // Granularity in VGA Lines } TVPOSCAP, FAR * LPTVPOSCAP, * PTVPOSCAP; /* ** Call this function to request the Driver to ** report all Size Capability ** ** INPUT: qin.dwSubFunc = QUERYGETSIZECAP ** OUTPUT: TVSIZECAP ** Note this is a good match for BrookTree but unknown now to do this on Chrontel */ typedef struct tvsizecap { DWORD dwMaxHorInput; // Maximum Input Horizontal Size in Active Pixels DWORD dwMaxVerInput; // Maximum Input Vertical Size in Active Lines DWORD dwMaxHorOutput; // Maximum Output Horizontal Size in Active Pixels DWORD dwMaxVerOutput; // Maximum Output Vertical Size in Active Pixels DWORD dwMinHorInput; // Minimum Input Horizontal Size in Active Pixels DWORD dwMinVerInput; // Minimum Input Vertical Size in Active Lines DWORD dwMinHorOutput; // Minimum Output Horizontal Size in Active Pixels DWORD dwMinVerOutput; // Minimum Output Vertical Size in Active Pixels DWORD dwHorStepSize; // In Percentage * 1000 DWORD dwVerStepSize; // In Percentage * 1000 } TVSIZECAP, FAR * LPTVSIZECAP, * PTVSIZECAP; /* ** Call this function to request the Driver to ** report on a Special Capability ** ** INPUT: qind.dwSubFunc = QUERYGETSPECIALCAP ** qind.dwCap = TV_CLOSED_CAPTION | ** TV_MACROVISION | ** TV_LCDPANEL ** OUTPUT: TVSPECCAP */ /**************************************************************************** ** ** Get Current Settings ** ****************************************************************************/ /* ** Call this function to request the Driver to ** report current Standard Setting ** ** INPUT: qin.dwSubFunc = QUERYGETSTANDARD or QUERYGETOVERRIDE ** OUTPUT: TVGETSTANDARD */ typedef struct tvgetstandard { DWORD dwStandard; // Standard Currently in Use } TVGETSTANDARD, FAR * LPTVGETSTANDARD, * PTVGETSTANDARD; /* ** Call this function to request the Driver to ** report current individual Picture Capability ** ** INPUT: qind.dwSubFunc = QUERYGETPICCONTROL ** qind.dwCap = TV_BRIGHTNESS | ** TV_CONTRAST | ** TV_GAMMA | ** TV_HUE | ** TV_SATURATION | ** TV_SHARPNESS ** OUTPUT: TVCURCAP */ typedef struct tvcurcap { DWORD dwCap; // Capability Requested DWORD dwStep; // Current Hardware Step we are on } TVCURCAP, FAR * LPTVCURCAP, * PTVCURCAP; /* ** Call this function to request the Driver to ** report current individual Filter Capability ** ** INPUT: qind.dwSubFunc = QUERYGETFILTERCONTROL ** qind.dwCap = TV_FLICKER | ** TV_CHROMA | ** TV_LUMA ** OUTPUT: TVCURCAP */ /* ** Call this function to request the Driver to ** report all current Position Capability ** ** INPUT: qin.dwSubFunc = QUERYGETPOSITIONCONTROL ** OUTPUT: TVCURPOS ** Note this is a good match for Chrontel but unknown now to do this on Brooktree */ typedef struct tvcurpos { DWORD dwCurLeft; // Current Left Position in Hardware Units DWORD dwCurRight; // Current Right Position in Hardware Units DWORD dwCurTop; // Current Top Position in Hardware Units DWORD dwCurBottom; // Current Bottom Position in Hardware Units } TVCURPOS, FAR * LPTVCURPOS, * PTVCURPOS; /* ** Call this function to request the Driver to ** report current Size Capability ** ** INPUT: qin.dwSubFunc = QUERYGETSIZECONTROL ** OUTPUT: TVCURSIZE ** Note this is a good match for BrookTree but unknown now to do this on Chrontel */ typedef struct tvcursize { DWORD dwCurHorInput; // Current Input Horizontal Size in Active Pixels DWORD dwCurVerInput; // Current Input Vertical Size in Active Lines DWORD dwCurHorOutput; // Current Output Horizontal Size in Active Pixels DWORD dwCurVerOutput; // Current Output Vertical Size in Active Pixels } TVCURSIZE, FAR * LPTVCURSIZE, * PTVCURSIZE; /* ** Call this function to request the Driver to ** report on current a Special Capability ** ** INPUT: qind.dwSubFunc = QUERYGETSPECIAL ** qind.dwCap = TV_CLOSED_CAPTION | ** TV_MACROVISION ** OUTPUT: TVCURSPEC */ /* ** Call this function to request the Driver to return ** in memory data on every connector ** ** INPUT: qin.dwSubFunc = QUERYGETCONSTATUS ** OUTPUT: TVCONSTATUS */ /**************************************************************************** ** ** Set Functions ** ****************************************************************************/ /* ** Call this function to request the Driver to ** change the current Standard Setting ** ** INPUT: TvSetStandard.dwSubFunc = QUERYSETSTANDARD ** TvSetStandard.dwStandard = TV_STANDARD_NTSCRS170A | ** TV_STANDARD_NTSCM | ** TV_STANDARD_NTSCN | ** TV_STANDARD_NTSC443 | ** TV_STANDARD_NTSCJAPAN | ** TV_STANDARD_PALBDGHI | ** TV_STANDARD_PALM | ** TV_STANDARD_PALN | ** TV_STANDARD_PALN_ARGENTINA | ** ** OUTPUT: None */ typedef struct tvsetstandard { DWORD dwSubFunc; // Sub Function DWORD dwStandard; // Standard Currently in Use } TVSETSTANDARD, FAR * LPTVSETSTANDARD, * PTVSETSTANDARD; /* ** Call this function to request the Driver to ** set individual Picture Capability ** ** INPUT: TVSetCap.dwSubFunc = QUERYSETPICCONTROL ** TVSetCap.dwCap = TV_BRIGHTNESS | ** TV_CONTRAST | ** TV_GAMMA | ** TV_HUE | ** TV_SATURATION | ** TV_SHARPNESS ** TVSetCap.dwStep = ** OUTPUT: None */ typedef struct tvsetcap { DWORD dwSubFunc; // SubFunction DWORD dwCap; // Capability Requested LONG dwStep; // Hardware Step to set } TVSETCAP, FAR * LPTVSETCAP, * PTVSETCAP; /* ** Call this function to request the Driver to ** set individual Filter Capability ** ** INPUT: TVSetCap.dwSubFunc = QUERYSETFILTERCONTROL ** TVSetCap.dwCap = TV_FLICKER | ** TV_CHROMA | ** TV_LUMA ** TVSetCap.dwStep = ** OUTPUT: None */ /* ** Call this function to request the Driver to ** move the Output Image ** ** INPUT: TVSetPos.dwSubFunc = QUERYSETPOSCONTROL ** TVSetPos.dwLeft = ** TVSetPos.dwRight = ** TVSetPos.dwTop = ** TVSetPos.dwBottom = ** OUTPUT: None ** Note this is a good match for Chrontel but unknown now to do this on Brooktree */ typedef struct tvsetpos { DWORD dwSubFunc; // SubFunction DWORD dwLeft; // Left Position in Hardware Units DWORD dwRight; // Right Position in Hardware Units DWORD dwTop; // Top Position in Hardware Units DWORD dwBottom; // Bottom Position in Hardware Units } TVSETPOS, FAR * LPTVSETPOS, * PTVSETPOS; /* ** Call this function to request the Driver to ** set the resize the input/output ** ** INPUT: TVSetSize.dwSubFunc = QUERYSETSIZECONTROL ** TvSetSize.dwHorOutput = ** TvSetSize.dwVerOutput = ** OUTPUT: None ** Note this is a good match for BrookTree but unknown now to do this on Chrontel */ typedef struct tvsetsize { DWORD dwSubFunc; // SubFunction DWORD dwOverScan; // Overscan enable/disable DWORD dwHorOutput; // Output Horizontal Size in Active Pixels DWORD dwVerOutput; // Output Vertical Size in Active Lines } TVSETSIZE, FAR * LPTVSETSIZE, * PTVSETSIZE; /* ** Call this function to request the Driver to ** set the a Special Capability ** ** INPUT: TVSetSpec.dwSubFunc = QUERYSETSPECIAL ** TVSetSpec.dwCap = TV_SETSPECIAL_CCAPTION | ** TV_SETSPECIAL_MACROVISION | ** TV_SETSPECIAL_LCDPANEL ** OUTPUT: None */ typedef struct tvsetspecial { DWORD dwSubFunc; // Sub Function DWORD dwCap; // Feature to set DWORD dwIndex; // Index to data array: 0 - none WORD wData[MAX_SPECIAL_DATA]; // Data array: format specific to caps DWORD dwIPclock; // Flat panel clock } TVSETSPECIAL, FAR * LPTVSETSPECIAL, * PTVSETSPECIAL; /* ** Call this function to request the Driver to enable/disable ** connectors ** ** INPUT: TVSetConnector.dwSubFunc = QUERYSETCONSTATUS ** Note i can range from 0 to < dwNumSimultaneous ** TVSetConnector.TVCon[i].dwType = TV_TYPE_SVIDEO | TV_TYPE_COMPOSITE | TV_TYPE_SCART ** TVSetConnector.TVCon[i].dwStatus = TV_CONNECTOR_ENABLED | 0x00 ** ** OUTPUT: None */ typedef struct tvsetconnector { DWORD dwSubFunc; // SubFunction TVCON TVCon[MAX_CONNECTORS]; // TV Connector Status } TVSETCONNECTOR, FAR * LPTVSETCONNECTOR, * PTVSETCONNECTOR; /**************************************************************************** ** ** Registry Functions ** ****************************************************************************/ /* ** Call this function to request the Driver to save ** in memory data to registry ** ** INPUT: qin.dwSubFunc = QUERYCOMMITREG ** OUTPUT: None */ /* ** Call this function to request the Driver to refresh ** in memory data with registry data ** ** INPUT: qin.dwSubFunc = QUERYREFRESH ** OUTPUT: None */ /**************************************************************************** ** ** Error codes ** ****************************************************************************/ #define TV_STANDARD_UNSUPPORTED (0x00000001L) #define TV_CONTROL_UNSUPPORTED (0x00000002L) #define TV_INVALID_DEVICE (0x000000ffL) /**************************************************************************** ** ** TV standards that we support taken from win98 ddk tvout.h ** ****************************************************************************/ #define VP_TV_STANDARD_NTSC_M 0x0001 // 75 IRE Setup #define VP_TV_STANDARD_NTSC_M_J 0x0002 // Japan, 0 IRE Setup #define VP_TV_STANDARD_PAL_B 0x0004 #define VP_TV_STANDARD_PAL_D 0x0008 #define VP_TV_STANDARD_PAL_H 0x0010 #define VP_TV_STANDARD_PAL_I 0x0020 #define VP_TV_STANDARD_PAL_M 0x0040 #define VP_TV_STANDARD_PAL_N 0x0080 #define VP_TV_STANDARD_SECAM_B 0x0100 #define VP_TV_STANDARD_SECAM_D 0x0200 #define VP_TV_STANDARD_SECAM_G 0x0400 #define VP_TV_STANDARD_SECAM_H 0x0800 #define VP_TV_STANDARD_SECAM_K 0x1000 #define VP_TV_STANDARD_SECAM_K1 0x2000 #define VP_TV_STANDARD_SECAM_L 0x4000 #define VP_TV_STANDARD_WIN_VGA 0x8000 // and the rest #define VP_TV_STANDARD_NTSC_433 0x00010000 #define VP_TV_STANDARD_PAL_G 0x00020000 #define VP_TV_STANDARD_PAL_60 0x00040000 #define VP_TV_STANDARD_SECAM_L1 0x00080000 #define VP_TV_STANDARD_PAL_NC VP_TV_STANDARD_SECAM_L1 // these describe use of BIOS_SCRATCH_REGISTER_2 (index 0x1e) bits #define BIOS_NTSC 0x01 // 00001 #define BIOS_PAL 0x02 // (BGDHI) 00010 #define BIOS_PAL_N 0x0a // 01010 #define BIOS_PAL_M 0x12 // 10010 #define BIOS_PAL_Nc 0x1a // 11010 #define BIOS_TVSTD_MASK (BIOS_NTSC | BIOS_PAL | BIOS_PAL_N | BIOS_PAL_M | BIOS_PAL_Nc) #define BIOS_LCD_ACTIVE 0x04 #define BIOS_TVOUT_ACTIVE 0x20 #define BIOS_TVOUT_COMPOSITE 0x40 #endif glide3x/h5/glide3/src/version.r0100700000175300010010000000051107725034670015637 0ustar johndoeNone#include #define __VERSION_REZ__ #include "MacGlide3.h" #include "rcver.h" Resource 'vers' (1, "") { MANVERSION, ((MANREVISION / 10) << 4) | (MANREVISION % 10), #if DEBUG development, #else /* !DEBUG */ release, #endif /* !DEBUG */ 0, verUS, BASE_VERSIONSTR, BASE_HWSTR" "BASE_VERSIONSTR" for MacOS" }; glide3x/h5/glide3/src/winsurf.cpp0100700000175300010010000002606007725034670016177 0ustar johndoeNone// // This sets up Windowed rendering // #include extern "C" { // All this is C Linked #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" #include "fxcmd.h" #include "gsfc.h" }; /* Begin hacky stuff to enable windowed Glide rendering in Windows */ #include static LPDIRECTDRAW lpDDraw1 = 0; static LPDIRECTDRAW2 lpDDraw2 = 0; static LPDIRECTDRAWSURFACE lpPrimSurf = 0; static LPDIRECTDRAWSURFACE lpColSurf = 0; static LPDIRECTDRAWSURFACE lpAuxSurf = 0; static LPDIRECTDRAWSURFACE lpTexSurf0 = 0; static LPDIRECTDRAWSURFACE lpTexSurf1 = 0; static HWND thehWnd = 0; static DWORD surfWidth = 0; static DWORD surfHeight = 0; static DWORD screenWidth = 0; static DWORD screenHeight = 0; static DWORD bpp = 0; static BOOL useDDOverlay = FALSE; static INT WindowPosX = 0; static INT WindowPosY = 0; extern "C" void doSplash( void ); extern "C" void _grReleaseWindowSurface(GrContext_t ctx); #define OVERLAY_COLOUR 0x0D0E0F /* This will create our DirectDraw surfaces and create the context */ extern "C" GrContext_t _grCreateWindowSurface(FxU32 hWnd, GrColorFormat_t format, GrOriginLocation_t origin, GrPixelFormat_t pixelformat, int nAuxBuffer) { /* Disable this for now */ // return 0; /* Allocate a context */ GrContext_t ctx = grSurfaceCreateContext(GR_SURFACECONTEXT_WINDOWED); GrGC *gc = (GrGC *)ctx; thehWnd = (HWND) hWnd; screenWidth = GetSystemMetrics(SM_CXSCREEN); screenHeight = GetSystemMetrics(SM_CYSCREEN); RECT clientRect; GetClientRect(thehWnd, &clientRect); surfWidth = clientRect.right - clientRect.left; surfHeight = clientRect.bottom - clientRect.top; switch(pixelformat) { case GR_PIXFMT_ARGB_8888: case GR_PIXFMT_AA_2_ARGB_8888: case GR_PIXFMT_AA_4_ARGB_8888: case GR_PIXFMT_AA_8_ARGB_8888: bpp = 32; break; default: if (0 && _GlideRoot.environment.outputBpp == 32) { gc->state.forced32BPP = 16; bpp = 32; } else bpp = 16; break; } bpp = 16; /* Now, create DirectDraw */ if ( DirectDrawCreate( NULL, &lpDDraw1, NULL ) != DD_OK) { GDBG_INFO(80, "DDraw Obj Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } GDBG_INFO(80, "DDraw Obj created!\n"); /* Get us a DirectDraw2 interface */ if ( lpDDraw1->QueryInterface (IID_IDirectDraw2, (LPVOID*)&lpDDraw2 ) != DD_OK ) { GDBG_INFO(80, "DDraw2 Obj Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } GDBG_INFO(80, "DDraw2 Obj created!\n"); /* Set the Coop level to normal */ lpDDraw2->SetCooperativeLevel((HWND) hWnd, DDSCL_NORMAL); /* Now create us a Primary surface */ DDSURFACEDESC ddsd; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY; if (lpDDraw2->CreateSurface(&ddsd, &lpPrimSurf, NULL) != DD_OK) { GDBG_INFO(80, "Primary Surface Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } /* Now create us a Colour surface */ if (useDDOverlay) do { memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY; ddsd.dwWidth = surfWidth; ddsd.dwHeight = screenHeight; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = bpp; ddsd.ddpfPixelFormat.dwRGBBitCount = 16; ddsd.ddpfPixelFormat.dwRBitMask = 0xF800; ddsd.ddpfPixelFormat.dwGBitMask = 0x07E0; ddsd.ddpfPixelFormat.dwBBitMask = 0x001F; if (lpDDraw2->CreateSurface(&ddsd, &lpColSurf, NULL) != DD_OK) { GDBG_INFO(80, "Overlay Colour Surface Create Failed!\n"); lpColSurf = 0; break; } RECT rectOverlay = {0,0,surfWidth,surfHeight}; RECT rectClient; DDOVERLAYFX ddofx; POINT p = {0, 0}; GetClientRect(thehWnd, &rectClient); ClientToScreen(thehWnd, &p); rectClient.bottom += p.y; rectClient.top = p.y; rectClient.left = p.x; rectClient.right += p.x; WindowPosX = p.x; WindowPosY = p.y; memset(&ddofx, 0, sizeof(ddofx)); ddofx.dwSize = sizeof(ddofx); ddofx.dckDestColorkey.dwColorSpaceLowValue = OVERLAY_COLOUR; ddofx.dckDestColorkey.dwColorSpaceHighValue = OVERLAY_COLOUR; HRESULT ddrval = lpColSurf->UpdateOverlay(&rectOverlay, lpPrimSurf, &rectClient, DDOVER_SHOW|DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE, &ddofx); if(ddrval != DD_OK) { GDBG_INFO(80, "Unable to update overlay!\n"); lpColSurf->Release(); lpColSurf = 0; break; } /* Now Fill Primary with the col */ DDBLTFX ddbfx; memset(&ddbfx, 0, sizeof(ddbfx)); ddbfx.dwSize = sizeof(DDBLTFX); ddbfx.dwFillColor = OVERLAY_COLOUR; lpPrimSurf->Blt(&rectClient, NULL, &rectClient, DDBLT_COLORFILL|DDBLT_WAIT, &ddbfx); //lpColSurf->Release(); //lpColSurf = 0; } while(0); if (!lpColSurf) { useDDOverlay = FALSE; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM; ddsd.dwWidth = surfWidth; ddsd.dwHeight = screenHeight; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = bpp; if (lpDDraw2->CreateSurface(&ddsd, &lpColSurf, NULL) != DD_OK) { GDBG_INFO(80, "Colour Surface Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } } /* Now create us a Aux surface */ if (nAuxBuffer) { memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM; ddsd.dwWidth = surfWidth; ddsd.dwHeight = screenHeight; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = bpp; if (lpDDraw2->CreateSurface(&ddsd, &lpAuxSurf, NULL) != DD_OK) { GDBG_INFO(80, "Aux Surface Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } } /* Now create us a Tex surface */ memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM; ddsd.dwWidth = 2048; ddsd.dwHeight = 2048; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = 16; if (lpDDraw2->CreateSurface(&ddsd, &lpTexSurf0, NULL) != DD_OK) { GDBG_INFO(80, "Tex Surface Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } if (gc->num_tmu == 2) { if (lpDDraw2->CreateSurface(&ddsd, &lpTexSurf1, NULL) != DD_OK) { GDBG_INFO(80, "Tex Surface Create Failed!\n"); _grReleaseWindowSurface(ctx); return 0; } } /* Select the Context */ grSelectContext(ctx); /* Set the Render Buffer */ grSurfaceSetRenderingSurface((GrSurface_t*) lpColSurf, FXFALSE); /* Set the Aux Buffer */ if (nAuxBuffer) grSurfaceSetAuxSurface((GrSurface_t*) lpAuxSurf); /* Now create the texture buffer0 and 1 */ grSurfaceSetTextureSurface(GR_TMU0, (GrSurface_t*) lpTexSurf0); if (gc->num_tmu == 2) grSurfaceSetTextureSurface(GR_TMU1, (GrSurface_t*) lpTexSurf1); /* Set some 'crap' */ gc->grHwnd = hWnd; gc->grColBuf = gc->state.num_buffers = 2; gc->grAuxBuf = nAuxBuffer; gc->grPixelFormat = (int) pixelformat; gc->chipmask = SST_CHIP_MASK_ALL_CHIPS; gc->state.color_format = format; gc->sliCount = 1; grSstOrigin(origin); /* Clear the buffers */ grBufferClear( 0x0, 0, 0 ); return ctx; } /* This will blit/flip our surfaces */ extern "C" void _grFlipWindowSurface() { // Blit from col to prim if (lpPrimSurf && lpColSurf) { POINT ptClient; ptClient.x = 0; ptClient.y = 0; ClientToScreen(thehWnd, &ptClient); if (!useDDOverlay) { RECT region; region.bottom = min(surfHeight,screenHeight-ptClient.y); region.right = min(surfWidth,screenWidth-ptClient.x); region.top = 0; region.left = 0; if (ptClient.y < 0) { region.top = -ptClient.y; ptClient.y = 0; } if (ptClient.x < 0) { region.left = -ptClient.x; ptClient.x = 0; } if (region.bottom != region.top && region.left != region.right) lpPrimSurf->BltFast(ptClient.x, ptClient.y, lpColSurf, ®ion, 0); } else { /* Need to update the overlay */ if (ptClient.x != WindowPosX || ptClient.y != WindowPosY) { WindowPosX = ptClient.x; WindowPosY = ptClient.y; RECT region; RECT rectClient; region.bottom = min(surfHeight,screenHeight-ptClient.y); region.right = min(surfWidth,screenWidth-ptClient.x); region.top = 0; region.left = 0; if (ptClient.y < 0) { region.top = -ptClient.y; rectClient.top = 0; } else { rectClient.top = ptClient.y; } if (ptClient.x < 0) { region.left = -ptClient.x; rectClient.left = 0; } else { rectClient.left = ptClient.x; } // Now we need to work out dest width and height rectClient.right = (region.right-region.left)+rectClient.left; rectClient.bottom = (region.bottom-region.top)+rectClient.top; DDOVERLAYFX ddofx; memset(&ddofx, 0, sizeof(ddofx)); ddofx.dwSize = sizeof(ddofx); ddofx.dckDestColorkey.dwColorSpaceLowValue = OVERLAY_COLOUR; ddofx.dckDestColorkey.dwColorSpaceHighValue = OVERLAY_COLOUR; HRESULT ddrval = lpColSurf->UpdateOverlay(®ion, lpPrimSurf, &rectClient, DDOVER_SHOW|DDOVER_DDFX|DDOVER_KEYDESTOVERRIDE, &ddofx); if(ddrval != DD_OK) { GDBG_INFO(80, "Unable to update overlay!\n"); lpColSurf->Release(); lpColSurf = 0; } else { /* Now Fill Primary with the col */ DDBLTFX ddbfx; memset(&ddbfx, 0, sizeof(ddbfx)); ddbfx.dwSize = sizeof(DDBLTFX); ddbfx.dwFillColor = OVERLAY_COLOUR; lpPrimSurf->Blt(&rectClient, NULL, &rectClient, DDBLT_COLORFILL|DDBLT_WAIT, &ddbfx); } } } } } /* This will release the context, and release the surfaces, and destroy the DDRAW objects */ extern "C" void _grReleaseWindowSurface(GrContext_t ctx) { // Release Context grSurfaceReleaseContext(ctx); GDBG_INFO(80, "Released context!\n"); // Now release all the surfaces if (lpTexSurf1) { lpTexSurf1->Release(); lpTexSurf1 = 0; } if (lpTexSurf0) { lpTexSurf0->Release(); lpTexSurf0 = 0; } if (lpAuxSurf) { lpAuxSurf->Release(); lpAuxSurf = 0; } if (lpColSurf) { lpColSurf->Release(); lpColSurf = 0; } if (lpPrimSurf) { lpPrimSurf->Release(); lpPrimSurf = 0; } GDBG_INFO(80, "All surfaces released\n"); // And the DirectDraw objects if (lpDDraw2) { lpDDraw2->Release(); lpDDraw2 = NULL; } if (lpDDraw1) { lpDDraw1->Release(); lpDDraw1 = NULL; } GDBG_INFO(80, "Direct Draw released\n"); } glide3x/h5/glide3/src/xdraw2.asm0100700000175300010010000002547707725034670015722 0ustar johndoeNone;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ;; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ;; ;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ;; THE UNITED STATES. ;; ;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ;; ;; $Header: /cvsroot/glide/glide3x/h5/glide3/src/xdraw2.asm,v 1.1.8.7 2003/07/07 23:29:06 koolsmoky Exp $ ;; $Revision: 1.1.8.7 $ ;; $Log: xdraw2.asm,v $ ;; Revision 1.1.8.7 2003/07/07 23:29:06 koolsmoky ;; cleaned logs ;; ;; ;; Revision 1.1 2000/06/15 00:27:43 joseph ;; Initial checkin into SourceForge. ;; ;; 12 4/05/99 11:34a Atai ;; added GLIDE_ALT_TAB for xdraw2.inc to query context in the retail build ;; ;; 11 3/19/99 11:26a Peter ;; expose direct fifo for gl ;; ;; 10 10/14/98 12:05p Peter ;; fixed my effed up assumption about non-volatile regs ;; ;; 9 10/12/98 9:51a Peter ;; dynamic 3DNow!(tm) ;; ;; 8 9/24/98 11:17a Dow ;; AMD 3DNow! (tm) mods ;; ;; 7 8/30/98 1:34p Dow ;; State & other optimizations ;; ;; 6 8/29/98 8:12p Dow ;; Clip optimization ;; ;; 5 7/01/98 8:41a Jdt ;; removed gc arg from trisetup funcs ;; ;; 4 8/03/98 6:36a Jdt ;; Add GC to trisetup arglist ;; ;; 3 6/09/98 11:59a Atai ;; 1. update glide header ;; 2. fix cull mode ;; 3. fix tri stats ;; ;; 8 5/18/98 3:21p Peter ;; dynamic culling changes ; ; 6 1/15/98 1:12p Peter ; dispatch w/o packing ; ; 5 11/06/97 3:47p Peter ; dispatch code w/ simulator ; ; 4 11/04/97 5:04p Peter ; cataclysm part deux ; ; 3 11/01/97 10:01a Peter ; tri dispatch stuff ; ; 2 10/30/97 6:53p Peter ; first real cut at tri asm ; ; 1 10/30/97 4:29p Peter ; asm tri code ; ; 2 7/07/97 2:14p Jdt ; assembly now on par with C code. ; ; 1 7/07/97 8:37a Jdt ; B4 Chip field fix. ;; %include "xos.inc" ;;; Definitions of cvg regs and glide root structures. %INCLUDE "fxgasm.h" extrn _GlideRoot extrn _grCommandTransportMakeRoom, 12 extrn _grValidateState %IFDEF HAL_CSIM extrn halStore32, 8 %ENDIF %MACRO GR_FIFO_WRITE 3 %IFDEF HAL_CSIM pushad pushfd ; push %3 ; mov eax, %1 ; add eax, %2 ; push eax ;call halStore32 %ifidni %3, eax lea edx, [%1 + %2] invoke halStore32, edx, %3 %else lea eax, [%1 + %2] invoke halStore32, eax, %3 %endif popfd popad %ELSE mov [%1 + %2], %3 %ENDIF %ENDMACRO ; GR_FIFO_WRITE %MACRO WRITE_MM1_FIFO_ALIGNED 1 ; 3DNow! %ifdef GL_AMD3D %IFDEF HAL_CSIM movd tempVal, mm1 ; previous param GR_FIFO_WRITE fifo, %1, tempVal punpckhdq mm1, mm1 ; current param movd tempVal, mm1 ; GR_FIFO_WRITE fifo, %1 + 4, tempVal %ELSE movq [fifo+%1], mm1 ; store current param | previous param %ENDIF %endif ; SSE %ifdef GL_SSE %IFDEF HAL_CSIM ; csim isn't complete yet movss tempVal,xmm1 ; previous param - no can do GR_FIFO_WRITE fifo, %1, tempVal unpcklps xmm1, xmm1 ; current param movss tempValm,xmm1 ; - no can do GR_FIFO_WRITE fifo, %1 + 4, tempVal %ELSE movlps [fifo+%1],xmm1 ; store current param | previous param %ENDIF %endif %ENDMACRO ; WRITE_MM1_FIFO_ALIGNED %MACRO WRITE_MM1LOW_FIFO 0 ; 3DNow %ifdef GL_AMD3D %IFDEF HAL_CSIM movd tempVal, mm1 ; previous param GR_FIFO_WRITE fifo, 0, tempVal ; %ELSE movd [fifo], mm1 ; store current param | previous param %ENDIF %endif ; SSE %ifdef GL_SSE %IFDEF HAL_CSIM ; csim isn't complete yet movss tempVal,xmm1 ; previous param - no can do GR_FIFO_WRITE fifo, 0, tempVal ; %ELSE movss [fifo],xmm1 ; store current param | previous param ?shouldn't this be movlps? %ENDIF %endif %ENDMACRO ; WRITE_MM1LOW_FIFO segment DATA One DD 1.0 Area DD 0 segment CONST $T2003 DD 12288.0 $T2005 DD 1.0 $T2006 DD 256.0 ; Arguments (STKOFF = 16 from 4 pushes) STKOFF equ 16 _va$ equ 4 + STKOFF _vb$ equ 8 + STKOFF _vc$ equ 12 + STKOFF ;; coordinate offsets into vertex. ;; NB: These are constants and are not ;; user settable like the rest of the ;; parameter offset. Weird. X equ 0 Y equ 4 %MACRO PROC_TYPE 1 %IFDEF GL_AMD3D proc _trisetup_3DNow_%1, 12 %ELIFDEF GL_SSE proc _trisetup_SSE_%1, 12 %ELSE proc _trisetup_Default_%1, 12 %ENDIF %ENDM ;; enables/disables trisProcessed and trisDrawn counters STATS equ 1 ;; NB: All of the base triangle procs expect to have the gc ;; passed from the caller in edx so that we can avoid ;; the agi from the far pointer. Screw w/ this at your ;; own peril. ;; ;; YOU HAVE BEEN WARNED ;-------------------------------------------------------------------------- segment TEXT ALIGN 32 PROC_TYPE clip_nocull_invalid %define GLIDE_VALIDATE_STATE 1 %define GLIDE_CLIP_COORDS 1 %define GLIDE_CULLING 0 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE clip_cull_invalid %define GLIDE_VALIDATE_STATE 1 %define GLIDE_CLIP_COORDS 1 %define GLIDE_CULLING 1 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE clip_cull_valid %define GLIDE_VALIDATE_STATE 0 %define GLIDE_CLIP_COORDS 1 %define GLIDE_CULLING 1 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE clip_nocull_valid %define GLIDE_VALIDATE_STATE 0 %define GLIDE_CLIP_COORDS 1 %define GLIDE_CULLING 0 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE win_nocull_invalid %define GLIDE_VALIDATE_STATE 1 %define GLIDE_CLIP_COORDS 0 %define GLIDE_CULLING 0 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE win_cull_invalid %define GLIDE_VALIDATE_STATE 1 %define GLIDE_CLIP_COORDS 0 %define GLIDE_CULLING 1 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE win_cull_valid %define GLIDE_VALIDATE_STATE 0 %define GLIDE_CLIP_COORDS 0 %define GLIDE_CULLING 1 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp ALIGN 32 PROC_TYPE win_nocull_valid %define GLIDE_VALIDATE_STATE 0 %define GLIDE_CLIP_COORDS 0 %define GLIDE_CULLING 0 %define GLIDE_PACK_RGB 0 %define GLIDE_PACK_ALPHA 0 %define GLIDE_GENERIC_SETUP 0 %INCLUDE "xdraw2.inc" %undef GLIDE_GENERIC_SETUP %undef GLIDE_PACK_ALPHA %undef GLIDE_PACK_RGB %undef GLIDE_CULLING %undef GLIDE_CLIP_COORDS %undef GLIDE_VALIDATE_STATE endp %IFDEF GL_AMD3D ALIGN 32 proc _trisetup_clip_coor_thunk, 12 %define procPtr eax %define vPtr ecx %define gc edx ; Current graphics context passed implicitly through edx ;; Call through to the gc->curArchProcs.drawTrianglesProc w/o ;; adding extra stuff to the stack. I wish we could actually ;; do a direct return here w/o too much work. lea vPtr, [esp + _va$ - STKOFF] ; Get vertex pointer address mov procPtr, [gc + drawTrianglesProc] ; Prefetch drawTriangles proc addr ;; If debugging make sure that we're in clip coordinates %IFDEF GLIDE_DEBUG test dword [gc + CoordinateSpace], 1 jnz __clipSpace xor eax, eax mov [eax], eax __clipSpace: %ENDIF ; GLIDE_DEBUG invoke procPtr, 1, 3, vPtr ; (*gc->curArchProcs.drawTrianglesProc)(grDrawVertexArray, 3, vPtr) ret ; pop 3 dwords (vertex addrs) and return endp %ENDIF ; GL_AMD3D %IFDEF GL_SSE ALIGN 32 proc _trisetup_SSE_clip_coor_thunk, 12 %define procPtr eax %define vPtr ecx %define gc edx ; Current graphics context passed implicitly through edx ;; Call through to the gc->curArchProcs.drawTrianglesProc w/o ;; adding extra stuff to the stack. I wish we could actually ;; do a direct return here w/o too much work. lea vPtr, [esp + _va$ - STKOFF] ; Get vertex pointer address mov procPtr, [gc + drawTrianglesProc] ; Prefetch drawTriangles proc addr ;; If debugging make sure that we're in clip coordinates %IFDEF GLIDE_DEBUG test dword [gc + CoordinateSpace], 1 jnz __clipSpace xor eax, eax mov [eax], eax __clipSpace: %ENDIF ; GLIDE_DEBUG invoke procPtr, 1, 3, vPtr ; (*gc->curArchProcs.drawTrianglesProc)(grDrawVertexArray, 3, vPtr) ret ; pop 3 dwords (vertex addrs) and return endp %ENDIF ; GL_SSE glide3x/h5/glide3/src/xdraw2.inc0100700000175300010010000013554207725034670015706 0ustar johndoeNone;; -*-asm-*- ;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ;; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ;; ;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ;; THE UNITED STATES. ;; ;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ;; ;; $Header: /cvsroot/glide/glide3x/h5/glide3/src/xdraw2.inc,v 1.1.8.6 2003/07/07 23:29:06 koolsmoky Exp $ ;; $Revision: 1.1.8.6 $ ;; $Log: xdraw2.inc,v $ ;; Revision 1.1.8.6 2003/07/07 23:29:06 koolsmoky ;; cleaned logs ;; ;; ;; Revision 1.1 2000/06/15 00:27:43 joseph ;; Initial checkin into SourceForge. ;; ; ; 2 10/30/97 6:53p Peter ; first real cut at tri asm ; ; 1 10/30/97 4:29p Peter ; asm tri code ; ; 2 7/07/97 2:14p Jdt ; assembly now on par with C code. ; ; 1 7/07/97 8:37a Jdt ; B4 Chip field fix. ;; ;; NB: All of the base triangle procs expect to have the gc ;; passed from the caller in edx so that we can avoid ;; the agi from the far pointer. Screw w/ this at your ;; own peril. ;; ;; YOU HAVE BEEN WARNED ; Ugly, but seems to workaround the problem with locally defined ; data segment globals not getting relocated properly when using ; djgpp. %define zArea One+04h %define zdxAB One+08h %define zdxBC One+0ch %define zdyAB One+10h %define zdyBC One+14h %define zculltest One+18h %define gc esi ; points to graphics context %ifdef GL_AMD3D ;--------------------------------------------------------------------------- ; start 3DNow! version ;--------------------------------------------------------------------------- %define gc edi ; points to graphics context %define fifo ebp ; points to fifo entries %define tempVal esi %IF GLIDE_CLIP_COORDS ;; NB: Currently, the 3DNow!(tm) clip coordinate stuff ;; thunks through to the grDrawTriangles functions ;; which has already been specialized for 3DNow!(tm). ;; This means that we should never get here. %IFDEF GLIDE_DEBUG xor eax, eax mov [eax], eax %ENDIF %ELSE %IF GLIDE_CULLING %define fa eax ; vtx a from caller %define fb ebx ; vtx b from caller %define fc ecx ; vtx c from caller %define cull edx ; cull mode %define intArea ecx ; area temp storage ;; Prologue stuff push edi ; save caller's register variable mov gc, edx ; our hoopti calling conventions pass this here push esi ; save caller's register variable push ebx ; save caller's register variable mov fb, [esp + _vb$ - 4] ; get base address of vertex B push ebp ; save frame pointer %if GLIDE_CLIP_COORDS mov esi, [gc+CoordinateSpace] ; which coord. space (clip/window)? %endif %if GLIDE_VALIDATE_STATE mov ebp, [gc + invalid] ; state validated? %endif %if GLIDE_CLIP_COORDS lea eax, [esp+ _va$] ; pointer to vertex pointers test esi, esi ; window coordinates ? jz win_coordinates ; yup invoke _grDrawTriangles, 1, 3, eax; draw the triangle in clip coordinate space pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD arguments off stack win_coordinates: %endif ; GLIDE_CLIP_COORDS %if GLIDE_VALIDATE_STATE test ebp, ebp ; does state need validation? jz no_validation ; valid, don't need to validate invoke _grValidateState ; validate state .no_validation: %endif ; GLIDE_VALIDATE_STATE mov cull, [gc + cull_mode]; get cull mode nop ; filler mov fc, [esp + _vc$] ; get base address of vertex C nop ; filler ALIGN 16 femms ; will use AMD3D, clear FPU/MMX registers test cull, cull ; culling enabled ? mov tempVal, [gc + curTriSize] ;; Cull Check jz .nocull ; nope, no culling mov fa, [esp + _va$] ; get base address of vertex A movq mm2, [fc + X] ; yc | xc shl cull, 31 ; culltest << 31 movq mm1, [fb + X] ; yb | xb add tempVal, 4 ; space required in fifo movq mm0, [fa + X] ; ya | xa mov ebx, [gc + fifoRoom] ; space available in fifo ;; Area_Computation pfsubr mm2, mm1 ; dyBC | dxBC pfsub mm0, mm1 ; dyAB | dxAB movq mm5, mm2 ; dyBC | dxBC punpckhdq mm2, mm2 ; dyBC | dyBC movq mm4, mm0 ; dyAB | dxAB punpckhdq mm0, mm0 ; dyAB | dyAB pfmul mm5, mm0 ; dyAB*dxBC pfmul mm4, mm2 ; dxAB*dyBC pfsub mm4, mm5 ; dxAB*dyBC - dxBC*dyAB movd intArea, mm4 ; vectored ! ; Zero Area Triangle Check test intArea, 7fffffffh ; if ((j & 0x7FFFFFFF) == 0) jz .__cullFail ; area zero, triangle culled xor intArea, cull ; if (j ^ (culltest << 31)) jge .__cullFail ; triangle facing away from viewer, culled cmp ebx, tempVal ; fifo space required >= space available ? jge .__triBegin ; yup, push out triangle data to Voodoo invoke _grCommandTransportMakeRoom, tempVal, 0, __LINE__; note: updates fifoPtr jmp .__triBegin ; merge back with short path ;; culling disabled ALIGN 16 .nocull: ;; Check to make sure that we have enough room for ;; the complete triangle packet. add tempVal, 4 ; fifo space needed mov ebx, [gc + fifoRoom] ; fifo space available cmp ebx, tempVal ; fifo spce available >= space needed ? jge .__triBegin ; yup, ready to draw triangle invoke _grCommandTransportMakeRoom, tempVal, 0, __LINE__; note: updates fifoPtr %ELSE ; !GLIDE_CULLING ;; Prologue stuff push edi ; save caller's register variable push esi ; save caller's register variable mov gc, edx ; gc in edx from caller push ebx ; save caller's register variable push ebp ; save frame pointer %if GLIDE_CLIP_COORDS mov edx, [gc+CoordinateSpace]; window coordinates or clip coordinates ? %endif %if GLIDE_VALIDATE_STATE mov ebp, [gc + invalid] ; state validated? %endif %if GLIDE_CLIP_COORDS lea eax, [esp+ _va$] ; pointer to vertex pointers test edx, edx ; window coordinates ? jz win_coordinates ; yup invoke _grDrawTriangles, 1, 3, eax; draw the triangle in coordinate space pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD arguments off stack ALIGN 16 win_coordinates: %endif %if GLIDE_VALIDATE_STATE test ebp, ebp ; does state need validation? jz no_validation ; valid, don't need to validate invoke _grValidateState ; validate state no_validation: %endif mov tempVal, [gc + curTriSize] ; data for whole triangle in bytes add tempVal, 4 ; fifo space needed (include 4-byte header) mov ebx, [gc + fifoRoom] ; fifo space available femms ; will use AMD3D, clear FPU/MMX registers cmp ebx, tempVal ; fifo spce available >= space needed ? jge .__triBegin ; yup, ready to draw triangle invoke _grCommandTransportMakeRoom, tempVal, 0, __LINE__; note: updates fifoPtr jmp .__triBegin ; large distance due to alignment %endif ; GLIDE_CULLING %define dlp ebx ; points to dataList structure %define dlpstrt ecx ; points to begin of dataList structure %define vertex edx ; the current vertex ALIGN 32 .__triBegin: mov eax, [gc+triPacketHdr]; Packet 3 header lea dlp,[gc + tsuDataList]; Reset the dataList mov fifo, [gc + fifoPtr] ; Fetch Fifo Ptr mov vertex, [esp + _va$] ; Current vertex = A mov dlpstrt, dlp ; save pointer to start of dataList test fifo, 4 ; is fifo pointer qword aligned ? jz .__fifo_aligned ; yes, it is qword aligned movq mm1, [vertex+X] ; y | x GR_FIFO_WRITE fifo, 0, eax ; write header to fifo; now qword aligned add fifo, 12 ; fifoPtr += 3*sizeof(FxU32) WRITE_MM1_FIFO_ALIGNED -8 ; PCI write y | x ;; here: "write buffer" empty mov eax, [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; at end of list ? jz .__paramLoopDoneWBzero1; yes, "write buffer" empty .__paramLoop1a: movd mm1, [eax+vertex] ; get next parameter mov eax, [dlp] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jz .__paramLoopDoneWBone1; exit, write buffer contains one DWORD movd mm2, [eax+vertex] ; get next parameter add dlp, 8 ; dlp += 2 mov eax, [dlp-4] ; offset = *(dlp + 1) add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jnz .__paramLoop1a ; nope, copy next parameter jmp .__paramLoopDoneWBzero1; write buffer empty .__fifo_aligned: movd mm2, [vertex+X] ; y | x of vertex A add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) movd mm1, [gc+triPacketHdr]; Packet 3 header punpckldq mm1, mm2 ; x | header WRITE_MM1_FIFO_ALIGNED -8 ; PCI write x | header movd mm1, [vertex+Y] ; 0 | y of vertex A mov eax, [dlp] ; get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; end of list ? jz .__paramLoopDoneWBone1; yes, "write buffer" has y data .__paramLoop1b: movd mm2, [eax+vertex] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; offset = *(dlp + 1) add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jz .__paramLoopDoneWBzero1; exit, "write buffer" empty movd mm1, [eax+vertex] ; get next parameter mov eax, [dlp-4] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jnz .__paramLoop1b ; nope, copy next parameter .__paramLoopDoneWBone1: ;; here: "write buffer" has one DWORD left over from vertex A mov dlp, dlpstrt ; reset the dataList mov vertex, [esp + _vb$] ; Current vertex = B movd mm2, [vertex+X] ; 0 | x if vertex B punpckldq mm1, mm2 ; x | old param WRITE_MM1_FIFO_ALIGNED 0 ; PCI write: x | old param add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) movd mm1, [vertex+Y] ; 0 | y of vertex B mov eax, [dlp] ; get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; end of list ? jz .__paramLoopDoneWBone2; yes, "write buffer" has y data .__paramLoop2b: movd mm2, [eax+vertex] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; offset = *(dlp + 1) add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jz .__paramLoopDoneWBzero2; exit, "write buffer" empty movd mm1, [eax+vertex] ; get next parameter mov eax, [dlp-4] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jnz .__paramLoop2b ; nope, copy next parameter jmp .__paramLoopDoneWBone2; write buffer contains one DWORD .__paramLoopDoneWBzero1: mov vertex, [esp + _vb$] ; Current vertex = B mov dlp, dlpstrt ; Reset the dataList movq mm1, [vertex+X] ; y | x of vertex B add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) WRITE_MM1_FIFO_ALIGNED -8 ; PCI write y | x of vertex B nop ; filler ;; here: "write buffer" empty mov eax, [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ cmp eax, 0 ; at end of list ? jz .__paramLoopDoneWBzero2; yes, "write buffer" empty .__paramLoop2a: movd mm1, [eax+vertex] ; get next parameter mov eax, [dlp] ; offset = *(dlp + 1) cmp eax, 0 ; at end of offset list (offset == 0) ? jz .__paramLoopDoneWBone2; exit, write buffer contains one DWORD movd mm2, [eax+vertex] ; get next parameter add dlp, 8 ; dlp += 2 mov eax, [dlp-4] ; offset = *(dlp + 1) add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jnz .__paramLoop2a ; nope, copy next parameter .__paramLoopDoneWBzero2: mov vertex, [esp + _vc$] ; Current vertex = C mov dlp, dlpstrt ; Reset the dataList movq mm1, [vertex+X] ; y | x of vertex C add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) WRITE_MM1_FIFO_ALIGNED -8 ; PCI write y | x of vertex C ;; here: "write buffer" empty mov eax, [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; at end of list ? jz .__paramLoopDoneWBzero3; yes, "write buffer" empty .__paramLoop3a: movd mm1, [eax+vertex] ; get next parameter mov eax, [dlp] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jz .__paramLoopDoneWBone3; exit, write buffer contains one DWORD movd mm2, [eax+vertex] ; get next parameter add dlp, 8 ; dlp += 2 mov eax, [dlp-4] ; offset = *(dlp + 1) add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jnz .__paramLoop3a ; nope, copy next parameter jmp .__paramLoopDoneWBzero3; write buffer empty .__paramLoopDoneWBone2: ;; here: "write buffer" has one DWORD left over from vertex B mov vertex, [esp + _vc$] ; Current vertex = C mov dlp, dlpstrt ; reset the dataList movd mm2, [vertex+X] ; 0 | x if vertex C punpckldq mm1, mm2 ; x | old param WRITE_MM1_FIFO_ALIGNED 0 ; PCI write: x | old param add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) movd mm1, [vertex+Y] ; 0 | y of vertex C nop ; filler mov eax, [dlp] ; get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; end of list ? jz .__paramLoopDoneWBone3; yes, "write buffer" has y data .__paramLoop3b: movd mm2, [eax+vertex] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; offset = *(dlp + 1) add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jz .__paramLoopDoneWBzero3; exit, "write buffer" empty movd mm1, [eax+vertex] ; get next parameter mov eax, [dlp-4] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jnz .__paramLoop3b ; nope, copy next parameter .__paramLoopDoneWBone3: ; "write buffer" contains one DWORD that needs to be flushed WRITE_MM1LOW_FIFO ; add fifo, 4 ; .__paramLoopDoneWBzero3: ;; Update gc->fifoPtr and gc->fifoRoom mov ecx, [gc + trisDrawn] ; _GlideRoot.stats.trisDrawn mov eax, fifo ; new fifo pointer mov ebx, [gc + fifoPtr] ; old fifo pointer mov [gc + fifoPtr], fifo ; save new fifo pointer mov edx, [gc + fifoRoom] ; old fifo space available inc ecx ; _GlideRoot.stats.trisDrawn++ mov esi, [gc + trisProcessed] ; _GlideRoot.stats.trisProcessed sub eax, ebx ; new fifo ptr - old fifo ptr = additional fifo space used mov [gc + trisDrawn], ecx ; sub edx, eax ; new fifo space available mov eax, 1h ; return value = triangle drawn mov [gc + fifoRoom], edx ; new fifo space available ;; Restore trashed registers .__triDone_nocull: inc esi ; _GlideRoot.stats.trisProcessed++ pop ebp ; restore frame pointer mov [gc + trisProcessed], esi ; pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable femms ; no more AMD3D code, clear FPU/MMX regs ret ; return to caller %IF GLIDE_CULLING .__cullFail: mov esi, [gc + trisProcessed]; triangles processed so far xor eax, eax ; return value = triangle not drawn femms ; no more AMD3D code, clear FPU/MMX regs .__triDone_cull: ;; Restore trashed registers inc esi ; _GlideRoot.stats.trisProcessed++; pop ebp ; restore frame pointer mov [gc + trisProcessed], esi pop ebx pop esi pop edi ret %ENDIF ; GLIDE_CULLING %ENDIF ; !GLIDE_CLIP_COORDS ;--------------------------------------------------------------------------- ; end 3DNow! version ;--------------------------------------------------------------------------- %endif ; GL_AMD3D %ifdef GL_SSE ;--------------------------------------------------------------------------- ; start SSE version - note: CSIM incomplete. ;--------------------------------------------------------------------------- %define gc edi ; points to graphics context %define fifo ebp ; points to fifo entries %define tempVal esi %IF GLIDE_CLIP_COORDS ;; NB: Currently, the 3DNow!(tm) clip coordinate stuff ;; thunks through to the grDrawTriangles functions ;; which has already been specialized for 3DNow!(tm). ;; This means that we should never get here. %IFDEF GLIDE_DEBUG xor eax, eax mov [eax], eax %ENDIF %ELSE %IF GLIDE_CULLING %define fa eax ; vtx a from caller %define fb ebx ; vtx b from caller %define fc ecx ; vtx c from caller %define cull edx ; cull mode %define intArea ecx ; area temp storage ;; Prologue stuff push edi ; save caller's register variable mov gc, edx ; our hoopti calling conventions pass this here push esi ; save caller's register variable push ebx ; save caller's register variable mov fb, [esp + _vb$ - 4] ; get base address of vertex B push ebp ; save frame pointer %if GLIDE_CLIP_COORDS mov esi, [gc+CoordinateSpace] ; which coord. space (clip/window)? %endif %if GLIDE_VALIDATE_STATE mov ebp, [gc + invalid] ; state validated? %endif %if GLIDE_CLIP_COORDS lea eax, [esp+ _va$] ; pointer to vertex pointers test esi, esi ; window coordinates ? jz win_coordinates ; yup invoke _grDrawTriangles, 1, 3, eax; draw the triangle in clip coordinate space pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD arguments off stack win_coordinates: %endif ; GLIDE_CLIP_COORDS %if GLIDE_VALIDATE_STATE test ebp, ebp ; does state need validation? jz no_validation ; valid, don't need to validate invoke _grValidateState ; validate state .no_validation: %endif ; GLIDE_VALIDATE_STATE mov cull, [gc + cull_mode]; get cull mode nop ; filler mov fc, [esp + _vc$] ; get base address of vertex C nop ; filler ALIGN 16 xorps xmm0,xmm0 ; clear SIMD register xorps xmm1,xmm1 xorps xmm2,xmm2 xorps xmm3,xmm3 xorps xmm4,xmm4 xorps xmm5,xmm5 xorps xmm6,xmm6 xorps xmm7,xmm7 test cull, cull ; culling enabled ? mov tempVal, [gc + curTriSize] ;; Cull Check jz .nocull ; nope, no culling mov fa, [esp + _va$] ; get base address of vertex A movlps xmm2,[fc + X] ; yc | xc shl cull, 31 ; culltest << 31 movlps xmm1,[fb + X] ; yb | xb add tempVal, 4 ; space required in fifo movlps xmm0,[fa + X] ; ya | xa mov ebx, [gc + fifoRoom] ; space available in fifo ;; Area_Computation movaps xmm5,xmm1 ; subps xmm5,xmm2 ; movaps xmm2,xmm5 ; dyBC | dxBC subps xmm0,xmm1 ; dyAB | dxAB movaps xmm5,xmm2 ; dyBC | dxBC unpcklps xmm2,xmm2 ; movhlps xmm2,xmm2 ; dyBC | dyBC movaps xmm4,xmm0 ; dyAB | dxAB unpcklps xmm0,xmm0 movhlps xmm0,xmm0 ; dyAB | dyAB mulss xmm5,xmm0 ; dyAB*dxBC mulss xmm4,xmm2 ; dxAB*dyBC subss xmm4,xmm5 ; dxAB*dyBC - dxBC*dyAB movss [zArea],xmm4 mov intArea,[zArea] ; vectored ! ; Zero Area Triangle Check test intArea, 7fffffffh ; if ((j & 0x7FFFFFFF) == 0) jz .__cullFail ; area zero, triangle culled xor intArea, cull ; if (j ^ (culltest << 31)) jge .__cullFail ; triangle facing away from viewer, culled cmp ebx, tempVal ; fifo space required >= space available ? jge .__triBegin ; yup, push out triangle data to Voodoo invoke _grCommandTransportMakeRoom, tempVal, 0, __LINE__; note: updates fifoPtr jmp .__triBegin ; merge back with short path ;; culling disabled ALIGN 16 .nocull: ;; Check to make sure that we have enough room for ;; the complete triangle packet. add tempVal, 4 ; fifo space needed mov ebx, [gc + fifoRoom] ; fifo space available cmp ebx, tempVal ; fifo spce available >= space needed ? jge .__triBegin ; yup, ready to draw triangle invoke _grCommandTransportMakeRoom, tempVal, 0, __LINE__; note: updates fifoPtr %ELSE ; !GLIDE_CULLING ;; Prologue stuff push edi ; save caller's register variable push esi ; save caller's register variable mov gc, edx ; gc in edx from caller push ebx ; save caller's register variable push ebp ; save frame pointer %if GLIDE_CLIP_COORDS mov edx, [gc+CoordinateSpace]; window coordinates or clip coordinates ? %endif %if GLIDE_VALIDATE_STATE mov ebp, [gc + invalid] ; state validated? %endif %if GLIDE_CLIP_COORDS lea eax, [esp+ _va$] ; pointer to vertex pointers test edx, edx ; window coordinates ? jz win_coordinates ; yup invoke _grDrawTriangles, 1, 3, eax; draw the triangle in coordinate space pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD arguments off stack ALIGN 16 win_coordinates: %endif %if GLIDE_VALIDATE_STATE test ebp, ebp ; does state need validation? jz no_validation ; valid, don't need to validate invoke _grValidateState ; validate state no_validation: %endif mov tempVal, [gc + curTriSize] ; data for whole triangle in bytes add tempVal, 4 ; fifo space needed (include 4-byte header) mov ebx, [gc + fifoRoom] ; fifo space available xorps xmm0,xmm0 ; clear SIMD register xorps xmm1,xmm1 xorps xmm2,xmm2 xorps xmm3,xmm3 xorps xmm4,xmm4 xorps xmm5,xmm5 xorps xmm6,xmm6 xorps xmm7,xmm7 cmp ebx, tempVal ; fifo spce available >= space needed ? jge .__triBegin ; yup, ready to draw triangle invoke _grCommandTransportMakeRoom, tempVal, 0, __LINE__; note: updates fifoPtr jmp .__triBegin ; large distance due to alignment %endif ; GLIDE_CULLING %define dlp ebx ; points to dataList structure %define dlpstrt ecx ; points to begin of dataList structure %define vertex edx ; the current vertex ALIGN 32 .__triBegin: mov eax, [gc+triPacketHdr]; Packet 3 header lea dlp,[gc + tsuDataList]; Reset the dataList mov fifo, [gc + fifoPtr] ; Fetch Fifo Ptr mov vertex, [esp + _va$] ; Current vertex = A mov dlpstrt, dlp ; save pointer to start of dataList test fifo, 4 ; is fifo pointer qword aligned ? jz .__fifo_aligned ; yes, it is qword aligned movlps xmm1,[vertex+X] ; y | x GR_FIFO_WRITE fifo, 0, eax ; write header to fifo; now qword aligned add fifo, 12 ; fifoPtr += 3*sizeof(FxU32) WRITE_MM1_FIFO_ALIGNED -8 ; PCI write y | x ;; here: "write buffer" empty mov eax, [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; at end of list ? jz .__paramLoopDoneWBzero1; yes, "write buffer" empty .__paramLoop1a: movss xmm1,[eax+vertex] ; get next parameter mov eax, [dlp] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jz .__paramLoopDoneWBone1; exit, write buffer contains one DWORD movss xmm2,[eax+vertex] ; get next parameter add dlp, 8 ; dlp += 2 mov eax, [dlp-4] ; offset = *(dlp + 1) add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jnz .__paramLoop1a ; nope, copy next parameter jmp .__paramLoopDoneWBzero1; write buffer empty .__fifo_aligned: movss xmm2,[vertex+X] ; 0 | x of vertex A GR_FIFO_WRITE fifo, 0, eax ; write header to fifo add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) movss [fifo-4],xmm2 ; PCI write x - not CSIM compatible!!!! movss xmm1,[vertex+Y] ; 0 | y of vertex A mov eax, [dlp] ; get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; end of list ? jz .__paramLoopDoneWBone1; yes, "write buffer" has y data .__paramLoop1b: movss xmm2,[eax+vertex] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; offset = *(dlp + 1) add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jz .__paramLoopDoneWBzero1; exit, "write buffer" empty movss xmm1,[eax+vertex] ; get next parameter mov eax, [dlp-4] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jnz .__paramLoop1b ; nope, copy next parameter .__paramLoopDoneWBone1: ;; here: "write buffer" has one DWORD left over from vertex A mov dlp, dlpstrt ; reset the dataList mov vertex, [esp + _vb$] ; Current vertex = B movss xmm2,[vertex+X] ; 0 | x if vertex B unpcklps xmm1,xmm2 ; x | old param WRITE_MM1_FIFO_ALIGNED 0 ; PCI write: x | old param add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) movss xmm1,[vertex+Y] ; 0 | y of vertex B mov eax, [dlp] ; get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; end of list ? jz .__paramLoopDoneWBone2; yes, "write buffer" has y data .__paramLoop2b: movss xmm2,[eax+vertex] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; offset = *(dlp + 1) add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jz .__paramLoopDoneWBzero2; exit, "write buffer" empty movss xmm1,[eax+vertex] ; get next parameter mov eax, [dlp-4] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jnz .__paramLoop2b ; nope, copy next parameter jmp .__paramLoopDoneWBone2; write buffer contains one DWORD .__paramLoopDoneWBzero1: mov vertex, [esp + _vb$] ; Current vertex = B mov dlp, dlpstrt ; Reset the dataList movlps xmm1,[vertex+X] ; y | x of vertex B add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) WRITE_MM1_FIFO_ALIGNED -8 ; PCI write y | x of vertex B nop ; filler ;; here: "write buffer" empty mov eax, [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ cmp eax, 0 ; at end of list ? jz .__paramLoopDoneWBzero2; yes, "write buffer" empty .__paramLoop2a: movss xmm1,[eax+vertex] ; get next parameter mov eax, [dlp] ; offset = *(dlp + 1) cmp eax, 0 ; at end of offset list (offset == 0) ? jz .__paramLoopDoneWBone2; exit, write buffer contains one DWORD movss xmm2,[eax+vertex] ; get next parameter add dlp, 8 ; dlp += 2 mov eax, [dlp-4] ; offset = *(dlp + 1) add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jnz .__paramLoop2a ; nope, copy next parameter .__paramLoopDoneWBzero2: mov vertex, [esp + _vc$] ; Current vertex = C mov dlp, dlpstrt ; Reset the dataList movlps xmm1,[vertex+X] ; y | x of vertex C add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) WRITE_MM1_FIFO_ALIGNED -8 ; PCI write y | x of vertex C ;; here: "write buffer" empty mov eax, [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; at end of list ? jz .__paramLoopDoneWBzero3; yes, "write buffer" empty .__paramLoop3a: movss xmm1,[eax+vertex] ; get next parameter mov eax, [dlp] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jz .__paramLoopDoneWBone3; exit, write buffer contains one DWORD movss xmm2,[eax+vertex] ; get next parameter add dlp, 8 ; dlp += 2 mov eax, [dlp-4] ; offset = *(dlp + 1) add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jnz .__paramLoop3a ; nope, copy next parameter jmp .__paramLoopDoneWBzero3; write buffer empty .__paramLoopDoneWBone2: ;; here: "write buffer" has one DWORD left over from vertex B mov vertex, [esp + _vc$] ; Current vertex = C mov dlp, dlpstrt ; reset the dataList movss xmm2,[vertex+X] ; 0 | x if vertex C unpcklps xmm1,xmm2 ; x | old param WRITE_MM1_FIFO_ALIGNED 0 ; PCI write: x | old param add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) movss xmm1,[vertex+Y] ; 0 | y of vertex C nop ; filler mov eax, [dlp] ; get first offset from the data list add dlp, 4 ; dlp++ test eax, eax ; end of list ? jz .__paramLoopDoneWBone3; yes, "write buffer" has y data .__paramLoop3b: movss xmm2,[eax+vertex] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; offset = *(dlp + 1) add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? WRITE_MM1_FIFO_ALIGNED -8 ; PCI write current param | previous param jz .__paramLoopDoneWBzero3; exit, "write buffer" empty movss xmm1,[eax+vertex] ; get next parameter mov eax, [dlp-4] ; offset = *(dlp + 1) test eax, eax ; at end of offset list (offset == 0) ? jnz .__paramLoop3b ; nope, copy next parameter .__paramLoopDoneWBone3: ; "write buffer" contains one DWORD that needs to be flushed WRITE_MM1LOW_FIFO ; add fifo, 4 ; .__paramLoopDoneWBzero3: ;; Update gc->fifoPtr and gc->fifoRoom mov ecx, [gc + trisDrawn] ; _GlideRoot.stats.trisDrawn mov eax, fifo ; new fifo pointer mov ebx, [gc + fifoPtr] ; old fifo pointer mov [gc + fifoPtr], fifo ; save new fifo pointer mov edx, [gc + fifoRoom] ; old fifo space available inc ecx ; _GlideRoot.stats.trisDrawn++ mov esi, [gc + trisProcessed] ; _GlideRoot.stats.trisProcessed sub eax, ebx ; new fifo ptr - old fifo ptr = additional fifo space used mov [gc + trisDrawn], ecx ; sub edx, eax ; new fifo space available mov eax, 1h ; return value = triangle drawn mov [gc + fifoRoom], edx ; new fifo space available ;; Restore trashed registers .__triDone_nocull: inc esi ; _GlideRoot.stats.trisProcessed++ pop ebp ; restore frame pointer mov [gc + trisProcessed], esi ; pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return to caller %IF GLIDE_CULLING .__cullFail: mov esi, [gc + trisProcessed]; triangles processed so far xor eax, eax ; return value = triangle not drawn .__triDone_cull: ;; Restore trashed registers inc esi ; _GlideRoot.stats.trisProcessed++; pop ebp ; restore frame pointer mov [gc + trisProcessed], esi pop ebx pop esi pop edi ret %ENDIF ; GLIDE_CULLING %ENDIF ; !GLIDE_CLIP_COORDS ;--------------------------------------------------------------------------- ; end SSE version ;--------------------------------------------------------------------------- %endif ; GL_SSE %ifndef GL_AMD3D %ifndef GL_SSE ;--------------------------------------------------------------------------- ; original code ;--------------------------------------------------------------------------- %IF GLIDE_CLIP_COORDS ;; NB: We should never hit this because the proc is ;; either specialized or we thunk through to ;; grDrawTriangles for the clipping etc. %IFDEF GLIDE_DEBUG xor eax, eax mov [eax], eax %ENDIF %ELSE ;; Prologue stuff push esi push edi push ebx push ebp ;; call getThreadValueSLOW ;; mov gc, eax %IF 0 ;;; TRICKY STUFF HERE: ;;; The following code could be expressed like this but MASM had difficulty with it ;;; mov eax, DWORD PTR fs:[18h] ;;; Remember, gc == esi db 064h db 0a1h db 018h db 00 db 00h db 00h add eax, DWORD PTR __GlideRoot + tlsOffset mov gc, [eax] %ELSE mov gc, edx %ENDIF %IFDEF GLIDE_ALT_TAB test gc, gc je .__triDone mov edx, [gc + windowed] test edx, 1 jnz .pastContextTest ; mov edx, DWORD [gc+lostContext] mov ebx, [edx] test ebx, 1 jnz .__triDone .pastContextTest: %ENDIF align 4 %IF GLIDE_VALIDATE_STATE ;;; GR_FLUSH_STATE() mov edx, DWORD [gc+invalid] test edx, edx je .no_validatioin invoke _grValidateState .no_validatioin: %ENDIF align 4 %IF GLIDE_CULLING %define fa eax ; vtx a from caller %define fb ebx ; vtx b from caller %define fc ecx ; vtx c from caller %define cull edx %define intArea ebp ; temp Y storage ; some useful floating load and store macros %define flds fld DWORD %define fsubs fsub DWORD %define fmuls fmul DWORD ;; Pre-load the current culling mode before all of the ;; floating point area stuff. mov fa, [esp + _va$] mov fb, [esp + _vb$] mov cull, [gc + cull_mode] mov fc, [esp + _vc$] test cull, cull jz .nocull shl cull, 31 ; culltest << 31 .Area_Computation: ; 47-3 ; jmp ret_pop0f flds [fa + X] ; xa fsubs [fb + X] ; dxAB flds [fb + X] ; | xb fsubs [fc + X] ; | dxBC flds [fb + Y] ; | | yb fsubs [fc + Y] ; | | dyBC flds [fa + Y] ; | | | ya fsubs [fb + Y] ; | | | dyAB fld st3 ; | | | | dxAB fmul st0, st2 ; | | | | t0 t0=dxAB*dyBC fld st3 ; | | | | | dxBC fmul st0, st2 ; | | | | | t1 t1=dxBC*dyAB fsubp st1,st0 ; | | | | area fst dword [zArea] ; | | | | area ;; Pop temp things from the sw culling off the fp stack fstp st0 ; 4 fstp st0 ; 3 fstp st0 ; 2 fstp st0 ; 1 fstp st0 ; 0 mov intArea, [zArea] ; j = *(long *)&area xor eax, eax ; Clear the return value (0 == culled) ; Zero Area Triangle Check and intArea, 7fffffffh ; if ((j & 0x7FFFFFFF) == 0) jz .__triDone ;; Triangle area check vs culling mode mov intArea, [zArea] ; reload area just in case we're culling xor intArea, cull ; if (j ^ (culltest << 31)) jge .__triDone .nocull: %ENDIF ; GLIDE_CULLING align 4 ;; Check to make sure that we have enough room for ;; the complete triangle packet. mov eax, [gc + curTriSize] mov ebx, [gc + fifoRoom] add eax, 4 cmp ebx, eax jge .__triBegin invoke _grCommandTransportMakeRoom, eax, 0, __LINE__ ;; Send triangle parameters %define dlp ebx ; points to dataList structure %define fifo ebp ; points to next entry in fifo %define vertex edx ; the current vertex %define vOffset ecx ; Current vertex offset %define packCol edi %define tempVal edi align 32 .__triBegin: mov fifo, [gc + fifoPtr] ; Fetch Fifo Ptr mov vOffset, 4 ; Starting vertex mov eax, [gc + triPacketHdr] ; Packet 3 header nop GR_FIFO_WRITE fifo, 0, eax ; Write packet header to fifo add fifo, 4 ; Advance fifo for hdr & x/y coordinate align 32 .__vertexStart: mov vertex, [esp + STKOFF + vOffset] ; Current vertex add fifo, 8 nop ; Avoid p5 agi w/ load of vertex ptr nop mov eax, DWORD [vertex] ; X lea dlp, [gc + tsuDataList] ; Reset the dataList GR_FIFO_WRITE fifo, -8, eax ; PCI write X mov eax, DWORD [vertex + 4] ; Y xor packCol, packCol ; Clear packed color GR_FIFO_WRITE fifo, -4, eax ; PCI write Y .__doParams: mov eax, DWORD [dlp] ; Get first offset from the data list add dlp, 4 ; dlp++ cmp eax, 0 ; Are we done? je .__nextVertex ;; Not using align directive here because it sometimes ;; introduces an agi for the eax use below. nop nop .__paramLoop: mov tempVal, DWORD [eax + vertex] ; Get the parameter from teh vertex add fifo, 4 ; fifoPtr += sizeof(FxU32) mov eax, DWORD [dlp] ; offset = *(dlp + 1) add dlp, 4 ; dlp++ cmp eax, 0 ; Are we done? GR_FIFO_WRITE fifo, -4, tempVal ; *fifoPtr = data jne .__paramLoop align 4 .__nextVertex: ;; On to the next vertex add vOffset, 4 cmp vOffset, 16 ; Offset of one past last vertex? jne .__vertexStart ;; Update gc->fifoPtr and gc->fifoRoom mov eax, fifo mov ebx, [gc + fifoPtr] mov [gc + fifoPtr], fifo sub eax, ebx mov ebx, [gc + trisDrawn] ; _GlideRoot.stats.trisDrawn++; sub [gc + fifoRoom], eax add ebx, 1 mov [gc + trisDrawn], ebx ;; return 1 (triangle drawn) mov eax, 1h .__triDone: ;; Restore trashed registers mov ecx, [gc + trisProcessed] pop ebp add ecx, 1 ; _GlideRoot.stats.trisProcessed++; pop ebx pop edi mov [gc + trisProcessed], ecx pop esi ret %ENDIF ; !GLIDE_CLIP_COOR %ENDIF ; !GL_SSE %ENDIF ; !GL_AMD3D glide3x/h5/glide3/src/xdraw3.asm0100700000175300010010000062205007725034670015711 0ustar johndoeNone;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ;; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ;; ;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ;; THE UNITED STATES. ;; ;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ;; ;; %include "xos.inc" extrn _GlideRoot extrn _grValidateState extrn _grCommandTransportMakeRoom, 12 %ifdef GL_AMD3D ;;-------------------------------------------------------------------------- ;; start AMD3D version ;;-------------------------------------------------------------------------- ;;; include listing.inc %INCLUDE "fxgasm.h" segment CONST ALIGN 8 _F256_F256 DD 43800000h, 43800000h ; 256 | 256 segment DATA ALIGN 8 btab DD 0, 0, 0, 0, 0, 0, 0, 0 atab DD 0, 0, 0, 0, 0, 0, 0, 0 vSize DD 0 strideinbytes DD 0 vertices DD 0 segment TEXT ALIGN 32 proc _grDrawTriangles_3DNow, 12 %define _mode 20 %define _count 24 %define _pointers 28 ; 930 : { ; 931 : #define FN_NAME "_grDrawTriangles" ; 932 : ; 933 : FxI32 ; 934 : #ifdef GLIDE_DEBUG ; 935 : vSize, ; 936 : #endif ; 937 : k; ; 938 : FxI32 stride = mode; ; 939 : float *vPtr; ; 940 : ; 941 : GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); ; 942 : ; 943 : GDBG_INFO_MORE(gc->myLevel, "(count = %d, pointers = 0x%x)\n", ; 944 : count, pointers); ; 945 : ; 946 : GR_FLUSH_STATE(); %define gc edi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define dlp ebp ; points to dataList structure %define vertexCount esi ; Current vertex counter in the packet %define vertexPtr ebx ; Current vertex pointer (in deref mode) %define vertex ebx ; Current vertex (in non-deref mode) %define dlpStart edx ; Pointer to start of offset list push edi ; save caller's register variable SET_TLSBASE eax ; get thread local storage base pointer push esi ; save caller's register variable SET_TLSOFFSET edx ; offset of GC into tls push ebx ; save caller's register variable mov vertexCount, [esp+_count-4]; number of vertices in triangles GET_GC eax, edx ; get GC for current thread mov vertexPtr, [esp+_pointers-4]; get current vertex pointer (deref mode) push ebp ; save frame pointer mov edx, [gc + invalid] ; state needs validation ? test vertexCount, vertexCount ; number of vertices <= 0 ? jle .tris_done ; yup, triangles are done test edx, edx ; do we need to validate state ? je .no_validation ; nope, it's valid invoke _grValidateState ; validate state .no_validation: ; 947 : ; 948 : #ifdef GLIDE_DEBUG ; 949 : GDBG_INFO(110, "%s: vSize = %d\n", FN_NAME, vSize); ; 950 : ; 951 : GDBG_INFO(110, "%s: paramMask = 0x%x\n", FN_NAME, gc->cmdTransportInfo.paramMask); ; 952 : #endif ; 953 : ; 954 : if (stride == 0) ; 955 : stride = gc->state.vData.vStride; ; 956 : ; 957 : ; 958 : _GlideRoot.stats.trisProcessed+=(count/3); ; 959 : ; 960 : if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { ;; We can operate in one of two modes: ;; ;; 0. We are stepping through an array of vertices, in which case ;; the stridesize is equal to the size of the vertex data, and ;; always > 4, since vertex data must a least contain x,y (ie 8 bytes). ;; vertexPtr is pointing to the array of vertices. ;; ;; 1. We are stepping through an array of pointers to vertices ;; in which case the stride is 4 bytes and we need to dereference ;; the pointers to get at the vertex data. vertexPtr is pointing ;; to the array of pointers to vertices. mov eax, [esp + _count] ; count mov ebp, 0AAAAAAABh ; 1/3*2^32*2 femms ; we'll use MMX; clear MMX/3DX state mul ebp ; edx:eax = 1/3*2*2^32*count; edx = 1/3*2*count nop ; filler mov eax, [gc + trisProcessed] ; trisProcessed shr edx, 1 ; count/3 add eax, edx ; trisProcessed += count/3 mov edx, [esp + _mode] ; get mode (0 or 1) mov ecx, [gc + CoordinateSpace]; coordinates space (window/clip) mov [gc + trisProcessed], eax ; trisProcessed test edx, edx ; mode 0 (array of vertices) ? jnz .deref_mode ; nope, it's mode 1 (array of pointers to vertices) mov edx, [gc + vertexStride] ; get stride in DWORDs shl edx, 2 ; stride in bytes test ecx, ecx ; coordinate space == 0 (window) ? mov [strideinbytes], edx ; save off stride (in bytes) jnz .clip_coordinates_ND ; nope, coordinate space != window ; 961 : while (count > 0) { ; 962 : FxI32 vcount = count >=15 ? 15 : count; ; 963 : GR_SET_EXPECTED_SIZE(vcount * gc->state.vData.vSize, 1); ; 964 : TRI_STRIP_BEGIN(kSetupStrip, vcount, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD); ; 965 : .win_coords_loop_ND: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_tri_begin_ND ; yup, start writing triangle data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_tri_begin_ND: mov eax, vertexCount ; number of vertices in triangles mov fifo, [gc + fifoPtr] ; get fifoPtr mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list or eax, ebp ; setup vertex count and type test fifo, 4 ; fifoPtr QWORD aligned ? jz .fifo_aligned_ND ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned ; 966 : for (k = 0; k < vcount; k++) { ; 967 : FxI32 i; ; 968 : FxU32 dataElem = 0; ; 969 : ; 970 : vPtr = pointers; ; 971 : if (mode) ; 972 : vPtr = *(float **)vPtr; ; 973 : (float *)pointers += stride; ; 974 : ; 975 : i = gc->tsuDataList[dataElem]; ; 976 : ; 977 : TRI_SETF(FARRAY(vPtr, 0)); ; 978 : TRI_SETF(FARRAY(vPtr, 4)); ; 979 : while (i != GR_DLIST_END) { ; 980 : TRI_SETF(FARRAY(vPtr, i)); ; 981 : dataElem++; ; 982 : i = gc->tsuDataList[dataElem]; ; 983 : } ; 984 : } ; 985 : TRI_END; ; 986 : GR_CHECK_SIZE(); ; 987 : count -= 15; ; 988 : } .win_vertex_loop_ND_WB0: ; nothing in "write buffer" mov eax, [dlpStart] ; get first offset from offset list mov dlp, dlpStart ; point to start of offset list movq mm1, [vertex] ; get vertex x,y add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) add dlp, 4 ; dlp++ test eax, eax ; if offset == 0, end of list movq [fifo-8], mm1 ; PCI write x, y jz .win_datalist_end_ND_WB0 ; no more vertex data, nothing in "write buffer" .win_datalist_loop_ND_WB0: ; nothing in "write buffer" movd mm1, [vertex + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_ND_WB1 ; exit, write buffer contains one DWORD movd mm2, [vertex + eax] ; get next parameter add dlp, 8 ; dlp++ mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) test eax, eax ; at end of offset list (offset == 0) ? punpckldq mm1, mm2 ; current param | previous param movq [fifo-8], mm1 ; PCI write current param | previous param jnz .win_datalist_loop_ND_WB0 ; nope, copy next parameter .win_datalist_end_ND_WB0: mov eax, [strideinbytes] ; get offset to next vertex dec vertexCount ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB0 ; yup, output next vertex .win_vertex_end_ND_WB0: mov eax, [gc + fifoPtr] ; old fifoPtr mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack .fifo_aligned_ND: movd mm1, eax ; move header into "write buffer" .win_vertex_loop_ND_WB1: ; one DWORD in "write buffer" movd mm2, [vertex] ; 0 | x of vertex add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [dlpStart + 4] ; point to start of offset list nop ; filler punpckldq mm1, mm2 ; packet header | x of vertex mov eax, [dlp-4] ; first offset in offset list movq [fifo-8], mm1 ; PCI write packet header | x of vertex movd mm1, [vertex+4] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? jz .win_datalist_end_ND_WB1 ; yup, no more vertex data, one DWORD in "write buffer" .win_datalist_loop_ND_WB1: ; one DWORD in "write buffer" movd mm2, [vertex + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movq [fifo-8], mm1 ; PCI write current param | previous param jz .win_datalist_end_ND_WB0 ; yes, exit, "write buffer" empty movd mm1, [vertex + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list cmp eax, 0 ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_ND_WB1 ; nope, copy next parameter .win_datalist_end_ND_WB1: mov eax, [strideinbytes] ; get offset to next vertex dec vertexCount ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB1 ; yup, output next vertex .win_vertex_end_ND_WB1: movd [fifo], mm1 ; flush "write buffer" mov eax, [gc + fifoPtr] ; old fifoPtr add fifo, 4 ; fifoPtr += sizeof(FxU32) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack align 32 .deref_mode: prefetch [vertexPtr] ; pre-load first group of pointers test ecx, ecx ; coordinate space == 0 (window) ? jnz .clip_coordinates_D ; nope, coordinate space != window .win_coords_loop_D: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_tri_begin_D ; yup, start writing triangle data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__ ; note: updates fifoPtr align 32 .win_tri_begin_D: mov eax, vertexCount ; number of vertices in triangles mov fifo, [gc + fifoPtr] ; get fifoPtr mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) or eax, ebp ; setup mode, vertex count, and type lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list test fifo, 4 ; fifoPtr QWORD aligned ? jz .fifo_aligned_D ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned .win_vertex_loop_D_WB0: ; nothing in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer lea dlp, [gc + tsuDataList] ; get pointer to offset list movq mm1, [edx] ; get vertex x,y mov eax, [dlp] ; get first offset from offset list add dlp, 4 ; dlp++ movq [fifo], mm1 ; PCI write x, y add fifo, 8 ; fifo += 2 test eax, eax ; if offset == 0, end of offset list je .win_datalist_end_D_WB0 ; no more vertex data, nothing in "write buffer" .win_datalist_loop_D_WB0: ; nothing in "write buffer" movd mm1, [edx + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_D_WB1 ; exit, write buffer contains one DWORD movd mm2, [edx + eax] ; get next parameter add dlp, 8 ; dlp++ mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) punpckldq mm1, mm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movq [fifo-8], mm1 ; PCI write current param | previous param jnz .win_datalist_loop_D_WB0 ; nope, copy next parameter .win_datalist_end_D_WB0: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB0 ; yup, output next vertex .win_vertex_end_D_WB0: mov eax, [gc + fifoPtr] ; old fifoPtr nop ; filler mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo nop ; filler mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) add ebp, eax ; new number of bytes available in fifo mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo test vertexCount, vertexCount ; any vertices left to process ? mov [esp + _count], vertexCount; remaining number of vertices to process jg .win_coords_loop_D ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack .fifo_aligned_D: movd mm1, eax ; move header into "write buffer" .win_vertex_loop_D_WB1: ; one DWORD in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [gc + tsuDataList] ; get pointer to start of offset list movd mm2, [edx] ; 0 | x of vertex add dlp, 4 ; dlp++ mov eax, [dlp-4] ; first offset in offset list punpckldq mm1, mm2 ; packet header | x of vertex movq [fifo-8], mm1 ; PCI write packet header | x of vertex movd mm1, [edx + 4] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? je .win_datalist_end_D_WB1 ; yup, no more vertex data, one DWORD in "write buffer" .win_datalist_loop_D_WB1: ; one DWORD in "write buffer" = MM1 movd mm2, [edx + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? movq [fifo-8], mm1 ; PCI write current param | previous param jz .win_datalist_end_D_WB0 ; yes, exit, "write buffer" empty movd mm1, [edx + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_D_WB1 ; nope, copy next parameter .win_datalist_end_D_WB1: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB1 ; yup, output next vertex .win_vertex_end_D_WB1: movd [fifo], mm1 ; flush "write buffer" mov eax, [gc + fifoPtr] ; old fifoPtr add fifo, 4 ; fifoPtr++ mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process cmp vertexCount, 0 ; any vertices left to process ? nop ; filler jg .win_coords_loop_D ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack ALIGN 32 ; 989 : } ; 990 : else { ; 991 : /* ; 992 : * first cut of clip space coordinate code, no optimization. ; 993 : */ ; 994 : float oow; ; 995 : ; 996 : while (count > 0) { ; 997 : FxI32 vcount = count >= 15 ? 15 : count; ; 998 : ; 999 : GR_SET_EXPECTED_SIZE(vcount * gc->state.vData.vSize, 1); ; 1000 : TRI_STRIP_BEGIN(kSetupStrip, vcount, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD); ; 1001 : ; 1002 : for (k = 0; k < vcount; k++) { ; 1003 : vPtr = pointers; ; 1004 : if (mode) ; 1005 : vPtr = *(float **)pointers; ; 1006 : oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset); ; 1007 : ; 1008 : /* x, y */ ; 1009 : TRI_SETF(FARRAY(vPtr, 0) ; 1010 : *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox); ; 1011 : TRI_SETF(FARRAY(vPtr, 4) ; 1012 : *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy); ; 1013 : (float *)pointers += stride; ; 1014 : ; 1015 : TRI_VP_SETFS(vPtr,oow); ; 1016 : } ; 1017 : TRI_END; ; 1018 : GR_CHECK_SIZE(); ; 1019 : count -= 15; ; 1020 : } ; 1021 : } .clip_coordinates_D: mov dword [strideinbytes], 4 ; unit stride for array of pointers to vertices .clip_coordinates_ND: %define dataElem ebp ; number of vertex components processed movd mm6,[_GlideRoot+pool_f255] ; GlideRoot.pool.f255 .clip_coords_begin: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .clip_tri_begin ; yup, start writing triangle data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__ ; note: updates fifoPtr align 32 .clip_tri_begin: mov edx, vertexCount ; number of vertices in triangles mov fifo, [gc + fifoPtr] ; get fifoPtr mov ebp, [gc + cullStripHdr] ; <2:0> = type shl edx, 6 ; <9:6> = vertex count (max 15) or edx, ebp ; setup mode, vertex count, and type mov [fifo], edx ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned .clip_for_begin: mov edx, vertexPtr ; vertex = vertexPtr (assume no-deref mode) mov eax, [esp+_mode] ; mode 0 = no deref, mode 1 = deref mov [vertices], vertexCount ; save numnber of vertices test eax, eax ; deref mode ? mov eax, [gc + wInfo_offset] ; get offset of W into vertex struct jz .clip_noderef ; yup, no-deref mode mov edx, [vertexPtr] ; vertex = *vertexPtr .clip_noderef: movd mm0, [edx + eax] ; 0 | W of current vertex pfrcp mm1, mm0 ; 0 | 1/W approx mov ebp, [strideinbytes] ; offset to next vertex/vertexPtr movq mm2, [edx] ; y | x of current vertex pfrcpit1 mm0, mm1 ; 0 | 1/W refine movq mm3, [gc + vp_hwidth] ; gc->state.Viewport.hheight | gc->state.Viewport.hwidth movq mm4, [gc + vp_ox] ; gc->state.Viewport.oy | gc->state.Viewport.ox add vertexPtr, ebp ; point to next vertex/VertexPtr pfrcpit2 mm0, mm1 ; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset mov esi, [gc + paramIndex] ; gc->state.paramIndex pfmul mm2, mm3 ; TRI_SETF(FARRAY(vPtr,0)*state.Viewport.hheight | TRI_SETF(FARRAY(vPtr,4)*state.Viewport.hwidth xor dataElem, dataElem ; dataElem = 0 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) punpckldq mm0, mm0 ; oow | oow pfmul mm2, mm0 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.height | TRI_SETF(FARRAY(vPtr, 0)*oow*gc->state.Viewport.hwidth pfadd mm2, mm4 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.hheight + gc->state.Viewport.oy) | ;;; FxI32 i, dataElem=0; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; if (gc->state.paramIndex & (STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA)) { \ ;;; if (gc->state.vData.colorType == GR_FLOAT) { \ ;;; if (gc->state.paramIndex & STATE_REQUIRES_IT_DRGB) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; } \ ;;; if (gc->state.paramIndex & STATE_REQUIRES_IT_ALPHA) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; } \ ;;; } \ ;;; else { \ ;;; DA_SETF(FARRAY(_s, i)); \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ ;;; } \ test esi, 3 ; STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA ? mov eax, [gc + tsuDataList] ; first entry from offset list movq [fifo-8], mm2 ; PCI write transformed x, y jz .clip_setup_ooz ; nope, no color at all needed cmp DWORD [gc+colorType], 0 ; gc->state.vData.colorType == GR_FLOAT ? jne .clip_setup_pargb ; nope, packed ARGB format test esi, 1 ; STATE_REQUIRES_IT_DRGB ? jz .clip_setup_a ; no, but definitely A movd mm2, [edx + eax] ; 0 | r mov eax, [gc + tsuDataList+4] ; offset of g part of vertex data pfmul mm2, mm6 ; 0 | r * 255.0f movd mm3, [edx + eax] ; 0 | g mov eax, [gc + tsuDataList + 8]; offset of b part of vertex data movd [fifo], mm2 ; PCI write r*255 pfmul mm3, mm6 ; 0 | g * 255.0f movd mm2, [edx + eax] ; 0 | b movd [fifo+4], mm3 ; PCI write g*255 mov dataElem, 12 ; dataElem = 3 pfmul mm2, mm6 ; 0 | b * 255.0f mov eax, [gc + tsuDataList+12] ; offset of A part of vertex data test esi, 2 ; STATE_REQUIRES_IT_ALPHA ? lea fifo, [fifo+12] ; fifoPtr += 3*sizeof(FxFloat) movd [fifo-4], mm2 ; PCI write b*255 jz .clip_setup_ooz ; nope, no alpha, proceeed with ooz .clip_setup_a: movd mm2, [eax+edx] ; 0 | a add fifo, 4 ; fifoPtr += sizeof(FxFloat) mov esp, esp ; filler add dataElem, 4 ; dataElem++ pfmul mm2, mm6 ; 0 | a * 255.0f mov eax, [gc+dataElem+tsuDataList]; offset of next part of vertex data movd [fifo-4], mm2 ; PCI write a*255 jmp .clip_setup_ooz ; check whether we need to push out z .clip_setup_pargb: movd mm2, [eax+edx] ; get packed ARGB data add fifo, 4 ; fifoPtr += sizeof(FxU32) mov dataElem, 4 ; dataElem = 1 (namely pargb) mov eax, [gc+tsuDataList+4] ; offset of next part of vertex data movd [fifo-4], mm2 ; PCI write packed ARGB ;;; if (gc->state.paramIndex & STATE_REQUIRES_OOZ) { \ ;;; if (gc->state.fbi_config.fbzMode & SST_DEPTH_FLOAT_SEL) { \ ;;; if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ ;;; } else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ ;;; else { \ ;;; DA_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth + gc->state.Viewport.oz); \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ ;;; } \ .clip_setup_ooz: test esi, 4 ; STATE_REQUIRES_OOZ ? jz .clip_setup_qow ; nope test DWORD [gc+fbi_fbzMode],200000h ; gc->state.fbi_config.fbzMode & SST_DEPTH_FLOAT_SEL != 0 ? je .clip_setup_ooz_nofog ; nope cmp DWORD [gc+qInfo_mode], 0 ; gc->state.vData.qInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_fog_oow ; nope mov eax, [gc + qInfo_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx + eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; 0 | q*oow movd [fifo-4], mm2 ; PCI write transformed Q jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_fog_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm3, [gc + depth_range] ; pfmul mm3, mm0 ; movd mm4, [gc + depth_range] ; depth range pfsub mm4, mm3 ; movd [fifo-4], mm4 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_ooz_nofog: movd mm2, [eax + edx] ; 0 | z component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem += 1 movd mm3, [gc + vp_hdepth] ; 0 | gc->state.Viewport.hdepth pfmul mm2, mm0 ; TRI_SETF(FARRAY(_s, i)*_oow movd mm4, [gc + vp_oz] ; 0 | gc->state.Viewport.oz pfmul mm2, mm3 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth mov eax, [gc+dataElem+tsuDataList]; offset of next vertex component pfadd mm2, mm4 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth+gc->state.Viewport.oz movd [fifo-4], mm2 ; PCI write transformed Z ;;; if (gc->state.paramIndex & STATE_REQUIRES_OOW_FBI) { \ ;;; if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.fogInfo.offset)*_oow); \ ;;; } \ ;;; else if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ ;;; } else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ .clip_setup_qow: test esi, 8 ; STATE_REQUIRES_OOW_FBI ? jz .clip_setup_qow0 ; nope cmp DWORD [gc+fogInfo_mode],0 ; gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_oow_nofog ; nope, no fog mov eax, [gc + fogInfo_offset] ; offset of fogInfo component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx + eax] ; 0 | fogInfo of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; fogInfo*oow movd [fifo-4], mm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 .clip_setup_oow_nofog: cmp DWORD [gc+qInfo_mode],0 ; gc->state.vData.qInfo.mode == GR_PARAM_ENABLE ? je .clip_setup_oow ; nope, write oow, not Q mov eax, [gc + qInfo_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx + eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; q*oow movd [fifo-4], mm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 .clip_setup_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd [fifo-4], mm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_W_TMU0) { \ ;;; if (gc->state.vData.q0Info.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.q0Info.offset)*_oow); \ ;;; } \ ;;; else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ .clip_setup_qow0: test esi, 16 ; STATE_REQUIRES_W_TMU0 ? jz .clip_setup_stow0 ; nope cmp DWORD [gc+q0Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow0 ; nope, not Q but W mov eax, [gc+q0Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx+eax] ; 0 | q0 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; q0*oow movd [fifo-4], mm2 ; PCI write transformed q0 jmp .clip_setup_stow0 ; continue with stow0 nop ; filler .clip_setup_oow0: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd [fifo-4], mm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU0) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[0].s_scale); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[0].t_scale); \ ;;; } \ .clip_setup_stow0: test esi, 32 ; STATE_REQUIRES_ST_TMU0 ? jz .clip_setup_qow1 ; nope movq mm7, [gc + tmu0_s_scale] ; state.tmu_config[0].t_scale | state.tmu_config[0].s_scale add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) movd mm2, [edx + eax] ; param1 mov eax,[gc+dataElem+tsuDataList+4];pointer to next vertex component pfmul mm7, mm0 ; oow*tmu0_t_scale | oow*tmu0_s_scale add dataElem, 8 ; dataElem += 2 movd mm3, [edx + eax] ; param2 punpckldq mm2, mm3 ; param2 | param1 pfmul mm2, mm7 ; param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale nop ; filler movq [fifo-8], mm2 ; PCI write param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale mov eax, [gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_W_TMU1) { \ ;;; if (gc->state.vData.q1Info.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.q1Info.offset)*_oow); \ ;;; } \ ;;; else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ .clip_setup_qow1: test esi, 64 ; STATE_REQUIRES_W_TMU1 ? jz .clip_setup_stow1 ; nope cmp DWORD [gc+q1Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow1 ; nope, not Q but W mov eax, [gc+q1Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx + eax] ; 0 | q1 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; q1*oow movd [fifo-4], mm2 ; PCI write transformed q1 jmp .clip_setup_stow1 ; continue with stow1 .clip_setup_oow1: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd [fifo-4], mm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU1) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[1].s_scale); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[1].t_scale); \ ;;; } \ .clip_setup_stow1: test esi, 128 ; STATE_REQUIRES_ST_TMU1 ? mov vertexCount, [vertices] ; get number of vertices movq mm7, [gc + tmu1_s_scale] ; state.tmu_config[1].t_scale | state.tmu_config[1].s_scale jz .clip_setup_end ; nope movd mm2, [edx + eax] ; param1 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) mov eax,[gc+dataElem+tsuDataList+4]; pointer to next vertex component pfmul mm7, mm0 ; oow*state.tmu_config[1].t_scale | oow*state.tmu_config[1].s_scale movd mm3, [edx + eax] ; param2 punpckldq mm2, mm3 ; param2 | param1 pfmul mm2, mm7 ; param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale movq [fifo-8], mm2 ; PCI write param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale .clip_setup_end: dec vertexCount ; vcount-- jnz .clip_for_begin ; until .clip_for_end: mov eax, [gc + fifoPtr] ; old fifoPtr mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process cmp vertexCount, 0 ; any vertices left to process ? jg .clip_coords_begin ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state .tris_done: pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters endp _pktype equ 20 _type equ 24 %define _mode 28 %define _count 32 %define _pointers 36 %define gc edi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define dlp ebp ; points to dataList structure %define vertexCount esi ; Current vertex counter in the packet %define vertexPtr ebx ; Current vertex pointer (in deref mode) %define vertex ebx ; Current vertex (in non-deref mode) %define dlpStart edx ; Pointer to start of offset list %define X 0 %define Y 4 ALIGN 32 proc _grDrawVertexList_3DNow_Window, 20 ; 132 : { SET_TLSBASE edx ; get thread local storage base pointer push edi ; save caller's register variable push esi ; save caller's register variable mov vertexCount, [esp+_count-8]; number of vertices in strip/fan push ebp ; save frame pointer SET_TLSOFFSET ebp ; GC position relative to tls base push ebx ; save caller's register variable mov vertexPtr, [esp+_pointers] ; get current vertex pointer (deref mode) ; get current vertex (non-deref mode) GET_GC edx, ebp ; get current graphics context from tls test vertexCount, vertexCount ; number of vertices <= 0 ? nop ; filler jle .strip_done ; yup, the strip/fan is done ;;; vSize = gc->state.vData.vSize ;;; if (stride == 0) ;;; stride = gc->state.vData.vStride; ;; We can operate in one of two modes: ;; ;; 0. We are stepping through an array of vertices, in which case ;; the stridesize is equal to the size of the vertex data, and ;; always > 4, since vertex data must a least contain x,y (ie 8 bytes). ;; vertexPtr is pointing to the array of vertices. ;; ;; 1. We are stepping through an array of pointers to vertices ;; in which case the stride is 4 bytes and we need to dereference ;; the pointers to get at the vertex data. vertexPtr is pointing ;; to the array of pointers to vertices. mov edx, [esp + _mode] ; get mode (0 or 1) mov eax, [gc + vertexSize] ; size of vertex data in bytes test edx, edx ; mode 0 (array of vertices) ? mov edx, [gc + vertexStride] ; get stride in DWORDs jnz .deref_mode ; nope, it's mode 1 (array of pointers to vertices) femms ; we'll use MMX; clear MMX/3DX state shl edx, 2 ; stride in bytes mov [strideinbytes], edx ; save off stride (in bytes) ;;; Draw the first (or possibly only) set. This is necessary because ;;; the packet is 3_BDDDDDD, and in the next set, the packet is 3_DDDDDD ;;; We try to make tstrip code simple to read. We combine the original code ;;; into a single loop by adding an extra packet type assignment at the end of the loop. ;;; ;;; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { ;;; while (count > 0) { ;;; FxI32 k, vcount = count >= 15 ? 15 : count; ;;; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); ;;; TRI_STRIP_BEGIN(type, vcount, vSize, pktype); .win_coords_loop_ND: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_strip_begin_ND ; yup, start writing strip data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_strip_begin_ND: ;;; Setup packet header ;;; mov eax, vertexCount ; number of vertices in strip/fan mov edx, [esp + _type] ; setup mode mov fifo, [gc + fifoPtr] ; get fifoPtr shl edx, 22 ; <27:22> = setup mode (kSetupStrip or kSetupFan) mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) or eax, edx ; setup mode and vertex count mov edx, [esp + _pktype] ; <5:3> = command (SSTCP_PKT3_BDDBDD, SSTCP_PKT3_BDDDDD, or SSTCP_PKT3_DDDDDD) or eax, ebp ; setup mode, vertex count, and type nop ; filler or eax, edx ; setup mode, vertex count, type, and command lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list test fifo, 4 ; fifoPtr QWORD aligned ? jz .fifo_aligned_ND ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned ;;; for (k = 0; k < vcount; k++) { ;;; FxI32 i; ;;; FxU32 dataElem; ;;; float *vPtr; ;;; vPtr = pointers; ;;; if (mode) ;;; vPtr = *(float **)vPtr ;;; (float *)pointers += stride; ;;; TRI_SETF(FARRAY(vPtr, 0)); ;;; dataElem = 0; ;;; TRI_SETF(FARRAY(vPtr, 4)); ;;; i = gc->tsuDataList[dataElem]; .win_vertex_loop_ND_WB0: ; nothing in "write buffer" mov eax, [dlpStart] ; get first offset from offset list lea dlp, [dlpStart+4] ; point to start of offset list movq mm1, [vertex+X] ; get vertex x,y add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) nop ; filler test eax, eax ; if offset == 0, end of list movq [fifo-8], mm1 ; PCI write x, y jz .win_datalist_end_ND_WB0 ; no more vertex data, nothing in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_ND_WB0: ; nothing in "write buffer" movd mm1, [vertex + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_ND_WB1 ; exit, write buffer contains one DWORD movd mm2, [vertex + eax] ; get next parameter add dlp, 8 ; dlp++ mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) test eax, eax ; at end of offset list (offset == 0) ? punpckldq mm1, mm2 ; current param | previous param movq [fifo-8], mm1 ; PCI write current param | previous param jnz .win_datalist_loop_ND_WB0 ; nope, copy next parameter .win_datalist_end_ND_WB0: mov eax, [strideinbytes] ; get offset to next vertex sub vertexCount, 1 ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB0 ; yup, output next vertex .win_vertex_end_ND_WB0: ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp + _pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo nop ; filler sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack ALIGN 32 .fifo_aligned_ND: movd mm1, eax ; move header into "write buffer" .win_vertex_loop_ND_WB1: ; one DWORD in "write buffer" movd mm2, [vertex + X] ; 0 | x of vertex add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [dlpStart + 4] ; point to start of offset list nop ; filler punpckldq mm1, mm2 ; packet header | x of vertex mov eax, [dlp-4] ; first offset in offset list movq [fifo-8], mm1 ; PCI write packet header | x of vertex movd mm1, [vertex + Y] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? jz .win_datalist_end_ND_WB1 ; yup, no more vertex data, one DWORD in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_ND_WB1: ; one DWORD in "write buffer" movd mm2, [vertex + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movq [fifo-8], mm1 ; PCI write current param | previous param jz .win_datalist_end_ND_WB0 ; yes, exit, "write buffer" empty movd mm1, [vertex+eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_ND_WB1 ; nope, copy next parameter .win_datalist_end_ND_WB1: mov eax, [strideinbytes] ; get offset to next vertex sub vertexCount, 1 ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB1 ; yup, output next vertex .win_vertex_end_ND_WB1: movd [fifo], mm1 ; flush "write buffer" add fifo, 4 ; fifoPtr += sizeof(FxU32) ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp+_pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack ALIGN 32 .deref_mode: femms ; we'll use MMX; clear FPU/MMX state prefetch [vertexPtr] ; pre-load first group of pointers .win_coords_loop_D: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_strip_begin_D ; yup, start writing strip data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_strip_begin_D: ;;; Setup packet header ;;; mov eax, vertexCount ; number of vertices in strip/fan mov edx, [esp + _type] ; setup mode mov fifo, [gc + fifoPtr] ; get fifoPtr shl edx, 22 ; <27:22> = setup mode (kSetupStrip or kSetupFan) mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) or eax, edx ; setup mode and vertex count mov edx, [esp + _pktype] ; <5:3> = command (SSTCP_PKT3_BDDBDD, SSTCP_PKT3_BDDDDD, or SSTCP_PKT3_DDDDDD) or eax, ebp ; setup mode, vertex count, and type mov ebp, 4 ; test bit 2 or eax, edx ; setup mode, vertex count, type, and command lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list test fifo, ebp ; fifoPtr QWORD aligned ? jz .fifo_aligned_D ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned ;;; for (k = 0; k < vcount; k++) { ;;; FxI32 i; ;;; FxU32 dataElem; ;;; float *vPtr; ;;; vPtr = pointers; ;;; if (mode) ;;; vPtr = *(float **)vPtr ;;; (float *)pointers += stride; ;;; TRI_SETF(FARRAY(vPtr, 0)); ;;; dataElem = 0; ;;; TRI_SETF(FARRAY(vPtr, 4)); ;;; i = gc->tsuDataList[dataElem]; .win_vertex_loop_D_WB0: ; nothing in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer lea dlp, [gc + tsuDataList] ; get pointer to offset list; dlp ++ add dlp, 4 ; dlp ++ movq mm1, [edx + X] ; get vertex x,y add fifo, 8 ; fifo += 2 mov eax, [dlp - 4] ; get first offset from offset list movq [fifo-8], mm1 ; PCI write x, y test eax, eax ; if offset == 0, end of offset list je .win_datalist_end_D_WB0 ; no more vertex data, nothing in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_D_WB0: ; nothing in "write buffer" movd mm1, [edx + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_D_WB1 ; exit, write buffer contains one DWORD add dlp, 8 ; dlp++ movd mm2, [edx + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) punpckldq mm1, mm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? movq [fifo-8], mm1 ; PCI write current param | previous param jnz .win_datalist_loop_D_WB0 ; nope, copy next parameter .win_datalist_end_D_WB0: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB0 ; yup, output next vertex .win_vertex_end_D_WB0: ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp + _pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) add ebp, eax ; new number of bytes available in fifo mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_D ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack ALIGN 32 .fifo_aligned_D: movd mm1, eax ; move header into "write buffer" .win_vertex_loop_D_WB1: ; one DWORD in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [gc + tsuDataList] ; get pointer to start of offset list movd mm2, [edx + X] ; 0 | x of vertex add dlp, 4 ; dlp++ mov eax, [dlp-4] ; first offset in offset list punpckldq mm1, mm2 ; packet header | x of vertex movq [fifo-8], mm1 ; PCI write packet header | x of vertex movd mm1, [edx + Y] ; 0 | y of vertex test eax, eax ; offset == 0 (list empty) ? je .win_datalist_end_D_WB1 ; yup, no more vertex data, one DWORD in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_D_WB1: ; one DWORD in "write buffer" = MM1 movd mm2, [edx + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 punpckldq mm1, mm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movq [fifo-8], mm1 ; PCI write current param | previous param jz .win_datalist_end_D_WB0 ; yes, exit, "write buffer" empty movd mm1, [edx + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list cmp eax, 0 ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_D_WB1 ; nope, copy next parameter .win_datalist_end_D_WB1: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB1 ; yup, output next vertex .win_vertex_end_D_WB1: movd [fifo], mm1 ; flush "write buffer" add fifo, 4 ; fifoPtr++ ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp+_pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop nop ; filler sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo cmp vertexCount, 0 ; any vertices left to process ? mov [esp + _count], vertexCount; remaining number of vertices to process jg .win_coords_loop_D ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state .strip_done: pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack endp ALIGN 32 proc _grDrawVertexList_3DNow_Clip, 20 ; 132 : { SET_TLSBASE edx ; get thread local storage base pointer push edi ; save caller's register variable push esi ; save caller's register variable mov vertexCount, [esp+_count-8]; number of vertices in strip/fan push ebp ; save frame pointer SET_TLSOFFSET ebp ; GC position relative to tls base push ebx ; save caller's register variable mov vertexPtr, [esp+_pointers] ; get current vertex pointer (deref mode) ; get current vertex (non-deref mode) GET_GC edx, ebp ; get current graphics context from tls test vertexCount, vertexCount ; number of vertices <= 0 ? jle .strip_done ; yup, the strip/fan is done ;;; vSize = gc->state.vData.vSize ;;; if (stride == 0) ;;; stride = gc->state.vData.vStride; ;; We can operate in one of two modes: ;; ;; 0. We are stepping through an array of vertices, in which case ;; the stridesize is equal to the size of the vertex data, and ;; always > 4, since vertex data must a least contain x,y (ie 8 bytes). ;; vertexPtr is pointing to the array of vertices. ;; ;; 1. We are stepping through an array of pointers to vertices ;; in which case the stride is 4 bytes and we need to dereference ;; the pointers to get at the vertex data. vertexPtr is pointing ;; to the array of pointers to vertices. mov edx, [esp + _mode] ; get mode (0 or 1) mov eax, [gc + vertexSize] ; size of vertex data in bytes test edx, edx ; mode 0 (array of vertices) ? mov edx, [gc + vertexStride] ; get stride in DWORDs movd mm6, [_GlideRoot+pool_f255]; GlideRoot.pool.f255 mov dword [strideinbytes], 4 ; array of pointers jnz .clip_coords_begin ; nope, it's mode 1 .clip_coordinates_ND: shl edx, 2 ; stride in bytes mov [strideinbytes], edx ; save off stride (in bytes) align 32 .clip_coords_begin: %define dataElem ebp ; number of vertex components processed ;;; { ;;; float oow; ;;; while (count > 0) { ;;; FxI32 k, vcount = count >= 15 ? 15 : count; sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 mov eax, [gc+fifoRoom] ; fifo space available add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send add ecx, 4 ; add header size ==> total packet size nop ; filler cmp eax, ecx ; fifo space avail >= packet size ? jge .clip_strip_begin ; yup, start writing strip data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .clip_strip_begin: ;;; TRI_STRIP_BEGIN(type, vcount, vSize, pktype) mov edx, [esp + _type] ; setup mode mov eax, vertexCount ; number of vertices in strip/fan mov fifo, [gc + fifoPtr] ; get fifoPtr shl eax, 6 ; <9:6> = vertex count (max 15) mov ebp, [gc + cullStripHdr] ; <2:0> = type shl edx, 22 ; <27:22> = setup mode (kSetupStrip or kSetupFan) or eax, edx ; setup mode and vertex count mov edx, [esp + _pktype] ; <5:3> = command (SSTCP_PKT3_BDDBDD, SSTCP_PKT3_BDDDDD, or SSTCP_PKT3_DDDDDD) or eax, ebp ; setup mode, vertex count, and type add fifo, 4 ; fifoPtr += sizeof(FxU32) or eax, edx ; setup mode, vertex count, type, and command mov [fifo-4], eax ; PCI write header ;;; for (k = 0; k < vcount; k++) { ;;; float *vPtr ;;; vPtr = pointers .clip_for_begin: ;;; if (mode) ;;; vPtr = *(float **)vPtr mov edx, vertexPtr ; vertex = vertexPtr (assume no-deref mode) mov eax, [esp+_mode] ; mode 0 = no deref, mode 1 = deref mov [vertices], vertexCount ; save numnber of vertices test eax, eax ; deref mode ? mov eax, [gc+wInfo_offset] ; get offset of W into vertex struct jz .clip_noderef ; yup, no-deref mode mov edx, [vertexPtr] ; vertex = *vertexPtr lea esp, [esp] ; filler .clip_noderef: ;;; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset) movd mm0, [edx+eax] ; 0 | W of current vertex pfrcp mm1, mm0 ; 0 | 1/W approx mov ebp, [strideinbytes] ; offset to next vertex/vertexPtr movq mm2, [edx] ; y | x of current vertex pfrcpit1 mm0, mm1 ; 0 | 1/W refine movq mm3, [gc+vp_hwidth] ; gc->state.Viewport.hheight | gc->state.Viewport.hwidth movq mm4, [gc+vp_ox] ; gc->state.Viewport.oy | gc->state.Viewport.ox add vertexPtr, ebp ; point to next vertex/VertexPtr pfrcpit2 mm0, mm1 ; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset mov esi, [gc+paramIndex] ; gc->state.paramIndex ;;; /* x, y */ ;;; TRI_SETF(FARRAY(vPtr, 0) ;;; *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox) ;;; TRI_SETF(FARRAY(vPtr, 4) ;;; *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy) pfmul mm2, mm3 ; TRI_SETF(FARRAY(vPtr,0)*state.Viewport.hheight | TRI_SETF(FARRAY(vPtr,4)*state.Viewport.hwidth xor dataElem, dataElem ; dataElem = 0 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) punpckldq mm0, mm0 ; oow | oow pfmul mm2, mm0 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.height | TRI_SETF(FARRAY(vPtr, 0)*oow*gc->state.Viewport.hwidth pfadd mm2, mm4 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.hheight + gc->state.Viewport.oy) | test esi, 3 ; STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA ? mov eax, [gc+tsuDataList] ; first entry from offset list ;;; (float *)pointers += stride ;;; TRI_VP_SETFS(vPtr, oow); movq [fifo-8], mm2 ; PCI write transformed x, y jz .clip_setup_ooz ; nope, no color at all needed cmp DWORD [gc+colorType], 0 ; gc->state.vData.colorType == GR_FLOAT ? jne .clip_setup_pargb ; nope, packed ARGB format test esi, 1 ; STATE_REQUIRES_IT_DRGB ? jz .clip_setup_a ; no, but definitely A movd mm2, [edx + eax] ; 0 | r mov eax, [gc+tsuDataList+4] ; offset of g part of vertex data pfmul mm2, mm6 ; 0 | r * 255.0f movd mm3, [edx + eax] ; 0 | g mov eax, [gc+tsuDataList+8] ; offset of b part of vertex data movd [fifo], mm2 ; PCI write r*255 pfmul mm3, mm6 ; 0 | g * 255.0f movd mm2, [edx + eax] ; 0 | b movd [fifo+4], mm3 ; PCI write g*255 mov dataElem, 12 ; dataElem = 3 pfmul mm2, mm6 ; 0 | b * 255.0f mov eax, [gc+tsuDataList+12] ; offset of A part of vertex data test esi, 2 ; STATE_REQUIRES_IT_ALPHA ? lea fifo, [fifo+12] ; fifoPtr += 3*sizeof(FxFloat) movd [fifo-4], mm2 ; PCI write b*255 jz .clip_setup_ooz ; nope, no alpha, proceeed with ooz .clip_setup_a: movd mm2, [eax+edx] ; 0 | a add fifo, 4 ; fifoPtr += sizeof(FxFloat) mov esp, esp ; filler add dataElem, 4 ; dataElem++ pfmul mm2, mm6 ; 0 | a * 255.0f mov eax, [gc+dataElem+tsuDataList]; offset of next part of vertex data movd [fifo-4], mm2 ; PCI write a*255 jmp .clip_setup_ooz ; check whether we need to push out z ALIGN 32 .clip_setup_pargb: movd mm2, [eax+edx] ; get packed ARGB data add fifo, 4 ; fifoPtr += sizeof(FxU32) mov dataElem, 4 ; dataElem = 1 (namely pargb) mov eax, [gc+tsuDataList+4] ; offset of next part of vertex data movd [fifo-4], mm2 ; PCI write packed ARGB .clip_setup_ooz: test esi, 4 ; STATE_REQUIRES_OOZ ? jz .clip_setup_qow ; nope test DWORD [gc+fbi_fbzMode],200000h ; gc->state.fbi_config.fbzMode & SST_DEPTH_FLOAT_SEL != 0 ? je .clip_setup_ooz_nofog ; nope cmp DWORD [gc+qInfo_mode], 0 ; gc->state.vData.qInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_fog_oow ; nope mov eax, [gc + qInfo_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx + eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; 0 | q*oow movd [fifo-4], mm2 ; PCI write transformed Q jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_fog_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm3, [gc + depth_range] ; pfmul mm3, mm0 ; movd mm4, [gc + depth_range] ; depth range pfsub mm4, mm3 ; movd [fifo-4], mm4 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_ooz_nofog: movd mm2, [eax + edx] ; 0 | z component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem += 1 movd mm3, [gc + vp_hdepth] ; 0 | gc->state.Viewport.hdepth pfmul mm2, mm0 ; TRI_SETF(FARRAY(_s, i)*_oow movd mm4, [gc + vp_oz] ; 0 | gc->state.Viewport.oz pfmul mm2, mm3 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth mov eax, [gc+dataElem+tsuDataList]; offset of next vertex component pfadd mm2, mm4 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth+gc->state.Viewport.oz movd [fifo-4], mm2 ; PCI write transformed Z .clip_setup_qow: test esi, 8 ; STATE_REQUIRES_OOW_FBI ? jz .clip_setup_qow0 ; nope cmp DWORD [gc+fogInfo_mode],0 ; gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_oow_nofog ; nope, no fog mov eax, [gc + fogInfo_offset] ; offset of fogInfo component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx + eax] ; 0 | fogInfo of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; fogInfo*oow movd [fifo-4], mm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 .clip_setup_oow_nofog: cmp DWORD [gc+qInfo_mode],0 ; does vertex have Q component ? je .clip_setup_oow ; nope, not Q but W add fifo, 4 ; fifoPtr += sizeof(FxFloat) mov eax, [gc+qInfo_offset] ; offset of Q component of vertex add dataElem, 4 ; dataElem++ movd mm2, [edx+eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; q*oow movd [fifo-4], mm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 ALIGN 32 .clip_setup_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd [fifo-4], mm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_qow0: test esi, 16 ; STATE_REQUIRES_W_TMU0 ? jz .clip_setup_stow0 ; nope cmp DWORD [gc+q0Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow0 ; nope, not Q but W mov eax, [gc+q0Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx+eax] ; 0 | q0 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; q0*oow movd [fifo-4], mm2 ; PCI write transformed q0 jmp .clip_setup_stow0 ; continue with stow0 ALIGN 32 .clip_setup_oow0: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd [fifo-4], mm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_stow0: test esi, 32 ; STATE_REQUIRES_ST_TMU0 ? jz .clip_setup_qow1 ; nope movq mm7, [gc + tmu0_s_scale] ; state.tmu_config[0].t_scale | state.tmu_config[0].s_scale add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) movd mm2, [edx+eax] ; param1 mov eax,[gc+dataElem+tsuDataList+4];pointer to next vertex component pfmul mm7, mm0 ; oow*tmu0_t_scale | oow*tmu0_s_scale add dataElem, 8 ; dataElem += 2 movd mm3, [edx+eax] ; param2 punpckldq mm2, mm3 ; param2 | param1 pfmul mm2, mm7 ; param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale movq [fifo-8], mm2 ; PCI write param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale mov eax, [gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_qow1: test esi, 64 ; STATE_REQUIRES_W_TMU1 ? jz .clip_setup_stow1 ; nope cmp DWORD [gc+q1Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow1 ; nope, not Q but W mov eax, [gc+q1Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd mm2, [edx+eax] ; 0 | q1 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component pfmul mm2, mm0 ; q1*oow movd [fifo-4], mm2 ; PCI write transformed q1 jmp .clip_setup_stow1 ; continue with stow1 ALIGN 32 .clip_setup_oow1: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movd [fifo-4], mm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_stow1: test esi, 128 ; STATE_REQUIRES_ST_TMU1 ? mov vertexCount, [vertices] ; get number of vertices movq mm7, [gc + tmu1_s_scale] ; state.tmu_config[1].t_scale | state.tmu_config[1].s_scale jz .clip_setup_end ; nope movd mm2, [edx+eax] ; param1 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) mov eax,[gc+dataElem+tsuDataList+4]; pointer to next vertex component pfmul mm7, mm0 ; oow*state.tmu_config[1].t_scale | oow*state.tmu_config[1].s_scale movd mm3, [edx+eax] ; param2 punpckldq mm2, mm3 ; param2 | param1 pfmul mm2, mm7 ; param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale movq [fifo-8], mm2 ; PCI write param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale .clip_setup_end: ; 206 : for (k = 0; k < vcount; k++) { dec vertexCount ; vcount-- jnz .clip_for_begin ; until .clip_for_end: ; 221 : } ; 222 : TRI_END; mov eax, [gc + fifoPtr] ; old fifoPtr mov esp, esp ; filler nop ; filler mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process cmp vertexCount, 0 ; any vertices left to process ? mov DWORD [esp+_pktype], 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) jg .clip_coords_begin ; loop if number of vertices to process >= 0 femms ; no more MMX code; clear MMX/FPU state .strip_done: ;;; } ;;; #undef FN_NAME ;;; } /* _grDrawVertexList */ pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 5 DWORD parameters off stack endp ;;-------------------------------------------------------------------------- ;; end AMD3D version ;;-------------------------------------------------------------------------- %endif ; GL_AMD3D %ifdef GL_SSE ;;-------------------------------------------------------------------------- ;; start SSE version ;;-------------------------------------------------------------------------- ;;; include listing.inc %INCLUDE "fxgasm.h" segment CONST ALIGN 8 _F256_F256 DD 43800000h, 43800000h ; 256 | 256 segment DATA ALIGN 8 btab DD 0, 0, 0, 0, 0, 0, 0, 0 atab DD 0, 0, 0, 0, 0, 0, 0, 0 vSize DD 0 strideinbytes DD 0 vertices DD 0 segment TEXT ALIGN 32 proc _grDrawTriangles_SSE, 12 %define _mode 20 %define _count 24 %define _pointers 28 ; 930 : { ; 931 : #define FN_NAME "_grDrawTriangles" ; 932 : ; 933 : FxI32 ; 934 : #ifdef GLIDE_DEBUG ; 935 : vSize, ; 936 : #endif ; 937 : k; ; 938 : FxI32 stride = mode; ; 939 : float *vPtr; ; 940 : ; 941 : GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); ; 942 : ; 943 : GDBG_INFO_MORE(gc->myLevel, "(count = %d, pointers = 0x%x)\n", ; 944 : count, pointers); ; 945 : ; 946 : GR_FLUSH_STATE(); %define gc edi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define dlp ebp ; points to dataList structure %define vertexCount esi ; Current vertex counter in the packet %define vertexPtr ebx ; Current vertex pointer (in deref mode) %define vertex ebx ; Current vertex (in non-deref mode) %define dlpStart edx ; Pointer to start of offset list push edi ; save caller's register variable SET_TLSBASE eax ; get thread local storage base pointer push esi ; save caller's register variable SET_TLSOFFSET edx ; offset of GC into tls push ebx ; save caller's register variable mov vertexCount, [esp+_count-4]; number of vertices in triangles GET_GC eax, edx ; get GC for current thread mov vertexPtr, [esp+_pointers-4]; get current vertex pointer (deref mode) push ebp ; save frame pointer mov edx, [gc + invalid] ; state needs validation ? test vertexCount, vertexCount ; number of vertices <= 0 ? jle .tris_done ; yup, triangles are done test edx, edx ; do we need to validate state ? je .no_validation ; nope, it's valid invoke _grValidateState ; validate state .no_validation: ; 947 : ; 948 : #ifdef GLIDE_DEBUG ; 949 : GDBG_INFO(110, "%s: vSize = %d\n", FN_NAME, vSize); ; 950 : ; 951 : GDBG_INFO(110, "%s: paramMask = 0x%x\n", FN_NAME, gc->cmdTransportInfo.paramMask); ; 952 : #endif ; 953 : ; 954 : if (stride == 0) ; 955 : stride = gc->state.vData.vStride; ; 956 : ; 957 : ; 958 : _GlideRoot.stats.trisProcessed+=(count/3); ; 959 : ; 960 : if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { ;; We can operate in one of two modes: ;; ;; 0. We are stepping through an array of vertices, in which case ;; the stridesize is equal to the size of the vertex data, and ;; always > 4, since vertex data must a least contain x,y (ie 8 bytes). ;; vertexPtr is pointing to the array of vertices. ;; ;; 1. We are stepping through an array of pointers to vertices ;; in which case the stride is 4 bytes and we need to dereference ;; the pointers to get at the vertex data. vertexPtr is pointing ;; to the array of pointers to vertices. mov eax, [esp + _count] ; count mov ebp, 0AAAAAAABh ; 1/3*2^32*2 xorps xmm0,xmm0 ; clear SIMD register xorps xmm1,xmm1 xorps xmm2,xmm2 xorps xmm3,xmm3 xorps xmm4,xmm4 xorps xmm5,xmm5 xorps xmm6,xmm6 xorps xmm7,xmm7 mul ebp ; edx:eax = 1/3*2*2^32*count; edx = 1/3*2*count nop ; filler mov eax, [gc + trisProcessed] ; trisProcessed shr edx, 1 ; count/3 add eax, edx ; trisProcessed += count/3 mov edx, [esp + _mode] ; get mode (0 or 1) mov ecx, [gc + CoordinateSpace]; coordinates space (window/clip) mov [gc + trisProcessed], eax ; trisProcessed test edx, edx ; mode 0 (array of vertices) ? jnz .deref_mode ; nope, it's mode 1 (array of pointers to vertices) mov edx, [gc + vertexStride] ; get stride in DWORDs shl edx, 2 ; stride in bytes test ecx, ecx ; coordinate space == 0 (window) ? mov [strideinbytes], edx ; save off stride (in bytes) jnz .clip_coordinates_ND ; nope, coordinate space != window ; 961 : while (count > 0) { ; 962 : FxI32 vcount = count >=15 ? 15 : count; ; 963 : GR_SET_EXPECTED_SIZE(vcount * gc->state.vData.vSize, 1); ; 964 : TRI_STRIP_BEGIN(kSetupStrip, vcount, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD); ; 965 : .win_coords_loop_ND: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_tri_begin_ND ; yup, start writing triangle data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_tri_begin_ND: mov eax, vertexCount ; number of vertices in triangles mov fifo, [gc + fifoPtr] ; get fifoPtr mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list or eax, ebp ; setup vertex count and type test fifo, 4 ; fifoPtr QWORD aligned ? jz .fifo_aligned_ND ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned ; 966 : for (k = 0; k < vcount; k++) { ; 967 : FxI32 i; ; 968 : FxU32 dataElem = 0; ; 969 : ; 970 : vPtr = pointers; ; 971 : if (mode) ; 972 : vPtr = *(float **)vPtr; ; 973 : (float *)pointers += stride; ; 974 : ; 975 : i = gc->tsuDataList[dataElem]; ; 976 : ; 977 : TRI_SETF(FARRAY(vPtr, 0)); ; 978 : TRI_SETF(FARRAY(vPtr, 4)); ; 979 : while (i != GR_DLIST_END) { ; 980 : TRI_SETF(FARRAY(vPtr, i)); ; 981 : dataElem++; ; 982 : i = gc->tsuDataList[dataElem]; ; 983 : } ; 984 : } ; 985 : TRI_END; ; 986 : GR_CHECK_SIZE(); ; 987 : count -= 15; ; 988 : } .win_vertex_loop_ND_WB0: ; nothing in "write buffer" mov eax, [dlpStart] ; get first offset from offset list mov dlp, dlpStart ; point to start of offset list movlps xmm1, [vertex] ; 0 | 0 | x | y get vertex x,y add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) add dlp, 4 ; dlp++ test eax, eax ; if offset == 0, end of list movlps [fifo-8], xmm1 ; PCI write x, y jz .win_datalist_end_ND_WB0 ; no more vertex data, nothing in "write buffer" .win_datalist_loop_ND_WB0: ; nothing in "write buffer" movss xmm1,[vertex + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_ND_WB1 ; exit, write buffer contains one DWORD movss xmm2,[vertex + eax] ; get next parameter add dlp, 8 ; dlp++ mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) test eax, eax ; at end of offset list (offset == 0) ? unpcklps xmm1, xmm2 ; current param | previous param movlps [fifo-8],xmm1 ; PCI write current param | previous param jnz .win_datalist_loop_ND_WB0 ; nope, copy next parameter .win_datalist_end_ND_WB0: mov eax, [strideinbytes] ; get offset to next vertex dec vertexCount ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB0 ; yup, output next vertex .win_vertex_end_ND_WB0: mov eax, [gc + fifoPtr] ; old fifoPtr mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack .fifo_aligned_ND: mov [fifo], eax ; PCI write packet header movss xmm2, [vertex] ; 0 | x of vertex add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [dlpStart + 4] ; point to start of offset list nop ; filler mov eax, [dlp-4] ; first offset in offset list movss [fifo-4], xmm2 ; PCI write x of vertex movss xmm1,[vertex+4] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? jz .win_datalist_end_ND_WB1 ; yup, no more vertex data, one DWORD in "write buffer" jmp .win_datalist_loop_ND_WB1 .win_vertex_loop_ND_WB1: ; one DWORD in "write buffer" movss xmm2,[vertex] ; 0 | x of vertex add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [dlpStart + 4] ; point to start of offset list nop ; filler unpcklps xmm1, xmm2 ; packet header | x of vertex ?reversed? mov eax, [dlp-4] ; first offset in offset list movlps [fifo-8], xmm1 ; PCI write packet header | x of vertex movss xmm1,[vertex+4] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? jz .win_datalist_end_ND_WB1 ; yup, no more vertex data, one DWORD in "write buffer" .win_datalist_loop_ND_WB1: ; one DWORD in "write buffer" movss xmm2,[vertex + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movlps [fifo-8],xmm1 ; PCI write current param | previous param jz .win_datalist_end_ND_WB0 ; yes, exit, "write buffer" empty movss xmm1,[vertex + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list cmp eax, 0 ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_ND_WB1 ; nope, copy next parameter .win_datalist_end_ND_WB1: mov eax, [strideinbytes] ; get offset to next vertex dec vertexCount ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB1 ; yup, output next vertex .win_vertex_end_ND_WB1: movss [fifo],xmm1 ; flush "write buffer" mov eax, [gc + fifoPtr] ; old fifoPtr add fifo, 4 ; fifoPtr += sizeof(FxU32) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack align 32 .deref_mode: prefetchnta [vertexPtr] ; pre-load first group of pointers test ecx, ecx ; coordinate space == 0 (window) ? jnz .clip_coordinates_D ; nope, coordinate space != window .win_coords_loop_D: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_tri_begin_D ; yup, start writing triangle data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_tri_begin_D: mov eax, vertexCount ; number of vertices in triangles mov fifo, [gc + fifoPtr] ; get fifoPtr mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) or eax, ebp ; setup mode, vertex count, and type lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list test fifo, 4 ; fifoPtr QWORD aligned ? jz .fifo_aligned_D ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned .win_vertex_loop_D_WB0: ; nothing in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer lea dlp, [gc + tsuDataList] ; get pointer to offset list movlps xmm1,[edx] ; get vertex x,y mov eax, [dlp] ; get first offset from offset list add dlp, 4 ; dlp++ movlps [fifo],xmm1 ; PCI write x, y add fifo, 8 ; fifo += 2 test eax, eax ; if offset == 0, end of offset list je .win_datalist_end_D_WB0 ; no more vertex data, nothing in "write buffer" .win_datalist_loop_D_WB0: ; nothing in "write buffer" movss xmm1,[edx + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_D_WB1 ; exit, write buffer contains one DWORD movss xmm2,[edx + eax] ; get next parameter add dlp, 8 ; dlp++ mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) unpcklps xmm1,xmm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movlps [fifo-8],xmm1 ; PCI write current param | previous param jnz .win_datalist_loop_D_WB0 ; nope, copy next parameter .win_datalist_end_D_WB0: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB0 ; yup, output next vertex .win_vertex_end_D_WB0: mov eax, [gc + fifoPtr] ; old fifoPtr nop ; filler mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo nop ; filler mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) add ebp, eax ; new number of bytes available in fifo mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo test vertexCount, vertexCount ; any vertices left to process ? mov [esp + _count], vertexCount; remaining number of vertices to process jg .win_coords_loop_D ; loop if number of vertices to process >= 0 pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack .fifo_aligned_D: mov [fifo], eax ; PCI write hacket header mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [gc + tsuDataList] ; get pointer to start of offset list movss xmm2,[edx] ; 0 | x of vertex add dlp, 4 ; dlp++ mov eax, [dlp-4] ; first offset in offset list movss [fifo-4], xmm2 ; PCI write x of vertex movss xmm1,[edx + 4] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? je .win_datalist_end_D_WB1 ; yup, no more vertex data, one DWORD in "write buffer" jmp .win_datalist_loop_D_WB1 .win_vertex_loop_D_WB1: ; one DWORD in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [gc + tsuDataList] ; get pointer to start of offset list movss xmm2,[edx] ; 0 | x of vertex add dlp, 4 ; dlp++ mov eax, [dlp-4] ; first offset in offset list unpcklps xmm1,xmm2 ; packet header | x of vertex ?reversed? movlps [fifo-8],xmm1 ; PCI write packet header | x of vertex movss xmm1,[edx + 4] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? je .win_datalist_end_D_WB1 ; yup, no more vertex data, one DWORD in "write buffer" .win_datalist_loop_D_WB1: ; one DWORD in "write buffer" = MM1 movss xmm2,[edx + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? movlps [fifo-8],xmm1 ; PCI write current param | previous param jz .win_datalist_end_D_WB0 ; yes, exit, "write buffer" empty movss xmm1,[edx + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_D_WB1 ; nope, copy next parameter .win_datalist_end_D_WB1: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB1 ; yup, output next vertex .win_vertex_end_D_WB1: movss [fifo],xmm1 ; flush "write buffer" mov eax, [gc + fifoPtr] ; old fifoPtr add fifo, 4 ; fifoPtr++ mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process cmp vertexCount, 0 ; any vertices left to process ? nop ; filler jg .win_coords_loop_D ; loop if number of vertices to process >= 0 pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters off stack ALIGN 32 ; 989 : } ; 990 : else { ; 991 : /* ; 992 : * first cut of clip space coordinate code, no optimization. ; 993 : */ ; 994 : float oow; ; 995 : ; 996 : while (count > 0) { ; 997 : FxI32 vcount = count >= 15 ? 15 : count; ; 998 : ; 999 : GR_SET_EXPECTED_SIZE(vcount * gc->state.vData.vSize, 1); ; 1000 : TRI_STRIP_BEGIN(kSetupStrip, vcount, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD); ; 1001 : ; 1002 : for (k = 0; k < vcount; k++) { ; 1003 : vPtr = pointers; ; 1004 : if (mode) ; 1005 : vPtr = *(float **)pointers; ; 1006 : oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset); ; 1007 : ; 1008 : /* x, y */ ; 1009 : TRI_SETF(FARRAY(vPtr, 0) ; 1010 : *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox); ; 1011 : TRI_SETF(FARRAY(vPtr, 4) ; 1012 : *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy); ; 1013 : (float *)pointers += stride; ; 1014 : ; 1015 : TRI_VP_SETFS(vPtr,oow); ; 1016 : } ; 1017 : TRI_END; ; 1018 : GR_CHECK_SIZE(); ; 1019 : count -= 15; ; 1020 : } ; 1021 : } .clip_coordinates_D: mov dword [strideinbytes], 4 ; unit stride for array of pointers to vertices .clip_coordinates_ND: %define dataElem ebp ; number of vertex components processed movss xmm6,[_GlideRoot+pool_f255]; GlideRoot.pool.f255 .clip_coords_begin: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .clip_tri_begin ; yup, start writing triangle data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .clip_tri_begin: mov edx, vertexCount ; number of vertices in triangles mov fifo, [gc + fifoPtr] ; get fifoPtr mov ebp, [gc + cullStripHdr] ; <2:0> = type shl edx, 6 ; <9:6> = vertex count (max 15) or edx, ebp ; setup mode, vertex count, and type mov [fifo], edx ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned .clip_for_begin: mov edx, vertexPtr ; vertex = vertexPtr (assume no-deref mode) mov eax, [esp+_mode] ; mode 0 = no deref, mode 1 = deref mov [vertices], vertexCount ; save numnber of vertices test eax, eax ; deref mode ? mov eax, [gc + wInfo_offset] ; get offset of W into vertex struct jz .clip_noderef ; yup, no-deref mode mov edx, [vertexPtr] ; vertex = *vertexPtr .clip_noderef: movss xmm1,[edx + eax] ; 0 | W of current vertex rcpss xmm0,xmm1 ; 0 | 1/W approx mov ebp, [strideinbytes] ; offset to next vertex/vertexPtr movlps xmm2,[edx] ; y | x of current vertex movlps xmm3,[gc + vp_hwidth] ; gc->state.Viewport.hheight | gc->state.Viewport.hwidth movlps xmm4,[gc + vp_ox] ; gc->state.Viewport.oy | gc->state.Viewport.ox add vertexPtr, ebp ; point to next vertex/VertexPtr mulss xmm1,xmm0 ; 0 | 1/W refine mulss xmm1,xmm0 addss xmm0,xmm0 subss xmm0,xmm1 ; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset mov esi, [gc + paramIndex] ; gc->state.paramIndex mulps xmm2,xmm3 ; TRI_SETF(FARRAY(vPtr,0)*state.Viewport.hheight | TRI_SETF(FARRAY(vPtr,4)*state.Viewport.hwidth xor dataElem, dataElem ; dataElem = 0 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) unpcklps xmm0,xmm0 ; oow | oow mulps xmm2,xmm0 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.height | TRI_SETF(FARRAY(vPtr, 0)*oow*gc->state.Viewport.hwidth addps xmm2,xmm4 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.hheight + gc->state.Viewport.oy) | ;;; FxI32 i, dataElem=0; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; if (gc->state.paramIndex & (STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA)) { \ ;;; if (gc->state.vData.colorType == GR_FLOAT) { \ ;;; if (gc->state.paramIndex & STATE_REQUIRES_IT_DRGB) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; } \ ;;; if (gc->state.paramIndex & STATE_REQUIRES_IT_ALPHA) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_GlideRoot.pool.f255); \ ;;; } \ ;;; } \ ;;; else { \ ;;; DA_SETF(FARRAY(_s, i)); \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ ;;; } \ test esi, 3 ; STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA ? mov eax, [gc + tsuDataList] ; first entry from offset list movlps [fifo-8],xmm2 ; PCI write transformed x, y jz .clip_setup_ooz ; nope, no color at all needed cmp DWORD [gc+colorType], 0 ; gc->state.vData.colorType == GR_FLOAT ? jne .clip_setup_pargb ; nope, packed ARGB format test esi, 1 ; STATE_REQUIRES_IT_DRGB ? jz .clip_setup_a ; no, but definitely A movss xmm2,[edx + eax] ; 0 | r mov eax, [gc + tsuDataList+4] ; offset of g part of vertex data mulss xmm2,xmm6 ; 0 | r * 255.0f movss xmm3,[edx + eax] ; 0 | g mov eax, [gc + tsuDataList + 8]; offset of b part of vertex data movss [fifo],xmm2 ; PCI write r*255 mulss xmm3,xmm6 ; 0 | g * 255.0f movss xmm2,[edx + eax] ; 0 | b movss [fifo+4],xmm3 ; PCI write g*255 mov dataElem, 12 ; dataElem = 3 mulss xmm2,xmm6 ; 0 | b * 255.0f mov eax, [gc + tsuDataList+12] ; offset of A part of vertex data test esi, 2 ; STATE_REQUIRES_IT_ALPHA ? lea fifo, [fifo+12] ; fifoPtr += 3*sizeof(FxFloat) movss [fifo-4],xmm2 ; PCI write b*255 jz .clip_setup_ooz ; nope, no alpha, proceeed with ooz .clip_setup_a: movss xmm2,[eax+edx] ; 0 | a add fifo, 4 ; fifoPtr += sizeof(FxFloat) mov esp, esp ; filler add dataElem, 4 ; dataElem++ mulss xmm2,xmm6 ; 0 | a * 255.0f mov eax, [gc+dataElem+tsuDataList]; offset of next part of vertex data movss [fifo-4],xmm2 ; PCI write a*255 jmp .clip_setup_ooz ; check whether we need to push out z .clip_setup_pargb: mov dataElem,[eax+edx] ; get packed ARGB data add fifo, 4 ; fifoPtr += sizeof(FxU32) mov [fifo-4],dataElem ; PCI write packed ARGB mov dataElem, 4 ; dataElem = 1 (namely pargb) mov eax, [gc+tsuDataList+4] ; offset of next part of vertex data ;;; if (gc->state.paramIndex & STATE_REQUIRES_OOZ) { \ ;;; if (gc->state.fbi_config.fbzMode & SST_DEPTH_FLOAT_SEL) { \ ;;; if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ ;;; } else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ ;;; else { \ ;;; DA_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth + gc->state.Viewport.oz); \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ ;;; } \ .clip_setup_ooz: test esi, 4 ; STATE_REQUIRES_OOZ ? jz .clip_setup_qow ; nope test DWORD [gc+fbi_fbzMode],200000h ; gc->state.fbi_config.fbzMode & SST_DEPTH_FLOAT_SEL != 0 ? je .clip_setup_ooz_nofog ; nope cmp DWORD [gc+qInfo_mode], 0 ; gc->state.vData.qInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_fog_oow ; nope mov eax, [gc + qInfo_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx + eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2, xmm0 ; 0 | q*oow movss [fifo-4],xmm2 ; PCI write transformed Q jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_fog_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm3,[gc + depth_range] ; mulss xmm3, xmm0 movss xmm4,[gc + depth_range] ; depth range subss xmm4,xmm3 ; movss [fifo-4],xmm4 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_ooz_nofog: movss xmm2,[eax + edx] ; 0 | z component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem += 1 movss xmm3,[gc + vp_hdepth] ; 0 | gc->state.Viewport.hdepth mulss xmm2,xmm0 ; TRI_SETF(FARRAY(_s, i)*_oow movss xmm4,[gc + vp_oz] ; 0 | gc->state.Viewport.oz mulss xmm2,xmm3 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth mov eax, [gc+dataElem+tsuDataList]; offset of next vertex component addss xmm2,xmm4 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth+gc->state.Viewport.oz movss [fifo-4],xmm2 ; PCI write transformed Z ;;; if (gc->state.paramIndex & STATE_REQUIRES_OOW_FBI) { \ ;;; if (gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.fogInfo.offset)*_oow); \ ;;; } \ ;;; else if (gc->state.vData.qInfo.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.qInfo.offset)*_oow); \ ;;; } else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ .clip_setup_qow: test esi, 8 ; STATE_REQUIRES_OOW_FBI ? jz .clip_setup_qow0 ; nope cmp DWORD [gc+fogInfo_mode],0 ; gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_oow_nofog ; nope, no fog mov eax, [gc + fogInfo_offset] ; offset of fogInfo component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx + eax] ; 0 | fogInfo of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; fogInfo*oow movss [fifo-4],xmm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 .clip_setup_oow_nofog: cmp DWORD [gc+qInfo_mode],0 ; gc->state.vData.qInfo.mode == GR_PARAM_ENABLE ? je .clip_setup_oow ; nope, write oow, not Q mov eax, [gc + qInfo_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx + eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; q*oow movss [fifo-4],xmm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 .clip_setup_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss [fifo-4],xmm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_W_TMU0) { \ ;;; if (gc->state.vData.q0Info.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.q0Info.offset)*_oow); \ ;;; } \ ;;; else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ .clip_setup_qow0: test esi, 16 ; STATE_REQUIRES_W_TMU0 ? jz .clip_setup_stow0 ; nope cmp DWORD [gc+q0Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow0 ; nope, not Q but W mov eax, [gc+q0Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx+eax] ; 0 | q0 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; q0*oow movss [fifo-4],xmm2 ; PCI write transformed q0 jmp .clip_setup_stow0 ; continue with stow0 nop ; filler .clip_setup_oow0: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss [fifo-4],xmm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU0) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[0].s_scale); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[0].t_scale); \ ;;; } \ .clip_setup_stow0: test esi, 32 ; STATE_REQUIRES_ST_TMU0 ? jz .clip_setup_qow1 ; nope movlps xmm7,[gc + tmu0_s_scale] ; state.tmu_config[0].t_scale | state.tmu_config[0].s_scale add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) movss xmm2,[edx + eax] ; param1 mov eax,[gc+dataElem+tsuDataList+4];pointer to next vertex component mulps xmm7,xmm0 ; oow*tmu0_t_scale | oow*tmu0_s_scale add dataElem, 8 ; dataElem += 2 movss xmm3,[edx + eax] ; param2 unpcklps xmm2,xmm3 ; param2 | param1 mulps xmm2,xmm7 ; param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale nop ; filler movlps [fifo-8],xmm2 ; PCI write param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale mov eax, [gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_W_TMU1) { \ ;;; if (gc->state.vData.q1Info.mode == GR_PARAM_ENABLE) { \ ;;; DA_SETF(FARRAY(_s, gc->state.vData.q1Info.offset)*_oow); \ ;;; } \ ;;; else { \ ;;; DA_SETF(_oow); \ ;;; } \ ;;; dataElem++; \ ;;; i = gc->tsuDataList[dataElem]; \ ;;; } \ .clip_setup_qow1: test esi, 64 ; STATE_REQUIRES_W_TMU1 ? jz .clip_setup_stow1 ; nope cmp DWORD [gc+q1Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow1 ; nope, not Q but W mov eax, [gc+q1Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx + eax] ; 0 | q1 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; q1*oow movss [fifo-4],xmm2 ; PCI write transformed q1 jmp .clip_setup_stow1 ; continue with stow1 .clip_setup_oow1: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss [fifo-4],xmm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component ;;; if (gc->state.paramIndex & STATE_REQUIRES_ST_TMU1) { \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[1].s_scale); \ ;;; DA_SETF_SCALE_ADVANCE(_s,_oow*gc->state.tmu_config[1].t_scale); \ ;;; } \ .clip_setup_stow1: test esi, 128 ; STATE_REQUIRES_ST_TMU1 ? mov vertexCount, [vertices] ; get number of vertices movlps xmm7,[gc + tmu1_s_scale] ; state.tmu_config[1].t_scale | state.tmu_config[1].s_scale jz .clip_setup_end ; nope movss xmm2,[edx + eax] ; param1 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) mov eax,[gc+dataElem+tsuDataList+4]; pointer to next vertex component mulps xmm7,xmm0 ; oow*state.tmu_config[1].t_scale | oow*state.tmu_config[1].s_scale movss xmm3,[edx + eax] ; param2 unpcklps xmm2,xmm3 ; param2 | param1 mulps xmm2,xmm7 ; param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale movlps [fifo-8],xmm2 ; PCI write param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale .clip_setup_end: dec vertexCount ; vcount-- jnz .clip_for_begin ; until .clip_for_end: mov eax, [gc + fifoPtr] ; old fifoPtr mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process cmp vertexCount, 0 ; any vertices left to process ? jg .clip_coords_begin ; loop if number of vertices to process >= 0 .tris_done: pop ebp ; restore frame pointer pop ebx ; restore caller's register variable pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 3 DWORD parameters endp _pktype equ 20 _type equ 24 %define _mode 28 %define _count 32 %define _pointers 36 %define gc edi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define dlp ebp ; points to dataList structure %define vertexCount esi ; Current vertex counter in the packet %define vertexPtr ebx ; Current vertex pointer (in deref mode) %define vertex ebx ; Current vertex (in non-deref mode) %define dlpStart edx ; Pointer to start of offset list %define X 0 %define Y 4 ALIGN 32 proc _grDrawVertexList_SSE_Window, 20 ; 132 : { SET_TLSBASE edx ; get thread local storage base pointer push edi ; save caller's register variable push esi ; save caller's register variable mov vertexCount, [esp+_count-8]; number of vertices in strip/fan push ebp ; save frame pointer SET_TLSOFFSET ebp ; GC position relative to tls base push ebx ; save caller's register variable mov vertexPtr, [esp+_pointers] ; get current vertex pointer (deref mode) ; get current vertex (non-deref mode) GET_GC edx, ebp ; get current graphics context from tls test vertexCount, vertexCount ; number of vertices <= 0 ? nop ; filler jle .strip_done ; yup, the strip/fan is done ;;; vSize = gc->state.vData.vSize ;;; if (stride == 0) ;;; stride = gc->state.vData.vStride; ;; We can operate in one of two modes: ;; ;; 0. We are stepping through an array of vertices, in which case ;; the stridesize is equal to the size of the vertex data, and ;; always > 4, since vertex data must a least contain x,y (ie 8 bytes). ;; vertexPtr is pointing to the array of vertices. ;; ;; 1. We are stepping through an array of pointers to vertices ;; in which case the stride is 4 bytes and we need to dereference ;; the pointers to get at the vertex data. vertexPtr is pointing ;; to the array of pointers to vertices. mov edx, [esp + _mode] ; get mode (0 or 1) mov eax, [gc + vertexSize] ; size of vertex data in bytes test edx, edx ; mode 0 (array of vertices) ? mov edx, [gc + vertexStride] ; get stride in DWORDs jnz .deref_mode ; nope, it's mode 1 (array of pointers to vertices) xorps xmm0,xmm0 ; clear SIMD register xorps xmm1,xmm1 xorps xmm2,xmm2 xorps xmm3,xmm3 xorps xmm4,xmm4 xorps xmm5,xmm5 xorps xmm6,xmm6 xorps xmm7,xmm7 shl edx, 2 ; stride in bytes mov [strideinbytes], edx ; save off stride (in bytes) ;;; Draw the first (or possibly only) set. This is necessary because ;;; the packet is 3_BDDDDDD, and in the next set, the packet is 3_DDDDDD ;;; We try to make tstrip code simple to read. We combine the original code ;;; into a single loop by adding an extra packet type assignment at the end of the loop. ;;; ;;; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { ;;; while (count > 0) { ;;; FxI32 k, vcount = count >= 15 ? 15 : count; ;;; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); ;;; TRI_STRIP_BEGIN(type, vcount, vSize, pktype); .win_coords_loop_ND: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_strip_begin_ND ; yup, start writing strip data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_strip_begin_ND: ;;; Setup packet header ;;; mov eax, vertexCount ; number of vertices in strip/fan mov edx, [esp + _type] ; setup mode mov fifo, [gc + fifoPtr] ; get fifoPtr shl edx, 22 ; <27:22> = setup mode (kSetupStrip or kSetupFan) mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) or eax, edx ; setup mode and vertex count mov edx, [esp + _pktype] ; <5:3> = command (SSTCP_PKT3_BDDBDD, SSTCP_PKT3_BDDDDD, or SSTCP_PKT3_DDDDDD) or eax, ebp ; setup mode, vertex count, and type nop ; filler or eax, edx ; setup mode, vertex count, type, and command lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list test fifo, 4 ; fifoPtr QWORD aligned ? jz .fifo_aligned_ND ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned ;;; for (k = 0; k < vcount; k++) { ;;; FxI32 i; ;;; FxU32 dataElem; ;;; float *vPtr; ;;; vPtr = pointers; ;;; if (mode) ;;; vPtr = *(float **)vPtr ;;; (float *)pointers += stride; ;;; TRI_SETF(FARRAY(vPtr, 0)); ;;; dataElem = 0; ;;; TRI_SETF(FARRAY(vPtr, 4)); ;;; i = gc->tsuDataList[dataElem]; .win_vertex_loop_ND_WB0: ; nothing in "write buffer" mov eax, [dlpStart] ; get first offset from offset list lea dlp, [dlpStart+4] ; point to start of offset list movlps xmm1,[vertex+X] ; get vertex x,y add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) nop ; filler test eax, eax ; if offset == 0, end of list movlps [fifo-8],xmm1 ; PCI write x, y jz .win_datalist_end_ND_WB0 ; no more vertex data, nothing in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_ND_WB0: ; nothing in "write buffer" movss xmm1,[vertex + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_ND_WB1 ; exit, write buffer contains one DWORD movss xmm2,[vertex + eax] ; get next parameter add dlp, 8 ; dlp++ mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) test eax, eax ; at end of offset list (offset == 0) ? unpcklps xmm1,xmm2 ; current param | previous param movlps [fifo-8],xmm1 ; PCI write current param | previous param jnz .win_datalist_loop_ND_WB0 ; nope, copy next parameter .win_datalist_end_ND_WB0: mov eax, [strideinbytes] ; get offset to next vertex sub vertexCount, 1 ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB0 ; yup, output next vertex .win_vertex_end_ND_WB0: ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp + _pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo nop ; filler sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack ALIGN 32 .fifo_aligned_ND: mov [fifo], eax ; PCI write packet header movss xmm2,[vertex + X] ; 0 | x of vertex add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [dlpStart + 4] ; point to start of offset list nop ; filler mov eax, [dlp-4] ; first offset in offset list movss [fifo-4], xmm2 ; PCI write x of vertex movss xmm1,[vertex + Y] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? jz .win_datalist_end_ND_WB1 ; yup, no more vertex data, one DWORD in "write buffer" jmp .win_datalist_loop_ND_WB1 .win_vertex_loop_ND_WB1: ; one DWORD in "write buffer" movss xmm2,[vertex + X] ; 0 | x of vertex add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [dlpStart + 4] ; point to start of offset list nop ; filler unpcklps xmm1,xmm2 ; packet header | x of vertex ?reversed? mov eax, [dlp-4] ; first offset in offset list movlps [fifo-8],xmm1 ; PCI write packet header | x of vertex movss xmm1,[vertex + Y] ; 0 | y of vertex cmp eax, 0 ; offset == 0 (list empty) ? jz .win_datalist_end_ND_WB1 ; yup, no more vertex data, one DWORD in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_ND_WB1: ; one DWORD in "write buffer" movss xmm2,[vertex + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movlps [fifo-8],xmm1 ; PCI write current param | previous param jz .win_datalist_end_ND_WB0 ; yes, exit, "write buffer" empty movss xmm1,[vertex+eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_ND_WB1 ; nope, copy next parameter .win_datalist_end_ND_WB1: mov eax, [strideinbytes] ; get offset to next vertex sub vertexCount, 1 ; another vertex done. Any left? lea vertex, [vertex + eax] ; points to next vertex jnz .win_vertex_loop_ND_WB1 ; yup, output next vertex .win_vertex_end_ND_WB1: movss [fifo],xmm1 ; flush "write buffer" add fifo, 4 ; fifoPtr += sizeof(FxU32) ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp+_pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_ND ; loop if number of vertices to process >= 0 pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack ALIGN 32 .deref_mode: xorps xmm0,xmm0 ; clear SIMD register xorps xmm1,xmm1 xorps xmm2,xmm2 xorps xmm3,xmm3 xorps xmm4,xmm4 xorps xmm5,xmm5 xorps xmm6,xmm6 xorps xmm7,xmm7 prefetchnta [vertexPtr] ; pre-load first group of pointers .win_coords_loop_D: sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send mov eax, [gc + fifoRoom] ; fifo space available add ecx, 4 ; add header size ==> total packet size cmp eax, ecx ; fifo space avail >= packet size ? jge .win_strip_begin_D ; yup, start writing strip data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .win_strip_begin_D: ;;; Setup packet header ;;; mov eax, vertexCount ; number of vertices in strip/fan mov edx, [esp + _type] ; setup mode mov fifo, [gc + fifoPtr] ; get fifoPtr shl edx, 22 ; <27:22> = setup mode (kSetupStrip or kSetupFan) mov ebp, [gc + cullStripHdr] ; <2:0> = type shl eax, 6 ; <9:6> = vertex count (max 15) or eax, edx ; setup mode and vertex count mov edx, [esp + _pktype] ; <5:3> = command (SSTCP_PKT3_BDDBDD, SSTCP_PKT3_BDDDDD, or SSTCP_PKT3_DDDDDD) or eax, ebp ; setup mode, vertex count, and type mov ebp, 4 ; test bit 2 or eax, edx ; setup mode, vertex count, type, and command lea dlpStart, [gc+tsuDataList] ; pointer to start of offset list test fifo, ebp ; fifoPtr QWORD aligned ? jz .fifo_aligned_D ; yup mov [fifo], eax ; PCI write packet type add fifo, 4 ; fifo pointer now QWORD aligned ;;; for (k = 0; k < vcount; k++) { ;;; FxI32 i; ;;; FxU32 dataElem; ;;; float *vPtr; ;;; vPtr = pointers; ;;; if (mode) ;;; vPtr = *(float **)vPtr ;;; (float *)pointers += stride; ;;; TRI_SETF(FARRAY(vPtr, 0)); ;;; dataElem = 0; ;;; TRI_SETF(FARRAY(vPtr, 4)); ;;; i = gc->tsuDataList[dataElem]; .win_vertex_loop_D_WB0: ; nothing in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer lea dlp, [gc + tsuDataList] ; get pointer to offset list; dlp ++ add dlp, 4 ; dlp ++ movlps xmm1,[edx + X] ; get vertex x,y add fifo, 8 ; fifo += 2 mov eax, [dlp - 4] ; get first offset from offset list movlps [fifo-8],xmm1 ; PCI write x, y test eax, eax ; if offset == 0, end of offset list je .win_datalist_end_D_WB0 ; no more vertex data, nothing in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_D_WB0: ; nothing in "write buffer" movss xmm1,[edx + eax] ; get next parameter mov eax, [dlp] ; get next offset from offset list test eax, eax ; at end of offset list (offset == 0) ? jz .win_datalist_end_D_WB1 ; exit, write buffer contains one DWORD add dlp, 8 ; dlp++ movss xmm2,[edx + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) unpcklps xmm1,xmm2 ; current param | previous param test eax, eax ; at end of offset list (offset == 0) ? movlps [fifo-8],xmm1 ; PCI write current param | previous param jnz .win_datalist_loop_D_WB0 ; nope, copy next parameter .win_datalist_end_D_WB0: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB0 ; yup, output next vertex .win_vertex_end_D_WB0: ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp + _pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) add ebp, eax ; new number of bytes available in fifo mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process test vertexCount, vertexCount ; any vertices left to process ? nop ; filler jg .win_coords_loop_D ; loop if number of vertices to process >= 0 pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack ALIGN 32 .fifo_aligned_D: mov [fifo], eax ; PCI write packet header mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [gc + tsuDataList] ; get pointer to start of offset list movss xmm2,[edx + X] ; 0 | x of vertex add dlp, 4 ; dlp++ mov eax, [dlp-4] ; first offset in offset list movss [fifo-4], xmm2 ; PCI write x of vertex movss xmm1,[edx + Y] ; 0 | y of vertex test eax, eax ; offset == 0 (list empty) ? je .win_datalist_end_D_WB1 ; yup, no more vertex data, one DWORD in "write buffer" jmp .win_datalist_loop_D_WB1 .win_vertex_loop_D_WB1: ; one DWORD in "write buffer" mov edx, [vertexPtr] ; dereference pointer, edx points to vertex add vertexPtr, 4 ; next pointer add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) lea dlp, [gc + tsuDataList] ; get pointer to start of offset list movss xmm2,[edx + X] ; 0 | x of vertex add dlp, 4 ; dlp++ mov eax, [dlp-4] ; first offset in offset list unpcklps xmm1,xmm2 ; packet header | x of vertex ?reversed? movlps [fifo-8],xmm1 ; PCI write packet header | x of vertex movss xmm1,[edx + Y] ; 0 | y of vertex test eax, eax ; offset == 0 (list empty) ? je .win_datalist_end_D_WB1 ; yup, no more vertex data, one DWORD in "write buffer" ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_loop_D_WB1: ; one DWORD in "write buffer" = MM1 movss xmm2,[edx + eax] ; get next parameter add fifo, 8 ; fifoPtr += 2*sizeof(FxU32) mov eax, [dlp] ; get next offset from offset list add dlp, 8 ; dlp += 2 unpcklps xmm1,xmm2 ; current param | previous param cmp eax, 0 ; at end of offset list (offset == 0) ? movlps [fifo-8],xmm1 ; PCI write current param | previous param jz .win_datalist_end_D_WB0 ; yes, exit, "write buffer" empty movss xmm1,[edx + eax] ; get next parameter mov eax, [dlp-4] ; get next offset from offset list cmp eax, 0 ; at end of offset list (offset == 0) ? jnz .win_datalist_loop_D_WB1 ; nope, copy next parameter .win_datalist_end_D_WB1: dec vertexCount ; another vertex done. Any left? jnz .win_vertex_loop_D_WB1 ; yup, output next vertex .win_vertex_end_D_WB1: movss [fifo],xmm1 ; flush "write buffer" add fifo, 4 ; fifoPtr++ ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov ebp, 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov eax, [gc + fifoPtr] ; old fifoPtr mov [esp+_pktype], ebp ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop nop ; filler sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr sub vertexCount, 15 ; remaining number of vertices to process add ebp, eax ; new number of bytes available in fifo mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo cmp vertexCount, 0 ; any vertices left to process ? mov [esp + _count], vertexCount; remaining number of vertices to process jg .win_coords_loop_D ; loop if number of vertices to process >= 0 .strip_done: pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restire caller's register variable ret ; return, pop 5 DWORD parameters off stack endp ALIGN 32 proc _grDrawVertexList_SSE_Clip, 20 ; 132 : { SET_TLSBASE edx ; get thread local storage base pointer push edi ; save caller's register variable push esi ; save caller's register variable mov vertexCount, [esp+_count-8]; number of vertices in strip/fan push ebp ; save frame pointer SET_TLSOFFSET ebp ; GC position relative to tls base push ebx ; save caller's register variable mov vertexPtr, [esp+_pointers] ; get current vertex pointer (deref mode) ; get current vertex (non-deref mode) GET_GC edx, ebp ; get current graphics context from tls test vertexCount, vertexCount ; number of vertices <= 0 ? jle .strip_done ; yup, the strip/fan is done ;;; vSize = gc->state.vData.vSize ;;; if (stride == 0) ;;; stride = gc->state.vData.vStride; ;; We can operate in one of two modes: ;; ;; 0. We are stepping through an array of vertices, in which case ;; the stridesize is equal to the size of the vertex data, and ;; always > 4, since vertex data must a least contain x,y (ie 8 bytes). ;; vertexPtr is pointing to the array of vertices. ;; ;; 1. We are stepping through an array of pointers to vertices ;; in which case the stride is 4 bytes and we need to dereference ;; the pointers to get at the vertex data. vertexPtr is pointing ;; to the array of pointers to vertices. mov edx, [esp + _mode] ; get mode (0 or 1) mov eax, [gc + vertexSize] ; size of vertex data in bytes test edx, edx ; mode 0 (array of vertices) ? mov edx, [gc + vertexStride] ; get stride in DWORDs movss xmm6,[_GlideRoot+pool_f255]; GlideRoot.pool.f255 mov dword [strideinbytes], 4 ; array of pointers jnz .clip_coords_begin ; nope, it's mode 1 .clip_coordinates_ND: shl edx, 2 ; stride in bytes mov [strideinbytes], edx ; save off stride (in bytes) align 32 .clip_coords_begin: %define dataElem ebp ; number of vertex components processed ;;; { ;;; float oow; ;;; while (count > 0) { ;;; FxI32 k, vcount = count >= 15 ? 15 : count; sub vertexCount, 15 ; vertexCount >= 15 ? CF=0 : CF=1 mov ecx, [gc + vertexSize] ; bytes of data for each vertex sbb eax, eax ; vertexCount >= 15 ? 00000000:ffffffff and vertexCount, eax ; vertexCount >= 15 ? 0 : vertexcount-15 mov eax, [gc+fifoRoom] ; fifo space available add vertexCount, 15 ; vertexcount >= 15 ? 15 :vertexcount imul ecx, vertexCount ; total amount of vertex data we'll send add ecx, 4 ; add header size ==> total packet size nop ; filler cmp eax, ecx ; fifo space avail >= packet size ? jge .clip_strip_begin ; yup, start writing strip data invoke _grCommandTransportMakeRoom, ecx, 0, __LINE__; note: updates fifoPtr align 32 .clip_strip_begin: ;;; TRI_STRIP_BEGIN(type, vcount, vSize, pktype) mov edx, [esp + _type] ; setup mode mov eax, vertexCount ; number of vertices in strip/fan mov fifo, [gc + fifoPtr] ; get fifoPtr shl eax, 6 ; <9:6> = vertex count (max 15) mov ebp, [gc + cullStripHdr] ; <2:0> = type shl edx, 22 ; <27:22> = setup mode (kSetupStrip or kSetupFan) or eax, edx ; setup mode and vertex count mov edx, [esp + _pktype] ; <5:3> = command (SSTCP_PKT3_BDDBDD, SSTCP_PKT3_BDDDDD, or SSTCP_PKT3_DDDDDD) or eax, ebp ; setup mode, vertex count, and type add fifo, 4 ; fifoPtr += sizeof(FxU32) or eax, edx ; setup mode, vertex count, type, and command mov [fifo-4], eax ; PCI write header ;;; for (k = 0; k < vcount; k++) { ;;; float *vPtr ;;; vPtr = pointers .clip_for_begin: ;;; if (mode) ;;; vPtr = *(float **)vPtr mov edx, vertexPtr ; vertex = vertexPtr (assume no-deref mode) mov eax, [esp+_mode] ; mode 0 = no deref, mode 1 = deref mov [vertices], vertexCount ; save numnber of vertices test eax, eax ; deref mode ? mov eax, [gc+wInfo_offset] ; get offset of W into vertex struct jz .clip_noderef ; yup, no-deref mode mov edx, [vertexPtr] ; vertex = *vertexPtr lea esp, [esp] ; filler .clip_noderef: ;;; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset) movss xmm1,[edx+eax] ; 0 | W of current vertex rcpss xmm0,xmm1 ; 0 | 1/W approx mov ebp, [strideinbytes] ; offset to next vertex/vertexPtr movlps xmm2,[edx] ; y | x of current vertex movlps xmm3,[gc+vp_hwidth] ; gc->state.Viewport.hheight | gc->state.Viewport.hwidth movlps xmm4,[gc+vp_ox] ; gc->state.Viewport.oy | gc->state.Viewport.ox add vertexPtr, ebp ; point to next vertex/VertexPtr mulss xmm1,xmm0 ; 0 | 1/W refine mulss xmm1,xmm0 addss xmm0,xmm0 subss xmm0,xmm1 ; oow = 1.0f / FARRAY(vPtr, gc->state.vData.wInfo.offset mov esi, [gc+paramIndex] ; gc->state.paramIndex ;;; /* x, y */ ;;; TRI_SETF(FARRAY(vPtr, 0) ;;; *oow*gc->state.Viewport.hwidth + gc->state.Viewport.ox) ;;; TRI_SETF(FARRAY(vPtr, 4) ;;; *oow*gc->state.Viewport.hheight + gc->state.Viewport.oy) mulps xmm2,xmm3 ; TRI_SETF(FARRAY(vPtr,0)*state.Viewport.hheight | TRI_SETF(FARRAY(vPtr,4)*state.Viewport.hwidth xor dataElem, dataElem ; dataElem = 0 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) unpcklps xmm0,xmm0 ; oow | oow mulps xmm2,xmm0 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.height | TRI_SETF(FARRAY(vPtr, 0)*oow*gc->state.Viewport.hwidth addps xmm2,xmm4 ; TRI_SETF(FARRAY(vPtr, 4)*oow*gc->state.Viewport.hheight + gc->state.Viewport.oy) | test esi, 3 ; STATE_REQUIRES_IT_DRGB | STATE_REQUIRES_IT_ALPHA ? mov eax, [gc+tsuDataList] ; first entry from offset list ;;; (float *)pointers += stride ;;; TRI_VP_SETFS(vPtr, oow); movlps [fifo-8],xmm2 ; PCI write transformed x, y jz .clip_setup_ooz ; nope, no color at all needed cmp DWORD [gc+colorType], 0 ; gc->state.vData.colorType == GR_FLOAT ? jne .clip_setup_pargb ; nope, packed ARGB format test esi, 1 ; STATE_REQUIRES_IT_DRGB ? jz .clip_setup_a ; no, but definitely A movss xmm2,[edx + eax] ; 0 | r mov eax, [gc+tsuDataList+4] ; offset of g part of vertex data mulss xmm2,xmm6 ; 0 | r * 255.0f movss xmm3,[edx + eax] ; 0 | g mov eax, [gc+tsuDataList+8] ; offset of b part of vertex data movss [fifo],xmm2 ; PCI write r*255 mulss xmm3,xmm6 ; 0 | g * 255.0f movss xmm2,[edx + eax] ; 0 | b movss [fifo+4],xmm3 ; PCI write g*255 mov dataElem, 12 ; dataElem = 3 mulss xmm2,xmm6 ; 0 | b * 255.0f mov eax, [gc+tsuDataList+12] ; offset of A part of vertex data test esi, 2 ; STATE_REQUIRES_IT_ALPHA ? lea fifo, [fifo+12] ; fifoPtr += 3*sizeof(FxFloat) movss [fifo-4],xmm2 ; PCI write b*255 jz .clip_setup_ooz ; nope, no alpha, proceeed with ooz .clip_setup_a: movss xmm2,[eax+edx] ; 0 | a add fifo, 4 ; fifoPtr += sizeof(FxFloat) mov esp, esp ; filler add dataElem, 4 ; dataElem++ mulss xmm2,xmm6 ; 0 | a * 255.0f mov eax, [gc+dataElem+tsuDataList]; offset of next part of vertex data movss [fifo-4],xmm2 ; PCI write a*255 jmp .clip_setup_ooz ; check whether we need to push out z ALIGN 32 .clip_setup_pargb: mov dataElem,[eax+edx] ; get packed ARGB data add fifo, 4 ; fifoPtr += sizeof(FxU32) mov [fifo-4],dataElem ; PCI write packed ARGB mov dataElem, 4 ; dataElem = 1 (namely pargb) mov eax, [gc+tsuDataList+4] ; offset of next part of vertex data .clip_setup_ooz: test esi, 4 ; STATE_REQUIRES_OOZ ? jz .clip_setup_qow ; nope test DWORD [gc+fbi_fbzMode],200000h ; gc->state.fbi_config.fbzMode & SST_DEPTH_FLOAT_SEL != 0 ? je .clip_setup_ooz_nofog ; nope cmp DWORD [gc+qInfo_mode], 0 ; gc->state.vData.qInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_fog_oow ; nope mov eax, [gc + qInfo_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx + eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; 0 | q*oow movss [fifo-4],xmm2 ; PCI write transformed Q jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_fog_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm3,[gc + depth_range] ; mulss xmm3,xmm0 ; movss xmm4,[gc + depth_range] ; depth range subss xmm4,xmm3 ; movss [fifo-4],xmm4 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component jmp .clip_setup_qow ; check whether we need to write Q or W .clip_setup_ooz_nofog: movss xmm2,[eax + edx] ; 0 | z component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem += 1 movss xmm3,[gc + vp_hdepth] ; 0 | gc->state.Viewport.hdepth mulss xmm2,xmm0 ; TRI_SETF(FARRAY(_s, i)*_oow movss xmm4,[gc + vp_oz] ; 0 | gc->state.Viewport.oz mulss xmm2,xmm3 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth mov eax, [gc+dataElem+tsuDataList]; offset of next vertex component addss xmm2,xmm4 ; 0 | TRI_SETF(FARRAY(_s, i)*_oow*gc->state.Viewport.hdepth+gc->state.Viewport.oz movss [fifo-4],xmm2 ; PCI write transformed Z .clip_setup_qow: test esi, 8 ; STATE_REQUIRES_OOW_FBI ? jz .clip_setup_qow0 ; nope cmp DWORD [gc+fogInfo_mode],0 ; gc->state.vData.fogInfo.mode == GR_PARAM_ENABLE ? jz .clip_setup_oow_nofog ; nope, no fog mov eax, [gc + fogInfo_offset] ; offset of fogInfo component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx + eax] ; 0 | fogInfo of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; fogInfo*oow movss [fifo-4],xmm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 .clip_setup_oow_nofog: cmp DWORD [gc+qInfo_mode],0 ; does vertex have Q component ? je .clip_setup_oow ; nope, not Q but W add fifo, 4 ; fifoPtr += sizeof(FxFloat) mov eax, [gc+qInfo_offset] ; offset of Q component of vertex add dataElem, 4 ; dataElem++ movss xmm2,[edx+eax] ; 0 | q of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; q*oow movss [fifo-4],xmm2 ; PCI write transformed Q jmp .clip_setup_qow0 ; continue with q0 ALIGN 32 .clip_setup_oow: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss [fifo-4],xmm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_qow0: test esi, 16 ; STATE_REQUIRES_W_TMU0 ? jz .clip_setup_stow0 ; nope cmp DWORD [gc+q0Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow0 ; nope, not Q but W mov eax, [gc+q0Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx+eax] ; 0 | q0 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; q0*oow movss [fifo-4],xmm2 ; PCI write transformed q0 jmp .clip_setup_stow0 ; continue with stow0 ALIGN 32 .clip_setup_oow0: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss [fifo-4],xmm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_stow0: test esi, 32 ; STATE_REQUIRES_ST_TMU0 ? jz .clip_setup_qow1 ; nope movlps xmm7,[gc + tmu0_s_scale] ; state.tmu_config[0].t_scale | state.tmu_config[0].s_scale add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) movss xmm2,[edx+eax] ; param1 mov eax,[gc+dataElem+tsuDataList+4];pointer to next vertex component mulps xmm7,xmm0 ; oow*tmu0_t_scale | oow*tmu0_s_scale add dataElem, 8 ; dataElem += 2 movss xmm3,[edx+eax] ; param2 unpcklps xmm2,xmm3 ; param2 | param1 mulps xmm2,xmm7 ; param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale movlps [fifo-8],xmm2 ; PCI write param2*oow*tmu0_t_scale | param1*oow*tmu0_s_scale mov eax, [gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_qow1: test esi, 64 ; STATE_REQUIRES_W_TMU1 ? jz .clip_setup_stow1 ; nope cmp DWORD [gc+q1Info_mode],0 ; does vertex have Q component ? je .clip_setup_oow1 ; nope, not Q but W mov eax, [gc+q1Info_offset] ; offset of Q component of vertex add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss xmm2,[edx+eax] ; 0 | q1 of vertex mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component mulss xmm2,xmm0 ; q1*oow movss [fifo-4],xmm2 ; PCI write transformed q1 jmp .clip_setup_stow1 ; continue with stow1 ALIGN 32 .clip_setup_oow1: add fifo, 4 ; fifoPtr += sizeof(FxFloat) add dataElem, 4 ; dataElem++ movss [fifo-4],xmm0 ; PCI write oow mov eax,[gc+dataElem+tsuDataList]; pointer to next vertex component .clip_setup_stow1: test esi, 128 ; STATE_REQUIRES_ST_TMU1 ? mov vertexCount, [vertices] ; get number of vertices movlps xmm7,[gc + tmu1_s_scale] ; state.tmu_config[1].t_scale | state.tmu_config[1].s_scale jz .clip_setup_end ; nope movss xmm2,[edx+eax] ; param1 add fifo, 8 ; fifoPtr += 2*sizeof(FxFloat) mov eax,[gc+dataElem+tsuDataList+4]; pointer to next vertex component mulps xmm7,xmm0 ; oow*state.tmu_config[1].t_scale | oow*state.tmu_config[1].s_scale movss xmm3,[edx+eax] ; param2 unpcklps xmm2,xmm3 ; param2 | param1 mulps xmm2,xmm7 ; param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale movlps [fifo-8],xmm2 ; PCI write param2*oow*state.tmu_config[1].t_scale | param1*oow*state.tmu_config[1].s_scale .clip_setup_end: ; 206 : for (k = 0; k < vcount; k++) { dec vertexCount ; vcount-- jnz .clip_for_begin ; until .clip_for_end: ; 221 : } ; 222 : TRI_END; mov eax, [gc + fifoPtr] ; old fifoPtr mov esp, esp ; filler nop ; filler mov ebp, [gc + fifoRoom] ; old number of bytes available in fifo mov vertexCount, [esp + _count]; remaining vertices before previous loop sub eax, fifo ; old fifoPtr - new fifoPtr (fifo room used) mov [gc + fifoPtr], fifo ; save current fifoPtr add ebp, eax ; new number of bytes available in fifo sub vertexCount, 15 ; remaining number of vertices to process mov [gc + fifoRoom], ebp ; save current number of bytes available in fifo mov [esp + _count], vertexCount; remaining number of vertices to process cmp vertexCount, 0 ; any vertices left to process ? mov DWORD [esp+_pktype], 16 ; pktype = SSTCP_PKT3_DDDDDD (strip continuation) jg .clip_coords_begin ; loop if number of vertices to process >= 0 .strip_done: ;;; } ;;; #undef FN_NAME ;;; } /* _grDrawVertexList */ pop ebx ; restore caller's register variable pop ebp ; restore frame pointer pop esi ; restore caller's register variable pop edi ; restore caller's register variable ret ; return, pop 5 DWORD parameters off stack endp ;;-------------------------------------------------------------------------- ;; end SSE version ;;-------------------------------------------------------------------------- %endif ; GL_SSE ;;-------------------------------------------------------------------------- ;; start original code ;;-------------------------------------------------------------------------- %ifndef GL_AMD3D %ifndef GL_MMX %ifndef GL_SSE ;;; include listing.inc %INCLUDE "fxgasm.h" segment CONST _F1 DD 1.0 _F256 DD 256.0 _VPF1 DD 1.0 _VPF256 DD 256.0 segment DATA vSize DD 0 ccoow DD 0 packetVal DD 0 strideinbytes DD 0 oowa DD 0 vPtr0 DD 0 vPtr1 DD 0 vPtr2 DD 0 segment TEXT _pktype equ 20 _type equ 24 _mode equ 28 _count equ 32 _pointers equ 36 %define gc esi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define dlp ebp ; points to dataList structure %define vertexCount ebx ; Current vertex counter in the packet %define vertexPtr edi ; Current vertex pointer ALIGN 32 proc _drawvertexlist, 20 ; 132 : { SET_TLSBASE eax ; get thread local storage base pointer push esi SET_TLSOFFSET esi ; GC position relative to tls base push edi GET_GC eax, esi push ebx ;;; GR_DCL_GC ;;; vSize = gc->state.vData.vSize ;;; if (stride == 0) ;;; stride = gc->state.vData.vStride; push ebp mov ecx, DWORD [gc+vertexSize] mov edx, DWORD [esp+_mode] mov vertexCount, DWORD [esp+_count] mov vertexPtr, DWORD [esp+_pointers] mov DWORD [vSize], ecx shl edx, 2 ;;; mov ecx, DWORD [gc+CoordinateSpace] test edx, edx jne .no_stride mov edx, DWORD [gc+vertexStride] shl edx, 2 align 4 .no_stride: ;;; Draw the first (or possibly only) set. This is necessary because ;;; the packet is 3_BDDDDDD, and in the next set, the packet is 3_DDDDDD ;;; We try to make tstrip code simple to read. We combine the original code ;;; into a single loop by adding an extra packet type assignment at the end of the loop. ;;; ;;; if (gc->state.grCoordinateSpaceArgs.coordinate_space_mode == GR_WINDOW_COORDS) { ;;; test ecx, ecx mov DWORD [strideinbytes], edx ;;; while (count > 0) { ;;; FxI32 k, vcount = count >= 15 ? 15 : count; ;;; GR_SET_EXPECTED_SIZE(vcount * vSize, 1); ;;; TRI_STRIP_BEGIN(type, vcount, vSize, pktype); mov eax, DWORD [esp+_count] ;;; jne clip_coordinates test eax, eax jle .strip_done align 4 .window_coords_begin: cmp vertexCount, 15 ; 0000000fH jl .win_partial_packet mov vertexCount, 15 ; 0000000fH align 4 .win_partial_packet: mov eax, DWORD [vSize] mov ecx, DWORD [gc+fifoRoom] imul eax, vertexCount add eax, 4 cmp ecx, eax jge .win_strip_begin invoke _grCommandTransportMakeRoom, eax, 0, __LINE__ align 4 .win_strip_begin: ;;; Setup pacet header ;;; mov fifo, DWORD [gc+fifoPtr] mov eax, vertexCount mov edx, DWORD [esp+_type] mov ebp, DWORD [gc+cullStripHdr] shl edx, 22 ; 00000010H add fifo, 4 shl eax, 6 or ebp, edx or eax, ebp mov edx, DWORD [esp+_pktype] or eax, edx nop mov DWORD [fifo-4], eax ;;; for (k = 0; k < vcount; k++) { ;;; FxI32 i; ;;; FxU32 dataElem; ;;; float *vPtr; ;;; vPtr = pointers; ;;; if (mode) ;;; vPtr = *(float **)vPtr ;;; (float *)pointers += stride; ;;; TRI_SETF(FARRAY(vPtr, 0)); ;;; dataElem = 0; ;;; TRI_SETF(FARRAY(vPtr, 4)); ;;; i = gc->tsuDataList[dataElem]; align 4 .win_for_begin: mov edx, vertexPtr mov eax, DWORD [strideinbytes] cmp eax, 4 jne .win_no_deref mov edx, DWORD [vertexPtr] align 4 .win_no_deref: add fifo, 8 add vertexPtr, eax mov eax, DWORD [edx] mov ebp, DWORD [edx+4] mov DWORD [fifo-8], eax mov eax, DWORD [gc+tsuDataList] mov DWORD [fifo-4], ebp test eax, eax lea dlp, [gc+tsuDataList] je .win_datalist_end align 4 ;;; while (i != GR_DLIST_END) { ;;; TRI_SETF(FARRAY(vPtr, i)); ;;; dataElem++; ;;; i = gc->tsuDataList[dataElem]; ;;; } .win_datalist_begin: add fifo, 4 add dlp, 4 mov eax, DWORD [edx+eax] nop mov DWORD [fifo-4], eax mov eax, DWORD [dlp] test eax, eax jne .win_datalist_begin .win_datalist_end: dec vertexCount jne .win_for_begin .win_for_end: ;;; TRI_END; ;;; Prepare for the next packet (if the strip size is longer than 15) ;;; GR_CHECK_SIZE(); ;;; count -= 15; ;;; pktype = SSTCP_PKT3_DDDDDD; ;;; } mov eax, DWORD [gc+fifoPtr] mov edx, DWORD [gc+fifoRoom] sub eax, fifo mov vertexCount, DWORD [esp+_count] add edx, eax sub vertexCount, 15 ; 0000000fH mov DWORD [gc+fifoRoom], edx mov DWORD [esp+_count], vertexCount mov DWORD [gc+fifoPtr], fifo test vertexCount, vertexCount mov DWORD [esp+_pktype], 16 ; 00000010H jg .window_coords_begin .strip_done: pop ebp pop ebx pop edi pop esi ret ; 00000014H endp %define gc esi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define vertexPtr edx ; pointer to vertex or vertex array ALIGN 32 proc _vpdrawvertexlist, 20 SET_TLSBASE eax ; tls base pointer push esi SET_TLSOFFSET esi ; gc position relative to tls base push edi push ebx GET_GC eax, esi push ebp mov ecx, DWORD [esp+_mode] mov edi, DWORD [esp+_pointers] mov eax, DWORD [gc+wInfo_offset] test ecx, ecx je .w_no_dref mov edi, DWORD [edi] align 4 .w_no_dref: ;;; load first w fld DWORD [edi+eax] fdivr DWORD [_F1] mov ecx, DWORD [gc+vertexSize] mov edx, DWORD [esp+_mode] mov edi, DWORD [esp+_count] ;;; mov vertexArray, DWORD [esp+_pointers] shl edx, 2 mov DWORD [vSize], ecx test edx, edx jne .no_stride mov edx, DWORD [gc+vertexStride] shl edx, 2 align 4 .no_stride: mov DWORD [strideinbytes], edx mov eax, DWORD [esp+_type] shl eax, 16 ; 00000010H mov DWORD [packetVal], eax .clip_coords_begin: cmp edi, 15 jl .clip_partial_packet mov edi, 15 .clip_partial_packet: ;;; GR_SET_EXPECTED_SIZE(vcount * vSize, 1) mov eax, DWORD [vSize] mov ecx, DWORD [gc+fifoRoom] imul eax, edi add eax, 4 cmp ecx, eax jge .clip_strip_begin invoke _grCommandTransportMakeRoom, eax, 0, __LINE__ align 4 .clip_strip_begin: ;;; TRI_STRIP_BEGIN(type, vcount, vSize, pktype) mov fifo, DWORD [gc+fifoPtr] mov eax, edi mov edx, DWORD [packetVal] mov ebp, DWORD [gc+cullStripHdr] or eax, edx add fifo, 4 shl eax, 6 mov edx, DWORD [esp+_pktype] or eax, ebp or eax, edx mov DWORD [fifo-4], eax mov vertexPtr, DWORD [esp+_pointers] mov eax, DWORD [esp+_mode] test eax, eax je .clip_for_begin mov vertexPtr, DWORD [vertexPtr] align 4 .clip_for_begin: add fifo, 8 mov ebp, DWORD [strideinbytes] add DWORD [esp+_pointers], ebp mov eax, DWORD [gc+paramIndex] xor ebp, ebp mov ebx, DWORD [gc+tsuDataList] ;;; ; setup x and y fld DWORD [gc+vp_hwidth] fmul DWORD [vertexPtr] fmul st0, st1 fadd DWORD [gc+vp_ox] fxch st1 fld DWORD [gc+vp_hheight] fmul DWORD [vertexPtr+4] test al, 3 fmul st0, st1 fadd DWORD [gc+vp_oy] fxch st1 fstp DWORD [ccoow] fxch st1 fstp DWORD [fifo-8] fstp DWORD [fifo-4] ;;; ; set up color je .clip_setup_ooz cmp DWORD [gc+colorType], ebp jne .clip_setup_pargb test al, 1 je .clip_setup_a add fifo, 12 mov ebp, 3 fld DWORD [_GlideRoot+pool_f255] fmul DWORD [ebx+vertexPtr] fld DWORD [_GlideRoot+pool_f255] fmul DWORD [ebx+vertexPtr+4] fld DWORD [_GlideRoot+pool_f255] fmul DWORD [ebx+vertexPtr+8] fxch st2 fstp DWORD [fifo-12] fstp DWORD [fifo-8] fstp DWORD [fifo-4] mov ebx, DWORD [gc+tsuDataList+12] align 4 .clip_setup_a: test al, 2 je .clip_setup_ooz add fifo, 4 inc ebp fld DWORD [ebx+vertexPtr] fmul DWORD [_GlideRoot+pool_f255] fstp DWORD [fifo-4] mov ebx, DWORD [gc+ebp*4+tsuDataList] jmp .clip_setup_ooz align 4 .clip_setup_pargb: add fifo, 4 mov ebx, DWORD [ebx+vertexPtr] mov DWORD [fifo-4], ebx nop mov ebp, 1 mov ebx, DWORD [gc+tsuDataList+4] align 4 .clip_setup_ooz: test al, 4 je .clip_setup_qow add fifo, 4 inc ebp test DWORD [gc+fbi_fbzMode], 200000h je .clip_setup_ooz_nofog mov ebx, DWORD [gc+qInfo_mode] test ebx, ebx je .clip_setup_fog_oow mov ebx, DWORD [gc+qInfo_offset] fld DWORD [vertexPtr+ebx] fmul DWORD [ccoow] fstp DWORD [fifo-4] mov ebx, DWORD [gc+ebp*4+tsuDataList] jmp .clip_setup_qow align 4 .clip_setup_fog_oow: fld DWORD [_F1] fsub DWORD [ccoow] fmul DWORD [gc+depth_range] fstp DWORD [fifo-4] mov ebx, DWORD [gc+ebp*4+tsuDataList] jmp .clip_setup_qow align 4 .clip_setup_ooz_nofog: fld DWORD [ebx+vertexPtr] fmul DWORD [gc+vp_hdepth] fmul DWORD [ccoow] fadd DWORD [gc+vp_oz] fstp DWORD [fifo-4] mov ebx, DWORD [gc+ebp*4+tsuDataList] align 4 .clip_setup_qow: test al, 8 je .clip_setup_qow0 mov ebx, DWORD [gc+fogInfo_mode] test ebx, ebx je .clip_setup_oow_nofog mov ebx, DWORD [gc+fogInfo_offset] fld DWORD [vertexPtr+ebx] fmul DWORD [ccoow] fstp DWORD [fifo] jmp .clip_setup_oow_inc align 4 .clip_setup_oow_nofog: mov ebx, DWORD [gc+qInfo_mode] test ebx, ebx je .clip_setup_oow mov ebx, DWORD [gc+qInfo_offset] fld DWORD [vertexPtr+ebx] fmul DWORD [ccoow] fstp DWORD [fifo] jmp .clip_setup_oow_inc align 4 .clip_setup_oow: mov ebx, DWORD [ccoow] mov DWORD [fifo], ebx align 4 .clip_setup_oow_inc: mov ebx, DWORD [gc+ebp*4+tsuDataList+4] add fifo, 4 inc ebp align 4 .clip_setup_qow0: test al, 16 je .clip_setup_stow0 mov ebx, DWORD [gc+q0Info_mode] cmp ebx, 1 jne .clip_setup_oow0 mov ebx, DWORD [gc+q0Info_offset] fld DWORD [ebx+vertexPtr] fmul DWORD [ccoow] fstp DWORD [fifo] jmp .clip_setup_oow0_inc align 4 .clip_setup_oow0: mov ebx, DWORD [ccoow] mov DWORD [fifo], ebx align 4 .clip_setup_oow0_inc: mov ebx, DWORD [gc+ebp*4+tsuDataList+4] add fifo, 4 inc ebp align 4 .clip_setup_stow0: test al, 32 je .clip_setup_qow1 fld DWORD [ccoow] fmul DWORD [ebx+vertexPtr] add fifo, 8 add ebp, 2 fmul DWORD [gc+tmu0_s_scale] fld DWORD [ccoow] fmul DWORD [ebx+vertexPtr+4] mov ebx, DWORD [gc+ebp*4+tsuDataList] fmul DWORD [gc+tmu0_t_scale] fxch fstp DWORD [fifo-8] fstp DWORD [fifo-4] align 4 .clip_setup_qow1: test al, 64 je .clip_setup_stow1 mov ebx, DWORD [gc+q1Info_mode] cmp ebx, 1 jne .clip_setup_oow1 mov ebx, DWORD [gc+q1Info_offset] fld DWORD [ebx+vertexPtr] fmul DWORD [ccoow] fstp DWORD [fifo] jmp .clip_setup_oow1_inc align 4 .clip_setup_oow1: mov ebx, DWORD [ccoow] mov DWORD [fifo], ebx align 4 .clip_setup_oow1_inc: mov ebx, DWORD [gc+ebp*4+tsuDataList+4] add fifo, 4 inc ebp align 4 .clip_setup_stow1: test al, 128 je .clip_setup_end fld DWORD [ccoow] fmul DWORD [ebx+vertexPtr] add fifo, 8 fmul DWORD [gc+tmu1_s_scale] fld DWORD [ccoow] fmul DWORD [ebx+vertexPtr+4] mov ebx, DWORD [gc+ebp*4+tsuDataList+4] fmul DWORD [gc+tmu1_t_scale] fxch fstp DWORD [fifo-8] fstp DWORD [fifo-4] align 4 .clip_setup_end: dec edi jz .clip_for_end mov vertexPtr, DWORD [esp+_pointers] mov ebx, DWORD [esp+_mode] test ebx, ebx je .w_clip_no_deref mov vertexPtr, DWORD [vertexPtr] align 4 .w_clip_no_deref: mov ebx, DWORD [gc+wInfo_offset] fld DWORD [ebx+vertexPtr] fdivr DWORD [_F1] jmp .clip_for_begin align 4 .clip_for_end: mov ebx, DWORD [gc+fifoPtr] mov edx, DWORD [gc+fifoRoom] sub ebx, fifo mov edi, DWORD [esp+_count] add edx, ebx sub edi, 15 ; 0000000fH mov DWORD [gc+fifoRoom], edx mov DWORD [esp+_count], edi mov DWORD [gc+fifoPtr], fifo mov DWORD [esp+_pktype], 16 ; 00000010H jle .strip_done mov edx, DWORD [esp+_pointers] mov ebx, DWORD [esp+_mode] test ebx, ebx je .w1_clip_no_deref mov edx, DWORD [edx] align 4 .w1_clip_no_deref: mov ebx, DWORD [gc+wInfo_offset] fld DWORD [ebx+edx] fdivr DWORD [_F1] jmp .clip_coords_begin align 4 .strip_done: pop ebp pop ebx pop edi pop esi ret ; 00000014H endp %define gc esi ; points to graphics context %define fifo ecx ; points to next entry in fifo %define vertexPtr edi ; Current vertex pointer ;; NB: All of the base triangle procs expect to have the gc ;; passed from the caller in edx so that we can avoid ;; the agi from the far pointer. Screw w/ this at your ;; own peril. ;; ;; YOU HAVE BEEN WARNED ALIGN 32 proc _vptrisetup_cull, 12 _va equ 20 _vb equ 24 _vc equ 28 push ebx push esi push edi mov gc, edx ; ; AJB: Clip Coord mode needs to call grValidateState ; mov edx, [gc + invalid] ; state needs validation ? test edx, edx ; do we need to validate state ? je .no_validation ; nope, it's valid invoke _grValidateState ; validate state .no_validation: mov ecx, DWORD [esp+_va-4] mov eax, DWORD [gc+wInfo_offset] push ebp nop ;;; ; oow[0] = 1.0f / FARRAY(va, gc->state.vData.wInfo.offset) fld DWORD [eax+ecx] fdivr DWORD [_F1] mov ecx, DWORD [esp+_vb] mov ebx, DWORD [esp+_vc] nop nop mov ebp, DWORD [eax+ecx] mov edi, DWORD [eax+ebx] mov DWORD [vPtr1], ebp mov DWORD [vPtr2], edi ;;; ; GR_SET_EXPECTED_SIZE(_GlideRoot.curTriSize, 1) mov eax, DWORD [gc+curTriSize] mov ecx, DWORD [gc+fifoRoom] add eax, 4 nop cmp ecx, eax jge .setup_pkt_hdr invoke _grCommandTransportMakeRoom, eax, 0, __LINE__ align 4 .setup_pkt_hdr: ;;; ; TRI_STRIP_BEGIN(kSetupStrip, 3, gc->state.vData.vSize, SSTCP_PKT3_BDDBDD) mov fifo, DWORD [gc+fifoPtr] mov eax, DWORD [gc+cullStripHdr] add fifo, 4 lea ebp, [esp+_va] or eax, 192 ; 000000c0H mov edx, 0 mov DWORD [fifo-4], eax mov vertexPtr, DWORD [ebp] mov eax, DWORD [gc+paramIndex] nop ;;; Begin loop align 4 .begin_for_loop: add edx, 4 add fifo, 8 xor ebx, ebx mov ebp, DWORD [gc+tsuDataList] ;;; ; setup x and y fld DWORD [gc+vp_hwidth] fmul DWORD [vertexPtr] fmul st0, st1 fadd DWORD [gc+vp_ox] fxch st1 fld DWORD [vertexPtr+4] fmul DWORD [gc+vp_hheight] test al, 3 fmul st0, st1 fadd DWORD [gc+vp_oy] fxch st1 fstp DWORD [oowa] fxch st1 fstp DWORD [fifo-8] fstp DWORD [fifo-4] ;;; ; set up color je .clip_setup_ooz cmp DWORD [gc+colorType], ebx jne .clip_setup_pargb test al, 1 je .clip_setup_a add fifo, 12 add ebx, 3 fld DWORD [_GlideRoot+pool_f255] fmul DWORD [vertexPtr+ebp] fld DWORD [_GlideRoot+pool_f255] fmul DWORD [vertexPtr+ebp+4] fld DWORD [_GlideRoot+pool_f255] fmul DWORD [vertexPtr+ebp+8] fxch st2 fstp DWORD [fifo-12] fstp DWORD [fifo-8] fstp DWORD [fifo-4] mov ebp, DWORD [gc+tsuDataList+12] align 4 .clip_setup_a: test al, 2 je .clip_setup_ooz add fifo, 4 inc ebx fld DWORD [vertexPtr+ebp] fmul DWORD [_GlideRoot+pool_f255] fstp DWORD [fifo-4] mov ebp, DWORD [gc+tsuDataList+ebx*4] jmp .clip_setup_ooz align 4 .clip_setup_pargb: add fifo, 4 mov ebx, DWORD [vertexPtr+ebp] mov DWORD [fifo-4], ebx nop mov ebx, 1 mov ebp, DWORD [gc+tsuDataList+4] align 4 .clip_setup_ooz: test al, 4 je .clip_setup_qow add fifo, 4 inc ebx test DWORD [gc+fbi_fbzMode], 200000h je .clip_setup_ooz_nofog mov ebp, DWORD [gc+qInfo_mode] test ebp, ebp je .clip_setup_fog_oow mov ebp, DWORD [gc+qInfo_offset] fld DWORD [vertexPtr+ebp] fmul DWORD [oowa] fstp DWORD [fifo-4] mov ebp, DWORD [gc+tsuDataList+ebx*4] jmp .clip_setup_qow align 4 .clip_setup_fog_oow: fld DWORD [_F1] fsub DWORD [oowa] fmul DWORD [gc+depth_range] fstp DWORD [fifo-4] mov ebp, DWORD [gc+tsuDataList+ebx*4] jmp .clip_setup_qow align 4 .clip_setup_ooz_nofog: fld DWORD [vertexPtr+ebp] fmul DWORD [gc+vp_hdepth] fmul DWORD [oowa] fadd DWORD [gc+vp_oz] fstp DWORD [fifo-4] mov ebp, DWORD [gc+tsuDataList+ebx*4] align 4 .clip_setup_qow: test al, 8 je .clip_setup_qow0 cmp DWORD [gc+fogInfo_mode], 1 jne .clip_setup_oow_nofog mov ebp, DWORD [gc+fogInfo_offset] fld DWORD [oowa] fmul DWORD [vertexPtr+ebp] fstp DWORD [fifo] jmp .clip_setup_oow_inc align 4 .clip_setup_oow_nofog: cmp DWORD [gc+qInfo_mode], 1 jne .clip_setup_oow mov ebp, DWORD [gc+qInfo_offset] fld DWORD [oowa] fmul DWORD [vertexPtr+ebp] fstp DWORD [fifo] jmp .clip_setup_oow_inc align 4 .clip_setup_oow: mov ebp, DWORD [oowa] mov DWORD [fifo], ebp align 4 .clip_setup_oow_inc: mov ebp, DWORD [gc+tsuDataList+ebx*4+4] add fifo, 4 inc ebx align 4 .clip_setup_qow0: test al, 16 ; 00000010H je .clip_setup_stow0 cmp DWORD [gc+q0Info_mode], 1 jne .clip_setup_oow0 mov ebp, DWORD [gc+q0Info_offset] fld DWORD [oowa] fmul DWORD [ebp+vertexPtr] fstp DWORD [fifo] jmp .clip_setup_oow0_inc align 4 .clip_setup_oow0: mov ebp, DWORD [oowa] mov DWORD [fifo], ebp align 4 .clip_setup_oow0_inc: mov ebp, DWORD [gc+tsuDataList+ebx*4+4] add fifo, 4 inc ebx align 4 .clip_setup_stow0: test al, 32 je .clip_setup_qow1 fld DWORD [oowa] fmul DWORD [vertexPtr+ebp] add fifo, 8 add ebx, 2 fmul DWORD [gc+tmu0_s_scale] fld DWORD [oowa] fmul DWORD [vertexPtr+ebp+4] mov ebp, DWORD [gc+tsuDataList+ebx*4] fmul DWORD [gc+tmu0_t_scale] fxch fstp DWORD [fifo-8] fstp DWORD [fifo-4] align 4 .clip_setup_qow1: test al, 64 je .clip_setup_stow1 cmp DWORD [gc+q1Info_mode], 1 jne .clip_setup_oow1 mov ebp, DWORD [gc+q1Info_offset] fld DWORD [vertexPtr+ebp] fmul DWORD [oowa] fstp DWORD [fifo] jmp .clip_setup_oow1_inc align 4 .clip_setup_oow1: mov ebp, DWORD [oowa] mov DWORD [fifo], ebp align 4 .clip_setup_oow1_inc: mov ebp, DWORD [gc+tsuDataList+ebx*4+4] add fifo, 4 inc ebx align 4 .clip_setup_stow1: test al, 128 je .clip_setup_end fld DWORD [oowa] fmul DWORD [vertexPtr+ebp] add fifo, 8 fmul DWORD [gc+tmu1_s_scale] fld DWORD [oowa] fmul DWORD [vertexPtr+ebp+4] fmul DWORD [gc+tmu1_t_scale] fxch fstp DWORD [fifo-8] fstp DWORD [fifo-4] align 4 .clip_setup_end: cmp edx, 12 je .update_fifo_ptr fld DWORD [vPtr0+edx] fdivr DWORD [_F1] lea ebx, [esp+_va] mov ebp, DWORD [gc+wInfo_offset] mov vertexPtr, DWORD [ebx+edx] jmp .begin_for_loop align 4 .update_fifo_ptr: mov ebx, DWORD [gc+fifoPtr]; Move gcFifo->fifoPtr to ebx mov edx, DWORD [gc+fifoRoom]; move gcFifo->fifoRoom to edx sub ebx, fifo ; subtract local fifo copy from ebx ; this yields the negative of what we ; wrote to the fiof mov eax, 1 ; place a 1 in eax for return add edx, ebx ; add (now negative) amount written to ; the fifo to our local copy of the ; fifoRoom variable mov DWORD [gc+fifoRoom], edx; move the local fifoRoom ; back to the gc mov DWORD [gc+fifoPtr], fifo; move local fifoPointer ; back to gc mov ebx, DWORD [gc+trisProcessed]; load trisProcessed ; into register ;;; ; _GlideRoot.stats.trisProcessed++ inc ebx ; increment trisProcessed mov DWORD [gc+trisProcessed], ebx; Store trisProcessed ; back to GC ;; Clean up the stack // FIXED by JHunter (wrong order, trashed edi/esi and ebx) pop ebp pop edi pop esi pop ebx ret ; 0000000cH endp %endif ; !GL_SSE %endif ; !GL_MMX %endif ; !GL_AMD3D glide3x/h5/glide3/src/xdrawppc.asm0100700000175300010010000002137507725034670016334 0ustar johndoeNone; ; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ; ; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ; THE UNITED STATES. ; ; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ; MACRO MakeFunction &fnName EXPORT &fnName[DS] EXPORT .&fnName[PR] TC &fnName[TC], &fnName[DS] CSECT &fnName[DS] DC.L .&fnName[PR] DC.L TOC[tc0] CSECT .&fnName[PR] FUNCTION .&fnName[PR] ENDM INCLUDE 'PPCInline.inc' ; ====================================================================== ; external global variables ; ====================================================================== import _threadValueMacOS import ._grCommandTransportMakeRoom import ._grValidateState toc tc _threadValueMacOS[TC], _threadValueMacOS IF 1 linkageArea: set 24 ; constant comes from the PowerPC Runtime Architecture Document CalleesParams: set 32 ; always leave space for GPR's 3-10 CalleesLocalVars: set 0 ; ClickHandler doesn't have any numGPRs: set 7 ; num volitile GPR's (GPR's 13-31) numFPRs: set 9 ; num volitile FPR's (FPR's 14-31) spaceToSave: set linkageArea + CalleesParams + CalleesLocalVars + 4*numGPRs + 8*numFPRs MakeFunction _trisetup_Default_win_cull_invalid _trisetup_Default_win_cull_invalid_begin: mflr r7 ; Get return address in volatile register lwz r0,invalid(r6) ; load state flag stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) cmplwi r0,$0000 ; check state flag (sets cr0) lwz r0,cull_mode(r6) ; load cull mode addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) cmplwi cr1,r0,$0000 ; check culling mode (sets cr1) stw r7,8(sp) addi r31,r6,0 stwu sp,-128(sp) beq+ @noValidate ; check valid state flag (via cr0), predict branch to true bl ._grValidateState nop lwz r0,cull_mode(r31) ; reload cull mode into r0 ; 1 cycle stall cmplwi cr1,r0,$0000 ; redo cull check since cr1 could have been trashed align 3 @noValidate: beq- cr1,@noCull ; check for culling being disabled, predict as not taken lfs fp4,4(29) ; load bY rlwinm r6,r0,31,0,0 ; get cull mode in top bit lfs fp0,4(r28) ; load aY lfs fp5,0(r29) ; load bX lfs fp1,0(r30) ; load cX fsubs fp0,fp0,fp4 ; fp0 = dyAB lfs fp3,0(r28) ; load aX fsubs fp1,fp5,fp1 ; fp1 = dxBC lfs fp2,4(r30) ; load cY fsubs fp3,fp3,fp5 ; fp3 = dxAB fsubs fp2,fp4,fp2 ; fp2 = dyBC fmuls fp0,fp1,fp0 ; fp0 = dxBC * dyAB ; 2 cycle stall fmsubs fp0,fp3,fp2,fp0 ; fp0 = dxAB * dyBC - dxBC * dyAB ; 2 cycle stall stfs fp0,-32(sp) ; 1 cycle stall lwz r7,-32(sp) ; 1 cycle stall rlwinm. r0,r7,0,1,31 ; check for zero area bne+ @nonZeroArea ; okay so far... li r3,$0000 @culledReturn: lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr align 3 ; allign branch target doubleword address @nonZeroArea: xor. r0,r7,r6 ; check culling blt @noCull li r3,-1 b @culledReturn align 3 @noCull: INCLUDE 'xdrawppc.inc' _trisetup_Default_win_cull_invalid_end: MakeFunction _trisetup_Default_win_nocull_invalid _trisetup_Default_win_nocull_invalid_begin: mflr r7 ; Get return address in volatile register lwz r0,invalid(r6) ; load state flag stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) cmplwi r0,$0000 ; check state flag (sets cr0) addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) stw r7,8(sp) addi r31,r6,0 stwu sp,-128(sp) beq+ @noValidate ; check valid state flag (via cr0), predict branch to true bl ._grValidateState nop ; 1 cycle stall align 3 @noValidate: INCLUDE 'xdrawppc.inc' _trisetup_Default_win_nocull_invalid_end: MakeFunction _trisetup_Default_win_cull_valid _trisetup_Default_win_cull_valid_begin: mflr r7 ; Get return address in volatile register lwz r0,cull_mode(r6) ; load cull mode stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) cmplwi cr1,r0,$0000 ; check culling mode (sets cr1) addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) stw r7,8(sp) addi r31,r6,0 stwu sp,-128(sp) beq- cr1,@noCull ; check for culling being disabled, predict as not taken lfs fp4,4(29) ; load bY rlwinm r6,r0,31,0,0 ; get cull mode in top bit lfs fp0,4(r28) ; load aY lfs fp5,0(r29) ; load bX lfs fp1,0(r30) ; load cX fsubs fp0,fp0,fp4 ; fp0 = dyAB lfs fp3,0(r28) ; load aX fsubs fp1,fp5,fp1 ; fp1 = dxBC lfs fp2,4(r30) ; load cY fsubs fp3,fp3,fp5 ; fp3 = dxAB fsubs fp2,fp4,fp2 ; fp2 = dyBC fmuls fp0,fp1,fp0 ; fp0 = dxBC * dyAB ; 2 cycle stall fmsubs fp0,fp3,fp2,fp0 ; fp0 = dxAB * dyBC - dxBC * dyAB ; 2 cycle stall stfs fp0,-32(sp) ; 1 cycle stall lwz r7,-32(sp) ; 1 cycle stall rlwinm. r0,r7,0,1,31 ; check for zero area bne+ @nonZeroArea ; okay so far... li r3,$0000 @culledReturn: lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr align 3 ; allign branch target doubleword address @nonZeroArea: xor. r0,r7,r6 ; check culling blt @noCull li r3,-1 b @culledReturn align 3 @noCull: INCLUDE 'xdrawppc.inc' _trisetup_Default_win_cull_valid_end: MakeFunction _trisetup_Default_win_nocull_valid _trisetup_Default_win_nocull_valid_begin: mflr r7 ; Get return address in volatile register stw r28,-16(sp) addi r28,r3,0 stw r29,-12(sp) addi r29,r4,0 stw r30,-8(sp) addi r30,r5,0 stw r31,-4(sp) addi r31,r6,0 stw r7,8(sp) stwu sp,-128(sp) INCLUDE 'xdrawppc.inc' _trisetup_Default_win_nocull_valid_end: ENDIF IF 1 ; About 3 clock cycles of stalls in the code below, waiting for loads. (But ; about 12 clocks that could be used for something else) MakeFunction grDrawTriangle lwz r6,_threadValueMacOS[TC](RTOC) ; Get pointer to thread value lwz r6,0(r6) ; get thread value (gc) addis r7,r6,1 ; add 64K lwz r12,triSetupProc(r7) ; load triangle dispatch vector lwz r7,0(r12) ; grab function pointer ;lwz rtoc,4(r12) ; load new TOC mtctr r7 ; move to ctr bctr ; jump to triangle setup function ENDIFglide3x/h5/glide3/src/xdrawppc.inc0100700000175300010010000003161207725034670016320 0ustar johndoeNone; ; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ; ; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ; THE UNITED STATES. ; ; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ; IF 1 ; Start of triangle setup ; at this point, registers look like this: ; ; r28 - vertex A ; r29 - vertex B ; r30 - vertex C ; r31 - gc ; First step, check for fifo room. lwz r6,curTriSize(r31) ; get triangle data size lwz r0,fifoRoom(r31) ; get fifo room lwz r7,fifoPtr(r31) ; get fifo pointer addi r6,r6,4 ; add in packet header size cmpw cr1,r0,r6 ; is there enough room? (set CR1) li r10,-4 ; keep r10 around as -4 bge+ cr1,@gotFifoRoom ; use CR1 li r4,0 ; XXX - FIXME!!! li r5,0 addi r3,r6,0 bl ._grCommandTransportMakeRoom lwz r7,fifoPtr(r31) ; reload fifo pointer li r10,-4 ; reload r10 align 3 ; Register usage is as follows: ; ; r7 - fifoPtr ; r8 - ??? ; r9 - alignment check ; r10 - pointer to "buffer" on the stack (-8 offset) ; r5 - constant 4 @gotFifoRoom: stw r28,-16(sp) subi r28,sp,16 ; get pointer to first vertex pointer stw r29,-12(sp) addi r29,r0,3 ; vertex count stw r30,-8(sp) mtctr r29 ; store count in CTR lwz r6,triPacketHdr(r31) ; get packet header rlwinm. r0,r7,0,29,31 ; check FIFO alignment... (set CR0) subi r10,sp,32 ; get pointer to magic buffer addi r5,r0,4 ; get constant offset of 4 into r5 bne @vertex_align ; do aligned case ; FIFO pointer is already aligned, so store to buffer stwbrx r6,r0,r10 b @vertex_begin_half @vertex_align: stwbrx r6,r0,r7 ; store packet header into fifo addi r7,r7,4 ; update fifo pointer ; buffer is empty, so store X and Y, then flush buffer @vertex_begin_empty: lwz r29,0(r28) ; load vertex pointer addi r28,r28,4 ; calc next pointer lwz r4,tsuDataList(r31) ; load first data index directly addi r11,r31,tsuDataList ; get pointer to data list (1st entry) lwz r3,0(r29) ; load X addi r7,r7,8 ; increment FIFO pointer lwz r6,4(r29) ; load Y cmplwi cr0,r4,$0000 ; set CR0 for end of data list... stwbrx r3,r0,r10 ; store to buffer[0] stwbrx r6,r5,r10 ; store to buffer[1] lfd fp0,0(r10) ; load fifo value stfd fp0,-8(r7) ; store fifo value b @vertex_loop_empty @vertex_begin_half: lwz r29,0(r28) ; load vertex pointer addi r28,r28,4 ; get next pointer lwz r8,tsuDataList(r31) ; load first data index directly addi r11,r31,tsuDataList ; get pointer to data list (1st entry) lwz r3,0(r29) ; load X addi r7,r7,8 ; increment FIFO pointer lwz r6,4(r29) ; load Y cmplwi cr1,r8,$0000 ; set CR1 for end of data list... stwbrx r3,r5,r10 ; store to buffer[1] lfd fp0,0(r10) ; load fifo value stwbrx r6,r0,r10 ; store to buffer[0] stfd fp0,-8(r7) ; store fifo value b @vertex_loop_half @vertex_loop_empty beq cr0,@vertex_end_empty ; precomputed cr0 lwzu r8,4(r11) ; grab next index lwzx r3,r4,r29 ; load current data item cmplwi cr1,r8,$0000 ; set CR1 for end of data list... stwbrx r3,r0,r10 ; store data item ; fall through... @vertex_loop_half beq cr1,@vertex_end_half ; precomputed cr1 lwzu r4,4(r11) ; grab next index lwzx r3,r8,r29 ; load current data item addi r7,r7,8 ; update fifo pointer cmplwi cr0,r4,$0000 ; set CR0 for end of data list... stwbrx r3,r5,r10 ; store data item lfd fp0,0(r10) ; load fifo data stfd fp0,-8(r7) ; store fifo data b @vertex_loop_empty ; go do next data item. @vertex_end_empty bdnz @vertex_begin_empty b @vertex_end @vertex_end_half bdnz @vertex_begin_half lwz r3,0(r10) stwx r3,r0,r7 ; store last data item addi r7,r7,4 ; update fifo pointer @vertex_end: ; WHEW! Okay, now update FIFO pointer & fifo data availability before we go. lwz r3,autoBump(r31) ; get autoBump flag lwz r4,fifoPtr(r31) ; get original fifo pointer lwz r5,bumpPos(r31) ; get next bump pos (in case we need it) lwz r0,fifoRoom(r31) ; get fifo free cmplwi cr0,r3,$0000 ; check auto bump flag subf r4,r4,r7 ; calc amount used cmpw cr1,r5,r7 ; is bumpPos > fifoPtr? lwz r6,lastBump(r31) ; get last bump pos subf r0,r4,r0 ; calc new amount free stw r0,fifoRoom(r31) ; save free stw r7,fifoPtr(r31) ; save new fifo pointer bne+ @no_bump ; if we're auto bumping, then skip bump bgt+ cr1,@no_bump ; if we haven't reached bump pos, then skip bump ; Need to bump. We have current fifo ptr in r7, last bump pos in r6 lwz r3,bumpSize(r31) subf r6,r6,r7 ; r6 = bytes to bump stw r7,lastBump(r31) ; store current as last bump pos sri r6,r6,2 ; convert difference to words addis r5,r31,1 ; get gc + 64K sli r3,r3,2 ; convert bump words to bytes lwz r5,cRegs(r5) ; get pointer to command transport registers add r3,r3,r7 ; calc next bump position stw r3,bumpPos(r31) ; store next bump position (don't care if it's past the end of the fifo...) addi r4,r0,cmdFifo0Bump ; r4 = offset to bump register stwbrx r6,r4,r5 ; hit bump register ; And we're outta here... @no_bump ; Final cleanup code begins here. Return FXTRUE. li r3,1 lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr ELSE ; Start of triangle setup ; at this point, registers look like this: ; ; r28 - vertex A ; r29 - vertex B ; r30 - vertex C ; r31 - gc ; First step, check for fifo room. lwz r6,curTriSize(r31) ; get triangle data size lwz r0,fifoRoom(r31) ; get fifo room lwz r7,fifoPtr(r31) ; get fifo pointer addi r6,r6,4 ; add in packet header size cmpw cr1,r0,r6 ; is there enough room? (set CR1) li r10,-4 ; keep r10 around as -4 bge+ cr1,@gotFifoRoom ; use CR1 li r4,0 ; XXX - FIXME!!! li r5,0 addi r3,r6,0 bl ._grCommandTransportMakeRoom lwz r7,fifoPtr(r31) ; reload fifo pointer li r10,-4 ; reload r10 align 3 ; Register usage is as follows: ; ; r7 - fifoPtr ; r8 - ??? ; r9 - alignment check ; r10 - pointer to "buffer" on the stack (-8 offset) ; r5 - constant 4 @gotFifoRoom: stw r28,-16(sp) subi r28,sp,16 ; get pointer to first vertex pointer stw r29,-12(sp) addi r29,r0,3 ; vertex count stw r30,-8(sp) mtctr r29 ; store count in CTR addi r6,r31,triPacketHdr lwbrx r6,r0,r6 addi r0,r0,4 ; constant 4 stw r6,0(r7) ; store packet header into fifo addi r7,r7,4 ; update fifo pointer ; buffer is empty, so store X and Y, then flush buffer @vertex_begin: lwz r29,0(r28) ; load vertex pointer addi r28,r28,4 ; calc next pointer lwbrx r3,r0,r29 ; load X lwbrx r4,r29,r0 ; load Y lwz r5,tsuDataList(r31) ; load first data index directly addi r11,r31,tsuDataList ; get pointer to data list (1st entry) stw r3,0(r7) addi r7,r7,4 stw r4,0(r7) addi r7,r7,4 cmplwi cr0,r5,$0000 ; set CR0 for end of data list... ; dst r0,r28 ; try to preload next vector @vertex_loop beq cr0,@vertex_end ; precomputed cr0 lwzu r8,4(r11) ; grab next index lwbrx r3,r5,r29 ; load current data item cmplwi cr0,r8,$0000 ; set CR1 for end of data list... mr r5,r8 stw r3,0(r7) ; store data item addi r7,r7,4 ; increment fifo ptr b @vertex_loop @vertex_end bdnz @vertex_begin ; WHEW! Okay, now update FIFO pointer & fifo data availability before we go. lwz r3,autoBump(r31) ; get autoBump flag lwz r4,fifoPtr(r31) ; get original fifo pointer lwz r5,bumpPos(r31) ; get next bump pos (in case we need it) lwz r0,fifoRoom(r31) ; get fifo free cmplwi cr0,r3,$0000 ; check auto bump flag subf r4,r4,r7 ; calc amount used cmpw cr1,r5,r7 ; is bumpPos > fifoPtr? lwz r6,lastBump(r31) ; get last bump pos subf r0,r4,r0 ; calc new amount free stw r0,fifoRoom(r31) ; save free stw r7,fifoPtr(r31) ; save new fifo pointer bne+ @no_bump ; if we're auto bumping, then skip bump bgt+ cr1,@no_bump ; if we haven't reached bump pos, then skip bump ; Need to bump. We have current fifo ptr in r7, last bump pos in r6 lwz r3,bumpSize(r31) subf r6,r6,r7 ; r6 = bytes to bump stw r7,lastBump(r31) ; store current as last bump pos sri r6,r6,2 ; convert difference to words addis r5,r31,1 ; get gc + 64K sli r3,r3,2 ; convert bump words to bytes lwz r5,cRegs(r5) ; get pointer to command transport registers add r3,r3,r7 ; calc next bump position stw r3,bumpPos(r31) ; store next bump position (don't care if it's past the end of the fifo...) addi r4,r0,cmdFifo0Bump ; r4 = offset to bump register stwbrx r6,r4,r5 ; hit bump register ; And we're outta here... @no_bump ; Final cleanup code begins here. Return FXTRUE. li r3,1 lwz r0,136(sp) addi sp,sp,128 ; 1 cycle stall mtlr r0 lwz r28,-16(sp) lwz r29,-12(sp) lwz r30,-8(sp) lwz r31,-4(sp) blr ENDIF glide3x/h5/glide3/src/xos.inc0100700000175300010010000000531007725034670015275 0ustar johndoeNone; ; compulsory header for h5/glide3/xdraw* assembly specializations (NASM) ; ; $Header: /cvsroot/glide/glide3x/h5/glide3/src/Attic/xos.inc,v 1.1.2.2 2003/06/13 07:22:59 dborca Exp $ ; $Log: xos.inc,v $ ; Revision 1.1.2.2 2003/06/13 07:22:59 dborca ; more fixes to NASM sources ; ; Revision 1.1.2.1 2003/06/07 09:53:25 dborca ; initial checkin for NASM sources ; ;--------------------------------------- ; platform defines ;--------------------------------------- %define XOS_DJGPP 1 %define XOS_LINUX 2 %define XOS_WIN32 4 %define STDCALL 0 ;--------------------------------------- ; pick up the right OS ;--------------------------------------- %ifdef __DJGPP__ %define XOS XOS_DJGPP %elifdef __linux__ %define XOS XOS_LINUX %elifdef __WIN32__ %define XOS XOS_WIN32 %define STDCALL 1 %else %error Unknown OS %endif ;--------------------------------------- ; general purpose macros ;--------------------------------------- %macro extrn 1-2 0 %if (XOS == XOS_WIN32) && STDCALL && (%2 > 0) %define %1 %1@%2 %endif extern %1 %endmacro %macro globl 1-2 0 %if (XOS == XOS_WIN32) && STDCALL && (%2 > 0) %define %1 %1@%2 %endif global %1 %endmacro %macro proc 1-2 0 %push proc %if STDCALL && (%2 > 0) %define %$ret RET %2 %else %define %$ret RET %endif globl %1, %2 %1: %endmacro %macro endp 0 %ifnctx proc %error Mismatched `endp'/`proc' %else %pop %endif %endmacro %macro ret 0 %ifnctx proc RET %else %$ret %endif %endmacro %macro invoke 1-* %rep %0 - 1 %rotate -1 push %1 %endrep %rotate -1 call %1 %if (STDCALL == 0) && (%0 > 1) add esp, 4 * (%0 - 1) %endif %endmacro ;--------------------------------------- ; Windows ;--------------------------------------- %if XOS == XOS_WIN32 %define TEXT .text align=32 %define DATA .data align=32 %define CONST .rdata align=32 %macro SET_TLSBASE 1 mov %1, dword [fs:18h] ; get thread local storage base pointer %endmacro %macro SET_TLSOFFSET 1 mov %1, [_GlideRoot+tlsOffset] ; offset of GC into tls %endmacro %macro GET_GC 2 mov gc, [%1 + %2] %endmacro %endif ;--------------------------------------- ; DJGPP ;--------------------------------------- %if XOS == XOS_DJGPP %define TEXT .text %define DATA .data %define CONST .rodata extrn threadValueDJGPP %macro SET_TLSBASE 1 %endmacro %macro SET_TLSOFFSET 1 %endmacro %macro GET_GC 2 mov gc, [threadValueDJGPP] %endmacro %endif ;--------------------------------------- ; Linux ;--------------------------------------- %if XOS == XOS_LINUX %define TEXT .text align=32 %define DATA .data align=32 %define CONST .rodata align=32 extrn threadValueLinux %macro SET_TLSBASE 1 %endmacro %macro SET_TLSOFFSET 1 %endmacro %macro GET_GC 2 mov gc, [threadValueLinux] %endmacro %endif glide3x/h5/glide3/src/xtexdl.asm0100700000175300010010000006443307725034670016016 0ustar johndoeNone;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ;; FULL TEXT OF THE NON-WARRANTY PROVISIONS. ;; ;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ;; THE UNITED STATES. ;; ;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ;; ;; $Header: /cvsroot/glide/glide3x/h5/glide3/src/xtexdl.asm,v 1.1.8.6 2003/07/07 23:29:06 koolsmoky Exp $ ;; $Revision: 1.1.8.6 $ ;; $Log: xtexdl.asm,v $ ;; Revision 1.1.8.6 2003/07/07 23:29:06 koolsmoky ;; cleaned logs ;; ;; ;; Revision 1.1 2000/06/15 00:27:43 joseph ;; Initial checkin into SourceForge. ;; ;; 10 8/17/99 6:35p Atai ;; fixed amd debug mode ;; ;; 9 4/08/99 1:22p Atai ;; added contect check for _grTexDownload_3DNow_MMX ;; ;; 8 3/19/99 11:26a Peter ;; expose direct fifo for gl ;; ;; 7 2/02/99 4:36p Peter ;; download through lfb rather than texture port ;; ;; 6 12/17/98 2:36p Atai ;; check in Norbert's fix for texture download width correction ;; ;; 5 12/07/98 11:33a Peter ;; norbert's re-fixes of my merge ;; ;; 4 11/02/98 5:34p Atai ;; merge direct i/o code ;; ;; 3 10/20/98 5:34p Atai ;; added #ifdefs for hwc ;; ;; 2 10/14/98 12:05p Peter ;; fixed my effed up assumption about non-volatile regs ;; ;; 1 10/09/98 6:48p Peter ;; 3DNow!(tm) version of wide texture downloads ;; ;; 3 10/07/98 9:43p Peter ;; triangle procs for 3DNow!(tm) ;; ;; 2 10/05/98 7:43p Peter ;; 3DNow!(tm) happiness everywhere ;; ;; 1 10/05/98 6:01p Peter ;; mmx stuff for 3DNow!(tm) capable processors ;; %include "xos.inc" %ifdef USE_PACKET_FIFO extrn _grCommandTransportMakeRoom, 12 %endif ;;; Definitions of cvg regs and glide root structures. %INCLUDE "fxgasm.h" ; Arguments (STKOFF = 16 from 4 dword pushes) STACKOFFSET equ 16 _gc$ equ 4 + STACKOFFSET _baseAddr$ equ 8 + STACKOFFSET _maxS$ equ 12 + STACKOFFSET _minT$ equ 16 + STACKOFFSET _maxT$ equ 20 + STACKOFFSET _texData$ equ 24 + STACKOFFSET ;; NB: The first set of registers (eax, ecx, and edx) are volatile across ;; function calls. The remaining registers are supposedly non-volatile ;; so they only store things that are non-volatile across the call. %define fifo ebp ; fifo ptr in inner loop %define gc esi ; graphics context %define dataPtr edi ; pointer to exture data to be downloaded %define curT ebx ; counter for texture scan lines (t-coordinate) %define curS ecx ; texture s-coordinate %define fRoom edx ; room available in fifo (in bytes) ;-------------------------------------------------------------------------- %IFNDEF GL_SSE2 ;-------------------------------------------------------------------------- ; ; GL_AMD3D, GL_MMX ; ;-------------------------------------------------------------------------- segment TEXT ALIGN 32 %IFDEF GL_AMD3D proc _grTexDownload_3DNow_MMX, 24 %ENDIF %IFDEF GL_MMX proc _grTexDownload_MMX, 24 %ENDIF push ebx ; save caller's register variable mov curT, [esp + _maxT$ - 12] ; curT = maxT push esi ; save caller's register variable mov eax, [esp + _minT$ - 8] ; minT push edi ; save caller's register variable mov gc, [esp + _gc$ - 4] ; gc push ebp ; save caller's register variable mov dataPtr, [esp + _texData$]; dataPtr %IFDEF GLIDE_ALT_TAB test gc, gc je .dlDone mov edx, DWORD [gc+lostContext] mov ecx, [edx] test ecx, 1 jnz .dlDone %ENDIF sub curT, eax ; curT = maxT - minT mov fifo, [gc + fifoPtr] ; fifoPtr mov curS, [esp + _maxS$] ; curS = maxS add curT, 1 ; curT = maxT - minT + 1 %IFDEF GL_AMD3D femms ; we'll use MMX/3DNow!, make sure FPU register cleared %ENDIF %IFDEF GL_MMX emms ; we'll use MMX %ENDIF mov edx, curS ; curS = maxS = scanline width in DWORDs movd mm3, [esp + _baseAddr$] ; 0 | address of texture to download shl curS, 2 ; scan line width (in bytes) mov eax, [esp + _minT$] ; 0 | minT mov [esp + _maxS$], curS ; save scan line width (in bytes) shl edx, 3 ; packetHdr<21:3> = maxS = scanline width in DWORDs imul eax, curS ; TEX_ROW_ADDR_INCR(minT) = minT * TEX_ROW_ADDR_INCR(1) movd mm2, curS ; 0 | TEX_ROW_ADDR_INCR(1) or edx, 00000005h ; packetHdr<31:30> = lfb port ; packetHdr<21:3> = maxS ; packetHdr<2:0> = packetType 5 movd mm1, edx ; 0 | packetHdr movd mm4, eax ; 0 | TEX_ROW_ADDR_INCR(minT) psllq mm2, 32 ; TEX_ROW_ADDR_INCR(1) | 0 paddd mm3, mm4 ; 0 | texAddr = texBaseAddr + TEX_ROW_ADDR_INCR(minT) mov fRoom, [gc + fifoRoom] ; get available fifoRoom (in bytes) punpckldq mm1, mm3 ; hdr2 = texAddr | hdr1 = packetHdr ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo, ecx = curS = maxS ;; edx = fifoRoom, mm1 = texAddr|packetHdr, mm2 = TEX_ROW_ADDR_INCR(1)|0 test fifo, 4 ; is fifo QWORD aligned ? jz .startDownload ; yup, start texture download cmp fRoom, 4 ; enough room for NULL packet in fifo? jge .mmxAlignFifo ; yes, write NULL packet to align fifo %ifdef USE_PACKET_FIFO invoke _grCommandTransportMakeRoom, 4, 0, __LINE__; make fifo room %endif mov fifo, [gc + fifoPtr] ; fifoPtr modified by _grCommandTransportMakeRoom, reload mov fRoom, [gc + fifoRoom] ; fifoRoom modified by _grCommandTransportMakeRoom, reload mov curS, [esp + _maxS$] ; reload maxS (destroyed by call to _grCommandTransportMakeRoom) test fifo, 4 ; new fifoPtr QWORD aligned ? jz .startDownload ; yup, start texture download .mmxAlignFifo: mov DWORD [fifo], 0 ; write NULL packet sub fRoom, 4 ; fifoRoom -= 4 mov [gc + fifoRoom], fRoom ; store new fifoRoom add fifo, 4 ; fifoPtr += 4 %IFDEF GLIDE_DEBUG mov [gc + checkPtr], fifo ; checkPtr %ENDIF mov [gc + fifoPtr], fifo ; store new fifoPtr jmp .startDownload ; fifo aligned, download texture now align 32 ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo, ecx = maxS = curS ;; edx=fifoRoom, mm1 = texAddr|packetHdr, mm2 = TEX_ROW_ADDR_INCR(1)|0 .loopT: %IFDEF GLIDE_DEBUG ;; Make sure that we have a QWORD aligned fifoPtr; force GP if not aligned test fifo, 4 ; is fifoPtr QWORD aligned ? jz .alignmentOK ; yup, continue xor eax, eax ; create 0 mov [eax], eax ; move to DS:[0] forces GP .alignmentOK: %ENDIF ; GLIDE_DEBUG ;; Compute packet header words ;; hdr1: downloadSpace[31:30] numWords[21:3] packetType[2:0] ;; hdr2: download address[29:0] movq [fifo], mm1 ; store hdr2 | hdr1 add fifo, 8 ; increment fifo ptr (hdr1 + hdr2) ;; S coordinate inner loop unrolled for 8 texels a write .loopS: movq mm0, [dataPtr] ; load 64 bit data (8 texels) add fifo, 8 ; pre-increment fifoPtr += 2 * sizeof(FxU32) add dataPtr, 8 ; dataPtr += 2 * sizeof(FxU32) sub curS, 8 ; curS -= 2 * sizeof(FxU32) movq [fifo - 8], mm0 ; *fifoPtr = texelData[64 bits] jnz .loopS ; loop while curS > 0 mov ecx, [gc + fifoPtr] ; old fifo ptr nop ; filler mov eax, fifo ; new fifo ptr mov [gc + fifoPtr], fifo ; save new fifo ptr %IFDEF GLIDE_DEBUG mov [gc + checkPtr], fifo ; checkPtr %ENDIF sub eax, ecx ; new fifo ptr - old fifo ptr = fifo space used up mov curS, [esp + _maxS$] ; curS = maxS = width of scanline (bytes) sub fRoom, eax ; new fifo space available = old fifo space available - fifo space used up = new fifo space available sub curT, 1 ; curT-- mov [gc + fifoRoom], fRoom ; save new fifo space available jz .dlDone ; loop while curT > 0 ;; Check for room to write the next texture scanline ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo ;; edx = fifoRoom, mm1 = texAddr|packetHdr, mm2 = TEX_ROW_ADDR_INCR(1)|0 paddd mm1, mm2 ; texAddr+=TEX_ROW_ADDR_INCR(1) | packetHdr mov esp, esp ; filler .startDownload: lea eax, [curS+8] ; fifo space needed = scan line width + header size cmp fRoom, eax ; fifo space available >= fifo space required ? jge .loopT ; yup, write next scan line %ifdef USE_PACKET_FIFO invoke _grCommandTransportMakeRoom, eax, 0, __LINE__; make fifo room (if fifoPtr QWORD aligned before %endif mov fifo, [gc + fifoPtr] ; fifoPtr was modified by _grCommandTransportMakeRoom, reload mov fRoom, [gc + fifoRoom] ; fifoRoom was modified by _grCommandTransportMakeRoom, reload mov curS, [esp + _maxS$] ; curS = maxS = width of scanline (bytes) jmp .loopT ; we now have enough fifo room, write next scanline .dlDone: %IFDEF GL_AMD3D femms ; exit 3DNow!(tm) state %ENDIF %IFDEF GL_MMX emms ; exit MMX state %ENDIF pop ebp ; restore caller's register variable pop edi ; restore caller's register variable pop esi ; restore caller's register variable pop ebx ; restore caller's register variable ret ; pop 6 DWORD parameters and return endp %ELSE ; !GL_SSE2 ;-------------------------------------------------------------------------- ; ; GL_SSE2 ; ;-------------------------------------------------------------------------- segment TEXT ALIGN 32 proc _grTexDownload_SSE2_64, 24 push ebx ; save caller's register variable mov curT, [esp + _maxT$ - 12] ; curT = maxT push esi ; save caller's register variable mov eax, [esp + _minT$ - 8] ; minT push edi ; save caller's register variable mov gc, [esp + _gc$ - 4] ; gc push ebp ; save caller's register variable mov dataPtr, [esp + _texData$]; dataPtr %IFDEF GLIDE_ALT_TAB test gc, gc je .dlDone mov edx, DWORD [gc+lostContext] mov ecx, [edx] test ecx, 1 jnz .dlDone %ENDIF sub curT, eax ; curT = maxT - minT mov fifo, [gc + fifoPtr] ; fifoPtr mov curS, [esp + _maxS$] ; curS = maxS add curT, 1 ; curT = maxT - minT + 1 pxor xmm0,xmm0 ; clear SIMD2 register pxor xmm1,xmm1 pxor xmm2,xmm2 pxor xmm3,xmm3 pxor xmm4,xmm4 pxor xmm5,xmm5 pxor xmm6,xmm6 pxor xmm7,xmm7 mov edx, curS ; curS = maxS = scanline width in DWORDs movd xmm3,[esp + _baseAddr$] ; 0 | address of texture to download shl curS, 2 ; scan line width (in bytes) mov eax, [esp + _minT$] ; 0 | minT mov [esp + _maxS$], curS ; save scan line width (in bytes) shl edx, 3 ; packetHdr<21:3> = maxS = scanline width in DWORDs imul eax, curS ; TEX_ROW_ADDR_INCR(minT) = minT * TEX_ROW_ADDR_INCR(1) movd xmm2,curS ; 0 | TEX_ROW_ADDR_INCR(1) or edx, 00000005h ; packetHdr<31:30> = lfb port ; packetHdr<21:3> = maxS ; packetHdr<2:0> = packetType 5 movd xmm1,edx ; 0 | packetHdr movd xmm4,eax ; 0 | TEX_ROW_ADDR_INCR(minT) psllq xmm2,32 ; TEX_ROW_ADDR_INCR(1) | 0 paddd xmm3,xmm4 ; 0 | texAddr = texBaseAddr + TEX_ROW_ADDR_INCR(minT) mov fRoom, [gc + fifoRoom] ; get available fifoRoom (in bytes) punpckldq xmm1,xmm3 ; hdr2 = texAddr | hdr1 = packetHdr ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo, ecx = curS = maxS ;; edx = fifoRoom, xmm1 = texAddr|packetHdr, xmm2 = TEX_ROW_ADDR_INCR(1)|0 test fifo, 4 ; is fifo QWORD aligned ? jz .startDownload ; yup, start texture download cmp fRoom, 4 ; enough room for NULL packet in fifo? jge .xmmAlignFifo ; yes, write NULL packet to align fifo %ifdef USE_PACKET_FIFO invoke _grCommandTransportMakeRoom, 4, 0, __LINE__; make fifo room %endif mov fifo, [gc + fifoPtr] ; fifoPtr modified by _grCommandTransportMakeRoom, reload mov fRoom, [gc + fifoRoom] ; fifoRoom modified by _grCommandTransportMakeRoom, reload mov curS, [esp + _maxS$] ; reload maxS (destroyed by call to _grCommandTransportMakeRoom) test fifo, 4 ; new fifoPtr QWORD aligned ? jz .startDownload ; yup, start texture download .xmmAlignFifo: mov DWORD [fifo], 0 ; write NULL packet sub fRoom, 4 ; fifoRoom -= 4 mov [gc + fifoRoom], fRoom ; store new fifoRoom add fifo, 4 ; fifoPtr += 4 %IFDEF GLIDE_DEBUG mov [gc + checkPtr], fifo ; checkPtr %ENDIF mov [gc + fifoPtr], fifo ; store new fifoPtr jmp .startDownload ; fifo aligned, download texture now align 32 ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo, ecx = maxS = curS ;; edx=fifoRoom, xmm1 = texAddr|packetHdr, xmm2 = TEX_ROW_ADDR_INCR(1)|0 .loopT: %IFDEF GLIDE_DEBUG ;; Make sure that we have a QWORD aligned fifoPtr; force GP if not aligned test fifo, 4 ; is fifoPtr QWORD aligned ? jz .alignmentOK ; yup, continue xor eax, eax ; create 0 mov [eax], eax ; move to DS:[0] forces GP .alignmentOK: %ENDIF ; GLIDE_DEBUG ;; Compute packet header words ;; hdr1: downloadSpace[31:30] numWords[21:3] packetType[2:0] ;; hdr2: download address[29:0] movq [fifo],xmm1 ; store hdr2 | hdr1 add fifo, 8 ; increment fifo ptr (hdr1 + hdr2) ;; S coordinate inner loop unrolled for 8 texels a write .loopS: movq xmm0,[dataPtr] ; load 64 bit data (8 texels) add fifo, 8 ; pre-increment fifoPtr += 2 * sizeof(FxU32) add dataPtr, 8 ; dataPtr += 2 * sizeof(FxU32) sub curS, 8 ; curS -= 2 * sizeof(FxU32) movq [fifo - 8],xmm0 ; *fifoPtr = texelData[64 bits] jnz .loopS ; loop while curS > 0 mov ecx, [gc + fifoPtr] ; old fifo ptr nop ; filler mov eax, fifo ; new fifo ptr mov [gc + fifoPtr], fifo ; save new fifo ptr %IFDEF GLIDE_DEBUG mov [gc + checkPtr], fifo ; checkPtr %ENDIF sub eax, ecx ; new fifo ptr - old fifo ptr = fifo space used up mov curS, [esp + _maxS$] ; curS = maxS = width of scanline (bytes) sub fRoom, eax ; new fifo space available = old fifo space available - fifo space used up = new fifo space available sub curT, 1 ; curT-- mov [gc + fifoRoom], fRoom ; save new fifo space available jz .dlDone ; loop while curT > 0 ;; Check for room to write the next texture scanline ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo ;; edx = fifoRoom, xmm1 = texAddr|packetHdr, xmm2 = TEX_ROW_ADDR_INCR(1)|0 paddd xmm1,xmm2 ; texAddr+=TEX_ROW_ADDR_INCR(1) | packetHdr mov esp, esp ; filler .startDownload: lea eax, [curS+8] ; fifo space needed = scan line width + header size cmp fRoom, eax ; fifo space available >= fifo space required ? jge .loopT ; yup, write next scan line %ifdef USE_PACKET_FIFO invoke _grCommandTransportMakeRoom, eax, 0, __LINE__; make fifo room (if fifoPtr QWORD aligned before %endif mov fifo, [gc + fifoPtr] ; fifoPtr was modified by _grCommandTransportMakeRoom, reload mov fRoom, [gc + fifoRoom] ; fifoRoom was modified by _grCommandTransportMakeRoom, reload mov curS, [esp + _maxS$] ; curS = maxS = width of scanline (bytes) jmp .loopT ; we now have enough fifo room, write next scanline .dlDone: pop ebp ; restore caller's register variable pop edi ; restore caller's register variable pop esi ; restore caller's register variable pop ebx ; restore caller's register variable ret ; pop 6 DWORD parameters and return endp segment TEXT ALIGN 32 proc _grTexDownload_SSE2_128, 24 push ebx ; save caller's register variable mov curT, [esp + _maxT$ - 12] ; curT = maxT push esi ; save caller's register variable mov eax, [esp + _minT$ - 8] ; minT push edi ; save caller's register variable mov gc, [esp + _gc$ - 4] ; gc push ebp ; save caller's register variable mov dataPtr, [esp + _texData$]; dataPtr %IFDEF GLIDE_ALT_TAB test gc, gc je .dlDone mov edx, DWORD [gc+lostContext] mov ecx, [edx] test ecx, 1 jnz .dlDone %ENDIF sub curT, eax ; curT = maxT - minT mov fifo, [gc + fifoPtr] ; fifoPtr mov curS, [esp + _maxS$] ; curS = maxS add curT, 1 ; curT = maxT - minT + 1 pxor xmm0,xmm0 ; clear SIMD2 register pxor xmm1,xmm1 pxor xmm2,xmm2 pxor xmm3,xmm3 pxor xmm4,xmm4 pxor xmm5,xmm5 pxor xmm6,xmm6 pxor xmm7,xmm7 mov edx, curS ; curS = maxS = scanline width in DWORDs movd xmm3,[esp + _baseAddr$] ; 0 | address of texture to download shl curS, 2 ; scan line width (in bytes) mov eax, [esp + _minT$] ; 0 | minT mov [esp + _maxS$], curS ; save scan line width (in bytes) shl edx, 3 ; packetHdr<21:3> = maxS = scanline width in DWORDs imul eax, curS ; TEX_ROW_ADDR_INCR(minT) = minT * TEX_ROW_ADDR_INCR(1) movd xmm2,curS ; 0 | TEX_ROW_ADDR_INCR(1) or edx, 00000005h ; packetHdr<31:30> = lfb port ; packetHdr<21:3> = maxS ; packetHdr<2:0> = packetType 5 movd xmm1,edx ; 0 | packetHdr movd xmm4,eax ; 0 | TEX_ROW_ADDR_INCR(minT) psllq xmm2,32 ; TEX_ROW_ADDR_INCR(1) | 0 paddd xmm3,xmm4 ; 0 | texAddr = texBaseAddr + TEX_ROW_ADDR_INCR(minT) mov fRoom, [gc + fifoRoom] ; get available fifoRoom (in bytes) punpckldq xmm1,xmm3 ; hdr2 = texAddr | hdr1 = packetHdr ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo, ecx = curS = maxS ;; edx = fifoRoom, xmm1 = texAddr|packetHdr, xmm2 = TEX_ROW_ADDR_INCR(1)|0 test fifo, 4 ; is fifo QWORD aligned ? jz .startDownload ; yup, start texture download cmp fRoom, 4 ; enough room for NULL packet in fifo? jge .xmmAlignFifo ; yes, write NULL packet to align fifo %ifdef USE_PACKET_FIFO invoke _grCommandTransportMakeRoom, 4, 0, __LINE__; make fifo room %endif mov fifo, [gc + fifoPtr] ; fifoPtr modified by _grCommandTransportMakeRoom, reload mov fRoom, [gc + fifoRoom] ; fifoRoom modified by _grCommandTransportMakeRoom, reload mov curS, [esp + _maxS$] ; reload maxS (destroyed by call to _grCommandTransportMakeRoom) test fifo, 4 ; new fifoPtr QWORD aligned ? jz .startDownload ; yup, start texture download .xmmAlignFifo: mov DWORD [fifo], 0 ; write NULL packet sub fRoom, 4 ; fifoRoom -= 4 mov [gc + fifoRoom], fRoom ; store new fifoRoom add fifo, 4 ; fifoPtr += 4 %IFDEF GLIDE_DEBUG mov [gc + checkPtr], fifo ; checkPtr %ENDIF mov [gc + fifoPtr], fifo ; store new fifoPtr jmp .startDownload ; fifo aligned, download texture now align 32 ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo, ecx = maxS = curS ;; edx=fifoRoom, xmm1 = texAddr|packetHdr, xmm2 = TEX_ROW_ADDR_INCR(1)|0 .loopT: %IFDEF GLIDE_DEBUG ;; Make sure that we have a QWORD aligned fifoPtr; force GP if not aligned test fifo, 4 ; is fifoPtr QWORD aligned ? jz .alignmentOK ; yup, continue xor eax, eax ; create 0 mov [eax], eax ; move to DS:[0] forces GP .alignmentOK: %ENDIF ; GLIDE_DEBUG ;; Compute packet header words ;; hdr1: downloadSpace[31:30] numWords[21:3] packetType[2:0] ;; hdr2: download address[29:0] movq [fifo],xmm1 ; store hdr2 | hdr1 add fifo, 8 ; increment fifo ptr (hdr1 + hdr2) ;; S coordinate inner loop unrolled for 8 texels a write .loopS: movdqu xmm0, [dataPtr] ; load 128 bit data (8 texels) ; isn't 16 bytes aligned? add fifo, 16 ; pre-increment fifoPtr += 4 * sizeof(FxU32) add dataPtr, 16 ; dataPtr += 4 * sizeof(FxU32) sub curS, 16 ; curS -= 4 * sizeof(FxU32) movdqu [fifo - 16], xmm0 ; *fifoPtr = texelData[128 bits] ; isn't 16 bytes aligned? jnz .loopS ; loop while curS > 0 mov ecx, [gc + fifoPtr] ; old fifo ptr nop ; filler mov eax, fifo ; new fifo ptr mov [gc + fifoPtr], fifo ; save new fifo ptr %IFDEF GLIDE_DEBUG mov [gc + checkPtr], fifo ; checkPtr %ENDIF sub eax, ecx ; new fifo ptr - old fifo ptr = fifo space used up mov curS, [esp + _maxS$] ; curS = maxS = width of scanline (bytes) sub fRoom, eax ; new fifo space available = old fifo space available - fifo space used up = new fifo space available sub curT, 1 ; curT-- mov [gc + fifoRoom], fRoom ; save new fifo space available jz .dlDone ; loop while curT > 0 ;; Check for room to write the next texture scanline ;; ebx = curT, edi = dataPtr, esi = gc, ebp = fifo ;; edx = fifoRoom, xmm1 = texAddr|packetHdr, xmm2 = TEX_ROW_ADDR_INCR(1)|0 paddd xmm1,xmm2 ; texAddr+=TEX_ROW_ADDR_INCR(1) | packetHdr mov esp, esp ; filler .startDownload: lea eax, [curS+8] ; fifo space needed = scan line width + header size cmp fRoom, eax ; fifo space available >= fifo space required ? jge .loopT ; yup, write next scan line %ifdef USE_PACKET_FIFO invoke _grCommandTransportMakeRoom, eax, 0, __LINE__; make fifo room (if fifoPtr QWORD aligned before %endif mov fifo, [gc + fifoPtr] ; fifoPtr was modified by _grCommandTransportMakeRoom, reload mov fRoom, [gc + fifoRoom] ; fifoRoom was modified by _grCommandTransportMakeRoom, reload mov curS, [esp + _maxS$] ; curS = maxS = width of scanline (bytes) jmp .loopT ; we now have enough fifo room, write next scanline .dlDone: pop ebp ; restore caller's register variable pop edi ; restore caller's register variable pop esi ; restore caller's register variable pop ebx ; restore caller's register variable ret ; pop 6 DWORD parameters and return endp %ENDIF ; GL_SSE2 glide3x/h5/glide3/src/xtexdl_def.c0100700000175300010010000004516007725034670016272 0ustar johndoeNone/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Header: /cvsroot/glide/glide3x/h5/glide3/src/xtexdl_def.c,v 1.3.4.2 2003/06/05 08:23:57 koolsmoky Exp $ ** $Log: ** 7 3dfx 1.4.1.0.1.0 10/11/00 Brent Forced check in to enforce ** branching. ** 6 3dfx 1.4.1.0 06/20/00 Joseph Kain Changes to support the ** Napalm Glide open source release. Changes include cleaned up offensive ** comments and new legal headers. ** 5 3dfx 1.4 01/28/00 Kenneth Dyke Totoally revamped TMU ** register update mechanism to make 2PPC modes work right regardless of the ** order of Glide calls. Also fixed a few register config bugs found when ** switching between new and old style combine modes. ** 4 3dfx 1.3 01/18/00 Kenneth Dyke Added some sanity checking ** for texture download addresses. ** 3 3dfx 1.2 11/08/99 Kenneth Dyke Don't do 64-bit writes for ** PCI_BUMP_N_GRIND on PowerPC. ** 2 3dfx 1.1 09/22/99 Larry warner Created download procedures ** for FXT1 format. ** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator ** $ ** ** 9 8/05/99 5:03p Larryw ** FXT1 format works now. ** ** 8 7/29/99 7:07p Larryw ** Pave the way for FXT1 (but not quite there yet). ** ** 7 7/08/99 6:51p Kcd ** 64-bit texture download code for MacOS. ** ** 6 6/14/99 5:16p Larryw ** Added 32-bit texture format support. ** ** 5 2/18/99 5:28p Peter ** download/source for everything ** ** 4 2/10/99 2:01p Peter ** cleanup small mip downloads w/ fewer tetsts ** ** 3 2/02/99 4:36p Peter ** download through lfb rather than texture port ** ** 2 12/03/98 2:56p Atai ** fixed 16_1 texture download ** ** 1 10/09/98 6:48p Peter ** base texture download procs ** ** 2 10/05/98 7:43p Peter ** 3DNow!(tm) happiness everywhere ** ** 1 10/03/98 3:37p Peter ** Texture download vectors ** */ #include <3dfx.h> #define FX_DLL_DEFINITION #include #include #include "fxglide.h" /* Because this is uma the memory controller can either direct the * download indirectly via the texture port which is offset from the * hw address in texBaseAddr or we can try to address the bits * directly via 2d lfb accesses. */ #define PACKET5_MODE SSTCP_PKT5_LFB void FX_CSTYLE _grTexDownload_Default_4_4(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { /* for DXT1 8*4 mipmaps */ #define FN_NAME "_grTexDownload_Default_4_4" #if 0 const FxU16 *src16 = (const FxU16*)texData; FxI32 t = minT; src16++; for (; t <= maxT; t+=4) { FxU32 tex_address = tmuBaseAddr + (t << 2UL), s; LINEAR_WRITE_BEGIN(2, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < 2; s++) { LINEAR_WRITE_SET(tex_address, (FxU32)(*src16)); tex_address++; src16+=4; } LINEAR_WRITE_END(); } #else const FxU32 *src32 = (const FxU32*)texData; FxI32 t = minT; /* Ok, what we do is write 8 bytes at a time (4 'half' lines) */ /* Anyone attempting to do partial DXT1 uploads is a moron */ for (; t <= maxT; t+=4) { FxU32 tex_address = tmuBaseAddr + (t << 2UL); int s; LINEAR_WRITE_BEGIN(2, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s=0;s<2;s++) { const FxU32 t0 = *src32; LINEAR_WRITE_SET(tex_address, t0); tex_address++; src32++; } LINEAR_WRITE_END(); } #endif #undef FN_NAME } void FX_CSTYLE _grTexDownload_Default_4_8(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_4_8" const FxU32 *src32 = (const FxU32*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t << 2UL); const FxU32 t0 = *src32; LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); LINEAR_WRITE_SET(tex_address, t0); LINEAR_WRITE_END(); tex_address++; src32++; } #undef FN_NAME } void FX_CSTYLE _grTexDownload_Default_4_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_4_WideS" const FxU32 *src32 = (const FxU32*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t * (maxS << 2UL)); FxI32 s; LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s++) { const FxU32 t0 = *src32; LINEAR_WRITE_SET(tex_address, t0); tex_address++; src32++; } LINEAR_WRITE_END(); } #undef FN_NAME } void FX_CSTYLE _grTexDownload_Default_8_1(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_8_1" #define kTexelAlignShift 0x02UL const FxU8 *src8 = (const FxU8*)texData; const FxI32 endTAligned = ((maxT + 1) & ~((0x01UL << kTexelAlignShift) - 1UL)); FxI32 t = minT; FxU32 tex_address = tmuBaseAddr + t; for(; t < endTAligned; t += (0x01UL << kTexelAlignShift)) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); LINEAR_WRITE_SET(tex_address, *(const FxU32*)src8); LINEAR_WRITE_END(); src8 += 4; tex_address += sizeof(FxU32); } /* Copy any remaining stuff if any. There can be at most 3 scanlines * each 1 texel wide, but we don't want to whack any other texture * data so we have to make sure that we're setting the w0 write mask * along w/ the shifting for the data. */ if (endTAligned < maxT + 1) { FxU32 texData = 0x00UL, texMask = 0x0FUL, texShift = 0UL; FxI32 shiftTexel = 0; FxU32 shiftData, shiftMask; for(; t <= maxT; t++) { texData |= (*src8++ << (texShift << 3UL)); texMask ^= (0x01UL << texShift); texShift++; } GR_ASSERT(texShift <= 4); /* W/ really small lod levels the download address can be * unaligned for packet5. This is bad since the address gets * truncated. Do even more magic bit twiddling here to convert the * whole word into aligned writes w/ the right byte masks again. */ { const FxU32 texAddrSlop = (tex_address & 0x03UL); if (texAddrSlop != 0x00UL) { tex_address &= ~0x03UL; shiftTexel = (texShift - texAddrSlop); if (shiftTexel > 0) { shiftMask = (((texMask >> texAddrSlop) | (0x0FUL << shiftTexel)) & 0x0FUL); shiftData = (texData >> (texAddrSlop << 0x03UL)); } texMask = (((texMask << texAddrSlop) | (0x0FUL >> (0x04UL - texAddrSlop))) & 0x0FUL); texData = (texData << (texAddrSlop << 0x03UL)); } } LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, texMask, 0x00UL); LINEAR_WRITE_SET(tex_address, texData); LINEAR_WRITE_END(); if (shiftTexel > 0) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address + 0x04UL, shiftMask, 0x00UL); LINEAR_WRITE_SET(tex_address + 0x04UL, shiftData); LINEAR_WRITE_END(); } } #undef kTexelAlignShift #undef FN_NAME } void FX_CSTYLE _grTexDownload_Default_8_2(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_8_2" #define kTexelAlignShift 0x01UL const FxU8 *src8 = (const FxU8*)texData; const FxI32 endTAligned = ((maxT + 1) & ~((0x01UL << kTexelAlignShift) - 1UL)); FxI32 t = minT; FxU32 tex_address = tmuBaseAddr + (t << 1UL); for(; t < endTAligned; t += (0x01UL << kTexelAlignShift)) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); LINEAR_WRITE_SET(tex_address, *(const FxU32*)src8); LINEAR_WRITE_END(); src8 += 4; tex_address += sizeof(FxU32); } /* Copy any remaining stuff if any. There should only be one * texture scanline left so we have to set the w0 write mask up so * that we don't trash any other data. */ if (endTAligned < maxT + 1) { const FxU32 texData = ((*(src8 + 1) << 8) | (*(src8 + 0) << 0)); GR_ASSERT(t == maxT); LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x0CUL, 0x00UL); LINEAR_WRITE_SET(tex_address, texData); LINEAR_WRITE_END(); } #undef kTexelAlignShift #undef FN_NAME } void FX_CSTYLE _grTexDownload_Default_8_4(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_8_4" const FxU8 *src8 = (const FxU8*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t << 2UL); FxI32 s; LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s++ ) { const FxU32 t0 = *(const FxU32*)src8; GDBG_INFO(195, "s = %d, t = %d, address = 0x%x\n", s, t, (FxU32) tex_address - (FxU32) gc->tex_ptr + 0x200000); LINEAR_WRITE_SET_8(tex_address, t0); tex_address += 4; src8 += 4; } LINEAR_WRITE_END(); } #undef FN_NAME } #if macintosh && !DEBUG && !PCI_BUMP_N_GRIND void FX_CSTYLE _grTexDownload_Default_8_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_8_WideS" const FxU8 *src8 = (const FxU8*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t * (maxS << 2)); FxI32 s; /* Align fifo to 64 bits. */ { if((FxU32)gc->cmdTransportInfo.fifoPtr & 4) { GR_CHECK_FOR_ROOM(0, 1); SET_LINEAR_8(*gc->cmdTransportInfo.fifoPtr++,0); gc->cmdTransportInfo.fifoRoom -= sizeof(FxU32); } } LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s += 2) { const FxU32 t0 = *(const FxU32*)(src8 + 0), t1 = *(const FxU32*)(src8 + 4); union { FxU32 buff[2]; double doub; } buff; SET_LINEAR_8(buff.buff[0],t0); SET_LINEAR_8(buff.buff[1],t1); *(double *)packetPtr = buff.doub; packetPtr += 2; tex_address += 8; src8 += 8; } LINEAR_WRITE_END(); } #undef FN_NAME } #else void FX_CSTYLE _grTexDownload_Default_8_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_8_WideS" const FxU8 *src8 = (const FxU8*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t * (maxS << 2)); FxI32 s; LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s += 2) { const FxU32 t0 = *(const FxU32*)(src8 + 0), t1 = *(const FxU32*)(src8 + 4); GDBG_INFO(195, "s = %d, t = %d, address = 0x%x\n", s, t, (FxU32) tex_address - (FxU32) gc->tex_ptr + 0x200000); LINEAR_WRITE_SET_8(tex_address + 0, t0); LINEAR_WRITE_SET_8(tex_address + 4, t1); tex_address += 8; src8 += 8; } LINEAR_WRITE_END(); } #undef FN_NAME } #endif extern void FX_CSTYLE _grTexDownload_Default_16_1(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_16_1" const FxU16 *src16 = (const FxU16*)texData; const FxI32 endTAligned = ((maxT + 1) & ~0x01UL); FxI32 t = minT; FxU32 tex_address = tmuBaseAddr + (t << 1UL); /* Do dword aligned writes */ for (; t < endTAligned; t += 2) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); LINEAR_WRITE_SET_16(tex_address, *(const FxU32*)src16); LINEAR_WRITE_END(); src16 += 2; tex_address += sizeof(FxU32); } /* There can only be one line of slop so we deal w/ this by the bits * of the w0 write mask so that other data does not get whacked in * the process. */ if (endTAligned < maxT + 1) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x0CUL, 0x00UL); LINEAR_WRITE_SET(tex_address, (FxU32)(*src16)); LINEAR_WRITE_END(); } #undef FN_NAME } extern void FX_CSTYLE _grTexDownload_Default_16_2(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_16_2" const FxU16 *src16 = (const FxU16*)texData; FxI32 t = minT; FxU32 tex_address = tmuBaseAddr + (t << 1UL); /* Copy things that are going to be dword aligned */ for (; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); LINEAR_WRITE_SET(tex_address, *(const FxU32*)src16); LINEAR_WRITE_END(); src16 += 2; tex_address += sizeof(FxU32); } #undef FN_NAME } #if macintosh && !DEBUG && !PCI_BUMP_N_GRIND extern void FX_CSTYLE _grTexDownload_Default_16_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_16_WideS" const FxU16 *src16 = (const FxU16*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t * (maxS << 2)); FxI32 s; /* Align fifo to 64 bits. */ { if((FxU32)gc->cmdTransportInfo.fifoPtr & 4) { GR_CHECK_FOR_ROOM(0, 1); SET_LINEAR_8(*gc->cmdTransportInfo.fifoPtr++,0); gc->cmdTransportInfo.fifoRoom -= sizeof(FxU32); } } LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s += 2) { union { FxU32 buff[2]; double doub; } buff; const FxU32 t0 = *(const FxU32*)(src16 + 0); const FxU32 t1 = *(const FxU32*)(src16 + 2); SET_LINEAR_16(buff.buff[0],t0); SET_LINEAR_16(buff.buff[1],t1); *(double *)packetPtr = buff.doub; packetPtr += 2; tex_address += 8; src16 += 4; } LINEAR_WRITE_END(); } #undef FN_NAME } #else extern void FX_CSTYLE _grTexDownload_Default_16_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_16_WideS" const FxU16 *src16 = (const FxU16*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t * (maxS << 2)); FxI32 s; LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s += 2) { const FxU32 t0 = *(const FxU32*)(src16 + 0); const FxU32 t1 = *(const FxU32*)(src16 + 2); GDBG_INFO(195, "s = %d, t = %d, address = 0x%x\n", s, t, (FxU32) tex_address - (FxU32) gc->tex_ptr + 0x200000); LINEAR_WRITE_SET_16(tex_address + 0, t0); LINEAR_WRITE_SET_16(tex_address + 4, t1); tex_address += 8; src16 += 4; } LINEAR_WRITE_END(); } #undef FN_NAME } #endif void FX_CSTYLE _grTexDownload_Default_32_1(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_32_1" const FxU32 *src32 = (const FxU32*)texData; FxI32 t = minT; FxU32 tex_address = tmuBaseAddr + (t << 2UL); for (; t <= maxT; t++) { LINEAR_WRITE_BEGIN(1, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); LINEAR_WRITE_SET(tex_address, *src32); LINEAR_WRITE_END(); src32 += 1; tex_address += sizeof(FxU32); } #undef FN_NAME } void FX_CSTYLE _grTexDownload_Default_32_WideS(struct GrGC_s* gc, const FxU32 tmuBaseAddr, const FxI32 maxS, const FxI32 minT, const FxI32 maxT, void* texData) { #define FN_NAME "_grTexDownload_Default_32_WideS" const FxU32 *src32 = (const FxU32*)texData; FxI32 t = minT; for (; t <= maxT; t++) { FxU32 tex_address = tmuBaseAddr + (t * (maxS << 2)); FxI32 s; LINEAR_WRITE_BEGIN(maxS, PACKET5_MODE, (FxU32)tex_address, 0x00UL, 0x00UL); for (s = 0; s < maxS; s += 2) { const FxU32 t0 = *src32; const FxU32 t1 = *(src32 + 1); GDBG_INFO(195, "s = %d, t = %d, address = 0x%x\n", s, t, (FxU32) tex_address - (FxU32) gc->tex_ptr + 0x200000); LINEAR_WRITE_SET(tex_address, t0); LINEAR_WRITE_SET(tex_address + 4, t1); tex_address += 8; src32 += 2; } LINEAR_WRITE_END(); } #undef FN_NAME } glide3x/h5/glide3/tests/0040700000175300010010000000000007725034436014345 5ustar johndoeNoneglide3x/h5/glide3/tests/alpha.3df0100700000175300010010000025260407143552273016037 0ustar johndoeNone3df v1.0 a8 lod range: 1 256 aspect ratio: 1 1  "$'+/27;AGKORSSSSTTVWXXYYZ[^`cfjpvzwroljigfeccb`_^^\\[ZZYXXXWVVUTSQNLJHGDCA@><<;:9754/,($   #'*-16;@EKORSTTSTTUWXYXYZ[\`beinu}}ytpmkjhgfdcba`_^^\\[ZYYXYXWWWVUSSQNKIGDC@><<:976521-+&"   "'*-06:@EJORSTTTTTUWXYXYY[\`adhmrz{wspmkjhgfddbb`^\\[[[[ZYYYXXWXVVUSROLIGDC@>;:975420/,($    "&*,05;@DJNRTUUTTUUWXXYYY[\_behlqw}xurpnljigfdcba__^[[[ZZZYYYXXXXWVUUROMJHDB>=;975421-+*&"    "&*,05:@DJOSTUVVVVVXYYYZZ[\_begkpu~{wurpnlkigedbaa_^\[Z[ZZYZYYXXZYWVVUSQMKHEC><:76520/,*'$    "&*-06;@DJOTUVWWVWXXYZZZ[[\`begknt|~zwtsqomkihedcb`_\[[[[ZZZYYYYYYYXWVUTQMKIEB><:7521-,*'$"    #'+-26<@EKOTWXXXXXXYZ[[[[\^_bdgjnt{}zwvtronljhfdca`_^[[[ZYYYYYXXXXXWWVUSQMJHDA><9641/,*(&#    $(,029;7420-+('$"  "&(-059=BGLRVYZ[[[[[[\^^^^_`acfhjnsz|zyxvuronkihecb`^\[ZYYXXWWWWWWWVWVUTROMJGCA=;741/,*'$#   #'+/26;>CHMRWZ\^^^^^^^``````bdfilosz}{yxwusqnljheca_^[ZZYXXWWVVVVVUVVUTSQNLIGC@<9620-,('$"  "$(,147<@EJNSX[__`````aaababcdehjmpv{|{ywvtqomjheda_^[ZYXXVUTUTUUTTTTSSQQMKIEB><9620-+('$"   #&*/26:=BGKOUZ_aaabbbacccddddegilotw||zxwuspnkifca_\[YYXVSSRQSSSRSRSRQONLJHDB>;9520-+('$#"   #(,059<@CIMRWZ`ddddddddeeeeffghjmqvz~~{zxuspnkhfda^[ZXWVTRRQONQQOQQOONNMLIGDA>;9521-+*'&$    $(-26:=AEJNSW\bfgffefefgggghhikmosw|~{ywtqolifda_\ZWVUSOOONMMMMMNMMLLKJIEDA>;9641/,+*'$##"  "&+/49<>CGJOTY^dgiiihgghhiijjjkmosvz~}ywurolifdb^[YWUSQNNMMKIKKKLKKKKJJHEDA@<:7441/-+*'&&#"   #'+15:>ADHLQUY_dijkkjiiijkkklmnorvx||xuspmjgd`^[XVTRQMLLKIHIJJJJJIIHHHEDAA=<:65210-,+('&$"    $(,16;>CEILRVZaeklnmmkkjklmmnoprtw{}ywtqmjfda^ZXVSQQKKJIHGEGHHHHHHHHHEDCA@><:65210/,+('$#"   "&*-47<:775210/,*(&$#  #&+05:>BDEINSW^cgnqrrqqpnnoqrrsvxz}~zurokhea^[XUSOMKHGEDDEEGGHHGIIIIIIHHEDA@=<;77521-,+('#"  #',16;>CEGJNSX^chorttssqqpqrsuwy{}~{wsolieb_[XUSQLJJGEDGEEGGHHIIJKKLLLKJHECBA=<:7641/-+($"   "$(-27;>CGHKMTX^diotvvutssrrtvxz{}~ytqmifb_[XUSOMKIIGGEEGHHIIJLNNNOQONMLJHECA>=;9641-,(&#   "&*/27<@CGHJMSX_djpuwxwwuusuuxz}~{vqmjfc`\YVSQMLKIIHHHHIJKLMNQRRTTTTRQMLJHEB@>;:520,*'$   #'+/59<751/+'$"  "&*-15:>ADHJLQUY^diouz{{zzyxxy|~{upkgda^ZXVTRQONMMNNORSUVX[\_`aab`_\ZWSOKIEB@=961/+'$"   #'+/26;>BEIKMQUZ^diouz||{{yyz{|}}~|wqlheb_[YXUTRRQQQRSTVWZ\_abddefeec`[XURLIEB@=961/+'$"  "$(,049;@CGILNRVZ_cinv{}}}{{zz{}}{zyz}~xrmheb_\ZXVVUTTTUUVXZ\_bdeghhiiigeb^YURMJGB@<951/+'$    #&*/25:=ACHJMOSV[`chnu{}~~|{{z}~~zwvvx{~xsnieca^ZXXWWVWWWXY\_adfhjkkllljifc^[WRMJGB@<751-*($   "#'+/27;@BDIKNQUX[`dhmtz}~~}|||~zvsstw|}xsnjfca^[ZYYXXXY[^_bcegjlmoooomljgc`[VSNJGB@<751-*($   #$(,14:=ADGJMOSUX\aehmsy}~}}}~}ytsrty|~xsnkgda_[[ZZZZZ^_`bdfiknoqrrqpnljhd`[WSOJGB@<740,*'$   "#'*/26;>ADHKMQTWY^aeimsy|~~~{wsstu{}xsokgda_\[[[[[\_acegjlnprstsrqomjhd`[XSNKHB@<640,(&#    $(,059=ACGILOSVX[_beimrx|~zustuz~|vrokgda_\[[[\^_acehjmnqrstuusrpnjieb\XTOLHB>;62/,(&#    #&(-26:>ADGKMQTWZ\`cfimrx|}yutux}}zurnkhda_\\[\^_abdgilnprsuvvutsqolifb^YTQLGC>;62/,*&#    $'+/47=ADEILNSUX[_bcfjmrx||yvvw}~{wtpnkgda_\[[\^`acehjmoqstvvvutsqomkfb^ZVQLHC@;720,*'#"   $(,15:>CEGJLOSVY^`cdgjlrw|~{ywy|}zvtrpmjgda`^\[\^`adeijmpqsuwwvvusqpmkgc`[VRLID@<740,*'#"   #&*-17;ADGIJLQTWZ_bdfhjmrw||{{}~zxusrpnligda`^\[^^`bdgijmprsuvvvvvtrpnkie`\WSNIEA<951-+'$"  "#'+/49=BDHJKNRUX[`beghknrv|}}}}yurqpomljifdb`_^\^^`bdfiknpqsuwvwwvtsqokjeb^XTOKGB=:61/+'$"  "$'+05:@CEIKMORUY\adghjlnqw|~{vsommmllkjhgeba__^^_`bdfhjmprtvwwwvvutroljfc^YUQLHC>:62/+'$"   "&*,17;ADGJLLOSWZ_aegijmnrw|{vqmjihiiiihhfdba`____`bdehjmprtwwwxwvvtrpmjgd`[WRMID@;720+($"   #'+/47=AEHJLMOTWZ^behjknosw||vqkhfeefghhhhfdcb``___`acdgjlortwwxwwwvuspmkhea\XSMIE@;740+($"   $'+05:>BEHKMNQTWZ_beijlnpsx}yrlgdbaabdffggeedcaa``_`acdfilortwwxxxwvvsqnlifb^XSNJEA<740,($"   "&(,26;@CGIKMNQUW[_bfikmoqty||vohda`^^`adegfffedcaa```abdfiloruwxyyyxwvtromjfb^YUOKEA<740,($"    #'+049BDHJLNORUX\_beilortw{yrlfb^\ZZ[^`ceggggfdcbaaabdefimorvxzyzzzyxvtqnjhc`ZUQKGB=950,($"  #'*-16;>BDHJLNQSUX\`bfjmprvx|xrlfb^\ZZZ[_bdfggggfedcbbcdfgjmotvxzz{z{zxwtrnkhd`ZUQKGB=940,($"   $'+/27;>BEHILNQSVY\`cfjmqtwy}~xrmgc_[ZZZ[^`cfghhggedcccddfhkmqtxz{{||{{zwvrolhd`ZVQKGB=940,($#   "$(,059<>CEGJLNRTWY\`cgjnrux{~xtnhd`[ZYYZ\_behihiggedcddegikoqtxz|{|||{yxvrokhda[WQLGB=940,($#  "&*-25:<@BDGJLORUWZ\`dgkpsvz~~ztpkfb^ZYXZ[^aegiiihgfeedefhjloruxz||||||zxvsolhea[VQLGB=951,(&#   #'*/16:=>BDGJMOSUX[_acglpsx|zvrmgc`[XXXZ\`cgijiihggffggikmosuxz||}}}}zxvroliea[VQLGB=950-(&#  "$(+026;=>BDGJMOSWZ\_behmqvz~{wsnjea[YXXY[_behjkjhhggggijknqsvy{|}}~}}{xvsplhda[VQLHB=:61-*&#  "$*,147;<@BDHJMRTW[^acfjnrw{|yuqkhc^ZWXXZ\`dgijjjihhghijmorsxy{|}~~}{ywsplieb\WRLHB>:61-*&#    #&+-257;=@BDGJNRUX\_bdgjosw||yurmhd^ZXWXY[_bfijjiiiiiijlnprtxz|}~}|zxsqmiea\WRMHC>:61-*&#     $'+/269;=@BDGJNSVZ^acehkotx}~zvsnjf`[XUWXZ^aehjjjiiijjlnoqstxz|}}|zwtpliea\XSMHC>:61-+&$"  "&(+/269;=>ADHKNSW[_bdfhlotz~~zwtokgb[YVWWY\`cgiiiiiijkmnprtvy{~~|{wtqmieb\XSNIC@;62/+'$"  "&*,0279;=>ADHKNTX\`cegimpu{|xuplhc^ZWVWX[_afhiiiiijkmoqsuwy|~}zwtqmjeb\XTMID@;72/+($"  #&(-0269;=@BDHLQUY^adehjmqv||xuqmhe\ZXUVWY\`dfhihhijkmpqsuwy{~}{wtqmjfb^XTMIE@<720+($"  #'*-0269;=@BDHLRWZ_befikorv}}yurmieaZXUVWX[_begghhiikmprtuwz|~|{wtqnjfb^YTMJGA<920,(&"   #'*-027:;=@BEIMSW[_cfhjlorx}}yurnjfa[XVVWX[^adfghhiikmprtux{}}{wtqmjfb_YUNJGA<:41,*&#    #'*-1469;=@BGINSY^adgikmptx~~}}}}}~~zvrnjgb[YVVVWY\`bfffghjlmpruwy|~~{xuqmkgc`ZUOKGA=:41-*&#    #'*-046:;<>CGJNUZ_behklnptx~}{yxwwwxxz}yvqnkgc^YVVVVYZ_bdefggikmorux{}~|wuqmkgc`ZVOKHB>:51-+'#    $'*-146:<=@CGLOUZ_cgilnoquz}{yxwvuttttuy~yvrnkgc_YVVVUWZ^abdefgijmprvx{~~{wuqmkgc`[VQLHC>:52-+'$    $'*-0479;=@CHLQV[`ehjlnpsv{|{xwvttrrqqqqtz~yurnkgc_YVVUUWY\`adeefhjlorvy}~{wuqmkhc`[WQMIC>:52-+'$   #&*-1469<>@DHMSW\afikmoqtw{}|ywvtsrqponnnpv¿}yuqmjgc_ZXVVVWY[_`bdefhjmosvz~~{wuqnkhd`[WRMID@;62/+($    $&*-046:<>ADINSY_cgjmopsuw}|ywvusrqpnlkjjlqy}ytpmifc_ZYWVVVXZ^`bdefhjmpsw|~|xurnkhda\WRNJD@;64/,($"   $&*-047:<>BEJOTZ`diknorsux}~{xwutsrpomkiihils}yuplieb_[YXVVVWZ^`bcefhjmpsx||xurokhea\XSNJEA<740,(&"   #'*-147:=@BGJQUZ`eiloprtux}|ywvtsrrpnljihfgioy¿zvqmieb_ZYXVVVWY\_abdegilpsx||xurokhea^XUOJEA<750,*&#   #&*-147:=@CGKRV\bfjmpqsuvy||ywutsrqpnljhgeefkt{vrmiea^ZYXVUVWY[^`bdefilosx||yvsokhd`\YUOKEB=951-*&#   #&*-147;=@CHLRW^cgkmprsuwz}|xwussrrpomkigfeehp}{vrmiea_ZYXVUUVXZ^`bdefhkosw}|zwsokhda\YUQKGB=951-*&#   #&*-159;=ACIMSX^chkoqstvwz}|ywtssrrqomljhfeegny¾|vrmheb_YYXVVUUXZ^`bceehknsw}}zwsokhda\YUQLGC>:61/*'#    #'*-259;>ADINTX_dimprsuvxz~~zwutssrqpnljigfeflv|wrmieb^ZXXVVUVWZ\`bcdegjorw|}zwsolhd`\YTQLGC>:61/+'$     #'+/259<@BGKOTZ`fimqstvwx{~|xvtssrqpomkihfefjs|wsnieb^ZYXVVUVWZ\_`bdeginqv{}zwsolhd`\YURLHD>;62/+'$   #'+/25:<@CGKQV[bgjnrtvwxy{~~{wussrqpomljhgffip}¾}xsnjeb^ZXXWVUVWY\^`bdefilpuy}zwsplhd`\YURMHD@<720+($    "$'+/26:=@CHLRW\bhlostvwxy{~}xvsrqqpomljihgfhnw¿~ytnjfb_YXXWVVVWY[^`acefhkotx~}{wsplida\YTRMID@<740,($"   "$&+/26:>@CHLRW^chmpsuvwxy{~yvsrqpoomlkjhhghltyuojfc^YYXXWWWXZ\^`abdfgjnrw|~{wtplida\YURMIE@<950,(&"   "#&'+/25:>ADHMSX^cimqtvxwxy{~{vsqpoonmlkjihghjq~zupkfc_[YYXWWWYZ\^`abcefjlquz~zwtpmida\YUQMIEA=950,*&"   "#&'+/26:=ADHMSY_ejnruwxxyy{~|wsqoommmlkjihhhiox¿|vqlgc_\[YYXXYZ[\^`abcefhkpty}~zwtpmiea\XURLIEA=960-*&"   """#&'+/26:=ADHMSY`ekosvwxyyz{~}wspnmlllljjiihhimu¿}wqmhda^[ZZYZYZ[^_`abcdfgknrv{}{wtpmhea\XUQLIEA=:60-*'#   ""$$&'+/26:>ADHNTY`ekpswyyyyzz||wspmlkkjjjjjihhikr~¿~xrnjfc_^\[ZZZ[\^``accdfhjmpty~|zwsolhea\XUOLIEA=:61/+'#    "##$&&'(+/15:=ADHMSZ`fkqtwzz{z{{}|vsoljjjjjiiiiiiijpx{vqlhea_^\[[[\^_`abcceehilmrvz|yvsolheb\XTOLIEB=:61/+'#   "#$$&'''(+/15:=ADILSYaflrvwz{{{{||~{vroliihiiiiiiiiijmt}xsnjgca`^^^^_``aaccddfghjlptx|~{xurokhda\XSOKIEB=:62/+($   "#$&'('((*,/259CGKRW_fmrvz|}}||||}ytqmjhfffffghiiiiijow}ysplifccaa`abbbcdeffgghiilorvy|~~~}|ywspmjfb_ZWSNJHDA=;740,($"  #$&(**++++,/257<>BEKOV^elswz}}~~}}}}}xspligeddeefghhiiijms{wrokifdcccbbbcdffggghhghjlorvwyz{{zxurnlgda^YVRNJHDA=;740,*&"  "#&'*++,,,,-/147:=ADINU\elrw{}~~~}}}~}wsolifdcccdefghiiiikpy~yuroligeddcccdffghhhhhgfhjloqstvwwwusqlhec_[WURMJGC@=;640-*&#   "$&(+,------/1469<@CGLTZckrx|~~}|}~yurnkhfcbbbcddfghiiijmt~yuromkihfedefghhiiihgggggikmopqrssrpmjgca^YVSOMIGB@=:640-*&#    "$&(,-///-/-/1257:=@DJQWaiqw|~}}}~xtqmjhfcbaabcdefhhiiikpx}xvrpnkjhgffhhiiiiihhgffefgijjlnonmljhda_ZXURNLIGC@<:640-+'$    #$'*,-//0//-/02477;=AGMU^gov|~|~}wspmjhfcaaaaacefghhhiims}}yvspnljhhiiijkjjihhgffdddefghijjiigec_\XVSQMKHEB@=:640-+'$"   "$&'*,-0000///024569;>CIRZdmu}}}~yvromjhfdbaaaabcdfghhhhkqx}yuspnljiiikklkkkiihgfdbcbbbdeeeedcb`\YWUQNKJGDB><9640-+'$"   "#'(*,//0100/00124569;>EMWakt}}~~xtqomkifdcaaaaacdefggggims|}yvspnlkjjklmmllkjhgecba``^__``a`__\ZWVSOMKIECA=<9640-+(&"    #$&(*+/001100//1224457:AHR\hr{}wtqomlihecbaaaabceeffffgjov|yurqnmllmnnnnmljjhfca^^ZYYYZZZZZYXWUTRNMJHEB@=<7540-+(&#   #$''*,-/1210///01221246<:7520-+(&#   "$&'(+-/01100///00//-/04;DNYfr}}xvtrqpoljhfecbaaabbcccccccdhlry|zwvtssssuuvvvtrplhd_YURNLKKJJIIJIJKJIIGDB@><:6620-+(&#"  ""#$'*++-011100--/110-,/17AJUbny}xvtsrqpnlihfdcbaaaaabbbbbaacglry~|yxxvwwwwxyzzywtplfaZUOMJHGEEDDDEGGGHEECA>=;96520,+(&$"  ""$&'(*,-/0110/--02410/-/5=GQ^kw|xvtsrrqomjifecbaaaaaaaaaa```cfmry~{zyyyyzz{|}~~|yvojd\WQKHECBAA@AABCCDDDB@=<:76510,+(&$"  "#$&'*++/0110///145521002:CMYht{xwutsrrpmkiheccaaaaaa````_^^`chmrx~|{|||||~zsmh`YTMHDB>>====>@@ABBB@=<:76510,+(&$"  "##&'(++-/0111011466542126@JVdq~~{xwvutsrqoljhfdcbaaa````_^^[[[^bglpu|}}}}~~~xrke\VQID@=;:9::<<=>@AA><;:7641/,+(&$#  ""#$&((*+/1222224579765446=<;965410,+(&$#   ""$&&(*,/145555559;::9767:410/022579::::75440/,+('$#   "$$'*+-02699:9::;=@@>=<<=BHS`n|~|yyyxwwvtrpmjhedba`_^\[ZYYXVUSQOOQSWY^`cfjmptvx|{zyyyy{{|{||}}|||}~~}|}}|wqibYRJC<61/--/1245799975420/,+('$#   "#$'*+/1479;<<<;=ABCBA@>@BGO[kx~}|zyyxwvtrpmkhfdca`_^\ZYYWVTSQNLKKKMRUXY\adhloqsuvutttvvxwxyyxxxxxz|~~}||||wsme^VMG>92/,+,-012567775420/,+('$#   #$&'*,/149;<>>>>@BDGEDCBBCGNYfs~}|zzyyxwusqnlifeca`_^[ZYWVUSQNLJHGGHJMORTWZ`dhknprrrqqqqstttutttstvw{~~~}||}~~|zxsnhaZRJB;50,+,+-01255765420/,+('$#"  "$&'*,/159<>@ABBBDGJJIHDDEHMVan{}}|zzyxwusqoligeca`_\ZYXWUTQNLJHECBBCDEIKNSW[_cfjmooonnnnnnppopnnoqtw{~}||}}~~}}}{zywvrojc[UME=71,***,,0144565220/,+(&$#   "$&(*,/269<@BCDDDGIMMMLIIHIMU^jw~}}|zyxwvsroljhedba^[ZYWVTROMJHEC@====>@BEJNRVZ_cfjlkkjjjjjjkjjhhikorx|~}~~~}||{zzxwvtrqlie^WOIB:4-*((**-/12454200-,*(&$"  "$&'*,/26:=ADEGGHIKNRRQMLJJMSZfr}~}}}|zyxvtrpmjhfdb`^[YXVTROMKHEC@=;966669;>CGLQUY_ceggggggfffeedccehmty~~~}}{zywuusqnljgc_YSKD<50,'('(+-01224200-,*'&$"  #&'(,/26:=BEHIJJKMQTUTSOMLMRYcoy~}}}|zywuspmkifdb`^[YWVSOMKIECA=;741+((*+27DLRWY\__^^\\\[[ZXXX^cjqz}|yxusonkhfdb_\XTNIB;5-*&$&'*,-00120/,+*&$#  "$'*+/16:>CGJLNNORTWZ[ZWURRTYait{~|{|~}|zxvsqoligdb`\ZYVTOMJHDA>;940((((*++,,,,--;BHNSWYYYYXWWVVUTSTW^dow~~|zxuspmjheb`\ZWTNIB<6/+'$$&(+,-/010/+**&#"   $'*+-159>BHKMQQRTUX\^^[XVUW[bisz~}zxxz{~}}{xvtqoligdb`\ZXVRNKIEB@<951'((((**+,--/-//7>DJOSUUUTTSSRQQOOSYbju}|zxuspmifc`\YWURNJD=71,'$$$&(+-//0//+*($#  #'*+-059>CHKORSTUWY^aa_[YYZ_dktz~}{wuuwz}~}|ywtrpmjhdb`\ZXURNKHCA=:62''((((*++,,-//0/0/:5/*'$$&&(*,---,*('#"  #&*-047=BHLQTVWYZ[_cdcba`bfkry~}yvrrswy}~}{xvsqnkhfc`\ZWTRMJEB>;62((((((**++,-/000000//6=BDEDDDCCCCDEIQZfq}}zxurolifb^YVSOLIGC>;50+'$$$$'(*,,,,(''#"  $'+/27@@@@@@@ABDINXep|~|yxtqnlifc^YVSMJGDB@<60,(&$#$&'*+,++(&&"   &*,05;AGLQUXY[\^_`ddddfhlry}xwsstx|}}ywtrolifca\YWSOKHC@;62((((****++,,-/001111000//7::;;;;<>BDINXcoy}}{zxvtqnkhea_ZUQMJGCA>;51-*&###$'(**+('&$"  "'*-49>EKQVY[\^^_`bdeegiou{{yvuuxz|~}zxurpmigda\YVRNJGB=95/(((*****+++,--/011111000001012469;=@IOWcmv||zzyxwvusrpmjheb^YVQMIDB@=:61-*&$""$&'***('$"  "'+/5BDGQV_gnuz|zwurqpnnllkklllkjhfca\YUQMHD@=:952/+'$#"#&'(**'&#"  ',4ADGHRV[ciptutromlkigedddefgggfdc`[XUQLID@=;7640,'&###''*++(&#"  '/9CLU\acdcb`^^_bfkqz}~~}yvspliec_ZWSNJD@:6-((((***+*++,,---001111112214569;>ACEHJRUY`eimonmigfeba__\\\_abcdcb_\XUQLIDA=97540,(&$$&'(*+*(&#"   *4>IS[befeca^\^`eiqxzwtqmifc`ZXTNJD@:5+(((****+*++,,,-///111112222567;=@BDHJLRTV[`chiigdba_\[XUTUVWY[^__`^[XURMHDA<97641-+'&'&'*++*(&$"    -:EOZbghgda_[[_chow}yvrojgd`[XSNJD@:5*((**(****++,,,--/001112224457:<>BCGHINQSTVY^cddb`_[XVTSSRQNMSUWYZ\[ZXUQMIEA<:7641/+*('((+,-+*'$#" "     """"""  "2AMXbgjifc`\[\bfnv~zwsplhea[XTOJE@;5'*********++,,,-//001212444569;=@BDGHINQQQRUX\^^\[YVTTSSRQONMKMQSVXYXWTQMIEB=;7441/-+*(**+--,+(&$#""    """####"""  "",;IVaiklheb^[\afmu~}yupmjfa\XTOKEA;6****+*++**++,,,-//00122244557:<>BCEHIJOONMNQTVYYYWUTSQRQQNNMKJGHMQTVVVSOMJEB>:75420-++**+-///,*'$#""    """#$$$$$##""  """"6GU`innlgc_\\aglu~|wsokgc^YVQLGA;6,*(***++**++,+,-//00122244579;=@BDGHIMOOMKKMOSUUUTTRQONNNMLKJIGCHJOQRSSOMJEC>;754210-,++-/010,+'&$#"    "####$&$&&$$$#"  "#"1BR^iopojfa_^agnv}ytqmid`ZWRMHB<70((***++++++,+,-//00112445679;=ACEHGKOQNKJHIKNQSQSRONLMMLLKKIIEBADILOQQOMJEC@;754411/--,/0220-+('$#"  ##$#$&&''''&'&&#" "#"+ACEHHNQQMKHEGHKNROQOMKKJJKJJIHGDC@=DHLNOOLJGC@<9655210/0001421/-*'&$"   #$$$&&'''('('(&$#  """#"7JZgqtsokfcbdiqzzvrmid_YUOKE@;4(****++++++,+,--//11245567:;=@BDEGKQSQNJGCCEILOMNMKIIHHIIIHEECB><;CHLNNLKGD@<:76442111124442/-+(&$#"   #$$&&''((((((('&#" ""###2GWfrvusnifeglt|xtpkfa[WRKGA;6+**+++*+++++,,,-/011245679:<=ACDGGNSTSNJEBBCGJNMLKIGEEEGHGGEDCA><:@CIKMLJHDA=:965442222254420-+*($#"   $$$&&'((***(((''$"  ""####-BUdqvwuqlihinu~}wrmic^XTMIC=72(**++++*+++,,--/01124567:;<>@CDEJQTUSOJDA@BEILLJIGDCCDDEEDCCB@=;:7AEJKLJGDA=;975544242445421/,*($##   #$$'''(((****(('$#  "####&=Raovxxtplklqyytpjf`ZVOJD>:2***+++++*++,,--/01225569:;<@ACDEMRVVTOJD@>ADGJKHGDBAABBDDCBA@><:96;AGIJJGDA>;966554555555421/-+*&$#   ##$''''(((*(*(''$#" "#####:M`nvyywtonpt{}vrmgc^XRLHA;5***+++++++++,--/00245679:;=>BCDJOTWXVQJD@=>CEIIEDB@>@@AABAA@>=;9752<:965566556555520/+*&&#"   ##$&&'((((((*(''$#" ""#####6K[lvz{yvustx{tojf`ZUNIC=92***++++,++,,--/0012577:;<>@BCELQVYZWRKD>=>BDGGDC@><=>@@A@>>=<:97417@CGHHEB><:976667666554520/,*'&#"   "##&$&'(''''('&&$#  "#####1GXguz{zxwvx}wrmhc\WRKE@;5*+++,+,+++,,,-/0112569:;=>@BCIMSWZ[XSLE@<>ACEDCA@<<;<==>>=>;;976214;@DGHEA@=;9667776765545210,*'&#""   "##$$$&''''''&$$#"  "###$$,BTdry{{{z{||upkf`YUNIC=70+*+,+,,,,,,,-/0012569:<=>ABBJNTW[[YTLEA=>ACECB@><:;;<<<<<<:976510-6=BEEEB@=<:777677665545210-+'&$""   ""##$&&&&&&&$$#"  "###$##=Oaox{|{|}~wrmgb[WRKE@:4+*++,++,,+,,-/0122569;==>ABBINTX[\ZUMGB>>ABDCA@<;9::::<;<:976521/-27@CEDBA><:977777665542210-+(&$""   " "##$$$#$#$##   "#####$7L^lw{|}zsnid^XTMHB=7-++,,,,,,,,--/0124579;=>@AABHNSXZ\YUMIC@>@BDC@><:99999:::9765410-,*4;ACDB@>=:977776655422421-,(&$""   """#$####""  "######2GYgsy|}}vplfaZUOJE@:5++,,,,,,-,--/0124579;=>@AA@HMRVYZXUOHDA==ACA@=;997779797765421--+*19>ACB@><;999976544214420-,(&$#"   "#"""  """ """###$$/BTcpx{}xsnhc^WRLHA<6+++,,,,,,-,--/024569:<=>A@@GKQUXXWUOJE@=>@AA@<;997676666642200-,+(+4:>AA@><<999965521112211-,*&&#""   "   """"""""###$$(>O_lvz}ztoje_YTOIC>92++,--,------/024567:<=>@>>DJNSUWVSOKGA>>@A@@=;:7756555552110/,+*('/7<@@@==;:99754210001111-,*'&#""  """"""""##$$$#9K[hsx||uqlga[WQKGA<6++,,-,,,---/0014567:;=====;:766544442110/-,*((&,2:=@@==;:975421/--/0110/,*'&#""  """"#"""##$###4GVepw{|uqmic^XTMIC=94,,,,/----///0124679;;<<;:AEJMQSSRMJGDBAA@A><;976544221100--,+*(&$#/6;>>=<;:97421-,,+,-/00/,*'&#""  """#"""###$$##0BSakuz~{vrmid_ZUOJD@;6,,,-----/-//01145679:;::9>DILNOQOMKGECAA@@><<:765522100/--,++('&$#*17<==<;99520-+*((*+,/0/,*'&#""   """""#"##$###,=N^hsy}{vrnjea[WRLGB=74,,-----/-/0011456699999<@DHJMNOMLKHEDBA@@=<::7654220//-,,,**('&#"'/59<<;:9741-+('$&'(+-//,*'&#"  " """""""##$##$$9JYeqw|{vrnjfa\WSNIC@;6,-,-//--//0011245667676<>DGJKMLLKJHECB@@>=<;:965220/--,,++((''&$" *16:;;:9520,(&$#"$&*,--,*'$#"   """"""######$$6GVbmvz}yurokfb^XUOKEA<95,----/////00022455565;>ADHJKLKLKIHGDBA>>=;;:965210/-,,++(('&&$#" '-27:::651/+&# "#'+,,,('$"   """"#"####$#1BR_juy}|{{~~{wtrnkgc^YVRLHC>;7,----////00011124454;>@CEHIJJKKKJIGDBA>=<<;:76520/--,+*('('&$$#" */5799640,*$  $(+++(&$#   """"######$#-=L[gqwz{|}}|zxurpqsy}yvtqnkgc_ZWSMIDA=95----//////00010122:>@CDGHJJIJJJIIGEC@@=<<;:75520/-,+**(''&$$""" $+2676520,'#"&(**($#"   """"#####$#(:IVcksuwwwvuromkjilpw}xusqnkgd`[WTOKGB>;94-//---//////00109<@CEHHJJKJJJJIHGDBA@<<;;:95420--,+(('''$$##" (-26542/+'  $''('$#"  " """""####$#$6DR^gmqqppomljgecdfjqz~yuspnkhda\XUQMIDA=;74-///-////--0/47;@CGHIJJJIIJJIHHECCA>=<;:976420/-+**('&&##"#" $*02441/+& "$''&$#   """"" "####$#$2AMZcikkkjihfda```bgms}{vsqnlifb^YVSNJGC@=:65-/-////----16;=BEHKKKKLJIIIIHGGDBA>=<::976420/-+*(''&&###" &+0220-+&#$$$$"   """"""""######$1=KV_dfggedb`^\[[^`dinu|}ytrolifc_[WTQLIEB@<:750-/-/--/-159;9752------457;>CEIKMMMLIIIHHHGGEDBA><;99765210,,+('&$$$#"" &*/00-+&  ""    ""#"##$#""#####0:GQW[\\\ZYXWVVX[^`ceimqu{}}wtqnkifb_[WUQMIGDA=;:7552012457:=ADHKMNNLJIIIHHHGEDCBA@<:9765421/-+*''&$$##"" #',//-+'    ""#####"""####(1:ENTWYXWVUUUUVY[_acehlorvy|}yuromkhda\YVSNKHDB@=:976554567:<@CGILMNNJJJIHHHGGEECBA>=:9755420/,+*('&$##"" $*,//,'   "####$$$##""###,4<:9777667:<>BDHJKMMKKJIIHHGGGEDBA@><:7654210--+*''&$#""" "'+,-,'#  ""#$#$$&$$#""#"$/7>HMRTTSQOOQSUY^adfghilmnqstvw|}}|zwtrpnkheb^YVSNKHEB@=;:99799;=>ACEIJKLLLLKJIHHGGEDDCA@><97642210-,**(&&$#"" $(*,+($    "###$$&&&$$#"#"+2;AINRTSQMMMQSW[adgijkllmoopqstwx|}~{xvvvvwxyzzyvutrpmjhda\WTQLIEC@=<::99:;=@ACDGIJKMNMKKJIHHEEDDBA@>=<:664210/,+*(('$##"" "&(++*&"  " ""  """$$$&&&&$$$#"",5>DKORTSOMLMQUZ`eiklnonnnoopppsuwx{}}}}}}}{yxwwwxy}}xvrpoooprtuuuvutsqpmjgc_ZUSNJGCA><<;;;;=@ABDEHIJLMNMMJJIHGEDDDBA@=<;:65410/-,+**'&$#""  #'(**'#  "#"#####"" ###$&&''''$##""/7AGLQTUTQNMOTX_ejnqrssrrppoopqstvwyyyyyxxwvtsrqpqrtvx}zvroljiijlnprstuutrqolie`\WSOLHEB>=<<;<=>ABCDGHIKLMMNMKJIHGEDCCA@>=;;964400--,**('&$##" "$'**'#  ""#$$$&$$$$#" "#$$&&''''&$##(1:BJOSUVTROORV^djptxzzyxutrppqrtvwxyyyyxwvtrpomkjjkloqtx}zvqmjfccdfhlnprstttsqnkhc_YUQLIEB@><<<=>@BCDEHIJKMNNNMKJHHEDCCAA@=<;:96220/-,+**(&$##"""  #&(('#  "##$$$&&&&'&&&&''$$&'''''&&$#+2;DLRUWWVTRSUYbipw|}{wutsstvwx{||{yxwtrpmjhfdccdehlptx}}wrmiea``adfjmoqsuuurpmje`[WQNJHCA>>=>@ACDDGHIJLNONONMKJIGEDCBA@><<;975210/-++(('&&$#"  $&'&#  "#$$&'''''(((''(**'&''((''&$$+4=GMSWYYWWUVX_gox}{ywwwx||~~|ywurolheb`^\\^`cglptyxsojfa^\\`cfimostvvusplgc^XSOLHEBA@@@BCEGIHJLMOQQQQOMKJIGECBA@>=;;:96520/-,+*(''&$#"" "#$$   ##$&&'(((((****+,,,*'((((''$$,5=GNTY[[YYWY\ckv~~~}~}yvsplhd`\YXWWXZ^dhmrw}}vrmgc_[[\_beimptwwxvrnie`ZUOLIECCBBCDEGIJKMNQRRRRRONLIHGECA@>=<;:776420/-+++''&&$#""  ""  ""$&&'(((*+++++,-///-*(*(((&&$-5=GNUY\\[ZZ\bhpz}xurmid`\YVTRRTW[afjpuyxtoie`[ZZ\_dgkorvxyxuokfb[WRMJHEDDDGHIKKMNQSTSTSSROMLJHGDB@><<;:9975410-,++*''&$$#""   "#$&&'(*(++,,,,--/110/(**('''&-5>GNUY\^\\^aelv}xtpkfa\YTROMNRUY^chnsy~|vqlfa^ZZZ^afjorvxzywtnhc^XTNLJHGGGIKKMOQRTUUVUTTRQNLJHECA>=;;:97776410,++**&'&$#"""   "#$&&'(*+++,-,--/01421/**(('''-5=ENTY\^^_`chnyzvrnid_ZVRNMLMOTW\bhmsx}ytnic_[YY\_dimqvy{{zvrke`ZUQMKJIIJKMNQSUVVVWWWUTRRNLJGCA@<;;:77656421/,+**('&$$#""   "##&&'(*++,,-///0124421,***'''-5=EMSX\^__bejq|}xtplga\XTOLKJKMRW\ahmrw}}wrlf`\YYZ^bglquy||{xtlgc\WSQNLLLMOQRUWXYYXYXXVURQMKIEB@=;:9765552210/,+*(('&$##""   ""#$&'(*+++,-///01255640***(((*4;:76644222110-,+*(''&##""   ""#$&'(*++,,--/002257652+++*('(4;CKQVZ\_`cglu}yuqmhc\XTOLHGHJMQV[agmrw}wrle_ZXXZ_ekpv{}ysmhb^YWVTTTUXZ\^^___^\ZZXURNLHEB@<97654422100//-,**(''&##"  ""#$&''**+,--/00114677640,+**(*2:BJOTY[\_bflu{wspkf`ZVRMIGEEILOVZahmrw~{tnga[XXY^djpw}|wqkeb^[YWXXY\_abbbba`^\ZXURNJHC@=:754211000//---,**('&&##"  " "#&&'(*+,-//01124667764,,+***2:AHMSWY[^aeku}yvrmic^YTNJGDDEHKOVZahnsxwpjc\YXY\cipw}zuoieb_\[[\`bceeeddbb`^ZWTQLIEA=;76211000/-/---+**(('&$###   "#$&'(*+,-//00124679965-,++++29@GLSUXZ\`ekt~}xtpkfaZVQLHDCCDGKQV[ciot{zsme^YXX\bipw~~xsmieca`abdeghhggfdca^ZWSNKHC@;:64100220/,,,,,+*((''&$#""   "#$&'(*+,-//00124579:962--,,,27>EKOTVX[_cjr|~zwrnid^YTMIECAACGKRW^djpw~vnh`ZXXZ`how|vqnjgedffhijkkjigeca^YVRMJEB>:742022210/++++****(''&$$""   ""$&'(*+,-/0102245799965//-,-/7>DJOSVWY^bhoy}yuqlga[VQKGCAAACHLTX`fmsyyqib[XXY`gnwzuqnkihijjklmlkjhfca\XUOLID@<9420222100/******((('&&$$"""   "$&''*+,-/011224579:99600////7=CIMRTVW[`fnw}xsojd_YTMIDA@@ADIOV[bipv}|tle\XWX^emv~zurnllkmmnnnmmkieb`[WTNJGB>;652422200--((((((((''&&$$"""   "#$&'*+,-/011222569:;:7500//07=BHLQSVWY^dks}{wrmhb\VQKEB@>@AEKRX_elsxvnf_YVX[clt}yurpooopppponkheb_YVRMID@<752442210/-,'''''''&&&&&$#"""  "#$&'*+,-/002245569:;976011129=CHKORUVX\cjqz~ytpke`YTMHC@>>@AGMTZahpu|zqiaZWWZblt}yussrrrrrqonkheb^XUOLGB@;74144220/-,+&&&&'''&&&$$$"""" "#$&'(+,//012244567:;:97112249>BGKNRUVX[ahpy}wsnic\WQKEA>==>CHOW[dlrx}tld\XWYajs|yvttttssrpnlhd`\XSNJEB=:64022200--++$$&$$&&$&&$$#"" " ""$&'*+,//0124455679:::9522449>BGJNRTUX[`hox~yvqlf`XTMHC@=<<@EKSX`gmu}vnf_XWX`is}ywvuuttspnkhd_[VRLHDA<952111//-,,**$$$$$$$#$#$##"""    "#$'(++-01124455679:;;:744459>CGKMQTVX[ahox}xsoic\VOJEA=;;=BHNU[cjryzqi`ZWX_hr|ywvuttsomjfb_YUQLGC@;7510-//-,,**(####$########"""  ""   $&'(*+/01224555579;;<:95566:@CHKNQTWZ\cipyzvqlf`YRLGA=;;<@DJRX_fov}slc[XX^gq~}zxvvutromhda^WSNKGB>:752/-+*(****'$"""##"#""###"#" "##   #&'(+,-01244555579:;<;:7667;@DHKORUX[`ekrz}xsoic\VNJC@<;;=AHMU[clt~vnd^XX\eo|{xwvusrnkgd_ZVRMJEA=:6420,+*('$(('$""""""#"""""""  #$#"   #$'(+,-/1244556569:;<<;:679;:;=BHNV^gow|siaYX[cmy}ywvurpmjfa^XTOKHCA=:6420-+*('$#$###  ""  #$#"   "$&'*+-/12455555679;<<=<<:;>CGJMQUY^chot{zvpjd_XRKE@<::<@DKSZdlt~ulc\XZbkx~zxvtrolhea\WTNKGC@=:6410-+*''$$#""""   "##"  "#&'*+-/12455666769;<<===>>ACGJMRVZaeksx}wsmhaZTMHA=;9;=AHOW`iq{vnf^YYajw~zwutqolhd`[WSNJGC@=:7410-+*''$$#" """   """   #&'(+-/02456677679:<=>>>@@ADHJNRV[bgnu|}yupjd^VOJC=;99;@EKT\foxzph`ZY`it{yuspnkgc_ZVRNKGC@=:7510-,*''$$"""   "   "&'(,-/12456677779;<=>>@AABCGJNRV\bhow{vqlf`YRKE@;99;=CJRZcmv|rjb[Z_gr{ytspmifb^ZURNJHC@=:6510-,*('$$"""   ""$'(+-/12456777779:<>@@AABCDGJMRV\bhpx}xsnhaZTMGA<99:@ABBBCDGILQU[bhqy~yupjd^VOIC=;99;@ELV_ir{~ume`\_eo||xuqolhea\YURNJHC@=:652/-+*(&$$#" "#$  "#''*,-0256779999:;=>ABBCDCDGHKOTZagqx~zvrlf`YRKE@;99;>CJT[fpxvnhb_`fnz}xuqnkhda\YURNKHCA=:7420-+*(&$$"" #&&#   "#&'*+-0246799::::<=>ABCDDDDEHJMSY`gow|wsnhbZTMHA=:9;=CHRZdmu}vpidaafmy}xtrmjgd`\YURNJHCA=:7520-+*(&$#""  &&$" "#$'(,-0245699:::;<=@BBDDEDEDGILQV^dmv~|xtpjd\VOIC=;:;=BHQXajr{wqkfccgmy}ytqnjgca\XURMKGCA>;752/-+*(&$#"" "$#   #$'*,-0245679:::;<=@BCDEEEEDEHJNU[ckt|~}|xuqlf_XRJD@=;;>CHOW_hpv}|vqlhedgmw}xsqmigd`[XURNJGC@=:742/-**(&$#""    #$'(+-/1456799::;<=@BDEGEEEDDCHLRXahqx~}{xvrmgaYTLGB>==@CHOW^fmsy|}zuqmigfinwysqmifc`\XURNKGB@=:741/,+*(&$#""  "$'(*,/1455777::;<=@CEGHHGGDDEGJOV^emv~}}zxvrnhc[VNJDA@@BEJOW[dkpuyyxtqnjiijnvztpmifc`\XTQNJGB@=9741/,+*(&$#""   $&(*,-014567799:<=@BDGIIHHEEDBHLSZbjsz}{yxvsojd^XRLHCBCDHKQW[cinrtuurpnkjjkovztpmhec`[XTOMJEB><9641-,+('&#"""   "&'(+-/12456777:;=>BEHIIIIGEDDGJOV_gow}yyxvspkf`ZTOKGEEHJMRW[bgkoqrqpomlklmpw{vplheb`[WTOLJEB><9641-,*(&$#"""   "$&(*,-014556679;<>BEIJJJJHGEDEIMT\emu||yxwvsqlhc[WRMJIJJLOTW[aeikmooommmmnosy{vqlheb_[WSOLIDB@<9640-+*'&$#""   "#$(*+-/11245567:<>BDHJLKJIHGDGHLSZcjrzzxwvusqmid_YUQMLLMNRVX\adfhjkllklmnoquz}wqkgdb_ZWSOLIDB@<9620/,*'&$#"   #&'(+,-/01214469;=ADHJLLKJIHEEHLQX`ipv~zwvvtsqnjfa[XTRQORTVX[^acdfgghhjklnqtw|~wqkgc`^YVRNKHDB><7520-+*(&$#""   "#&(*+,--/011256:<@DHKLMLKJIHHILRW_gnt|zwuttsqokhc^ZXUTUVXY[^`accccdefgjlorwz|xqkfc_[YURMJHD@=:7420,+*'&&'''&$#    "#$'((++,-//01257;>CHKMMMLKJIIJMRW_flryzwttssqoliea^ZXXXZ[^_aabbaaaaacehlotx{~yqkfb_ZXTOMIGB@<:741/,+(+++****(&$ """"   "#$&''(*++,,-/026:=BEJLMNMMMKLLNRW^djpw~zwtssrqpmjhda^\\^``acccca`_^\^`bgjotz}yqkfb^YVSOLIEB>=9640/,-----,,,**(&# "#####"    ""$&&''***(*+,/47<@DILNOOOONNNQTW\cinu|~{wsrrrqpnlifdbaabcdfffeda_\YYZ^aejou{yqkfb\YUSNKHEB><9521-00000////,+*'&# "#$$$&$##    "##$$&'''''*+,-15:@CHLNQQQQQQQSTW\cinty~{xwwy}}wsqqqqpomkigfeffgijiigdb^ZXVWY\cinv{zrkea\XTQNKGDA>;7520211111100/-,*(&$  "##$&&&&$#  ""#$$$&$&'(*+--49=BHKNQSRSSTSTVY^chmry~|wusssuwz}wsqqqqponmkjiijjlmmmlifc^YVTUW[bhnv|yrkea\WTQLJGC@=:64444244442210/-**'$# "#$&&&''&$#   ""####$&''*+,-27<999777776665421/-,+(&$#""##$$&''''&$#    "#$''(++,-5:@EJOTWXYYYZZ[^`cgjmrvxyzywtqoligefgjnrx~ytqppqqqrrssstvwxxxvtplf`YVSSUY`fmu|}wqke_YVRMJHDA><;;::99997776520/-,*('&$###   #$$$&&&&&&$#"   #$&'(*+,,29>DIOTWY[[\\\^_acfikpsuvutspnkhfcbbdgkpuy|vrqqqrrstvwwx{|~}{vrmha[WUTVY`fmu{}uoje_YUQMJGBA@=<<<;;::::9765210-,+(('&&&$$$$$$$$#"$$$$&&&&&$#"    #$$''(++,27=DIOTXZ[^^__`aacfhknpqrqqomkheba``bdhlqwwsqqrssuwxy|}}{tojd^YVUW[agmtzztnie_[TQLJHEC@@>>==<<;:9977521/-,+*(('&&&''''&&&$# "#$&$$&$$##"   "#$&'(*++06>==<;:9975210-,,+**((((((*(''''&#  "#$$$####""    ""$&'(**+/5;BINUY\_`abbbcccegikmnmmljifca`^^^`acgmry}wtstuvx{~{toid_[Z\_dhmty~zvqmhc_YVSOLJGDDBAAA@>=<<;:975220-,,+*++**+*******'&&# "#$$###""     ""$$'(**+,4:AGNUY^`bbbccccdegijlllkjigdc`_^^^_`bfkqvyvuvwxy}~wrmgc_^_adinty}|ytpkfc^YVSOMKIGEDCBBA@>=<;:975220/-,,,,+++,+++,++*((&$" "#$#"""     #"#$&'**+,29@GNUZ_adcddddddefhikkkjhgedb`_^^^^`adint}}yxxxy}}upkfbaacgjntx}~~|yurojgb^ZVSQNLJJGEDCCBA@>=<;9754200---,,,,,,,--,,+++('&#""###"   " ""##$&'(*++07>EMTZ`befeeddedefhikkjjhgecb``_^^^_achms|~}}}ztojfddfikotx|~}{yvspmieb^ZXUSQNLKJHGGDCBA@><;:75521100////////////-,++('&" ""#"   """" ####$&''(*+-6=ELSZadfgfffeffffhijkjihgdcba`_^^__`bgkrzzrnjghhkmptx{}~~~~|{yvtqnkheb^[XVTRQOMLKIHGECCA@=<:976522110111110100000/,+*(&$" """"  """""""##$$&&'(*++4;DKSZadfhhggfffffhjjjjihgeccb`_____`bfkqy}wqmkjlmoqux{}~~~}}}||{xwuromjgda`[ZWVUSQOMLKJIHEDCA><;:975542224444222222100-,**($#" " "   ""#"##$#$$&$&'(*+2:BJQYadgijjihggggijkkkjhffdcb``____`bfkqy|uqoonpqtvy{|}}}}}{{zywtsqnkjfdc`^[YYVUTRQONLKJHEDBA><;:977656656655555442110-,+(&$"  "   "##$##$$$&$&&'(*+19AIQY`eikkkjihhhhijklljigfecb``____abgkqy{vrqqruvxy{|}|}|{{zxwusqomkhfeba`^\ZYXVUTSROMKJHEDB@><::99977777777776664210/-,*'&$"  "   "##$$$$$&&$&&''(*/7>HOW_fikmmlkjjiijjlllkihgfdba`____abgkqyzxuvvxyyz{{|}|{{yyxvtrpnmihfedba`_^[[YXWVTRQMLIHECA@>=<;;:::99::999976664210/,*('$#"      "#$&$&&&&'&'''(*+5=EOW_fjmopomlkkjjllmlljihfdcb``__`abgkqy{zyyzz{||||||zzyxwutrpnkihgfdddbba__\[YXWUSQNKIGDCB@>=<=<=<<;<;;;;:99965411/-+*'&##"     "#$&&&'&'''('((**2>>>====<<<<;::9764410/,*('&#""  " ""   "#$&'$'&'(((''((+09BKT\elqsttrqonlllmnmmlkigfcba```aacglrz~}}}||zzyxwvtsqomlkihhghggfeedcba_^[XVTRNLJIGDDCBBAAAA@@>>>==<;:976411/,+('&&#""" """"""    "#$'''''*((((((*-6>HR[dlqtuvvsqonllnnnmlkihfdba```aadgls{~|{{yywwutsponlkjiihiiiiihhgfeca_[YVTROMKJHGEDEDCCBBBAA@>>==;:96421/-+*('&$###"" "###""    #$'(''(*(******+4=EOYcjquwxxvsqonlmnnnmljhfdba```abdhmt|~|{{zywvutsponmlkkkkjklklmkjihfcb_[YWUSQMLKJIHGGEEDCCCBBA@@=<;965410/++('&&$$$###""#$$$#"    $&'''((****(***2:DMW`iqvxyyxurpnlmmnnmljigdba```abehnu~~|{zyxwutsqpnnmmllmmnnnnoomlkigeb_\ZXUTRQNLKJIIHHGEEDDCBA@>=;:76410-,+*(''&&$$$###$$&&&#"   "$&''((*++*****1:BJT^gnuyzzyusqomlmnnmlkigedba``abeinu~|zyxwvusrqppnonmnopqqrrrppnlifdb_\ZXVTSRONMMLKIHHGEEECBA>=<:96410/-+*('''&&&$&$$&''&$$"     #&'('(*++++++*19@IR[fmsx{|zxuqonmmnnmlkihedba`aabejov~|{zywvuttrrpqoppqrssttttsrqnljfdb^\ZXWUTSQONMMLKJIHGEECB@><;96420/-,+*('''''&&'''''('&#     #&'&'*++,++++17@HQXckrxz{{yvsqnmmmmmlkihfdca`aacejow~}|zyxwvuttssssrrstuvwwwwvurpnlhecb_\ZXWVTSRQQNNMLJJHGDDBA>=;96520/-,+**(((''(('((**('&#"   "#$''*+++,++,27>GNV`iovz||{wtronmmmmlkihfdcaaaacfkpw~||zyxwwwvuutuuuvwwxyyyyxvtqoliheb`_\[YWVTSSROOOMLJIHEDCA><;96420/--+***((*((***+***('$"    #&$'*++,++,27>DLU^fntx||{yurqnmmmllkihgdcaaaadglqy}|{{yzxwvvwvwwyy{|}}}{zxvrpmkifdb`_\ZZXWUTTRQOOMKJHEECA>=;975400--,+******+++,+++*('&"   "#$&'*+,,,/47>DKS[elrx{}|zwtqomlllkkihgdcbaabdgls|~}|{zzyyyyz{{|~~|yvsqnlifeca_^\ZYXWUUTSQONLJIGECA>=:976410/--,,+++,,+,,,-,,+*(&#    #$&(*++,05:>DKRYcjqvz}}|xurpnmlkkjihgdcbaabdhnt}~}||{{||}}~}zwuqoljhecba_^[ZYXWVUTSRNLKIGECA>=;976420/-,,,,,-,,--/---,,+(&$     ##&(*++05:>DKRYaiouz}}|zvrpnmlkkjihfeccbaceinu~~{xvromkigdca`^\[ZXXWVTRQOMLJHECA>=;:75410//--,----//0/////-+*'#     "#&((-15:>DKQX`houy|||zvsqonmlkiihfedccccejpw|yvtpnljhfcc`_^[ZZYWVUSQONLIGEDB@=<:764200/--/---/0000010/-,*'$     "&(-16:>DJQX`gmtx{|{zvtronmlkjihfedccccfjpw}zwuspmkigeca_^\[ZYXVUSRQNKIHECB@><:754200///////011111110/-+(&"     #(-15:>CJOW_flrwy{zzvtrpnmlkjihfeedccdgkqx|yvtpnljhfdca_^\[YXWUTRONKJHEDB@=;:774210///00001122222210-+(&#   #'+049=BINU\ejpuxyyyvtrpnmlljihfedddcdgkqy}zxvspoljhgdca`^\ZXWUTRONLJHGDC@=<:7752200//00111242442210/,*&#   $(-47<:97542110001222445455420/,*&"    &,16;>DKQX`fkpsuvutrqonmlljhgfeddddehms||ywurpnlkigeba_[ZXVUSONMJHGDBA>=;976522111222255666654410,(&"    $(/59=;:77542212222556676665420,*&"    #'+27:@DKRY`ekoqrsqpomlkkkjhffdccdefhns}~|yxuspnljgec`^[YWVTQNMJIHECB@><::7655444444566777776420,*&"   #&+/59=BIOV[bhloqppomljjjjihgfdccdefhns~¾~|ywtqoljheba_[ZWUTRONKIHEDB@>=;97665442455677799776520-*&"   #'*/17;@GKSY_dilooonlkjijjihfedccddfint~}zxtqnkjheca^[YWUTRONLJHGDBA@=;:9766545565777999776520-(&"   "&*-159=CJOV[bfjmnnnljihiiihfedcccefint~~{xtqnkifeb`^[YWUTRONLJIGDCB@=<;9976555666799:99996520-(&     $(,027;AGLSY_dhkmmmkjhggihgfeccccefint}ÿ~zvromigeca_\ZYVUTRQNLJIGEDB@>=;:997655667999::::96520,(&   $',-16:>CIQV[agjlmlkihfgghgfeccbddfint{~yuqnjhecb`^[ZXVTSRONLKIGGDCA@>=;;:7777697:9:::::96520,($   #&+-027=;;:97799:::::::97642/,'#   "$*,/15:>CJOV\bgkkkjhfddeffedcbccdehlry¾{vqlheca_^\[YXWUSSRQNMKJHGEDCB@@==;::999:::::;::97641/+&#  "$(,/127=<<::99:::::::977620,*&"   #'*,026:@DKQW\dhkkihfecdfeeeccbccehjqw{tpkfca_\[ZYXVUUSSQQOMMLKJHGEDDCB@@=<<:::::::::997651/,(#   #&*,/059=BINUZagijihfdcdeeedccbcdfhkov~~xrmhda^[ZZYXWVUTSRROOOMLLKIHGGEDBA@>=<;:::::9:9765540-+&"  "&*+-/27=<;;:::99765421/+($   !&-5@JQSSTVXY[_en|~tnjgdb`]\[YXXWVSOKFB>;963-&   &-5?IQTUUWXYZ^dlxysmjgdb_\[ZZYXXWURMGA<952.)"  &-6?IRVWWXYZ[_dkuxsokgda_\ZZYYXXWUSMGA;72.*%  !(/8AKTXYYZ[\]`ejt~xuqlhea^[ZYXWWWVURMF@:50+&!  #+2:CMV[]]^__`bflt~ywrnjea]ZYWVVUUTSPKF?93.)$  &.6=FPY_abbbcceiow|xtojfa\YWTRRRRQPNJD>83-)%   !)2:AIS]dffefggimt{{vqkfa[WTQOMMMMLKHC>84/+'$!  #+5=DLU_gjjiiklnrx~xslfa[VRNKIHIIIIGC@;72/+(%!  %.7@FMWajonmlnpsw}{unga[UQLHFEFGHHGFD@<851,)&"  '1:AGNXcmssqprux}wohb[UPJGEEFHIKKKJGC?<73.)%   !)3;CIOYdovvutvz}zqjc\VPKIGGIKMPRSRPKFB=82,&!  $,4=DIPYdowyxwy}~tkc]WRNLKKMQTXZ\[XSLFA;4-'!   '.6>EJQZcox{zyz~vld^YURQQRUY^adec_XPIC<5.'!  #)19@FLS[dny}|{|~xw|xme_[XVVX[^cgjkkhbZQJC<4-'!  %,46.'!  #*3=DJNS[bgkpw}qieeggfca__aeiotwwvtpjd\RI@7/'!  %-6>EKOT[bhmqxuia^_cffdba`adiotxxwuqlf]TJA80(!  !(09@FLPU[binszrg_[[`dffdbabeiouxyywsmg^ULA80(!  $+3:AGLPV\cjpv}~rh_ZZ]cfhgdccfkqvyzzytng_ULB80(!  %,5;AGLQW]ckrz~tja[X[`fihfeehlqwz||zunh_VLB80("   '.65.'    &-39>CLV_glpv}yvtrqr}}unf^WUW\adgjou{~xqjc[QH?6.'!   &-39>ENXbjnrx~zvsqnlls}tmf^XVW[`cfjpw}~xqkd\RI@7/("   &-39?FO[elpty}xtrpligk|ume^YVVY^beiow~xrkd\SI@80)"   &-4:@GQ\fmruy|vsrplifgs½vme]XVUX]adhowyrkd\TKA91*#   &.5;AIS^hosvz~wtrpnjgfnÿwme]XWUW\acgnwzskd\ULB:2+#  !'.55.'   #&()*/5;CKWeqy|||}tmhefghhjq}slfbaaacefghlrx|}{vpib[RKD>6/(!   %)+,,/49@HTcqz~~~}~|rkfccdfhil{yrlgecceghgghlptvvrlf_XQJD=70)"  !&*-.-.27IZl{~vojfbaacfgglyysnjijkkigecbcdeda\WQLGA<60*$  !$(,/0//0247ARfy|tokgcaabdefhpxrnllnnljfa][ZZZXVSNJE?:50*% !$'+.00//0019I^tztpmiebaacdddhr}wsqpqrqoiaZTPONNNMKGC>94/*% !$'*.00//00.3AVnytqokgdaaabbabhs{wvvwxyvpf[QJGEEEFFD@<83/*%  !#&),/0//2311;Ngyusqmieba```_^_gr~|{{|xm`SIB>=>?AA?;83.*&!  !$(+.12257649H_y~yvurojfca`_^\ZZ]dnw~}~vi[MA:678;=<:73.*&! !#'*/4778;<::CWr~zxvtqlgca_][YWUTW^elry}~~}}}}}sdUF:302589962.*&" !#',06;<GIHHGGM]r|wrle^WQKC9.&$&),-*&! '.7ALTX[_bcciu~wsu{}ytnhc]VOH@8.(()*+-/00029>???BJZo~{vqke]UNHA90($$'**($  !)2>KU[]_adgo{|wwz{uoic]UNF=3*()**+-/01002468;@IXl}~{ywusojd]UMF?91)$#%((&#  !*8GU]`_`bhr|z{~}wqjd]VNE;/()***+-/0111124782*%#%()%! "/AS_ca^_fq~ysle^VNE:.()***+-.0111137;@EMU^inlhd`]\^ab`[TMD=83,&$&))%!   %8O_fd_]bo~|ung_WOE:/))***+,./112359>CGMRW^ba]YVTRRTY[YTME=73.*()+*'#!   !##"! !.I_iha\an}yqiaXPE;/*****+,./12358<@EIMOOTXXURQOMKJMRURLF>730,*+.-)%"  "#$%%%$! !)@]lme_bo~~uld[QG<0)****+,./12369>BFKNKILQSQNLKJIECHNOLF?842/-.0/+&# !#$%''''$ "%8Xmrkdfrzqh^TJ?1)***++,-/1357;?DHNPJEFLOLIGHHFC?@GLLF@:6310231-($!!#%''()(%!!"#2RluqjkvwmbXNB5,***++,-01369<@DKRQIBBHKHDCDECA=;@HJG@;7543442.*&! !#%'(()(%"!"#.Kjwvqq|}rg]RF;/**+++,./147:=AENVTJ@@EGD@?AA@>;78AGFA;8655542/,'#   #$&''('$" !"#*DewywyxmbWK@4+*+++,-/148;>AGQXVK@?CDA=;=>=;9529CEB=96665430-($! !"$%%%$" !"#%<_u{|~rg\PE9/+,,,,-/148:7765431.($!  "##"! !"##5Wp{vk`UJ?2++,,,-/258:8764222.)$!   !!!"##0NjyzodZOD7-+,,,-/258;>>CMTTNE@@@=9755420.+)/:?>;8641/01.)$" !""""##,Ecu{qg]RG=2+,,-./147:;;@IOQMGB@?<964210.,)&)4<=;740,+-/.)%"  !"""##&<[p}{qi`VKB7.,-../025789?GLMLGC@><9631/-,*(%$,7;:60+'&),-)%"  !""###4TlzyqjaXOF=2,-../01357;AGJKJHD@=;963/-+*(&$!&2884.'!#)+)$!  !"""##0Letz|{xts{}vpjcZRI@7/-..//014:@DHIJJHD@=;962.,*(&$#!!*462,#%)'#   !"""##,C\kppmiffl{~vpkd\TLD=6/-./..17>EHJJIIGD@=;962.+)'%#" #.30* !%%"   """"##*>Tbfeb^]_ep|yqlf_WPHB;50..-/4:767:>DILLJIGFEC?;852/,)'$"!%+*"   !#$%%#"%1BMRQNQX`gjlmpruz~|xwxyxvsojd\TLE@<::;>BFJLLKIGECA>;730.+(&#!  ')%  "#"! !!#%&&$#(7FPSPNT_ipsrqppsvy{zyvsqqtz|smijnqssrnhaXOGA=;<>BDHKMMKIFDB@=:62/,*(%"! $(& "$%%%%$%&&''&$+;JTVSS[iv~}xutvz{{xupkgdeipx|rjc`djnrtrme[RJC?>?BEHKMONKHEB@=;940.+)'$"!  %#  #%'()))++)((&%,=MWYXZdt~|~|vpha[XY_hr|vlc]]cipuvqi_ULFBBDGJMPQQOKHDA>;:73/,*(&$"! !$&()++,.0/+)'&-=MX\\al~{skbYSPRYcnx|qf^Z^emuyvmcXOIGGJMPSTTSOKGC>;9752.+)'%#!  !#&(*+,-/240+('.8310/--+*(&#!  !$'),./13784/,.7EOV[dr~vmcXNFBDLWdp||n`Y\hw|qjeegiihe`YQIB:4110-++*('%#!   #&),.0137982..6CMTY`n~|si^SIBAEN[iusdZZevyqmlmnmje^WOF=6221/+((('&%#"!  #%),/0246994017BKRW]jzyoeYND?@GTan{yi\Xbuysqqqokd\TKB:322/-(&&&&%$""  "%),/13468:7339BJQV\hx~uk_SH@<@KYfu~n_X`tyutspjc[QH@820/-+'$$$$$#"!  !%),/23468::65:CJQW^iyzpeYMC<=EQ_n~tcZ_r}xusoh`XOF>72.+)(&#"""""" "!  $(+/24558;;98;@KYizyh[^oyvsmf]TLE=72-)&%$"!! !! #! $(+/24568:<;;?FMU]huyodWK@;?AFNV`m|}ti]PD;:@M]opa]j{upjcZRJC=72-)%#!   "&*.25788:=@ABFMVapwmaTG=:=HXj}td^g}|uoiaYQKD=72-)&#!  !%)-25799;>ABCFKT`ozqfXK@:;DSfxvhagz|tng`XQKD=72-)&#!#" !%)-2579:;?BDDEIQ^m~zsi]OC<;BPar~wkdgx}tmf_XQJD=72-)&#!!  $)-1469:DP^lw{umgjwtlf_XQJC<61,)&#! #'+03579;?EHHFEISbr}yuncWLECHQ]hqtrmjlwule_WPIB<61,(%"! "&*.1357:?EIJHEFN\l||wuog\RKIMS\eknmlmpyvld^WOHA<60,($"  !$(,.0248>DJKJGGMYhw{vtpj`XRPSX^beghjnt|wkc]VNGA;5/+(%$"  #&)+-.05;BILLJJNXer{usqle^YY\^aaaacgowxkb[TMF@93.+*))($ !! "$&()*,07?HMONNPXco{|tqpmidabdeda]Z\doyxkaYQKD>82/./.-,)#"#$#   "#$%'*-3=FNRSSTYbmw~xtsw}tppoljijllhaZUWao{xk`WPJC=7423320.*'" "$&&$!  !!#&)+1;ENTVWX\cjsz}{uokjnwtpppppprsrmdZTV_n{wk_VNHB<9776652.+($!"$%&%#   "%(*/9DNVZ\]_cioturnhdcgo{wqqrtvy{|zrg\UW`mzuj_UMGA=<;:9762.+)&%$##"! $%%$#! !$')-6BNW]_`acgloolhc``cju{ssux}wlaYZbmy}rh_VNHD@?><:963/,*)(((((&"!$$#"! !#&(+3ANY_bccdfjlkhda^^`fpwvx}}rg`_enx~xog^VPJGDB@><:730-++++++*(%!!#"!  "#%(*1>MZbeeeefijifc`^^_dm||~zogdhox~}ysle^WRNKHEC@>;7420......-+(%!"! !!"##$&)/;JYcgggfgijifca_^_clzxnkmrx|~~}{xtoid_ZURPMJGD@=97533333210.*'"  !"##$%&(,8HXdikihhjkjgeb___ckywrsvy{||{xuqlhda]ZWUROLHD@<:8877776420-)%!  !#$%&&&'*4EVdlomkjklkifc`_`ckzzyz{{{zyvsokhedb`][XUQLGC@><;;;::9741/+'$!   "%&'''')1ASdosrollmljgca``cl{~~~|{zxuroligggedb_[VQLHEBA@??>=<:630,)&#"!!"!   $&'()()/=Oaovvsnmmmkhda``dm}~|zxuromkjkkkjifa[WROKHFFDCB@><841-*'%$#""#$"  "%'(***.9K^nwyvqmmmkiea`aeo}zxusqonnopqpokfa\XTQNKJHFEC@=962.+)'&%%%&&$    #&(*++.8GYjuzxsommlifbaafp|ywutsrstuvvtpje`\XURPNLJGEB>:62.,*((''(((%!   #&)++/8EUeszzupmlkifbabgr|zywvwxy{|{wrmhc_\YVTROLIFB>:72/-+****++*'"   "&)+09DRbpy|xrnlkifcabhu}|{|}ztojea^[XVTQNKGC?;730.,,,,---,(#   !%*09DQ`nx{xsoljifdbcjw|vqlgc`]ZXVSOKGC?;730.--./00/-)$   !(09CP^luyxtpmkifdcdkzþ~ytojfc_\YVSPKGD@;841///01221/+%   $-7ALZhqvvsomkhfdcel{|wrnjgc_[WTPLHD@<852001245431,%    )3=HUblrsqnljheddfm}ľ|wrnjfa]XUPLHE@=:74323466652,%   &/8CO\gnpnljjgeccfn}{vplgb]YUQLIEB>;86444578752,%   %,4>IUaimljhhgdccfn~Ľ}vpkfb]XURNJFC?<97555789862,$  #*19CO[ekkifffdccfn}}tmgc_[WTQNJGDA>;976899:962+#  !(/5>IVaikheefdccfmzzphc_\XUSPMKHEC@=;989::9850*"  '-3:EQ]figddedbcflw½ukc^[YVTRPNLIGEB@=;:999863.'   &,29CO[eigddedbcfkv¾~rha\YXVTRPNLJHFCA><::99752-&  &6HSVX\eztjd_[YXUPF=5-!  (8JWZ[^fvtld^YXWUPF:0&  .>O]abdjxxoe\VRQPLD9.%  #4DUdiils~rf[RLIIHD<4,$  (9GXjqqu}wh[PIGIKKG?6-$  ,JVbo|~skb^ajruqfWE4'  $3BNZfq}lffc`bjsvsi[H7(  (7EP[httb^ceccjtxul]K8(  -:FR]kytc[`fffmvzxn^K9)  #0-   &3>Namywqmy~m^W[bjv}qcR?/!  &3@Req{}tojnm^WY`iv~rcSA1#  '5CUhs|vokin_WX_gtrdTC3$  !)5EXkv}xnjhyraYZ_ep~~rdTD4%   %*5DXny|wkhhpxh_^aekv~{pbSD5'  $)-3@Un|~sgdfjrhdeghlrrj^PC6(  &-.19Kipfbcfqskjjhdcc_VLA5*  '-/01>^{picacfu|sqrncWPNKF=4*  %,/127Q{zrlea`_cs{z}|mVE>??:3*  $+27:;Jqzuoga]YVYerz}}~~}xbH73772*! #,7?DFKe|xriaZTLEEM\hmnnpy~~}vhR9-.20)! !,9EMSS`{~{tkaXNC6/21(''# "! 5XebpyiXE2)*+-038@INTXTOMOQK>3-,+% $&&" -Rkhtq^I4**+-15;CLJILJGEBFI@611/(" $''$ (Kns~}gQ;-*+-16=GPJCEA@?;ISLA@<:952:@:642,$ !"8cxcN8-,-179530+1;:50/,% !"/V{yhUA1,.059AKJC=83/+')380((*% !")JnzxywiZI8/./2;DIHC=82,($"*2*&#  !"&@^dacryl_OA6006BIIGC=71*&""+'  !#"'=RVXakt~ypeWI=77>GKIFA;4.)$ $& !!"$%$,CQT`psrv|}xsurmpqm`OB=?EKLHC?92,'## "&'(*)&0IV]s~|qd]brmadoshUGCGMPNG@;6/*%" #'*-0/)1IZgwfVPYl~vc^kwq^POTWUND;52-($! !'+/33-1EWh~p]MJWm~}j]i||k_^b`XK>50.+'#   &+04622BSc~zhTEH[tr_hznlkcVF81-)'%#  %,04765AP`yt_JAMf}zcfysmaQ@4.)%$#"  $+1489:DRd}|iRACYwjeul]M>2*%"  "*158;?FVlr\E>OopeuiZK=2)#  !)169=BGUowdL>He|tg|ugXJ=2)#  (069?DFOhyjSCG^ssjzueWI<1)# %-27?GGK^zxm\MO\ilm|vdVH;0(# "(,1:FKLZrwod[[`acnwcSF90+(#  #&*5EOS[m}yvwoljjg\\mwaPC831/)"!$" "'1CSZ_irrjgr{rtxyp_[mt_OC<962+&##!##  !&.@Vacgkhb`iy}|ibn}}o^PGB>93.++*'!! !"%*;:961*#  %')3Oksoljd`g~~zuplkjg`VNHDB?:4-'$"#!  !'*1Igvsmjeai|xtrturi`XRMID=5/*('($  "'1Eauvnjfbk||yoe^XSMF>60,,-,'  "/C\quojfdn~tjc\VOG?71/010)  *=Tjqniedpƽ{qi`XPH@942453+  %5I_kjgddqµui`XPIB<75785+  !/@Uegeddpĺpc[UPKE@;8883(   --&# &LprK0+02,"!"FwZ8,1>HF>8795.$!T}fL]ouhN5'! !/9AXrQSlwfJ2$+6BTwx]WeseG2%#.BUl{~~mhcocE5+# 'A[hihqpy`J>4,(! &>_kfd{zqeZM@:4)  $9_pigwtn^PG;/(%  1Xnii}l\N?30-  (Jegjr^PC850  $B^ejr\PE<80 6`lTA!Dqn`S*#R|im`/ *]hof3/`xpk`5 1_qjx}xlP.4crOBRgfD'4kS1c_J_2wLOgN9?_aZy4\?/gͮ0aHJ~J aZy_u aZy)!?_// u aZy)!?_// u aZyB!?_?/ u aZyΟc?!?_/u u aZyΟc?!??_/u u aZyΟc?!??_/u u  aZyΟc?!??_/u u@  aZyΟc?!??_/u u@@  aZyΟc?!??_/u u@@  aZyΟc?!_?_/u u@  aZyΟc?!_?_/u u  aZyΟc?!_?_/u u   aZyΟc?!_?_/u    aZyΟc?!_?_/u    aZyc!_?_/u }   aZyc!_?_/u}   aZyc)_?_/}   aZyc)_?_/   aZyc)_?_/   aZyc)_?_/HH   aZyc)_?_/XX   aZyc)_?_/XX   aZyc)_?_/8X   aZyc)_?_/(X   aZy[)_?_/(X   aZy[)_?_O(X   aZy[)_?_(X   aZy[)___(X   aZy[)__w(X   aZy[)__(X   aZy[)__(X   aZy[)__(X aZy[)__(X   aZy[)__(X   aZy[)__(X   aZy[)__(X aZyZ)__08((p aZyZ)_0( % (0(  ` aZyZ18 85(Hp`  @` aZyZ10`1 &r (P PH    aZy[B0)@ 88P`` ! !`)`aZy(pp" %  @(1``1J@s)`aZy ``"8H)`֠@ R`aZyPhQ@`C 8x  @@)@aZy@P9@H (8``@s 9aZy(8)` @Bf hX(pH@``@ Rsր)`aZy  XhpH  )`sB ! 1aZy ` a88``)``)@@aZyaZ9kmֺuΟ_Ǘѿkmֺyu󶛝}}_kkmֺqqmv?ּknֺ<Qux_ֽ}:?knֺ}yu֥ym-vl #include #ifndef __linux__ #include #else #include #endif #include #include #include #include "tlib.h" typedef struct { FxU32 signature; FxU16 width; FxU16 height; FxU8 depth; FxU8 type; void *data; } LFB_Img; int hwconfig; static const char *version; static const char name[] = "display"; static const char purpose[] = "display a 16 bit frame buffer (565 format) dump out"; static const char usage[] = "-n -r -s srcimage -t testimage"; static const char *renderBufferString[] = { "GR_BUFFER_FRONTBUFFER", "GR_BUFFER_BACKBUFFER " }; static const char *sourceFormatString[] = { "GR_LFB_SRC_FMT_565 ", "GR_LFB_SRC_FMT_555 ", "GR_LFB_SRC_FMT_1555 ", "INVALID FORMAT ", "GR_LFB_SRC_FMT_888 ", "GR_LFB_SRC_FMT_8888 ", "INVALID FORMAT ", "INVALID FORMAT ", "INVALID FORMAT ", "INVALID FORMAT ", "INVALID FORMAT ", "INVALID FORMAT ", "GR_LFB_SRC_FMT_565_DEPTH ", "GR_LFB_SRC_FMT_555_DEPTH ", "GR_LFB_SRC_FMT_1555_DEPTH", "GR_LFB_SRC_FMT_ZA16 " }; void main( int argc, char **argv) { char match; char **remArgs; int rv; GrScreenResolution_t resolution = GR_RESOLUTION_640x480; float scrWidth = 640.0f; float scrHeight = 480.0f; int frames = -1; char srcfname[80], dstfname[80]; FILE *fp; void *mem; FxU32 filesize; LFB_Img src, dst, diff; FxBool txtdisplay = FXTRUE; void *image; FxU32 bpp; GrLfbSrcFmt_t sourceFormat; static FxU32 imageWidth; static FxU32 imageHeight; static void imageConvert( void *dst, void *src, GrLfbSrcFmt_t format, FxU32 *bpp ); srcfname[0] = 0; dstfname[0] = 0; /* Process Command Line Arguments */ while( rv = tlGetOpt( argc, argv, "nrst", &match, &remArgs ) ) { if ( rv == -1 ) { printf( "Unrecognized command line argument\n" ); printf( "%s %s\n", name, usage ); printf( "Available resolutions:\n%s\n", tlGetResolutionList() ); return; } switch( match ) { case 'n': frames = atoi( remArgs[0] ); break; case 'r': resolution = tlGetResolutionConstant( remArgs[0], &scrWidth, &scrHeight ); break; case 's': strcpy(srcfname, remArgs[0]); break; case 't': strcpy(dstfname, remArgs[0]); break; } } tlSetScreen( scrWidth, scrHeight ); version = grGetString( GR_VERSION ); printf( "%s:\n%s\n", name, purpose ); printf( "%s\n", version ); printf( "Resolution: %s\n", tlGetResolutionString( resolution ) ); if ( frames == -1 ) { printf( "Press A Key To Begin Test.\n" ); tlGetCH(); } /* Initialize Glide */ grGlideInit(); assert( hwconfig = tlVoodooType() ); tlVertexLayout(); grSstSelect( 0 ); assert( grSstWinOpen(tlGethWnd(), resolution, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ) ); tlConSet( 0.0f, 0.0f, 1.0f, 1.0f, 60, 30, 0xffffff ); /* Set up Render State - disable dithering */ grDitherMode( GR_DITHER_DISABLE ); /* Load src image from disk */ if (srcfname[0]) { fp = fopen(srcfname, "rb"); if (fp == NULL) srcfname[0] = 0; else { fseek(fp, 0, SEEK_END); filesize = ftell(fp); rewind(fp); /* readng the LFB file header */ fread(&src.signature, 4, 1, fp); if (src.signature != IMAGE_SRLE) { printf("%s file type incorrect\n"); return; } fread(&src.width, 2, 1, fp); fread(&src.height, 2, 1, fp); fread(&src.depth, 1, 1, fp); fread(&src.type, 1, 1, fp); mem = malloc(filesize-6); src.data = malloc(src.width*src.height*(src.depth/8)); /* reading the LFB data */ fread(mem, filesize-6, 1, fp); /* Simple16BitDecode(src.width,src.height,mem,src.data); */ SimpleRleDecode(src.width,src.height,2,mem,src.data); free(mem); fclose(fp); } } /* Load dst image from disk */ if (dstfname[0]) { fp = fopen(dstfname, "rb"); if (fp == NULL) dstfname[0] = 0; else { fseek(fp, 0, SEEK_END); filesize = ftell(fp); rewind(fp); /* readng the LFB file header */ fread(&dst.signature, 4, 1, fp); if (dst.signature != IMAGE_SRLE) { printf("%s file type incorrect\n"); return; } fread(&dst.width, 2, 1, fp); fread(&dst.height, 2, 1, fp); fread(&dst.depth, 1, 1, fp); fread(&dst.type, 1, 1, fp); mem = malloc(filesize-6); dst.data = malloc(dst.width*dst.height*(dst.depth/8)); /* reading the LFB data */ fread(mem, filesize-6, 1, fp); SimpleRleDecode(dst.width,dst.height,2,mem,dst.data); free(mem); fclose(fp); } } diff.width = 0; diff.height = 0; if (srcfname[0] && dstfname[0]) { FxU32 count; FxU16 *srcptr, *dstptr, *difptr; if ((src.width == dst.width) && (src.height == dst.height)) { diff.width = src.width; diff.height = src.height; diff.depth = src.depth; diff.data = malloc(diff.width*diff.height*(diff.depth/8)); count = diff.width * diff.height; srcptr = src.data; dstptr = dst.data; difptr = diff.data; while (count) { if (*srcptr == *dstptr) *difptr = 0; else *difptr = *srcptr ^ *dstptr; srcptr++; dstptr++; difptr++; count--; } } } sourceFormat = GR_LFB_SRC_FMT_565; if (srcfname[0]) { imageWidth = src.width; imageHeight = src.height; image = calloc( imageWidth * imageHeight, sizeof( FxU32 ) ); imageConvert( image, src.data, sourceFormat, &bpp ); } else if (dstfname[0]) { imageWidth = dst.width; imageHeight = dst.height; image = calloc( imageWidth * imageHeight, sizeof( FxU32 ) ); imageConvert( image, dst.data, sourceFormat, &bpp ); } if ( ( imageWidth > (FxU32)scrWidth ) || ( imageHeight > (FxU32)scrHeight ) ) return; while( frames-- ) { grBufferClear( 0x00303030, 0, 0 ); grLfbWriteRegion( GR_BUFFER_BACKBUFFER, 0, 0, sourceFormat, imageWidth, imageHeight, FXFALSE, imageWidth*bpp, image ); tlConClear(); if (txtdisplay) { tlConOutput("1 - lfb source format (%s)\n", sourceFormatString[sourceFormat] ); if (srcfname[0]) tlConOutput("s - display source image\n"); else tlConOutput("no source image\n"); if (dstfname[0]) tlConOutput("t - display test image\n"); else tlConOutput("no test image\n"); if (srcfname[0] && dstfname[0]) { if (diff.width > 0) tlConOutput("d - display differences\n"); else tlConOutput("source and test image size are not the same\n"); } tlConOutput("space - turn on/off text display\n"); tlConOutput("any other key to quit\n\n"); } /* tlConOutput( "1 - lfb source format (%s)\n" "+/- - change width of source image copied\n" "s - display source image\n" "t - display test image\n" "d - display differences\n" "any other key to quit\n\n", sourceFormatString[sourceFormat] ); */ tlConRender(); grBufferSwap( 1 ); while( tlKbHit() ) { switch( tlGetCH() ) { case '1': break; case '+': break; case '-': break; case 's': if (srcfname[0]) { imageWidth = src.width; imageHeight = src.height; imageConvert( image, src.data, sourceFormat, &bpp ); } break; case 't': if (dstfname[0]) { imageWidth = dst.width; imageHeight = dst.height; imageConvert( image, dst.data, sourceFormat, &bpp ); } break; case 'd': if (diff.width > 0) imageConvert( image, diff.data, sourceFormat, &bpp ); break; case ' ': txtdisplay = !txtdisplay; break; default: frames = 0; break; } } } grGlideShutdown(); if (srcfname[0]) free(src.data); if (dstfname[0]) free(dst.data); if (srcfname[0] && dstfname[0]) free(diff.data); free(image); return; } static void imageConvert( void *dst, void *src, GrLfbSrcFmt_t format, FxU32 *bpp ) { FxU32 x, y; FxU32 *longData = dst; FxU16 *shortData = dst; FxU16 *srcData = src; FxU32 longStride = 640; FxU32 shortStride = 640; FxU32 longColor; FxU16 shortColor; switch( format ) { case GR_LFB_SRC_FMT_565: case GR_LFB_SRC_FMT_555: case GR_LFB_SRC_FMT_1555: *bpp = 2; break; case GR_LFB_SRC_FMT_888: case GR_LFB_SRC_FMT_8888: case GR_LFB_SRC_FMT_565_DEPTH: case GR_LFB_SRC_FMT_1555_DEPTH: case GR_LFB_SRC_FMT_555_DEPTH: *bpp = 4; break; } for( y = 0; y < 480; y++ ) { for( x = 0; x < 640; x++ ) { switch( format ) { case GR_LFB_SRC_FMT_565: shortData[y*shortStride+x] = srcData[y*640+x]; break; case GR_LFB_SRC_FMT_555: case GR_LFB_SRC_FMT_1555: shortColor = srcData[y*640+x]; shortColor = (0x8000) | // Alpha == 1 ((shortColor >> 1) & 0x7C00) | ((shortColor >> 1) & 0x03E0) | ((shortColor) & 0x1f); shortData[y*shortStride+x] = shortColor; break; case GR_LFB_SRC_FMT_888: case GR_LFB_SRC_FMT_8888: longColor = srcData[y*640+x]; longColor = (0xFF000000) | ((longColor<<8)&0x00F80000) | ((longColor<<5)&0x0000FC00) | ((longColor<<3)&0x000000F8); longData[y*longStride+x] = longColor; break; case GR_LFB_SRC_FMT_565_DEPTH: longColor = srcData[y*640+x]; longData[y*longStride+x] = longColor; break; case GR_LFB_SRC_FMT_1555_DEPTH: case GR_LFB_SRC_FMT_555_DEPTH: longColor = srcData[y*640+x]; longColor = (0x00008000) | ((longColor>>1) & 0x00007C00) | ((longColor>>1) & 0x000003E0) | ((longColor ) & 0x0000001f); longData[y*longStride+x] = longColor; default: break; } } } return; } glide3x/h5/glide3/tests/glide.txs0100700000175300010010000025223207122022063016157 0ustar johndoeNoneTXSF 1.000000 9 256 128 4 00000023 1@U[ly#D*&$'1@U[ly,U dI iy*i::G9YyJJ/Z/J?:/O/J/[;9'GwZ:/??Z/J??K//J/?;/::wIK?/Z//?J//[///:/:/JYI)):?J/?/?/Z/?/?/:/O;/:*)Iw7)*Z?//O/J???OO???/:/;/J/+)YYYZ??//O?????OOO???//O;//??ZZzzzz_?J/?/????O?OOO?OOO?/?/K?/??O__zoO?/O:?/??OOOOOOO?>O?OOO??/?/K/O/OO_zz_O?/???????O??O??O?OO??O>OOO??/Ok//OjojO_????OOOOO??O?ONOO>OO>OO>OOOOOO??/J?//??zoOOOO??OON_ON_NO_NO>_>_NON_>NO_NO>OO?//O://OjzoOO???OO^^N^^^^ON_>_N_>_N_>_^NN_>N_NOOO?/J?//O_OO???_^nnnnN^>_>_N_N_>^>^_N_NN_N_>O??/?:?/Ozz_OO??O^n^~n^N>_>_ON_N_^^NNN_>N_>_>NOO??????O_K+Jo_O?O_^nnnnNo>>_ON_N_N^N^^NNN_N^_NN_>O>O_??OOJ++Y;++Jo__ONnn~nnn>nN^NoNO>O>O>o>N^^_^N^N^^^NN^_N_^>_OOOJ+;9Ww_N^^^nnnnn^^^_^^n>^OO>ON_N_N^NN_Nm?:=:**=I****:?Zz/K?O_NO?J?:*:*M]]]?OOmOO>_>O]*:I**::/:???OOO?/?/O_?_^n~nN^O^_>o^^^_?*I::**Y*::+JNOOOOONOOOO?NON?/O[OjjO_o^N^n~nnnN^O_/?OON_>_>O/_ONNO_NONON_>OO_N_>_O?Okz__~~nnNN>_?*??OO?:/_>o>^N_N>NON_N_N_>_NN_??[pjm~|~n~~~nnnno>>_^GY6Y:]_^N_^>_}}N^N^>_N_N_>OO_Zppp~nnN^^n^n^^^N_^N^rllm_O??_ppppppppp`aQQD4ppppppp|nn^^~n^n~n^n>^>_\lRRfpppppppppp`aaQQQ44ppppppn~nnn^nnl~^>?N^>\LRpppd#s`ppppk_|n~n^nnn^^^^^^br~~m_^O.MLpppq`piJb~~~n^^^^NNNNNrnnN^~n^>/J=6BBRbppppsa``q;KOb~~~nn^N^^~N^NO/:=6fM:M?O]]MuRppppppca`a`K+*_jpb~nn^NNO^n?/:=6^__>?OOO?fRppppppqtTQ`aap+:OjppRn^_/cpn~^]/:]=6pp_N__??_O?O*UppppppppqQQaQ`qy?_tpppbl~~nn/dppn~nN]/:]=6pp^_N_?_?O_O*epppppppppQQQaQ`;o_jppppR~:Sppp~~~n^N?M/]M6ppp}__NO_?OOO+7ppppppppSAQQaQI++__OppppR|~:Spppb^~nn^N>/J?=6pppp__>_O?_?/++wpqppppDQDQQw++;__Otppppb|/Sppppn^>_?]?-Fppppo>_>???O/+ipqppqqS4DQQQ;__?pppb|JSppppr^_O??]/=6pppp^_O>???O/+Ypppp`qD44QDa;;_??pqp:Bppppn^OO]/?J=6pppq^__O?_OO?+ypqsa44DQa;*_O?dpppbjBppp>O?>?/?<6pppq_N_O??_O++Kt``qsdT444DDt`q++)zO:Sppb|ORppp}N_._OOM6ppq^N_OO?_j9)+i`a``aQQQDDc#1#ADt`piyjb|}_.JRppr?J?_J?=6ppn}_>O?O_igg)9w````qstaPaQaQQQADA44Dq`99:db}}_O*RpO:/:/OJ/J=6q^_NOO_''w``a``a`aa`aaacsssd44444dq``qyK:dbm}_^_JBp^?*:/Z*:-6q_NOO_Gaa`a``aa`acs41#ATq``79GJS`b|]o}NO/dpn/;**:*:-6`m~^_O_oGw```q`a`at3144Dq``8kd`b|?**_m^^^?df/***:/:*=&`Ono_O_'```a`aa#$44DTq``ed``b|m?+*?N_?T`vm;*;/Z*:&O^noNO_zwa```a`aC144Dq`a`aud``b}/;+??O;C`VM++*+O>:JMF``ON^n_>_jS``a`asaQ#4444Dtq`aa`7a``b~^O*+J.Om;3aX*+**;+ '`]_^^oOOa``a`asaaQD#14DAP`a7da``R:*+9*]^JCaae* 9``LO^^~oNOOq`a`aa`asQaQa314DADTa`aaqa``R~J**+ IOmO*3aa`H I'a``BRLl|m]]mxWst`aa`a`aa`caQQc44DADQda`aagqP`aR\|/+) )+J??I3``#  +&&`a``a``a`aa``a`aa`a`aa`daQQax44DDQDaaPaaqa`a`aa`qRf\l<9 )):>Z&a``aa5  ++:-&Ta``a`aa``a`aa`a`aa`aa`dQaQQacccssssssuUESDDDQDQQaQ`aa`aa`a`aa`a`aa3()I::aa``a`aI  +3a`a`aa`a`aa`a`aa`aaaqttQaQQQQQDQAD44A41$%%TDQDQQQQaqsaaQ`atctaa`aa`aa`a`aaQ#)9**I33#33E3 ++HCU33U3VRVR\VVFVscccScSSSSSSCSeCe3UUUdDQQQQQQQaQQaQQaQPaaZ*Ffaa`aa`aa`aaQ5)&:K*)+ +:]^^nnOO>;YsTQQQQQQQaQQQaQPajZon^lfQ`aa`aa`aQ#8)9:  )+;* :N^_NO__*IcTQQQaQQQQaQaz/o^~N;9EQaPaaPaaPC(=))+ )  ):OOO_?_;)9scTQaQQQazj?_^N+)#aaQ`aaQ`TE<Ij) ) *:N_O_O+)IdaQg9;j/On? )(TaQaPaaQaD%V )   )i?_Z)+G)yj:?o?/Z++YEaaQaQ`QaQ2)   Yj?+7+)9:[/J?OO) )5DaQPaaQPaQ45(%()I/;Wi)+[J;9)))))UQaQQaQQaQQPTaQQH:k*K)WW'+*J/;++*?[kJJZ/JTQaQQaQQaQQaTK*+;Y) )Gw+ 7wi;+*++++IH3QQaQQQaU*;:W +iK++9wyZ[;;;*:K/iFFVJZZwY+wK+)7wZZ?/Z?J??/?ZZ?k_g) );;;)WjZj_ZOZO?Ojjjg')9;gg7)gGGzjwGwwg7Y''W8)7I'wW9GK'W{[IWzkIWGy97797yIwwGgwWZJ:JJW/?J/?;//J;y+I?/?/O?/J/K7jJ?/O??OO??/J?Z_zz_?/O???O?O?OO??:?/O?OOOO>O_>ONONOOO//ZOzO?O^n^^^O>_N_^N_N_O?//O_?Nn>N_>_^>^N_N_>OO?O[_^nnnn^^N_>ONoN^N_.Z.J?/ZZg_?^o?O??mJ/JJ?*:J??OOO?/_on^nNN??OO?ON_NNO_N_NOOjpsn~nnnNnbcRN^NNvbm_OOsccppn^~rNNN\psT`pj~^^NNn^NOMRpqa`;mb^Nl|n~^?=m_O]Vbpppaaai*_p^F|~m/]do>OO_9CppsdQa+J_pRFpp^>/]dpN_?O+WppsDQ?ZtpFpp^O?MBp__OO+psc4D+??qVpN?/]BpoOO?K;qs34DqtiYZtVqoOO]=Bpq_OO9YwastQQD34A`iwkq}_Fq:/J/=dq_Ow7``a`dtsu1D`Gwqq]^_Fp*:*B}__zgw`staq#1D`}:*OOH\;*/:MBa_n__qa`qa#1T`aW`q++M_6aY++3`]^n__a`aDDDP`|;:?H`9 *3`aBbVRF`aaqQQ4Qsca`a`aaqR2))*Jaa`T+8aa``a`aa`tsQTaTSdSCC35%sSQQQsaQxhBPaaQ#9*78')+I'7\l]gcdQQaQQaj?n}UTaPa3()9) + J_OO9caaij?^:EaQ`3"Y  YOZ I+IJO?* )EDaaQQ5)))yj+) g;;*+)*IY6QaQQaQUJZiI) 9wiWi;*++**Y6CFIZZOZ?OZg)+wW7'gw7iwYwW/?:/Jy???O??/jO_N_N_>NO?/__n^NO^NNO??y_^^^OJO/?ONOOjrn^n|NbvVcqZ|^nbVaZqr~p^/_?IC?qr}p_qNO+q3csgqmz]:qbOgy`qtCT?]J:fztsCdaaz*:9+TBfqqqsStacd3(9XU'9UBuRcsudaZ_H3Q#'):OIg+:IUTDE8:y7Y9y::JVGywggjzOOOO^^OON?~nb^fbbkbbV_Gb}RJFowsssttf9698V:8U(I:iyglide3x/h5/glide3/tests/lava.3df0100700000175300010010000025460407143552273015677 0ustar johndoeNone3df v1.1 p8 lod range: 1 256 aspect ratio: 1 1 s1JZBJcJ)!!!!!J{!!)!kJ:s1RZRRJB)ZsJB1:1):JJ1)JJ)11)ZckRs):RRB{k:1)!ZZk{cZcsBR)1Z)c{k{sc):1)!!!RBcֵ)1R:!Z~&0/DD^D#4@?KBB?4D//D#4@@??@?@@@@@@??@??@@@@?KL9)9K@44#DD/////D#4?B9::::9)+LL++LK@4D//0&EHatVtVaRHH !HH/##/04@K?@4C@KBLLBK?C3D/&5FE----"EEE-!!--"EFFF5&/#4@@CCC@?KBLLBB@?@C44D/0&5E"HV{P{hR F0/^D# 4C@KBBLLK@4##44@?KBBKK??@@@@@??@@CCC@@?B9)9B@4#DD/////DD#4@B9::::9)++9)9)9)+K?@4#D/<&E! aVhtVRJHH !!H!FD#//4@?@CC@?BLLLLLLBK?C3D/&5FE"-!!--"EE"!!---EF55&&</#4@@CCC@@KBBLLLBBK??@44D/0<&5F- JVa "F0/D#44@?KBBLB?@44@?KBBKBBK?@@@@@@@@@@4444@?KL+9)+L?4DD//////DD#4@B)9:::9)9)::::::9)+BK@4#/5RVPPPPPVRJH !-! /#D0D4@@@C@?KLLBBKBBBK@C D0<&5FE!!!EEE-!!!-"F5&/#4@@CC@@@?KBBKBBK?@@4#^0&5FFFFFFE!HRVt "E&<0/D#4C@?KBBLBK??KKBBLBBK??@@CCCC@@@C44344@?B)99K4#//////DDD#4@K9)99)9)9::77777:::9+K@4^&aPQQQPPP{VRIH -" &0DD//#4@@C@?KBLBBKKKK?@4#/0<&5E! H !"EEEE-!!-"E5&<0/#4@@CCC@@??KKKK??@C4D/5E"EHaRJF&0/#4C@?KBL+LBBKBLLBBK?@@C44444CCC44 ##4C@?L9)+L@4D////^DD#44@?L9)9:::777ooo777::9+KCD&aPQQPPPPPPPPtVJH !-!FDD/00^4C@@@@KBLLBK??@@@4#D/<&5E! HIJaaIH-EFFFE-!!-EF&0/#4@CCCC@@@@??@@@C4#/5 HIHH -- F&0/^4C@?KBL++LLBB@@C443###434444##D#4C@K9)KC#////^DD#44@?B+9):7ooooooo77:)B@#RV{P{PPPQPPPtaIH !"!!/D^//0//#4C@@??KBLLLB?@@@C44D00<&FHIaVtVtVaI !EF5FE-!-"EE&000/#4CCCCCCCC@@CC44#D0&E-HatVVRH---!!-&<0/^#4@?KBL+LBB?@C4#DDD^DD#434 #DD#4C@B)99L?3D///^D# 4C@?B+9:7oollloo7::9L? 0E-HRVVtVtV{PQQQQPPtaH -!50DDD///DD4C@??@KBBLLBB?@C44#D/<&E! JaVtaH!E555E"-"E50/000/#4CC4444444444#D/F! IJaV{PQPtI !-E&0^D#4@KBL++LLBK@C4#D/0///^D#43#DDD#44?B9)+B>#///^D#44C@?BL+9:77ooo77:)+L?3/4#/05E"HatPQ\$__MMM_QPta !E5&FF/C?@C444C@?KBBKBKK??@@@44#D//0&F"""!HHIIIIIIIHH !EFFFFFF5&/#4C4#/0<<0/DD^^//00<&55F IJJHHIRVt &005E&/?+)9)+LLLLLBBKK?@4#/&F5&/ @??4D//4B99)?3D/D3?9)9)LK?C3D/0<&F-HatPQ\$__MMM_\PhtIEF&5F54?K?C444@?KBBKBKK??@@C44#D/0&FEEEEEE-HHII !!-"EEEFFF5&&/#4C4#/<<////////00<&&&5E"HaRVtVaJH !5</^/&EFDK)9))+LLBBKBBBKBK?@4D05F5D4??@ /0D@9)B@ #4?:::9)+LBK@C D05E!HatPQ\$___MMM_Qt F&55D?KB?C44C@KBBKBBK??@@C44#D/0&55FFFFFF-HRaRH !!--EEEFF5&</ 4C4#/<<0//0//00&EIRVhtIE50/###5&4L+9)9LBBKBKKKKKKKK?@3^<&55&LLLBBK?@@44 #//<0/#4C@C4D&FEF&0D344444C?B++LBB@@C4D0<&FE! IaRVtVaRatPQQPPhI-50//00#?9:::9)9)99::::::9))LK?4#/<5FEEEE! HIHH !E5&&5FEEEEEEEF5</#4@??@@@C4444444##DD//0<&F! HRaaRaJIH !F/D/0<///4BLLBBK?@@C44#^/<<0^#4444D/5EF5/D44444@KL++LBB@@4#^05E-HRVVVtaaJatPQPPR -F0/^/00/4L::::::::::::::9)9LK@4D0&5FEEEEEE"! HHH F55FEEEEF5&<</#4@??@?@@@CCC444443##D/F! HJaRaaJH !F/D/0//#?LLLBBKK?@@44 DD/<&&&<0D#444D/&FFF&0/#4444@KL++LBBK@C4D/<&F JtVtaJHtPPPtH-F&/D#D/0D?9:77::::::::::::9)B@C#/0&5FFFFFFEE"! H -E5&<<5EEEEEF5&<0D3C@??@?@@@@@@@@@@C44#D0F! HJJaRaJH -F/D/00/0/CKLLLLBBKK??@C44#D//0<&5F55&0/D##D/05FF5/D#434C?BLLLBK?@C4#/05E! HaV{PPPta HaPPRF&</D##D/^4B)7777::::::::::9)K@4/05FFFFF5FFEE"! -F5&EEEEEE5&0/#4@@??@@@@@@@@??@@@C4#/F! IJRaRaIH !-F/D/00/&#@BBBBBKKK?@@444#D//<&5FEEEF&//^D/0<&5F5/D##44@?BKLLLBBBK?@C4#D05E-Hat{PQQQPa a{IF&/D344#D#@L:77777:::::::::9)LK4D0&&55F555555FEE"-!!-E5&<&EEEEE5&0/#4C@@@@@@@@??@???@@@4#/F IJRaRaJH -F&0D/00/5&