2009-07-28 21:32:10 +00:00
// Copyright (C) 2003 Dolphin Project.
2008-12-08 05:25:12 +00:00
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
# include <cmath>
2009-05-13 23:37:26 +00:00
# include "Common.h"
2008-12-08 05:25:12 +00:00
# include "Statistics.h"
# include "PixelShaderManager.h"
2008-12-26 12:47:32 +00:00
# include "VideoCommon.h"
2009-12-09 13:51:28 +00:00
# include "VideoConfig.h"
2011-01-31 01:28:32 +00:00
2011-01-29 04:31:56 +00:00
# include "RenderBase.h"
2008-12-08 05:25:12 +00:00
static int s_nColorsChanged [ 2 ] ; // 0 - regular colors, 1 - k colors
2009-08-31 20:58:57 +00:00
static int s_nIndTexMtxChanged ;
2008-12-25 21:44:56 +00:00
static bool s_bAlphaChanged ;
static bool s_bZBiasChanged ;
2009-02-08 22:08:20 +00:00
static bool s_bZTextureTypeChanged ;
static bool s_bDepthRangeChanged ;
2009-02-19 04:41:58 +00:00
static bool s_bFogColorChanged ;
static bool s_bFogParamChanged ;
2011-01-29 04:31:56 +00:00
static bool s_bFogRangeAdjustChanged ;
2010-09-23 02:17:48 +00:00
static int nLightsChanged [ 2 ] ; // min,max
2008-12-08 05:25:12 +00:00
static float lastRGBAfull [ 2 ] [ 4 ] [ 4 ] ;
static u8 s_nTexDimsChanged ;
2009-04-15 03:55:38 +00:00
static u8 s_nIndTexScaleChanged ;
2009-08-31 20:58:57 +00:00
static u32 lastAlpha ;
static u32 lastTexDims [ 8 ] ; // width | height << 16 | wrap_s << 28 | wrap_t << 30
static u32 lastZBias ;
2010-09-23 02:17:48 +00:00
static int nMaterialsChanged ;
2008-12-08 05:25:12 +00:00
2011-01-31 01:28:32 +00:00
inline void SetPSConstant4f ( unsigned int const_number , float f1 , float f2 , float f3 , float f4 )
{
g_renderer - > SetPSConstant4f ( const_number , f1 , f2 , f3 , f4 ) ;
}
inline void SetPSConstant4fv ( unsigned int const_number , const float * f )
{
g_renderer - > SetPSConstant4fv ( const_number , f ) ;
}
inline void SetMultiPSConstant4fv ( unsigned int const_number , unsigned int count , const float * f )
{
g_renderer - > SetMultiPSConstant4fv ( const_number , count , f ) ;
}
2008-12-26 10:43:18 +00:00
void PixelShaderManager : : Init ( )
{
2009-08-31 20:58:57 +00:00
lastAlpha = 0 ;
memset ( lastTexDims , 0 , sizeof ( lastTexDims ) ) ;
lastZBias = 0 ;
2009-09-15 21:49:15 +00:00
memset ( lastRGBAfull , 0 , sizeof ( lastRGBAfull ) ) ;
Dirty ( ) ;
}
void PixelShaderManager : : Dirty ( )
{
s_nColorsChanged [ 0 ] = s_nColorsChanged [ 1 ] = 15 ;
2010-08-30 04:05:06 +00:00
s_nTexDimsChanged = 0xFF ;
s_nIndTexScaleChanged = 0xFF ;
2009-09-15 21:49:15 +00:00
s_nIndTexMtxChanged = 15 ;
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true ;
2011-01-29 04:31:56 +00:00
s_bFogRangeAdjustChanged = s_bFogColorChanged = s_bFogParamChanged = true ;
2010-09-23 02:17:48 +00:00
nLightsChanged [ 0 ] = 0 ; nLightsChanged [ 1 ] = 0x80 ;
nMaterialsChanged = 15 ;
2008-12-26 10:43:18 +00:00
}
void PixelShaderManager : : Shutdown ( )
{
}
2012-03-24 03:47:28 +00:00
void PixelShaderManager : : SetConstants ( )
2008-12-08 05:25:12 +00:00
{
2011-06-20 05:48:12 +00:00
for ( int i = 0 ; i < 2 ; + + i )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
if ( s_nColorsChanged [ i ] )
2009-05-13 23:37:26 +00:00
{
2008-12-08 05:25:12 +00:00
int baseind = i ? C_KCOLORS : C_COLORS ;
2011-06-20 05:48:12 +00:00
for ( int j = 0 ; j < 4 ; + + j )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
if ( s_nColorsChanged [ i ] & ( 1 < < j ) )
2008-12-08 05:25:12 +00:00
SetPSConstant4fv ( baseind + j , & lastRGBAfull [ i ] [ j ] [ 0 ] ) ;
}
s_nColorsChanged [ i ] = 0 ;
}
}
2011-06-20 05:48:12 +00:00
if ( s_nTexDimsChanged )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
for ( int i = 0 ; i < 8 ; + + i )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
if ( s_nTexDimsChanged & ( 1 < < i ) )
SetPSTextureDims ( i ) ;
2008-12-08 05:25:12 +00:00
}
s_nTexDimsChanged = 0 ;
}
2011-06-20 05:48:12 +00:00
if ( s_bAlphaChanged )
2009-05-13 23:37:26 +00:00
{
2011-01-31 01:28:32 +00:00
SetPSConstant4f ( C_ALPHA , ( lastAlpha & 0xff ) / 255.0f , ( ( lastAlpha > > 8 ) & 0xff ) / 255.0f , 0 , ( ( lastAlpha > > 16 ) & 0xff ) / 255.0f ) ;
2009-02-08 22:08:20 +00:00
s_bAlphaChanged = false ;
2008-12-08 05:25:12 +00:00
}
2011-06-20 05:48:12 +00:00
if ( s_bZTextureTypeChanged )
{
2008-12-08 05:25:12 +00:00
float ftemp [ 4 ] ;
2011-06-20 05:48:12 +00:00
switch ( bpmem . ztex2 . type )
2009-05-13 23:37:26 +00:00
{
2009-10-31 13:40:53 +00:00
case 0 :
2011-06-20 05:48:12 +00:00
// 8 bits
2009-11-21 02:49:46 +00:00
ftemp [ 0 ] = 0 ; ftemp [ 1 ] = 0 ; ftemp [ 2 ] = 0 ; ftemp [ 3 ] = 255.0f / 16777215.0f ;
2008-12-08 05:25:12 +00:00
break ;
case 1 :
2009-02-08 22:08:20 +00:00
// 16 bits
2009-11-21 02:49:46 +00:00
ftemp [ 0 ] = 255.0f / 16777215.0f ; ftemp [ 1 ] = 0 ; ftemp [ 2 ] = 0 ; ftemp [ 3 ] = 65280.0f / 16777215.0f ;
2008-12-08 05:25:12 +00:00
break ;
case 2 :
2009-02-08 22:08:20 +00:00
// 24 bits
2009-11-21 02:49:46 +00:00
ftemp [ 0 ] = 16711680.0f / 16777215.0f ; ftemp [ 1 ] = 65280.0f / 16777215.0f ; ftemp [ 2 ] = 255.0f / 16777215.0f ; ftemp [ 3 ] = 0 ;
2008-12-08 05:25:12 +00:00
break ;
}
2009-02-08 22:08:20 +00:00
SetPSConstant4fv ( C_ZBIAS , ftemp ) ;
s_bZTextureTypeChanged = false ;
}
2011-06-20 05:48:12 +00:00
if ( s_bZBiasChanged | | s_bDepthRangeChanged )
2009-05-13 23:37:26 +00:00
{
2011-02-05 18:25:34 +00:00
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
// [0] = width/2
// [1] = height/2
// [2] = 16777215 * (farz - nearz)
// [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342
// [5] = 16777215 * farz
//ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias);
2011-04-11 01:49:32 +00:00
SetPSConstant4f ( C_ZBIAS + 1 , xfregs . viewport . farZ / 16777216.0f , xfregs . viewport . zRange / 16777216.0f , 0 , ( float ) ( lastZBias ) / 16777215.0f ) ;
2009-02-08 22:08:20 +00:00
s_bZBiasChanged = s_bDepthRangeChanged = false ;
2008-12-08 05:25:12 +00:00
}
2009-04-15 03:55:38 +00:00
// indirect incoming texture scales
2011-06-20 05:48:12 +00:00
if ( s_nIndTexScaleChanged )
2009-05-13 23:37:26 +00:00
{
2008-12-08 05:25:12 +00:00
// set as two sets of vec4s, each containing S and T of two ind stages.
float f [ 8 ] ;
2011-06-20 05:48:12 +00:00
if ( s_nIndTexScaleChanged & 0x03 )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
for ( u32 i = 0 ; i < 2 ; + + i )
2009-05-13 23:37:26 +00:00
{
2009-06-22 09:31:30 +00:00
f [ 2 * i ] = bpmem . texscale [ 0 ] . getScaleS ( i & 1 ) ;
f [ 2 * i + 1 ] = bpmem . texscale [ 0 ] . getScaleT ( i & 1 ) ;
2009-05-13 23:37:26 +00:00
PRIM_LOG ( " tex indscale%d: %f %f \n " , i , f [ 2 * i ] , f [ 2 * i + 1 ] ) ;
2009-04-15 03:55:38 +00:00
}
2011-01-31 01:28:32 +00:00
SetPSConstant4fv ( C_INDTEXSCALE , f ) ;
2008-12-08 05:25:12 +00:00
}
2009-04-15 03:55:38 +00:00
if ( s_nIndTexScaleChanged & 0x0c ) {
for ( u32 i = 2 ; i < 4 ; + + i ) {
2009-06-22 09:31:30 +00:00
f [ 2 * i ] = bpmem . texscale [ 1 ] . getScaleS ( i & 1 ) ;
f [ 2 * i + 1 ] = bpmem . texscale [ 1 ] . getScaleT ( i & 1 ) ;
2009-05-13 23:37:26 +00:00
PRIM_LOG ( " tex indscale%d: %f %f \n " , i , f [ 2 * i ] , f [ 2 * i + 1 ] ) ;
2011-06-20 05:48:12 +00:00
}
2011-01-31 01:28:32 +00:00
SetPSConstant4fv ( C_INDTEXSCALE + 1 , & f [ 4 ] ) ;
2009-04-15 03:55:38 +00:00
}
2011-06-20 05:48:12 +00:00
2009-04-15 03:55:38 +00:00
s_nIndTexScaleChanged = 0 ;
2008-12-08 05:25:12 +00:00
}
2011-06-20 05:48:12 +00:00
if ( s_nIndTexMtxChanged )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
for ( int i = 0 ; i < 3 ; + + i )
2009-05-13 23:37:26 +00:00
{
2011-06-20 05:48:12 +00:00
if ( s_nIndTexMtxChanged & ( 1 < < i ) )
2009-05-13 23:37:26 +00:00
{
2009-06-22 09:31:30 +00:00
int scale = ( ( u32 ) bpmem . indmtx [ i ] . col0 . s0 < < 0 ) |
( ( u32 ) bpmem . indmtx [ i ] . col1 . s1 < < 2 ) |
( ( u32 ) bpmem . indmtx [ i ] . col2 . s2 < < 4 ) ;
2008-12-08 05:25:12 +00:00
float fscale = powf ( 2.0f , ( float ) ( scale - 17 ) ) / 1024.0f ;
// xyz - static matrix
2009-05-13 23:37:26 +00:00
// TODO w - dynamic matrix scale / 256...... somehow / 4 works better
2009-04-15 03:55:38 +00:00
// rev 2972 - now using / 256.... verify that this works
2011-01-31 01:28:32 +00:00
SetPSConstant4f ( C_INDTEXMTX + 2 * i ,
2009-06-22 09:31:30 +00:00
bpmem . indmtx [ i ] . col0 . ma * fscale ,
bpmem . indmtx [ i ] . col1 . mc * fscale ,
bpmem . indmtx [ i ] . col2 . me * fscale ,
2009-04-15 03:55:38 +00:00
fscale * 4.0f ) ;
2009-05-13 23:37:26 +00:00
SetPSConstant4f ( C_INDTEXMTX + 2 * i + 1 ,
2009-06-22 09:31:30 +00:00
bpmem . indmtx [ i ] . col0 . mb * fscale ,
bpmem . indmtx [ i ] . col1 . md * fscale ,
bpmem . indmtx [ i ] . col2 . mf * fscale ,
2009-04-15 03:55:38 +00:00
fscale * 4.0f ) ;
2008-12-08 05:25:12 +00:00
2010-12-05 09:04:34 +00:00
PRIM_LOG ( " indmtx%d: scale=%f, mat=(%f %f %f; %f %f %f) \n " ,
i , 1024.0f * fscale ,
bpmem . indmtx [ i ] . col0 . ma * fscale , bpmem . indmtx [ i ] . col1 . mc * fscale , bpmem . indmtx [ i ] . col2 . me * fscale ,
bpmem . indmtx [ i ] . col0 . mb * fscale , bpmem . indmtx [ i ] . col1 . md * fscale , bpmem . indmtx [ i ] . col2 . mf * fscale ) ;
2008-12-08 05:25:12 +00:00
}
}
s_nIndTexMtxChanged = 0 ;
}
2009-02-19 04:41:58 +00:00
2011-06-20 05:48:12 +00:00
if ( s_bFogColorChanged )
2009-05-13 23:37:26 +00:00
{
2011-01-31 01:28:32 +00:00
SetPSConstant4f ( C_FOG , bpmem . fog . color . r / 255.0f , bpmem . fog . color . g / 255.0f , bpmem . fog . color . b / 255.0f , 0 ) ;
s_bFogColorChanged = false ;
2009-02-19 04:41:58 +00:00
}
2011-06-20 05:48:12 +00:00
if ( s_bFogParamChanged )
2009-05-13 23:37:26 +00:00
{
2009-12-09 13:51:28 +00:00
if ( ! g_ActiveConfig . bDisableFog )
{
2010-11-23 13:57:01 +00:00
//downscale magnitude to 0.24 bits
float b = ( float ) bpmem . fog . b_magnitude / 0xFFFFFF ;
float b_shf = ( float ) ( 1 < < bpmem . fog . b_shift ) ;
SetPSConstant4f ( C_FOG + 1 , bpmem . fog . a . GetA ( ) , b , bpmem . fog . c_proj_fsel . GetC ( ) , b_shf ) ;
2009-12-09 13:51:28 +00:00
}
else
2010-12-18 18:23:22 +00:00
SetPSConstant4f ( C_FOG + 1 , 0.0 , 1.0 , 0.0 , 1.0 ) ;
2011-06-20 05:48:12 +00:00
2009-02-19 04:41:58 +00:00
s_bFogParamChanged = false ;
}
2010-09-23 02:17:48 +00:00
2011-01-29 04:31:56 +00:00
if ( s_bFogRangeAdjustChanged )
{
if ( ! g_ActiveConfig . bDisableFog & & bpmem . fogRange . Base . Enabled = = 1 )
{
//bpmem.fogRange.Base.Center : center of the viewport in x axis. observation: bpmem.fogRange.Base.Center = realcenter + 342;
int center = ( ( u32 ) bpmem . fogRange . Base . Center ) - 342 ;
// normalice center to make calculations easy
2011-04-11 01:49:32 +00:00
float ScreenSpaceCenter = center / ( 2.0f * xfregs . viewport . wd ) ;
2011-01-29 04:31:56 +00:00
ScreenSpaceCenter = ( ScreenSpaceCenter * 2.0f ) - 1.0f ;
//bpmem.fogRange.K seems to be a table of precalculated coeficients for the adjust factor
//observations: bpmem.fogRange.K[0].LO apears to be the lowest value and bpmem.fogRange.K[4].HI the largest
// they always seems to be larger than 256 so my teory is :
// they are the coeficients from the center to th e border of the screen
// so to simplify i use the hi coeficient as K in the shader taking 256 as the scale
2011-04-11 01:49:32 +00:00
SetPSConstant4f ( C_FOG + 2 , ScreenSpaceCenter , ( float ) Renderer : : EFBToScaledX ( ( int ) ( 2.0f * xfregs . viewport . wd ) ) , bpmem . fogRange . K [ 4 ] . HI / 256.0f , 0.0f ) ;
2011-06-20 05:48:12 +00:00
}
else
SetPSConstant4f ( C_FOG + 2 , 0.0f , 1.0f , 1.0f , 0.0f ) ; // Need to update these values for older hardware that fails to divide by zero in shaders.
2011-01-29 04:31:56 +00:00
s_bFogRangeAdjustChanged = false ;
}
2011-03-19 00:50:34 +00:00
if ( g_ActiveConfig . bEnablePixelLighting & & g_ActiveConfig . backend_info . bSupportsPixelLighting ) // config check added because the code in here was crashing for me inside SetPSConstant4f
2010-09-23 02:17:48 +00:00
{
2011-02-05 18:25:34 +00:00
if ( nLightsChanged [ 0 ] > = 0 )
2010-09-23 02:17:48 +00:00
{
2011-02-05 18:25:34 +00:00
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
int istart = nLightsChanged [ 0 ] / 0x10 ;
int iend = ( nLightsChanged [ 1 ] + 15 ) / 0x10 ;
const float * xfmemptr = ( const float * ) & xfmem [ 0x10 * istart + XFMEM_LIGHTS ] ;
for ( int i = istart ; i < iend ; + + i )
2010-09-23 02:17:48 +00:00
{
2011-02-05 18:25:34 +00:00
u32 color = * ( const u32 * ) ( xfmemptr + 3 ) ;
float NormalizationCoef = 1 / 255.0f ;
SetPSConstant4f ( C_PLIGHTS + 5 * i ,
( ( color > > 24 ) & 0xFF ) * NormalizationCoef ,
( ( color > > 16 ) & 0xFF ) * NormalizationCoef ,
( ( color > > 8 ) & 0xFF ) * NormalizationCoef ,
( ( color ) & 0xFF ) * NormalizationCoef ) ;
xfmemptr + = 4 ;
for ( int j = 0 ; j < 4 ; + + j , xfmemptr + = 3 )
2010-09-23 02:17:48 +00:00
{
2011-02-05 18:25:34 +00:00
if ( j = = 1 & &
fabs ( xfmemptr [ 0 ] ) < 0.00001f & &
fabs ( xfmemptr [ 1 ] ) < 0.00001f & &
fabs ( xfmemptr [ 2 ] ) < 0.00001f )
{
// dist attenuation, make sure not equal to 0!!!
SetPSConstant4f ( C_PLIGHTS + 5 * i + j + 1 , 0.00001f , xfmemptr [ 1 ] , xfmemptr [ 2 ] , 0 ) ;
}
else
SetPSConstant4fv ( C_PLIGHTS + 5 * i + j + 1 , xfmemptr ) ;
2010-09-23 02:17:48 +00:00
}
}
2011-02-05 18:25:34 +00:00
nLightsChanged [ 0 ] = nLightsChanged [ 1 ] = - 1 ;
2010-09-23 02:17:48 +00:00
}
2011-02-05 18:25:34 +00:00
if ( nMaterialsChanged )
{
float GC_ALIGNED16 ( material [ 4 ] ) ;
float NormalizationCoef = 1 / 255.0f ;
for ( int i = 0 ; i < 4 ; + + i )
{
if ( nMaterialsChanged & ( 1 < < i ) )
{
u32 data = * ( xfregs . ambColor + i ) ;
2010-09-23 02:17:48 +00:00
2011-02-05 18:25:34 +00:00
material [ 0 ] = ( ( data > > 24 ) & 0xFF ) * NormalizationCoef ;
material [ 1 ] = ( ( data > > 16 ) & 0xFF ) * NormalizationCoef ;
material [ 2 ] = ( ( data > > 8 ) & 0xFF ) * NormalizationCoef ;
material [ 3 ] = ( data & 0xFF ) * NormalizationCoef ;
SetPSConstant4fv ( C_PMATERIALS + i , material ) ;
}
}
nMaterialsChanged = 0 ;
}
2010-09-23 02:17:48 +00:00
}
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void PixelShaderManager : : SetPSTextureDims ( int texid )
2008-12-08 05:25:12 +00:00
{
2010-08-29 19:34:54 +00:00
// texdims.xy are reciprocals of the real texture dimensions
// texdims.zw are the scaled dimensions
2009-04-15 03:55:38 +00:00
float fdims [ 4 ] ;
2010-08-29 19:34:54 +00:00
TCoordInfo & tc = bpmem . texcoords [ texid ] ;
fdims [ 0 ] = 1.0f / ( float ) ( lastTexDims [ texid ] & 0xffff ) ;
fdims [ 1 ] = 1.0f / ( float ) ( ( lastTexDims [ texid ] > > 16 ) & 0xfff ) ;
2010-08-30 04:05:06 +00:00
fdims [ 2 ] = ( float ) ( tc . s . scale_minus_1 + 1 ) ;
fdims [ 3 ] = ( float ) ( tc . t . scale_minus_1 + 1 ) ;
2008-12-08 05:25:12 +00:00
PRIM_LOG ( " texdims%d: %f %f %f %f \n " , texid , fdims [ 0 ] , fdims [ 1 ] , fdims [ 2 ] , fdims [ 3 ] ) ;
SetPSConstant4fv ( C_TEXDIMS + texid , fdims ) ;
}
2009-08-31 20:58:57 +00:00
// This one is high in profiles (0.5%). TODO: Move conversion out, only store the raw color value
// and update it when the shader constant is set, only.
2011-07-04 13:49:40 +00:00
void PixelShaderManager : : SetColorChanged ( int type , int num , bool high )
2008-12-08 05:25:12 +00:00
{
float * pf = & lastRGBAfull [ type ] [ num ] [ 0 ] ;
2011-07-04 13:49:40 +00:00
if ( ! high ) {
int r = bpmem . tevregs [ num ] . low . a ;
int a = bpmem . tevregs [ num ] . low . b ;
pf [ 0 ] = ( float ) r * ( 1.0f / 255.0f ) ;
pf [ 3 ] = ( float ) a * ( 1.0f / 255.0f ) ;
} else {
int b = bpmem . tevregs [ num ] . high . a ;
int g = bpmem . tevregs [ num ] . high . b ;
pf [ 1 ] = ( float ) g * ( 1.0f / 255.0f ) ;
pf [ 2 ] = ( float ) b * ( 1.0f / 255.0f ) ;
}
2008-12-08 05:25:12 +00:00
s_nColorsChanged [ type ] | = 1 < < num ;
PRIM_LOG ( " pixel %scolor%d: %f %f %f %f \n " , type ? " k " : " " , num , pf [ 0 ] , pf [ 1 ] , pf [ 2 ] , pf [ 3 ] ) ;
}
2008-12-26 10:43:18 +00:00
void PixelShaderManager : : SetAlpha ( const AlphaFunc & alpha )
2008-12-08 05:25:12 +00:00
{
2009-05-13 23:37:26 +00:00
if ( ( alpha . hex & 0xffff ) ! = lastAlpha )
{
2008-12-08 05:25:12 +00:00
lastAlpha = ( lastAlpha & ~ 0xffff ) | ( alpha . hex & 0xffff ) ;
s_bAlphaChanged = true ;
}
}
2008-12-26 10:43:18 +00:00
void PixelShaderManager : : SetDestAlpha ( const ConstantAlpha & alpha )
2008-12-08 05:25:12 +00:00
{
2009-05-13 23:37:26 +00:00
if ( alpha . alpha ! = ( lastAlpha > > 16 ) )
{
2008-12-08 05:25:12 +00:00
lastAlpha = ( lastAlpha & ~ 0xff0000 ) | ( ( alpha . hex & 0xff ) < < 16 ) ;
s_bAlphaChanged = true ;
}
}
2012-03-24 03:47:28 +00:00
void PixelShaderManager : : SetTexDims ( int texmapid , u32 width , u32 height , u32 wraps , u32 wrapt )
2008-12-08 05:25:12 +00:00
{
u32 wh = width | ( height < < 16 ) | ( wraps < < 28 ) | ( wrapt < < 30 ) ;
2012-03-24 03:47:28 +00:00
if ( lastTexDims [ texmapid ] ! = wh )
2009-05-13 23:37:26 +00:00
{
2012-03-24 03:47:28 +00:00
lastTexDims [ texmapid ] = wh ;
2011-06-20 05:48:12 +00:00
s_nTexDimsChanged | = 1 < < texmapid ;
2012-03-24 03:47:28 +00:00
}
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void PixelShaderManager : : SetZTextureBias ( u32 bias )
2008-12-08 05:25:12 +00:00
{
2009-05-13 23:37:26 +00:00
if ( lastZBias ! = bias )
{
2008-12-08 05:25:12 +00:00
s_bZBiasChanged = true ;
lastZBias = bias ;
}
}
2011-02-05 18:25:34 +00:00
void PixelShaderManager : : SetViewportChanged ( )
2009-02-08 22:08:20 +00:00
{
2011-02-05 18:25:34 +00:00
s_bDepthRangeChanged = true ;
2009-10-25 23:10:30 +00:00
}
2009-04-15 03:55:38 +00:00
void PixelShaderManager : : SetIndTexScaleChanged ( u8 stagemask )
2008-12-08 05:25:12 +00:00
{
2009-04-15 03:55:38 +00:00
s_nIndTexScaleChanged | = stagemask ;
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void PixelShaderManager : : SetIndMatrixChanged ( int matrixidx )
2008-12-08 05:25:12 +00:00
{
s_nIndTexMtxChanged | = 1 < < matrixidx ;
}
2009-08-31 20:58:57 +00:00
2009-02-08 22:08:20 +00:00
void PixelShaderManager : : SetZTextureTypeChanged ( )
{
s_bZTextureTypeChanged = true ;
2008-12-08 05:25:12 +00:00
}
2009-04-15 03:55:38 +00:00
void PixelShaderManager : : SetTexCoordChanged ( u8 texmapid )
2008-12-08 05:25:12 +00:00
{
2009-04-15 03:55:38 +00:00
s_nTexDimsChanged | = 1 < < texmapid ;
2008-12-08 05:25:12 +00:00
}
2009-02-19 04:41:58 +00:00
void PixelShaderManager : : SetFogColorChanged ( )
{
s_bFogColorChanged = true ;
}
void PixelShaderManager : : SetFogParamChanged ( )
{
s_bFogParamChanged = true ;
}
2011-01-29 04:31:56 +00:00
void PixelShaderManager : : SetFogRangeAdjustChanged ( )
{
s_bFogRangeAdjustChanged = true ;
}
2011-01-07 19:23:57 +00:00
void PixelShaderManager : : SetColorMatrix ( const float * pmatrix )
2008-12-08 05:25:12 +00:00
{
2011-01-07 19:23:57 +00:00
SetMultiPSConstant4fv ( C_COLORMATRIX , 7 , pmatrix ) ;
s_nColorsChanged [ 0 ] = s_nColorsChanged [ 1 ] = 15 ;
2008-12-08 05:25:12 +00:00
}
2010-09-23 02:17:48 +00:00
void PixelShaderManager : : InvalidateXFRange ( int start , int end )
{
if ( start < XFMEM_LIGHTS_END & & end > XFMEM_LIGHTS )
{
int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start - XFMEM_LIGHTS ;
int _end = end < XFMEM_LIGHTS_END ? end - XFMEM_LIGHTS : XFMEM_LIGHTS_END - XFMEM_LIGHTS ;
if ( nLightsChanged [ 0 ] = = - 1 )
{
nLightsChanged [ 0 ] = _start ;
nLightsChanged [ 1 ] = _end ;
}
else
{
if ( nLightsChanged [ 0 ] > _start ) nLightsChanged [ 0 ] = _start ;
if ( nLightsChanged [ 1 ] < _end ) nLightsChanged [ 1 ] = _end ;
}
}
}
2011-02-05 18:25:34 +00:00
void PixelShaderManager : : SetMaterialColorChanged ( int index )
2010-09-23 02:17:48 +00:00
{
nMaterialsChanged | = ( 1 < < index ) ;
}
2012-01-01 20:46:02 +00:00
2012-08-05 23:29:01 +00:00
ALPHA_PRETEST_RESULT PixelShaderManager : : AlphaPreTest ( )
{
u32 op = bpmem . alphaFunc . logic ;
u32 comp [ 2 ] = { bpmem . alphaFunc . comp0 , bpmem . alphaFunc . comp1 } ;
// First kill all the simple cases
switch ( op )
{
case 0 : // AND
if ( comp [ 0 ] = = ALPHACMP_ALWAYS & & comp [ 1 ] = = ALPHACMP_ALWAYS ) return ALPHAPT_ALWAYSPASS ;
if ( comp [ 0 ] = = ALPHACMP_NEVER | | comp [ 1 ] = = ALPHACMP_NEVER ) return ALPHAPT_ALWAYSFAIL ;
break ;
case 1 : // OR
if ( comp [ 0 ] = = ALPHACMP_ALWAYS | | comp [ 1 ] = = ALPHACMP_ALWAYS ) return ALPHAPT_ALWAYSPASS ;
if ( comp [ 0 ] = = ALPHACMP_NEVER & & comp [ 1 ] = = ALPHACMP_NEVER ) return ALPHAPT_ALWAYSFAIL ;
break ;
case 2 : // XOR
if ( ( comp [ 0 ] = = ALPHACMP_ALWAYS & & comp [ 1 ] = = ALPHACMP_NEVER ) | | ( comp [ 0 ] = = ALPHACMP_NEVER & & comp [ 1 ] = = ALPHACMP_ALWAYS ) )
return ALPHAPT_ALWAYSPASS ;
if ( ( comp [ 0 ] = = ALPHACMP_ALWAYS & & comp [ 1 ] = = ALPHACMP_ALWAYS ) | | ( comp [ 0 ] = = ALPHACMP_NEVER & & comp [ 1 ] = = ALPHACMP_NEVER ) )
return ALPHAPT_ALWAYSFAIL ;
break ;
case 3 : // XNOR
if ( ( comp [ 0 ] = = ALPHACMP_ALWAYS & & comp [ 1 ] = = ALPHACMP_NEVER ) | | ( comp [ 0 ] = = ALPHACMP_NEVER & & comp [ 1 ] = = ALPHACMP_ALWAYS ) )
return ALPHAPT_ALWAYSFAIL ;
if ( ( comp [ 0 ] = = ALPHACMP_ALWAYS & & comp [ 1 ] = = ALPHACMP_ALWAYS ) | | ( comp [ 0 ] = = ALPHACMP_NEVER & & comp [ 1 ] = = ALPHACMP_NEVER ) )
return ALPHAPT_ALWAYSPASS ;
break ;
default : PanicAlert ( " bad logic for alpha test? %08x " , op ) ;
}
return ALPHAPT_UNDEFINED ;
}
2012-01-01 20:46:02 +00:00
void PixelShaderManager : : DoState ( PointerWrap & p )
{
p . Do ( lastRGBAfull ) ;
p . Do ( lastAlpha ) ;
p . Do ( lastTexDims ) ;
p . Do ( lastZBias ) ;
if ( p . GetMode ( ) = = PointerWrap : : MODE_READ )
{
Dirty ( ) ;
}
}