📄 vertexshaderdx8.cpp
字号:
if ( !( byteCode.m_nSizeInBytes == 4 &&
( ( unsigned int * )byteCode.m_pRawData )[0] == 0x00000000 ) )
{
shader = ::CreatePixelShader( byteCode, info.m_pPrecompiledDXShader->m_nCentroidMask );
}
// Check again
if ( shader == INVALID_HARDWARE_PIXEL_SHADER )
{
// Set shader to ugly green for invalid shader...
shader = s_pIllegalMaterialPS;
Assert( 0 );
}
}
}
return (PixelShader_t)i;
}
//-----------------------------------------------------------------------------
// Destroys a pixel shader
//-----------------------------------------------------------------------------
void CShaderDictionary::DestroyPixelShader( PixelShader_t shader )
{
// Can't delete this one...
if ( (shader == INVALID_PIXEL_SHADER) || ((int)shader >= m_PixelShaders.Count()) )
return;
if (--m_PixelShaders[shader].m_nRefCount <= 0)
{
for (int i = m_PixelShaders[shader].m_nShaderCount; --i >= 0; )
{
HardwarePixelShader_t pixelShader = m_PixelShaders[shader].m_HardwareShaders[i];
if (pixelShader == INVALID_HARDWARE_PIXEL_SHADER)
continue;
// GR - invalid material hack
// don't delete shared shader used for hack
if ( pixelShader != s_pIllegalMaterialPS )
{
RECORD_COMMAND( DX8_DESTROY_PIXEL_SHADER, 1 );
RECORD_INT( ( int )pixelShader );
pixelShader->Release();
}
}
if ( m_PixelShaders[shader].m_HardwareShaders )
{
delete[] m_PixelShaders[shader].m_HardwareShaders;
}
m_PixelShaders.RemoveAt( shader );
}
}
//-----------------------------------------------------------------------------
// Destroys all pixel shaders
//-----------------------------------------------------------------------------
void CShaderDictionary::DestroyAllPixelShaders( )
{
for (int i = m_PixelShaders.First(); i != m_PixelShaders.InvalidIndex(); i = m_PixelShaders.Next(i) )
{
for (int j = m_PixelShaders[i].m_nShaderCount; --j >= 0; )
{
HardwarePixelShader_t pixelShader = m_PixelShaders[i].m_HardwareShaders[j];
if ( (pixelShader == INVALID_HARDWARE_PIXEL_SHADER) || ( pixelShader == s_pIllegalMaterialPS ))
continue;
RECORD_COMMAND( DX8_DESTROY_PIXEL_SHADER, 1 );
RECORD_INT( ( int )pixelShader );
pixelShader->Release();
}
if ( m_PixelShaders[i].m_HardwareShaders )
{
delete[] m_PixelShaders[i].m_HardwareShaders;
}
}
m_PixelShaders.RemoveAll();
}
//-----------------------------------------------------------------------------
// Gets the hardware pixel shader
//-----------------------------------------------------------------------------
HardwarePixelShader_t CShaderDictionary::GetHardwarePixelShader( PixelShader_t shader, int pshIndex )
{
return m_PixelShaders[shader].m_HardwareShaders[pshIndex];
}
//-----------------------------------------------------------------------------
// Vertex + pixel shader manager
//-----------------------------------------------------------------------------
class CShaderManager : public IShaderManager
{
public:
CShaderManager();
~CShaderManager();
// Methods of IShaderManager
virtual void Init( bool bPreloadShaders );
virtual void Shutdown();
virtual VertexShader_t CreateVertexShader( const char *pVertexShaderFile, int nStaticVshIndex = 0 );
virtual PixelShader_t CreatePixelShader( const char *pPixelShaderFile, int nStaticPshIndex = 0 );
virtual void SetVertexShaderIndex( int vshIndex = -1 );
virtual void SetPixelShaderIndex( int pshIndex = 0 );
virtual void SetVertexShader( VertexShader_t shader, int nStaticVshIndex = 0 );
virtual void SetPixelShader( PixelShader_t shader, int nStaticPshIndex = 0 );
virtual void* GetCurrentVertexShader();
virtual void* GetCurrentPixelShader();
virtual void ResetShaderState();
virtual ShaderDLL_t AddShaderDLL( );
virtual void RemoveShaderDLL( ShaderDLL_t hShaderDLL );
virtual void AddShaderDictionary( ShaderDLL_t hShaderDLL, IPrecompiledShaderDictionary *pDict );
virtual void SetShaderDLL( ShaderDLL_t hShaderDLL );
private:
// The low-level dx call to set the vertex shader state
void SetVertexShaderState( HardwareVertexShader_t shader );
// The low-level dx call to set the pixel shader state
void SetPixelShaderState( HardwarePixelShader_t shader );
private:
// Shaders defined in external DLLs
CUtlLinkedList< CShaderDictionary > m_ShaderDLLs;
ShaderDLL_t m_hCurrentShaderDLL;
// The current vertex + pixel shader
HardwareVertexShader_t m_HardwareVertexShader;
HardwarePixelShader_t m_HardwarePixelShader;
// The current vertex + pixel shader index
int m_nVertexShaderIndex;
int m_nPixelShaderIndex;
// Should we preload shaders?
bool m_bPreloadShaders;
};
//-----------------------------------------------------------------------------
// Singleton accessor
//-----------------------------------------------------------------------------
static CShaderManager s_ShaderManager;
IShaderManager *g_pShaderManager = &s_ShaderManager;
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CShaderManager::CShaderManager()
{
m_hCurrentShaderDLL = m_ShaderDLLs.InvalidIndex();
}
CShaderManager::~CShaderManager()
{
}
//-----------------------------------------------------------------------------
// Initialization, shutdown
//-----------------------------------------------------------------------------
void CShaderManager::Init( bool bPreloadShaders )
{
m_bPreloadShaders = bPreloadShaders;
CShaderDictionary::CreateErrorPS();
}
void CShaderManager::Shutdown()
{
for ( unsigned short i = m_ShaderDLLs.Head(); i != m_ShaderDLLs.InvalidIndex(); i = m_ShaderDLLs.Next(i) )
{
RemoveShaderDLL( i );
}
CShaderDictionary::DestroyErrorPS();
}
//-----------------------------------------------------------------------------
// Adds/removes shader DLLs
//-----------------------------------------------------------------------------
ShaderDLL_t CShaderManager::AddShaderDLL( )
{
return m_ShaderDLLs.AddToTail();
}
void CShaderManager::RemoveShaderDLL( ShaderDLL_t hShaderDLL )
{
// Destroy all vertex shaders
m_ShaderDLLs[hShaderDLL].DestroyAllVertexShaders( );
// Destroy all pixel shaders
m_ShaderDLLs[hShaderDLL].DestroyAllPixelShaders( );
m_ShaderDLLs.Remove( hShaderDLL );
}
//-----------------------------------------------------------------------------
// Adds precompiled shader dictionaries
//-----------------------------------------------------------------------------
void CShaderManager::AddShaderDictionary( ShaderDLL_t hShaderDLL, IPrecompiledShaderDictionary *pDict )
{
Assert( m_ShaderDLLs.IsValidIndex( hShaderDLL ) );
m_ShaderDLLs[hShaderDLL].AddShaderDictionary( pDict, m_bPreloadShaders );
}
//-----------------------------------------------------------------------------
// Sets the shader DLL index
//-----------------------------------------------------------------------------
void CShaderManager::SetShaderDLL( ShaderDLL_t hShaderDLL )
{
m_hCurrentShaderDLL = (hShaderDLL >= 0) ? hShaderDLL : m_ShaderDLLs.InvalidIndex();
}
//-----------------------------------------------------------------------------
// Creates and destroys vertex shaders
//-----------------------------------------------------------------------------
VertexShader_t CShaderManager::CreateVertexShader( char const* pFileName, int nStaticVshIndex )
{
if ( !pFileName || (m_hCurrentShaderDLL == m_ShaderDLLs.InvalidIndex()) )
return INVALID_VERTEX_SHADER;
VertexShader_t shader = m_ShaderDLLs[m_hCurrentShaderDLL].CreateVertexShader( pFileName, nStaticVshIndex );
if ( shader != INVALID_VERTEX_SHADER )
{
shader |= (m_hCurrentShaderDLL << 16);
}
return shader;
}
//-----------------------------------------------------------------------------
// Creates and destroys pixel shaders
//-----------------------------------------------------------------------------
PixelShader_t CShaderManager::CreatePixelShader( char const* pFileName, int nStaticPshIndex )
{
// FIXME: NOTE: We could also implement this by returning a unique PixelShader_t
// for each pFileName/nStaticPshIndex combination. I didn't do this because
// even though it's cleaner from the API standpoint because it would mean a
// much larger m_PixelShader dictionary + resulting slower search times.
if ( !pFileName || (m_hCurrentShaderDLL == m_ShaderDLLs.InvalidIndex()) )
return INVALID_PIXEL_SHADER;
PixelShader_t shader = m_ShaderDLLs[m_hCurrentShaderDLL].CreatePixelShader( pFileName, nStaticPshIndex );
if ( shader != INVALID_PIXEL_SHADER )
{
shader |= (m_hCurrentShaderDLL << 16);
}
return shader;
}
//-----------------------------------------------------------------------------
//
// Methods related to setting vertex + pixel shader state
//
//-----------------------------------------------------------------------------
void CShaderManager::SetVertexShaderIndex( int vshIndex )
{
m_nVertexShaderIndex = vshIndex;
}
void CShaderManager::SetPixelShaderIndex( int pshIndex )
{
m_nPixelShaderIndex = pshIndex;
}
void* CShaderManager::GetCurrentVertexShader()
{
return m_HardwareVertexShader;
}
void* CShaderManager::GetCurrentPixelShader()
{
return m_HardwarePixelShader;
}
//-----------------------------------------------------------------------------
// The low-level dx call to set the vertex shader state
//-----------------------------------------------------------------------------
void CShaderManager::SetVertexShaderState( HardwareVertexShader_t shader )
{
MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_SET_VERTEX_SHADER);
if ( m_HardwareVertexShader != shader )
{
RECORD_COMMAND( DX8_SET_VERTEX_SHADER, 1 );
RECORD_INT( ( int )shader ); // hack hack hack
#ifdef _DEBUG
HRESULT hr =
#endif
D3DDevice()->SetVertexShader( shader );
Assert( hr == D3D_OK );
m_HardwareVertexShader = shader;
MaterialSystemStats()->IncrementCountedStat( MATERIAL_SYSTEM_STATS_DYNAMIC_STATE, 1 );
}
}
//-----------------------------------------------------------------------------
// Sets a particular vertex shader as the current shader
//-----------------------------------------------------------------------------
void CShaderManager::SetVertexShader( VertexShader_t shader, int nStaticVshIndex )
{
// Determine which vertex shader to use...
if( shader == INVALID_VERTEX_SHADER )
{
SetVertexShaderState( 0 );
return;
}
int hShaderDLL = shader >> 16;
shader &= 0xFFFF;
int vshIndex = (m_nVertexShaderIndex >= 0) ? m_nVertexShaderIndex + nStaticVshIndex : -1;
HardwareVertexShader_t dxshader = m_ShaderDLLs[hShaderDLL].GetHardwareVertexShader( shader, vshIndex );
SetVertexShaderState( dxshader );
}
//-----------------------------------------------------------------------------
// The low-level dx call to set the pixel shader state
//-----------------------------------------------------------------------------
void CShaderManager::SetPixelShaderState( HardwarePixelShader_t shader )
{
MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_SET_PIXEL_SHADER);
if ( m_HardwarePixelShader != shader )
{
RECORD_COMMAND( DX8_SET_PIXEL_SHADER, 1 );
RECORD_INT( ( int )shader );
#ifdef _DEBUG
HRESULT hr =
#endif
D3DDevice()->SetPixelShader( shader );
Assert( !FAILED(hr) );
m_HardwarePixelShader = shader;
MaterialSystemStats()->IncrementCountedStat( MATERIAL_SYSTEM_STATS_DYNAMIC_STATE, 1 );
}
}
//-----------------------------------------------------------------------------
// Sets a particular pixel shader as the current shader
//-----------------------------------------------------------------------------
void CShaderManager::SetPixelShader( PixelShader_t shader, int nStaticPshIndex )
{
if( shader == INVALID_PIXEL_SHADER )
{
SetPixelShaderState( 0 );
return;
}
int hShaderDLL = shader >> 16;
shader &= 0xFFFF;
int pshIndex = m_nPixelShaderIndex + nStaticPshIndex;
Assert( pshIndex >= 0 );
HardwarePixelShader_t hardwarePixelShader = m_ShaderDLLs[hShaderDLL].GetHardwarePixelShader( shader, pshIndex );
Assert( hardwarePixelShader != INVALID_HARDWARE_PIXEL_SHADER );
SetPixelShaderState( hardwarePixelShader );
}
//-----------------------------------------------------------------------------
// Resets the shader state
//-----------------------------------------------------------------------------
void CShaderManager::ResetShaderState()
{
// This will force the calls to SetVertexShader + SetPixelShader to actually set the state
m_HardwareVertexShader = (HardwareVertexShader_t)-1;
m_HardwarePixelShader = (HardwarePixelShader_t)-1;
SetVertexShader( INVALID_VERTEX_SHADER );
SetPixelShader( INVALID_PIXEL_SHADER );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -