2013-04-17 21:09:55 -06:00
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
2008-12-07 22:25:12 -07:00
# include <cmath>
2009-05-13 17:37:26 -06:00
# include "Common.h"
2008-12-07 22:25:12 -07:00
# include "Statistics.h"
# include "PixelShaderManager.h"
2008-12-26 05:47:32 -07:00
# include "VideoCommon.h"
2009-12-09 06:51:28 -07:00
# include "VideoConfig.h"
2011-01-30 18:28:32 -07:00
2011-01-28 21:31:56 -07:00
# include "RenderBase.h"
2008-12-07 22:25:12 -07:00
static int s_nColorsChanged [ 2 ] ; // 0 - regular colors, 1 - k colors
2009-08-31 14:58:57 -06:00
static int s_nIndTexMtxChanged ;
2008-12-25 14:44:56 -07:00
static bool s_bAlphaChanged ;
static bool s_bZBiasChanged ;
2009-02-08 15:08:20 -07:00
static bool s_bZTextureTypeChanged ;
static bool s_bDepthRangeChanged ;
2009-02-18 21:41:58 -07:00
static bool s_bFogColorChanged ;
static bool s_bFogParamChanged ;
2011-01-28 21:31:56 -07:00
static bool s_bFogRangeAdjustChanged ;
2010-09-22 20:17:48 -06:00
static int nLightsChanged [ 2 ] ; // min,max
2008-12-07 22:25:12 -07:00
static float lastRGBAfull [ 2 ] [ 4 ] [ 4 ] ;
static u8 s_nTexDimsChanged ;
2009-04-14 21:55:38 -06:00
static u8 s_nIndTexScaleChanged ;
2009-08-31 14:58:57 -06:00
static u32 lastAlpha ;
static u32 lastTexDims [ 8 ] ; // width | height << 16 | wrap_s << 28 | wrap_t << 30
static u32 lastZBias ;
2010-09-22 20:17:48 -06:00
static int nMaterialsChanged ;
2008-12-07 22:25:12 -07:00
2013-10-07 08:02:24 -06:00
PixelShaderConstants PixelShaderManager : : constants ;
bool PixelShaderManager : : dirty ;
2011-01-30 18:28:32 -07:00
inline void SetPSConstant4f ( unsigned int const_number , float f1 , float f2 , float f3 , float f4 )
{
2013-10-07 08:02:24 -06:00
float4 * c = ( float4 * ) & PixelShaderManager : : constants ;
c [ const_number ] [ 0 ] = f1 ;
c [ const_number ] [ 1 ] = f2 ;
c [ const_number ] [ 2 ] = f3 ;
c [ const_number ] [ 3 ] = f4 ;
PixelShaderManager : : dirty = true ;
2011-01-30 18:28:32 -07:00
}
inline void SetPSConstant4fv ( unsigned int const_number , const float * f )
{
2013-10-07 08:02:24 -06:00
float4 * c = ( float4 * ) & PixelShaderManager : : constants ;
c [ const_number ] [ 0 ] = f [ 0 ] ;
c [ const_number ] [ 1 ] = f [ 1 ] ;
c [ const_number ] [ 2 ] = f [ 2 ] ;
c [ const_number ] [ 3 ] = f [ 3 ] ;
PixelShaderManager : : dirty = true ;
2011-01-30 18:28:32 -07:00
}
inline void SetMultiPSConstant4fv ( unsigned int const_number , unsigned int count , const float * f )
{
2013-10-07 08:02:24 -06:00
float4 * c = ( float4 * ) & PixelShaderManager : : constants ;
for ( u32 i = 0 ; i < count ; i + + )
{
c [ const_number + i ] [ 0 ] = f [ 0 + 4 * i ] ;
c [ const_number + i ] [ 1 ] = f [ 1 + 4 * i ] ;
c [ const_number + i ] [ 2 ] = f [ 2 + 4 * i ] ;
c [ const_number + i ] [ 3 ] = f [ 3 + 4 * i ] ;
}
PixelShaderManager : : dirty = true ;
2011-01-30 18:28:32 -07:00
}
2008-12-26 03:43:18 -07:00
void PixelShaderManager : : Init ( )
{
2009-08-31 14:58:57 -06:00
lastAlpha = 0 ;
memset ( lastTexDims , 0 , sizeof ( lastTexDims ) ) ;
lastZBias = 0 ;
2009-09-15 15:49:15 -06:00
memset ( lastRGBAfull , 0 , sizeof ( lastRGBAfull ) ) ;
2013-10-07 08:02:24 -06:00
memset ( & constants , 0 , sizeof ( constants ) ) ;
2009-09-15 15:49:15 -06:00
Dirty ( ) ;
}
void PixelShaderManager : : Dirty ( )
{
s_nColorsChanged [ 0 ] = s_nColorsChanged [ 1 ] = 15 ;
2010-08-29 22:05:06 -06:00
s_nTexDimsChanged = 0xFF ;
s_nIndTexScaleChanged = 0xFF ;
2009-09-15 15:49:15 -06:00
s_nIndTexMtxChanged = 15 ;
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true ;
2011-01-28 21:31:56 -07:00
s_bFogRangeAdjustChanged = s_bFogColorChanged = s_bFogParamChanged = true ;
2010-09-22 20:17:48 -06:00
nLightsChanged [ 0 ] = 0 ; nLightsChanged [ 1 ] = 0x80 ;
nMaterialsChanged = 15 ;
2013-10-07 08:02:24 -06:00
dirty = true ;
2008-12-26 03:43:18 -07:00
}
void PixelShaderManager : : Shutdown ( )
{
}
2012-09-02 12:00:15 -06:00
void PixelShaderManager : : SetConstants ( u32 components )
2008-12-07 22:25:12 -07:00
{
2012-09-02 12:00:15 -06:00
for ( int i = 0 ; i < 2 ; + + i )
2009-05-13 17:37:26 -06:00
{
2012-09-02 12:00:15 -06:00
if ( s_nColorsChanged [ i ] )
2009-05-13 17:37:26 -06:00
{
2012-09-02 12:00:15 -06:00
int baseind = i ? C_KCOLORS : C_COLORS ;
for ( int j = 0 ; j < 4 ; + + j )
2009-05-13 17:37:26 -06:00
{
2013-06-25 05:37:38 -06:00
if ( ( s_nColorsChanged [ i ] & ( 1 < < j ) ) )
2012-09-02 12:00:15 -06:00
{
SetPSConstant4fv ( baseind + j , & lastRGBAfull [ i ] [ j ] [ 0 ] ) ;
s_nColorsChanged [ i ] & = ~ ( 1 < < j ) ;
2013-06-25 05:37:38 -06:00
}
2012-09-02 12:00:15 -06:00
}
}
}
2008-12-07 22:25:12 -07:00
2011-06-19 23:48:12 -06:00
if ( s_nTexDimsChanged )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
for ( int i = 0 ; i < 8 ; + + i )
2009-05-13 17:37:26 -06:00
{
2013-06-25 05:37:38 -06:00
if ( ( s_nTexDimsChanged & ( 1 < < i ) ) )
2012-09-02 12:00:15 -06:00
{
2011-06-19 23:48:12 -06:00
SetPSTextureDims ( i ) ;
2012-09-02 12:00:15 -06:00
s_nTexDimsChanged & = ~ ( 1 < < i ) ;
2013-06-25 05:37:38 -06:00
}
2008-12-07 22:25:12 -07:00
}
}
2013-06-25 05:37:38 -06:00
if ( s_bAlphaChanged )
2009-05-13 17:37:26 -06:00
{
2011-01-30 18:28:32 -07:00
SetPSConstant4f ( C_ALPHA , ( lastAlpha & 0xff ) / 255.0f , ( ( lastAlpha > > 8 ) & 0xff ) / 255.0f , 0 , ( ( lastAlpha > > 16 ) & 0xff ) / 255.0f ) ;
2009-02-08 15:08:20 -07:00
s_bAlphaChanged = false ;
2013-06-25 05:37:38 -06:00
}
2008-12-07 22:25:12 -07:00
2013-06-25 05:37:38 -06:00
if ( s_bZTextureTypeChanged )
2011-06-19 23:48:12 -06:00
{
2013-03-19 19:51:12 -06:00
float ftemp [ 4 ] ;
switch ( bpmem . ztex2 . type )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
case 0 :
// 8 bits
ftemp [ 0 ] = 0 ; ftemp [ 1 ] = 0 ; ftemp [ 2 ] = 0 ; ftemp [ 3 ] = 255.0f / 16777215.0f ;
break ;
case 1 :
// 16 bits
ftemp [ 0 ] = 255.0f / 16777215.0f ; ftemp [ 1 ] = 0 ; ftemp [ 2 ] = 0 ; ftemp [ 3 ] = 65280.0f / 16777215.0f ;
break ;
case 2 :
// 24 bits
2009-11-20 19:49:46 -07:00
ftemp [ 0 ] = 16711680.0f / 16777215.0f ; ftemp [ 1 ] = 65280.0f / 16777215.0f ; ftemp [ 2 ] = 255.0f / 16777215.0f ; ftemp [ 3 ] = 0 ;
2008-12-07 22:25:12 -07:00
break ;
}
2009-02-08 15:08:20 -07:00
SetPSConstant4fv ( C_ZBIAS , ftemp ) ;
s_bZTextureTypeChanged = false ;
2013-06-25 05:37:38 -06:00
}
2009-02-08 15:08:20 -07:00
2013-06-25 05:37:38 -06:00
if ( s_bZBiasChanged | | s_bDepthRangeChanged )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
2011-02-05 11:25:34 -07:00
// [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-10 19:49:32 -06:00
SetPSConstant4f ( C_ZBIAS + 1 , xfregs . viewport . farZ / 16777216.0f , xfregs . viewport . zRange / 16777216.0f , 0 , ( float ) ( lastZBias ) / 16777215.0f ) ;
2009-02-08 15:08:20 -07:00
s_bZBiasChanged = s_bDepthRangeChanged = false ;
2013-06-25 05:37:38 -06:00
}
2008-12-07 22:25:12 -07:00
2013-03-19 19:51:12 -06:00
// indirect incoming texture scales
if ( s_nIndTexScaleChanged )
2009-05-13 17:37:26 -06:00
{
2008-12-07 22:25:12 -07:00
// set as two sets of vec4s, each containing S and T of two ind stages.
2013-03-19 19:51:12 -06:00
float f [ 8 ] ;
2011-06-19 23:48:12 -06:00
2013-06-25 05:37:38 -06:00
if ( s_nIndTexScaleChanged & 0x03 )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
for ( u32 i = 0 ; i < 2 ; + + i )
2009-05-13 17:37:26 -06:00
{
2009-06-22 03:31:30 -06:00
f [ 2 * i ] = bpmem . texscale [ 0 ] . getScaleS ( i & 1 ) ;
f [ 2 * i + 1 ] = bpmem . texscale [ 0 ] . getScaleT ( i & 1 ) ;
2009-05-13 17:37:26 -06:00
PRIM_LOG ( " tex indscale%d: %f %f \n " , i , f [ 2 * i ] , f [ 2 * i + 1 ] ) ;
2009-04-14 21:55:38 -06:00
}
2011-01-30 18:28:32 -07:00
SetPSConstant4fv ( C_INDTEXSCALE , f ) ;
2008-12-07 22:25:12 -07:00
}
2013-06-25 05:37:38 -06:00
if ( s_nIndTexScaleChanged & 0x0c )
2013-04-24 07:21:54 -06:00
{
2013-04-25 06:01:07 -06:00
for ( u32 i = 2 ; i < 4 ; + + i )
2013-04-24 07:21:54 -06:00
{
2009-06-22 03:31:30 -06:00
f [ 2 * i ] = bpmem . texscale [ 1 ] . getScaleS ( i & 1 ) ;
f [ 2 * i + 1 ] = bpmem . texscale [ 1 ] . getScaleT ( i & 1 ) ;
2009-05-13 17:37:26 -06:00
PRIM_LOG ( " tex indscale%d: %f %f \n " , i , f [ 2 * i ] , f [ 2 * i + 1 ] ) ;
2011-06-19 23:48:12 -06:00
}
2011-01-30 18:28:32 -07:00
SetPSConstant4fv ( C_INDTEXSCALE + 1 , & f [ 4 ] ) ;
2009-04-14 21:55:38 -06:00
}
2013-06-25 05:37:38 -06:00
s_nIndTexScaleChanged = 0 ;
2008-12-07 22:25:12 -07:00
}
2013-03-19 19:51:12 -06:00
if ( s_nIndTexMtxChanged )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
for ( int i = 0 ; i < 3 ; + + i )
2009-05-13 17:37:26 -06:00
{
2013-06-25 05:37:38 -06:00
if ( s_nIndTexMtxChanged & ( 1 < < i ) )
2009-05-13 17:37:26 -06:00
{
2009-06-22 03:31:30 -06: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-07 22:25:12 -07:00
float fscale = powf ( 2.0f , ( float ) ( scale - 17 ) ) / 1024.0f ;
// xyz - static matrix
2009-05-13 17:37:26 -06:00
// TODO w - dynamic matrix scale / 256...... somehow / 4 works better
2009-04-14 21:55:38 -06:00
// rev 2972 - now using / 256.... verify that this works
2011-01-30 18:28:32 -07:00
SetPSConstant4f ( C_INDTEXMTX + 2 * i ,
2013-03-19 19:51:12 -06:00
bpmem . indmtx [ i ] . col0 . ma * fscale ,
2009-06-22 03:31:30 -06:00
bpmem . indmtx [ i ] . col1 . mc * fscale ,
bpmem . indmtx [ i ] . col2 . me * fscale ,
2009-04-14 21:55:38 -06:00
fscale * 4.0f ) ;
2013-03-19 19:51:12 -06:00
SetPSConstant4f ( C_INDTEXMTX + 2 * i + 1 ,
bpmem . indmtx [ i ] . col0 . mb * fscale ,
2009-06-22 03:31:30 -06:00
bpmem . indmtx [ i ] . col1 . md * fscale ,
bpmem . indmtx [ i ] . col2 . mf * fscale ,
2009-04-14 21:55:38 -06:00
fscale * 4.0f ) ;
2008-12-07 22:25:12 -07:00
2010-12-05 02:04:34 -07: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 ) ;
2012-09-02 12:00:15 -06:00
s_nIndTexMtxChanged & = ~ ( 1 < < i ) ;
2013-06-25 05:37:38 -06:00
}
2008-12-07 22:25:12 -07:00
}
}
2009-02-18 21:41:58 -07:00
2013-06-25 05:37:38 -06:00
if ( s_bFogColorChanged )
2009-05-13 17:37:26 -06:00
{
2011-01-30 18:28:32 -07: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 ;
2013-06-25 05:37:38 -06:00
}
2009-02-18 21:41:58 -07:00
2013-06-25 05:37:38 -06:00
if ( s_bFogParamChanged )
2009-05-13 17:37:26 -06:00
{
2009-12-09 06:51:28 -07:00
if ( ! g_ActiveConfig . bDisableFog )
{
2010-11-23 06:57:01 -07: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 06:51:28 -07:00
}
else
2010-12-18 11:23:22 -07:00
SetPSConstant4f ( C_FOG + 1 , 0.0 , 1.0 , 0.0 , 1.0 ) ;
2011-06-19 23:48:12 -06:00
2009-02-18 21:41:58 -07:00
s_bFogParamChanged = false ;
2013-06-25 05:37:38 -06:00
}
2010-09-22 20:17:48 -06:00
2013-06-25 05:37:38 -06:00
if ( s_bFogRangeAdjustChanged )
2011-01-28 21:31:56 -07:00
{
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 ;
2013-04-07 15:11:29 -06:00
// normalize center to make calculations easy
2011-04-10 19:49:32 -06:00
float ScreenSpaceCenter = center / ( 2.0f * xfregs . viewport . wd ) ;
2011-01-28 21:31:56 -07:00
ScreenSpaceCenter = ( ScreenSpaceCenter * 2.0f ) - 1.0f ;
2013-04-07 15:11:29 -06:00
//bpmem.fogRange.K seems to be a table of precalculated coefficients for the adjust factor
//observations: bpmem.fogRange.K[0].LO appears to be the lowest value and bpmem.fogRange.K[4].HI the largest
// they always seems to be larger than 256 so my theory is :
// they are the coefficients from the center to the border of the screen
// so to simplify I use the hi coefficient as K in the shader taking 256 as the scale
2011-04-10 19:49:32 -06: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-19 23:48:12 -06:00
}
else
2013-04-24 07:21:54 -06:00
{
2011-06-19 23:48:12 -06:00
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.
2013-04-24 07:21:54 -06:00
}
2011-06-19 23:48:12 -06:00
2011-01-28 21:31:56 -07:00
s_bFogRangeAdjustChanged = false ;
2013-06-25 05:37:38 -06:00
}
2011-01-28 21:31:56 -07:00
2011-03-18 18:50:34 -06: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-22 20:17:48 -06:00
{
2011-02-05 11:25:34 -07:00
if ( nLightsChanged [ 0 ] > = 0 )
2010-09-22 20:17:48 -06:00
{
2011-02-05 11:25:34 -07: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-22 20:17:48 -06:00
{
2011-02-05 11:25:34 -07: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-22 20:17:48 -06:00
{
2011-02-05 11:25:34 -07: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
2013-04-24 07:21:54 -06:00
{
2011-02-05 11:25:34 -07:00
SetPSConstant4fv ( C_PLIGHTS + 5 * i + j + 1 , xfmemptr ) ;
2013-04-24 07:21:54 -06:00
}
2010-09-22 20:17:48 -06:00
}
}
2011-02-05 11:25:34 -07:00
nLightsChanged [ 0 ] = nLightsChanged [ 1 ] = - 1 ;
2010-09-22 20:17:48 -06:00
}
2011-02-05 11:25:34 -07:00
if ( nMaterialsChanged )
{
float GC_ALIGNED16 ( material [ 4 ] ) ;
float NormalizationCoef = 1 / 255.0f ;
2012-12-30 01:34:14 -07:00
for ( int i = 0 ; i < 2 ; + + i )
2011-02-05 11:25:34 -07:00
{
if ( nMaterialsChanged & ( 1 < < i ) )
{
u32 data = * ( xfregs . ambColor + i ) ;
2010-09-22 20:17:48 -06:00
2011-02-05 11:25:34 -07: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 ) ;
}
}
2013-06-25 05:37:38 -06:00
2012-12-30 01:34:14 -07:00
for ( int i = 0 ; i < 2 ; + + i )
{
if ( nMaterialsChanged & ( 1 < < ( i + 2 ) ) )
{
u32 data = * ( xfregs . matColor + i ) ;
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 + 2 , material ) ;
}
}
2011-02-05 11:25:34 -07:00
nMaterialsChanged = 0 ;
}
2010-09-22 20:17:48 -06:00
}
2008-12-07 22:25:12 -07:00
}
2008-12-26 03:43:18 -07:00
void PixelShaderManager : : SetPSTextureDims ( int texid )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
// texdims.xy are reciprocals of the real texture dimensions
// texdims.zw are the scaled dimensions
float fdims [ 4 ] ;
2010-08-29 13:34:54 -06:00
2013-03-19 19:51:12 -06:00
TCoordInfo & tc = bpmem . texcoords [ texid ] ;
2010-08-29 13:34:54 -06:00
fdims [ 0 ] = 1.0f / ( float ) ( lastTexDims [ texid ] & 0xffff ) ;
fdims [ 1 ] = 1.0f / ( float ) ( ( lastTexDims [ texid ] > > 16 ) & 0xfff ) ;
2010-08-29 22:05:06 -06:00
fdims [ 2 ] = ( float ) ( tc . s . scale_minus_1 + 1 ) ;
fdims [ 3 ] = ( float ) ( tc . t . scale_minus_1 + 1 ) ;
2008-12-07 22:25:12 -07:00
PRIM_LOG ( " texdims%d: %f %f %f %f \n " , texid , fdims [ 0 ] , fdims [ 1 ] , fdims [ 2 ] , fdims [ 3 ] ) ;
SetPSConstant4fv ( C_TEXDIMS + texid , fdims ) ;
}
2012-09-02 12:00:15 -06:00
// This one is high in profiles (0.5%).
// TODO: Move conversion out, only store the raw color value
2009-08-31 14:58:57 -06:00
// and update it when the shader constant is set, only.
2013-03-29 13:59:03 -06:00
// TODO: Conversion should be checked in the context of tev_fixes..
2011-07-04 07:49:40 -06:00
void PixelShaderManager : : SetColorChanged ( int type , int num , bool high )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
float * pf = & lastRGBAfull [ type ] [ num ] [ 0 ] ;
2013-04-24 07:21:54 -06:00
if ( ! high )
{
2011-07-04 07:49:40 -06:00
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 ) ;
2013-04-24 07:21:54 -06:00
}
else
{
2011-07-04 07:49:40 -06:00
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 ) ;
}
2013-04-24 07:21:54 -06:00
2013-03-19 19:51:12 -06: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-07 22:25:12 -07:00
}
2013-01-08 09:18:45 -07:00
void PixelShaderManager : : SetAlpha ( const AlphaTest & alpha )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
if ( ( alpha . hex & 0xffff ) ! = lastAlpha )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
lastAlpha = ( lastAlpha & ~ 0xffff ) | ( alpha . hex & 0xffff ) ;
s_bAlphaChanged = true ;
}
2008-12-07 22:25:12 -07:00
}
2008-12-26 03:43:18 -07:00
void PixelShaderManager : : SetDestAlpha ( const ConstantAlpha & alpha )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
if ( alpha . alpha ! = ( lastAlpha > > 16 ) )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
lastAlpha = ( lastAlpha & ~ 0xff0000 ) | ( ( alpha . hex & 0xff ) < < 16 ) ;
s_bAlphaChanged = true ;
}
2008-12-07 22:25:12 -07:00
}
2012-03-23 21:47:28 -06:00
void PixelShaderManager : : SetTexDims ( int texmapid , u32 width , u32 height , u32 wraps , u32 wrapt )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
u32 wh = width | ( height < < 16 ) | ( wraps < < 28 ) | ( wrapt < < 30 ) ;
if ( lastTexDims [ texmapid ] ! = wh )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
lastTexDims [ texmapid ] = wh ;
2011-06-19 23:48:12 -06:00
s_nTexDimsChanged | = 1 < < texmapid ;
2013-03-19 19:51:12 -06:00
}
2008-12-07 22:25:12 -07:00
}
2008-12-26 03:43:18 -07:00
void PixelShaderManager : : SetZTextureBias ( u32 bias )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
if ( lastZBias ! = bias )
2009-05-13 17:37:26 -06:00
{
2013-03-19 19:51:12 -06:00
s_bZBiasChanged = true ;
lastZBias = bias ;
}
2008-12-07 22:25:12 -07:00
}
2011-02-05 11:25:34 -07:00
void PixelShaderManager : : SetViewportChanged ( )
2009-02-08 15:08:20 -07:00
{
2011-02-05 11:25:34 -07:00
s_bDepthRangeChanged = true ;
2013-03-15 08:05:48 -06:00
s_bFogRangeAdjustChanged = true ; // TODO: Shouldn't be necessary with an accurate fog range adjust implementation
2009-10-25 17:10:30 -06:00
}
2009-04-14 21:55:38 -06:00
void PixelShaderManager : : SetIndTexScaleChanged ( u8 stagemask )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
s_nIndTexScaleChanged | = stagemask ;
2008-12-07 22:25:12 -07:00
}
2008-12-26 03:43:18 -07:00
void PixelShaderManager : : SetIndMatrixChanged ( int matrixidx )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
s_nIndTexMtxChanged | = 1 < < matrixidx ;
2008-12-07 22:25:12 -07:00
}
2009-08-31 14:58:57 -06:00
2009-02-08 15:08:20 -07:00
void PixelShaderManager : : SetZTextureTypeChanged ( )
{
s_bZTextureTypeChanged = true ;
2008-12-07 22:25:12 -07:00
}
2009-04-14 21:55:38 -06:00
void PixelShaderManager : : SetTexCoordChanged ( u8 texmapid )
2008-12-07 22:25:12 -07:00
{
2013-03-19 19:51:12 -06:00
s_nTexDimsChanged | = 1 < < texmapid ;
2008-12-07 22:25:12 -07:00
}
2009-02-18 21:41:58 -07:00
void PixelShaderManager : : SetFogColorChanged ( )
{
2013-03-19 19:51:12 -06:00
s_bFogColorChanged = true ;
2009-02-18 21:41:58 -07:00
}
void PixelShaderManager : : SetFogParamChanged ( )
{
2013-03-19 19:51:12 -06:00
s_bFogParamChanged = true ;
2009-02-18 21:41:58 -07:00
}
2011-01-28 21:31:56 -07:00
void PixelShaderManager : : SetFogRangeAdjustChanged ( )
{
2013-03-19 19:51:12 -06:00
s_bFogRangeAdjustChanged = true ;
2011-01-28 21:31:56 -07:00
}
2011-01-07 12:23:57 -07:00
void PixelShaderManager : : SetColorMatrix ( const float * pmatrix )
2008-12-07 22:25:12 -07:00
{
2011-01-07 12:23:57 -07:00
SetMultiPSConstant4fv ( C_COLORMATRIX , 7 , pmatrix ) ;
s_nColorsChanged [ 0 ] = s_nColorsChanged [ 1 ] = 15 ;
2008-12-07 22:25:12 -07:00
}
2010-09-22 20:17:48 -06: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 11:25:34 -07:00
void PixelShaderManager : : SetMaterialColorChanged ( int index )
2010-09-22 20:17:48 -06:00
{
nMaterialsChanged | = ( 1 < < index ) ;
}
2012-01-01 13:46:02 -07:00
void PixelShaderManager : : DoState ( PointerWrap & p )
{
p . Do ( lastRGBAfull ) ;
p . Do ( lastAlpha ) ;
p . Do ( lastTexDims ) ;
p . Do ( lastZBias ) ;
2013-10-07 08:02:24 -06:00
p . Do ( constants ) ;
p . Do ( dirty ) ;
2012-01-01 13:46:02 -07:00
if ( p . GetMode ( ) = = PointerWrap : : MODE_READ )
{
Dirty ( ) ;
}
}