2906 lines
97 KiB
C
2906 lines
97 KiB
C
/*
|
|
** 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$
|
|
** $Log:
|
|
** 34 GlideXP 1.26.1 12/14/01 Ryan Nunn Removed calls to
|
|
** MultitextureAndTrilinear(). That will now be called by g3LodBiasPerChip()
|
|
** 34 ve3d 1.26 06/24/02 KoolSmoky fixes for 4chip napalm
|
|
** 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 <glidesys.h>
|
|
|
|
#define FX_DLL_DEFINITION
|
|
#include <fxdll.h>
|
|
#include <glide.h>
|
|
|
|
#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:
|
|
-------------------------------------------------------------------*/
|
|
#if defined(__linux__) || defined(__WIN32__)
|
|
GR_EXT_ENTRY(grStipplePattern, void , (GrStipplePattern_t stipple))
|
|
{
|
|
#define FN_NAME "grStipplePattern"
|
|
|
|
GR_BEGIN_NOFIFOCHECK("grStippleMode\n", 85);
|
|
|
|
INVALIDATE(stipple);
|
|
|
|
STOREARG(grStipplePattern, stipple);
|
|
|
|
#undef FN_NAME
|
|
} /* grStipplePattern */
|
|
#endif /* __linux__ __WIN32__ */
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
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:
|
|
-------------------------------------------------------------------*/
|
|
#if defined(__linux__) || defined(__WIN32__)
|
|
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 */
|
|
#endif /* __linux__ || __WIN32__*/
|
|
|
|
/*-------------------------------------------------------------------
|
|
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));
|
|
#if defined(__linux__) || defined(__WIN32__)
|
|
_grStippleMode(LOADARG(grStippleMode, mode));
|
|
#endif /* __linux__ __WIN32__*/
|
|
_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 defined(__linux__) || defined(__WIN32__)
|
|
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();
|
|
}
|
|
#endif /* __linux__ __WIN32__ */
|
|
|
|
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 __linux__
|
|
void
|
|
_grInvalidateAll()
|
|
{
|
|
GR_DCL_GC;
|
|
|
|
grGlideSetState(&gc->state);
|
|
}
|
|
#endif /* defined(__linux__) */
|
|
|
|
#endif /* GLIDE3 */
|