Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1026 lines
26 KiB

//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#define DISABLE_PROTECTED_THINGS
#include "togl/rendermechanism.h"
#include "hardwareconfig.h"
#include "shaderapi/ishaderutil.h"
#include "shaderapi_global.h"
#include "materialsystem/materialsystem_config.h"
#include "tier1/convar.h"
#include "shaderdevicebase.h"
#include "tier0/icommandline.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
extern ConVar mat_slopescaledepthbias_shadowmap;
extern ConVar mat_depthbias_shadowmap;
static ConVar developer( "developer", "0", FCVAR_RELEASE, "Set developer message level" );
//-----------------------------------------------------------------------------
//
// Hardware Config!
//
//-----------------------------------------------------------------------------
static CHardwareConfig s_HardwareConfig;
CHardwareConfig *g_pHardwareConfig = &s_HardwareConfig;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CHardwareConfig, IMaterialSystemHardwareConfig,
MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, s_HardwareConfig )
CHardwareConfig::CHardwareConfig()
{
memset( &m_Caps, 0, sizeof( HardwareCaps_t ) );
memset( &m_ActualCaps, 0, sizeof( HardwareCaps_t ) );
memset( &m_UnOverriddenCaps, 0, sizeof( HardwareCaps_t ) );
m_bHDREnabled = false;
// FIXME: This is kind of a hack to deal with DX8 worldcraft startup.
// We can at least have this much texture
m_Caps.m_MaxTextureWidth = m_Caps.m_MaxTextureHeight = m_Caps.m_MaxTextureDepth = 256;
}
//-----------------------------------------------------------------------------
bool CHardwareConfig::GetHDREnabled( void ) const
{
// printf("\n CHardwareConfig::GetHDREnabled returning m_bHDREnabled value of %s on %8x", m_bHDREnabled?"true":"false", this );
return m_bHDREnabled;
}
void CHardwareConfig::SetHDREnabled( bool bEnable )
{
// printf("\n CHardwareConfig::SetHDREnabled setting m_bHDREnabled to value of %s on %8x", bEnable?"true":"false", this );
m_bHDREnabled = bEnable;
}
//-----------------------------------------------------------------------------
// Gets the recommended configuration associated with a particular dx level
//-----------------------------------------------------------------------------
void CHardwareConfig::ForceCapsToDXLevel( HardwareCaps_t *pCaps, int nDxLevel, const HardwareCaps_t &actualCaps )
{
if ( !IsPC() || nDxLevel > 100 )
return;
pCaps->m_nDXSupportLevel = nDxLevel;
switch( nDxLevel )
{
case 90:
pCaps->m_NumVertexSamplers = 0;
pCaps->m_nMaxVertexTextureDimension = 0;
pCaps->m_bSupportsVertexTextures = false;
pCaps->m_bSupportsBorderColor = false;
// 2b gets four lights, 2.0 gets two...
pCaps->m_SupportsPixelShaders_2_b = false;
pCaps->m_SupportsShaderModel_3_0 = false;
pCaps->m_MaxNumLights = 2;
pCaps->m_nMaxViewports = 1;
pCaps->m_NumPixelShaderConstants = 32;
pCaps->m_nMaxVertexTextureDimension = 0;
pCaps->m_bDX10Card = false;
pCaps->m_bDX10Blending = false;
pCaps->m_MaxVertexShader30InstructionSlots = 0;
pCaps->m_MaxPixelShader30InstructionSlots = 0;
pCaps->m_bSupportsCascadedShadowMapping = false;
pCaps->m_nCSMQuality = 0;
break;
case 92:
pCaps->m_NumVertexSamplers = 0;
pCaps->m_nMaxVertexTextureDimension = 0;
pCaps->m_bSupportsVertexTextures = false;
pCaps->m_bSupportsBorderColor = false;
// 2b gets four lights (iff supports static control flow otherwise 2), 2.0 gets two...
pCaps->m_SupportsShaderModel_3_0 = false;
if ( IsOpenGL() )
{
if ( IsOSX() )
{
pCaps->m_bSupportsStaticControlFlow = CommandLine()->CheckParm( "-glslcontrolflow" ) != NULL;
}
else
{
pCaps->m_bSupportsStaticControlFlow = !CommandLine()->CheckParm( "-noglslcontrolflow" );
}
pCaps->m_MaxUserClipPlanes = 2;
pCaps->m_UseFastClipping = false;
pCaps->m_MaxNumLights = pCaps->m_bSupportsStaticControlFlow ? 4 : 2;
}
else
{
pCaps->m_MaxNumLights = MAX_NUM_LIGHTS;
}
pCaps->m_nMaxViewports = 1;
pCaps->m_NumPixelShaderConstants = 32;
pCaps->m_nMaxVertexTextureDimension = 0;
pCaps->m_bDX10Card = false;
pCaps->m_bDX10Blending = false;
pCaps->m_MaxVertexShader30InstructionSlots = 0;
pCaps->m_MaxPixelShader30InstructionSlots = 0;
pCaps->m_bSupportsCascadedShadowMapping = false;
pCaps->m_nCSMQuality = 0;
break;
case 95:
pCaps->m_bDX10Card = false;
pCaps->m_bDX10Blending = false;
pCaps->m_nMaxViewports = 1;
pCaps->m_bSupportsBorderColor = false;
if ( IsOpenGL() )
{
if ( IsOSX() )
{
pCaps->m_bSupportsStaticControlFlow = CommandLine()->CheckParm( "-glslcontrolflow" ) != NULL;
}
else
{
pCaps->m_bSupportsStaticControlFlow = !CommandLine()->CheckParm( "-noglslcontrolflow" );
}
pCaps->m_MaxUserClipPlanes = 2;
pCaps->m_UseFastClipping = false;
pCaps->m_MaxNumLights = pCaps->m_bSupportsStaticControlFlow ? 4 : 2;
}
else
{
pCaps->m_MaxNumLights = MAX_NUM_LIGHTS;
}
break;
case 100:
if ( IsOpenGL() )
{
if ( IsOSX() )
{
pCaps->m_bSupportsStaticControlFlow = CommandLine()->CheckParm( "-glslcontrolflow" ) != NULL;
}
else
{
pCaps->m_bSupportsStaticControlFlow = !CommandLine()->CheckParm( "-noglslcontrolflow" );
}
pCaps->m_MaxUserClipPlanes = 2;
pCaps->m_UseFastClipping = false;
pCaps->m_MaxNumLights = pCaps->m_bSupportsStaticControlFlow ? 4 : 2;
}
else
{
pCaps->m_MaxNumLights = MAX_NUM_LIGHTS;
}
break;
default:
Assert( 0 );
break;
}
#ifdef _PS3
pCaps->m_NumPixelShaderConstants = MAX_FRAGMENT_PROGRAM_CONSTS; // this is somewhat of a lie... fragment shader constants are special on PS3 and we actually have a larger number of these
#endif
}
//-----------------------------------------------------------------------------
// Sets up the hardware caps given the specified DX level
//-----------------------------------------------------------------------------
void CHardwareConfig::SetupHardwareCaps( int nDXLevel, const HardwareCaps_t &actualCaps )
{
Assert( nDXLevel != 0 );
if ( nDXLevel < actualCaps.m_nMinDXSupportLevel )
{
Warning( "Trying to set dxlevel (%d) which is lower than the card can support (%d)!\n", nDXLevel, actualCaps.m_nMinDXSupportLevel );
}
if ( nDXLevel > actualCaps.m_nMaxDXSupportLevel )
{
Warning( "Trying to set dxlevel (%d) which is higher than the card can support (%d)!\n", nDXLevel, actualCaps.m_nMaxDXSupportLevel );
}
memcpy( &m_Caps, &actualCaps, sizeof(HardwareCaps_t) );
memcpy( &m_UnOverriddenCaps, &actualCaps, sizeof(HardwareCaps_t) );
// Don't bother with fallbacks for DX10 or consoles
#ifdef DX_TO_GL_ABSTRACTION
if ( nDXLevel >= 100 )
#else
if ( !( IsPC() || IsPosix() ) || ( nDXLevel >= 100 ) )
#endif
return;
// Don't bother with fallbacks for consoles.
if ( IsGameConsole() )
return;
int nForceDXLevel = CommandLine()->ParmValue( "-maxdxlevel", 0 );
if ( nForceDXLevel >= 90 )
{
nDXLevel = nForceDXLevel;
}
else
{
// Don't bother with fallbacks for DX10 or consoles
if ( !IsPC() || !IsPosix() || ( nDXLevel >= 100 ) )
return;
}
// Slam the support level to what we were requested
m_Caps.m_nDXSupportLevel = nDXLevel;
int nMaxDXLevel = CommandLine()->ParmValue( "-maxdxlevel", m_Caps.m_nMaxDXSupportLevel );
if ( IsOpenGL() )
{
// Prevent customers from ever trying to slam the dxlevel too low in GL mode.
nMaxDXLevel = MAX( nMaxDXLevel, 90 );
}
{
// We're falling back to some other dx level
ForceCapsToDXLevel( &m_Caps, m_Caps.m_nDXSupportLevel, m_ActualCaps );
}
// Read dxsupport.cfg which has config overrides for particular cards.
g_pShaderDeviceMgr->ReadHardwareCaps( m_Caps, m_Caps.m_nDXSupportLevel );
// This is the spot to validate read in caps versus actual caps.
if ( m_Caps.m_MaxUserClipPlanes > m_ActualCaps.m_MaxUserClipPlanes )
{
m_Caps.m_MaxUserClipPlanes = m_ActualCaps.m_MaxUserClipPlanes;
}
if ( m_Caps.m_MaxUserClipPlanes == 0 )
{
m_Caps.m_UseFastClipping = true;
}
// 2b supports more lights than just 2.0
if ( ( m_Caps.m_SupportsPixelShaders_2_b ) && ( m_Caps.m_nDXSupportLevel >= 92 ) )
{
m_Caps.m_MaxNumLights = MAX_NUM_LIGHTS;
}
else
{
m_Caps.m_MaxNumLights = MAX_NUM_LIGHTS-2;
}
if ( IsOpenGL() )
{
m_Caps.m_MaxNumLights = MIN( m_Caps.m_bSupportsStaticControlFlow ? MAX_NUM_LIGHTS : 2, m_Caps.m_MaxNumLights );
m_Caps.m_bSupportsShadowDepthTextures = true;
}
m_Caps.m_MaxNumLights = MIN( m_Caps.m_MaxNumLights, MAX_NUM_LIGHTS );
memcpy( &m_UnOverriddenCaps, &m_Caps, sizeof(HardwareCaps_t) );
}
//-----------------------------------------------------------------------------
// Sets up the hardware caps given the specified DX level
//-----------------------------------------------------------------------------
void CHardwareConfig::SetupHardwareCaps( const ShaderDeviceInfo_t& mode, const HardwareCaps_t &actualCaps )
{
memcpy( &m_ActualCaps, &actualCaps, sizeof(HardwareCaps_t) );
SetupHardwareCaps( mode.m_nDXLevel, actualCaps );
}
void CHardwareConfig::OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport )
{
if ( bOverrideEnabled )
{
m_Caps.m_bSupportsStreamOffset = bEnableSupport;
if ( !m_ActualCaps.m_bSupportsStreamOffset )
{
m_Caps.m_bSupportsStreamOffset = false;
}
}
else
{
// Go back to default
m_Caps.m_bSupportsStreamOffset = m_UnOverriddenCaps.m_bSupportsStreamOffset;
}
}
//-----------------------------------------------------------------------------
// Implementation of IMaterialSystemHardwareConfig
//-----------------------------------------------------------------------------
bool CHardwareConfig::HasStencilBuffer() const
{
return StencilBufferBits() > 0;
}
int CHardwareConfig::GetFrameBufferColorDepth() const
{
if ( !g_pShaderDevice )
return 0;
return ShaderUtil()->ImageFormatInfo( g_pShaderDevice->GetBackBufferFormat() ).m_nNumBytes;
}
int CHardwareConfig::GetSamplerCount() const
{
return m_Caps.m_NumSamplers;
}
int CHardwareConfig::GetVertexSamplerCount() const
{
return m_Caps.m_NumVertexSamplers;
}
bool CHardwareConfig::HasSetDeviceGammaRamp() const
{
return m_Caps.m_HasSetDeviceGammaRamp;
}
VertexCompressionType_t CHardwareConfig::SupportsCompressedVertices() const
{
return m_Caps.m_SupportsCompressedVertices;
}
bool CHardwareConfig::SupportsBorderColor() const
{
return m_Caps.m_bSupportsBorderColor;
}
bool CHardwareConfig::SupportsFetch4() const
{
return m_Caps.m_bSupportsFetch4;
}
float CHardwareConfig::GetShadowDepthBias() const
{
// FIXME: Should these not use convars?
return mat_depthbias_shadowmap.GetFloat();
}
float CHardwareConfig::GetShadowSlopeScaleDepthBias() const
{
// FIXME: Should these not use convars?
return mat_slopescaledepthbias_shadowmap.GetFloat();
}
bool CHardwareConfig::PreferZPrepass() const
{
return m_Caps.m_bPreferZPrepass;
}
bool CHardwareConfig::SuppressPixelShaderCentroidHackFixup() const
{
return m_Caps.m_bSuppressPixelShaderCentroidHackFixup;
}
bool CHardwareConfig::PreferTexturesInHWMemory() const
{
return m_Caps.m_bPreferTexturesInHWMemory;
}
bool CHardwareConfig::PreferHardwareSync() const
{
return m_Caps.m_bPreferHardwareSync;
}
bool CHardwareConfig::SupportsStaticControlFlow() const
{
return m_Caps.m_bSupportsStaticControlFlow;
}
bool CHardwareConfig::IsUnsupported() const
{
return m_Caps.m_bUnsupported;
}
ShadowFilterMode_t CHardwareConfig::GetShadowFilterMode( bool bForceLowQualityShadows, bool bPS30 ) const
{
#if PLATFORM_POSIX || !defined( PLATFORM_X360 )
static ConVarRef gpu_level( "gpu_level" );
int nGPULevel = gpu_level.GetInt();
const bool bUseLowQualityShadows = ( nGPULevel < 2 ) || ( bForceLowQualityShadows );
#endif
#if PLATFORM_POSIX
// Currently Mac or PS3
if ( !m_Caps.m_bSupportsShadowDepthTextures )
return SHADOWFILTERMODE_DEFAULT;
if ( IsOSXOpenGL() &&
( bUseLowQualityShadows || ( m_Caps.m_VendorID == VENDORID_INTEL ) ) )
{
return NVIDIA_PCF_CHEAP;
}
if( IsPS3() )
{
// PS3 shaders doesn't use the regular PC/POSIX values. It supports either 9 (the default) or 1 tap (fast) filtering.
return bForceLowQualityShadows ? GAMECONSOLE_SINGLE_TAP_PCF : GAMECONSOLE_NINE_TAP_PCF;
}
#elif defined( PLATFORM_X360 )
// X360
return bForceLowQualityShadows ? GAMECONSOLE_SINGLE_TAP_PCF : GAMECONSOLE_NINE_TAP_PCF;
#else
// PC
if ( !m_Caps.m_bSupportsShadowDepthTextures || !ShaderUtil()->GetConfig().ShadowDepthTexture() )
return SHADOWFILTERMODE_DEFAULT;
switch ( m_Caps.m_ShadowDepthTextureFormat )
{
case IMAGE_FORMAT_D16_SHADOW:
case IMAGE_FORMAT_D24X8_SHADOW:
if ( ( m_Caps.m_VendorID == VENDORID_NVIDIA ) || ( m_Caps.m_VendorID == VENDORID_INTEL ) )
{
if ( bUseLowQualityShadows )
return NVIDIA_PCF_CHEAP; // NVIDIA hardware bilinear PCF
else
return NVIDIA_PCF; // NVIDIA hardware PCF with larger kernel
}
if ( m_Caps.m_VendorID == VENDORID_ATI )
{
// PS30 shaders purposely don't support ATI_NOPCF to reduce the combo permutation space.
if ( ( !bPS30 ) && ( bUseLowQualityShadows ) )
{
return ATI_NOPCF; // Don't bother with a cheap Fetch 4
}
else
{
static bool bForceATIFetch4 = CommandLine()->CheckParm( "-forceatifetch4" ) ? true : false;
// Either PS30, or high quality shadows.
if ( m_Caps.m_bDX10Card && !bForceATIFetch4 )
return ( bUseLowQualityShadows ) ? NVIDIA_PCF_CHEAP : NVIDIA_PCF; // ATI wants us to run NVIDIA PCF on DX10 parts (this is the common case)
else if ( m_Caps.m_bSupportsFetch4 )
return ATI_NO_PCF_FETCH4; // ATI fetch4 depth texture sampling
else if ( bPS30 )
{
// We can't return ATI_NOPCF when using PS30 shaders. (This path should actually never get hit - either we're on a DX10 card or its fetch10 capable, I think.)
return ATI_NO_PCF_FETCH4;
}
else
{
return ATI_NOPCF; // ATI vanilla depth texture sampling
}
}
}
break;
default:
return SHADOWFILTERMODE_DEFAULT;
}
#endif
return SHADOWFILTERMODE_DEFAULT;
}
#if defined( CSTRIKE15 ) && defined( _X360 )
static ConVar r_shader_srgb( "r_shader_srgb", "0", 0, "-1 = use hardware caps. 0 = use hardware srgb. 1 = use shader srgb(software lookup)" ); // -1=use caps 0=off 1=on
static ConVar r_shader_srgbread( "r_shader_srgbread", "1", 0, "1 = use shader srgb texture reads, 0 = use HW" );
#else
static ConVar r_shader_srgb( "r_shader_srgb", "0", 0, "-1 = use hardware caps. 0 = use hardware srgb. 1 = use shader srgb(software lookup)" ); // -1=use caps 0=off 1=on
static ConVar r_shader_srgbread( "r_shader_srgbread", "0", 0, "1 = use shader srgb texture reads, 0 = use HW" );
#endif
int CHardwareConfig::NeedsShaderSRGBConversion() const
{
if ( IsX360() )
{
#if defined( CSTRIKE15 )
// [mariod] TODO - tidy up the use of this (now mostly obsolete) convar after PAX
if( r_shader_srgbread.GetBool() )
{
return false;
}
#else
// 360 always now uses a permanent hw solution
return false;
#endif
}
if ( IsPS3() )
{
// PS3 natively supports srgb in hardware
return false;
}
int cValue = r_shader_srgb.GetInt();
switch( cValue )
{
case 0:
return false;
case 1:
return true;
default:
return m_ActualCaps.m_bDX10Blending; // !!! change to return false after portal depot built!!!!!
}
}
bool CHardwareConfig::UsesSRGBCorrectBlending() const
{
int cValue = r_shader_srgb.GetInt();
return ( cValue == 0 ) && ( ( m_ActualCaps.m_bDX10Blending ) || IsX360() );
}
static ConVar mat_disablehwmorph( "mat_disablehwmorph", "0", FCVAR_DEVELOPMENTONLY, "Disables HW morphing for particular mods" );
static int s_bEnableFastVertexTextures = -1;
static bool s_bDisableHWMorph = false;
bool CHardwareConfig::HasFastVertexTextures() const
{
// NOTE: This disallows you to change mat_disablehwmorph on the fly
if ( s_bEnableFastVertexTextures < 0 )
{
s_bEnableFastVertexTextures = 1;
if ( CommandLine()->FindParm( "-disallowhwmorph" ) )
{
s_bEnableFastVertexTextures = 0;
}
s_bDisableHWMorph = ( mat_disablehwmorph.GetInt() != 0 );
}
return ( s_bEnableFastVertexTextures != 0 ) && ( !s_bDisableHWMorph ) && ( GetDXSupportLevel() >= 100 );
}
bool CHardwareConfig::ActualHasFastVertexTextures() const
{
// NOTE: This disallows you to change mat_disablehwmorph on the fly
if ( s_bEnableFastVertexTextures < 0 )
{
s_bEnableFastVertexTextures = 1;
if ( CommandLine()->FindParm( "-disallowhwmorph" ) )
{
s_bEnableFastVertexTextures = 0;
}
s_bDisableHWMorph = ( mat_disablehwmorph.GetInt() != 0 );
}
return ( s_bEnableFastVertexTextures != 0 ) && ( !s_bDisableHWMorph ) && ( GetMaxDXSupportLevel() >= 100 );
}
int CHardwareConfig::MaxHWMorphBatchCount() const
{
return ShaderUtil()->MaxHWMorphBatchCount();
}
int CHardwareConfig::MaximumAnisotropicLevel() const
{
return m_Caps.m_nMaxAnisotropy;
}
int CHardwareConfig::MaxTextureWidth() const
{
return m_Caps.m_MaxTextureWidth;
}
int CHardwareConfig::MaxTextureHeight() const
{
return m_Caps.m_MaxTextureHeight;
}
int CHardwareConfig::TextureMemorySize() const
{
return m_Caps.m_TextureMemorySize;
}
bool CHardwareConfig::SupportsMipmappedCubemaps() const
{
return m_Caps.m_SupportsMipmappedCubemaps;
}
int CHardwareConfig::NumVertexShaderConstants() const
{
return m_Caps.m_NumVertexShaderConstants;
}
int CHardwareConfig::NumBooleanVertexShaderConstants() const
{
return m_Caps.m_NumBooleanVertexShaderConstants;
}
int CHardwareConfig::NumIntegerVertexShaderConstants() const
{
return m_Caps.m_NumIntegerVertexShaderConstants;
}
int CHardwareConfig::NumPixelShaderConstants() const
{
return m_Caps.m_NumPixelShaderConstants;
}
int CHardwareConfig::NumBooleanPixelShaderConstants() const
{
return m_Caps.m_NumBooleanPixelShaderConstants;
}
int CHardwareConfig::NumIntegerPixelShaderConstants() const
{
return m_Caps.m_NumIntegerPixelShaderConstants;
}
int CHardwareConfig::MaxNumLights() const
{
return m_Caps.m_MaxNumLights;
}
int CHardwareConfig::MaxTextureAspectRatio() const
{
return m_Caps.m_MaxTextureAspectRatio;
}
int CHardwareConfig::MaxVertexShaderBlendMatrices() const
{
return m_Caps.m_MaxVertexShaderBlendMatrices;
}
// Useful for testing fastclip on Windows
extern ConVar mat_fastclip;
int CHardwareConfig::MaxUserClipPlanes() const
{
if ( mat_fastclip.GetBool() )
return 0;
return m_Caps.m_MaxUserClipPlanes;
}
bool CHardwareConfig::UseFastClipping() const
{
// rbarris broke this up for easier view of outcome in debugger
bool fastclip = mat_fastclip.GetBool();
bool result = m_Caps.m_UseFastClipping || fastclip;
return result;
}
int CHardwareConfig::MaxTextureDepth() const
{
return m_Caps.m_MaxTextureDepth;
}
int CHardwareConfig::GetDXSupportLevel() const
{
return m_Caps.m_nDXSupportLevel;
}
const char *CHardwareConfig::GetShaderDLLName() const
{
return ( m_Caps.m_pShaderDLL && m_Caps.m_pShaderDLL[0] ) ? m_Caps.m_pShaderDLL : "DEFAULT";
}
bool CHardwareConfig::ReadPixelsFromFrontBuffer() const
{
if ( IsX360() )
{
// future proof safety, not allowing the front read path
return false;
}
// GR - in DX 9.0a can blit from MSAA back buffer
return false;
}
bool CHardwareConfig::PreferDynamicTextures() const
{
if ( IsX360() )
{
// future proof safety, not allowing these
return false;
}
return m_Caps.m_PreferDynamicTextures;
}
bool CHardwareConfig::SupportsHDR() const
{
// This is a deprecated function. . use GetHDRType instead. For shipping HL2, this always being false is correct.
Assert( 0 );
return false;
}
bool CHardwareConfig::SupportsHDRMode( HDRType_t nHDRType ) const
{
switch( nHDRType )
{
case HDR_TYPE_NONE:
return true;
case HDR_TYPE_INTEGER:
return ( m_Caps.m_MaxHDRType == HDR_TYPE_INTEGER ) || ( m_Caps.m_MaxHDRType == HDR_TYPE_FLOAT );
case HDR_TYPE_FLOAT:
return ( m_Caps.m_MaxHDRType == HDR_TYPE_FLOAT );
}
return false;
}
bool CHardwareConfig::NeedsAAClamp() const
{
return false;
}
bool CHardwareConfig::NeedsATICentroidHack() const
{
return m_Caps.m_bNeedsATICentroidHack;
}
// This is the max dx support level supported by the card
int CHardwareConfig::GetMaxDXSupportLevel() const
{
return m_ActualCaps.m_nMaxDXSupportLevel;
}
int CHardwareConfig::GetMinDXSupportLevel() const
{
return ( developer.GetInt() > 0 ) ? 90 : m_ActualCaps.m_nMinDXSupportLevel;
}
bool CHardwareConfig::SpecifiesFogColorInLinearSpace() const
{
return m_Caps.m_bFogColorSpecifiedInLinearSpace;
}
bool CHardwareConfig::SupportsSRGB() const
{
return m_Caps.m_SupportsSRGB;
}
bool CHardwareConfig::FakeSRGBWrite() const
{
return m_Caps.m_FakeSRGBWrite;
}
bool CHardwareConfig::CanDoSRGBReadFromRTs() const
{
return m_Caps.m_CanDoSRGBReadFromRTs;
}
bool CHardwareConfig::SupportsGLMixedSizeTargets() const
{
return m_Caps.m_bSupportsGLMixedSizeTargets;
}
bool CHardwareConfig::IsAAEnabled() const
{
return g_pShaderDevice ? g_pShaderDevice->IsAAEnabled() : false;
// bool bAntialiasing = ( m_PresentParameters.MultiSampleType != D3DMULTISAMPLE_NONE );
// return bAntialiasing;
}
int CHardwareConfig::GetMaxVertexTextureDimension() const
{
return m_Caps.m_nMaxVertexTextureDimension;
}
HDRType_t CHardwareConfig::GetHDRType() const
{
// On MacOS, this value comes down from the engine, which read it from the registry...which doesn't exist on Mac, so we're slamming to true here
if ( IsOpenGL() )
{
g_pHardwareConfig->SetHDREnabled( true );
}
bool enabled = m_bHDREnabled;
int dxlev = GetDXSupportLevel();
int dxsupp = dxlev >= 90;
HDRType_t caps_hdr = m_Caps.m_HDRType;
HDRType_t result = HDR_TYPE_NONE;
//printf("\nCHardwareConfig::GetHDRType...");
if (enabled)
{
//printf("-> enabled...");
if (dxsupp)
{
//printf("-> supported...");
result = caps_hdr;
}
}
//printf("-> result is %d.\n", result);
return result;
/*
if ( m_bHDREnabled && ( GetDXSupportLevel() >= 90 ) )
return m_Caps.m_HDRType;
return HDR_TYPE_NONE;
*/
}
float CHardwareConfig::GetLightMapScaleFactor( void ) const
{
#ifdef _PS3
// PS3 uses floating point lightmaps but not the full HDR_TYPE_FLOAT codepath
return 1.0f;
#else // _PS3
switch( GetHDRType() )
{
case HDR_TYPE_FLOAT:
return 1.0;
break;
case HDR_TYPE_INTEGER:
return 16.0;
case HDR_TYPE_NONE:
default:
return GammaToLinearFullRange( 2.0 ); // light map scale
}
#endif // !_PS3
}
HDRType_t CHardwareConfig::GetHardwareHDRType() const
{
return m_Caps.m_HDRType;
}
bool CHardwareConfig::SupportsStreamOffset() const
{
return m_Caps.m_bSupportsStreamOffset;
}
int CHardwareConfig::StencilBufferBits() const
{
return g_pShaderDevice ? g_pShaderDevice->StencilBufferBits() : 0;
}
int CHardwareConfig:: MaxViewports() const
{
return m_Caps.m_nMaxViewports;
}
int CHardwareConfig::GetActualSamplerCount() const
{
return m_ActualCaps.m_NumSamplers;
}
int CHardwareConfig::GetActualVertexSamplerCount() const
{
return m_ActualCaps.m_NumVertexSamplers;
}
const char *CHardwareConfig::GetHWSpecificShaderDLLName() const
{
return m_Caps.m_pShaderDLL && m_Caps.m_pShaderDLL[0] ? m_Caps.m_pShaderDLL : NULL;
}
bool CHardwareConfig::SupportsShadowDepthTextures( void ) const
{
return m_Caps.m_bSupportsShadowDepthTextures;
}
ImageFormat CHardwareConfig::GetShadowDepthTextureFormat( void ) const
{
return m_Caps.m_ShadowDepthTextureFormat;
}
ImageFormat CHardwareConfig::GetHighPrecisionShadowDepthTextureFormat( void ) const
{
return m_Caps.m_HighPrecisionShadowDepthTextureFormat;
}
ImageFormat CHardwareConfig::GetNullTextureFormat( void ) const
{
return m_Caps.m_NullTextureFormat;
}
bool CHardwareConfig::SupportsCascadedShadowMapping( void ) const
{
#if defined(_PS3)
return m_Caps.m_bSupportsCascadedShadowMapping;
#elif defined(_X360)
return m_Caps.m_bSupportsCascadedShadowMapping;
#else
return m_Caps.m_bSupportsCascadedShadowMapping && ( GetDXSupportLevel() >= 95 );
#endif
}
CSMQualityMode_t CHardwareConfig::GetCSMQuality( void ) const
{
#if defined( _X360 ) || defined( _PS3 )
return CSMQUALITY_VERY_LOW;
#else
return (CSMQualityMode_t)m_Caps.m_nCSMQuality;
#endif
}
bool CHardwareConfig::SupportsBilinearPCFSampling() const
{
if( IsOpenGL() || IsPS3() || IsX360() )
return true;
if ( ( m_Caps.m_VendorID == VENDORID_NVIDIA ) || ( m_Caps.m_VendorID == VENDORID_INTEL ) )
return true;
static bool bForceATIFetch4 = CommandLine()->CheckParm( "-forceatifetch4" ) ? true : false;
if ( bForceATIFetch4 )
return false;
// Non-DX10 class ATI cards (pre-X2000) don't support bilinear PCF in hardware.
if ( ( m_Caps.m_VendorID == VENDORID_ATI ) && ( m_Caps.m_bDX10Card ) )
return true;
return false;
}
// Returns the CSM static combo to select given the current card's capablities and the configured CSM quality level.
CSMShaderMode_t CHardwareConfig::GetCSMShaderMode( CSMQualityMode_t nQualityLevel ) const
{
#if defined( _X360 ) || defined( _PS3 )
return CSMSHADERMODE_LOW_OR_VERY_LOW;
#endif
// Special case for ATI DX9-class (pre ATI HD 2xxx) cards that don't support NVidia-style PCF filtering - always set to CSMSHADERMODE_ATIFETCH4.
if ( !SupportsBilinearPCFSampling() )
return CSMSHADERMODE_ATIFETCH4;
int nMode = nQualityLevel - 1;
if ( nMode < CSMSHADERMODE_LOW_OR_VERY_LOW )
nMode = CSMSHADERMODE_LOW_OR_VERY_LOW;
else if ( nMode > CSMSHADERMODE_HIGH )
nMode = CSMSHADERMODE_HIGH;
return static_cast< CSMShaderMode_t >( nMode );
}
bool CHardwareConfig::GetCSMAccurateBlending( void ) const
{
return m_bCSMAccurateBlending;
}
void CHardwareConfig::SetCSMAccurateBlending( bool bEnable )
{
m_bCSMAccurateBlending = bEnable;
}
bool CHardwareConfig::SupportsResolveDepth( void ) const
{
static ConVarRef mat_resolveFullFrameDepth( "mat_resolveFullFrameDepth" );
static ConVarRef gpu_level( "gpu_level" );
if ( ( gpu_level.GetInt() >= 2 ) &&
( mat_resolveFullFrameDepth.GetInt() == 1 ) )
{
#if defined(DX_TO_GL_ABSTRACTION)
{
if ( gGL->m_bHave_GL_EXT_framebuffer_blit )
{
return true;
}
else
{
return false;
}
}
#else
{
if ( g_pHardwareConfig->ActualCaps().m_bSupportsINTZ &&
( g_pHardwareConfig->ActualCaps().m_bSupportsRESZ || ( g_pHardwareConfig->ActualCaps().m_VendorID == VENDORID_NVIDIA ) ) )
{
return true;
}
else
{
return false;
}
}
#endif
}
else
{
return false;
}
}
bool CHardwareConfig::HasFullResolutionDepthTexture(void) const
{
static ConVarRef mat_resolveFullFrameDepth( "mat_resolveFullFrameDepth" );
if ( SupportsResolveDepth() || ( mat_resolveFullFrameDepth.GetInt() == 2 ) )
{
return true;
}
else
{
return false;
}
}
#ifdef _PS3
#include "hardwareconfig_ps3nonvirt.h"
#include "hardwareconfig_ps3nonvirt.inl"
#endif