📄 shaderapidx8.cpp
字号:
static CMaterialSystemStatsDX8 g_Stats;
CMaterialSystemStatsDX8 *g_pStats = &g_Stats;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CMaterialSystemStatsDX8, IMaterialSystemStats,
MATERIAL_SYSTEM_STATS_INTERFACE_VERSION, g_Stats )
//-----------------------------------------------------------------------------
// Accessors for major interfaces
//-----------------------------------------------------------------------------
IShaderUtil* g_pShaderUtil = 0;
IBaseFileSystem* g_pFileSystem = 0;
IDirect3DDevice* D3DDevice()
{
return g_ShaderAPIDX8.D3DDevice();
}
IDirect3D* D3D()
{
return g_ShaderAPIDX8.D3D();
}
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CShaderAPIDX8::CShaderAPIDX8() :
m_pD3D(0), m_pD3DDevice(0), m_Textures( 32 ), m_DisplayLost(false),
m_CurrStack(-1), m_ModifyTextureIdx(-1), m_pRenderMesh(0), m_OtherAppInitializing(false),
m_IsResizing(false), m_CurrentFrame(0), m_CachedAmbientLightCube(STATE_CHANGED),
m_InSelectionMode(false), m_SelectionMinZ(FLT_MAX), m_SelectionMaxZ(FLT_MIN),
m_pSelectionBuffer(0), m_pSelectionBufferEnd(0), m_ModifyTextureLockedLevel(-1),
m_pDebugFont( NULL ), m_pBackBufferSurface(0), m_pZBufferSurface(0)
{
memset( m_pMatrixStack, 0, sizeof(ID3DXMatrixStack*) * NUM_MATRIX_MODES );
memset( &m_DynamicState, 0, sizeof(m_DynamicState) );
memset( &m_Mode, 0, sizeof(m_Mode) );
memset( &m_Caps, 0, sizeof(m_Caps) );
m_FirstLightmapId = m_LastLightmapId = -1;
m_Mode.m_Format = (ImageFormat)-1;
m_DynamicState.m_HeightClipMode = MATERIAL_HEIGHTCLIPMODE_DISABLE;
m_nWindowHeight = m_nWindowWidth = 0;
m_SceneFogColor[0] = 0;
m_SceneFogColor[1] = 0;
m_SceneFogColor[2] = 0;
m_SceneFogMode = MATERIAL_FOG_NONE;
// 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 = 256;
// We haven't yet detected whether we support CreateQuery or not yet.
m_DeviceSupportsCreateQuery = -1;
}
CShaderAPIDX8::~CShaderAPIDX8()
{
if (m_DynamicState.m_pPixelShaderConstant)
delete[] m_DynamicState.m_pPixelShaderConstant;
if (m_DynamicState.m_pVertexShaderConstant)
delete[] m_DynamicState.m_pVertexShaderConstant;
}
//-----------------------------------------------------------------------------
// Initialization
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::Init( IShaderUtil* pShaderUtil, IBaseFileSystem* pFileSystem, int nAdapter, int nAdapterFlags )
{
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
m_pFrameSyncQueryObject = NULL;
// So others can access it
g_pShaderUtil = pShaderUtil;
g_pFileSystem = pFileSystem;
// Read dx support levels
ReadDXSupportLevels();
// Create the main interface
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (!m_pD3D)
return false;
// Set up hardware information for this adapter...
m_DeviceType = (nAdapterFlags & MATERIAL_INIT_REFERENCE_RASTERIZER) ?
D3DDEVTYPE_REF : D3DDEVTYPE_HAL;
m_DisplayAdapter = nAdapter;
if ( m_DisplayAdapter >= (UINT)GetDisplayAdapterCount() )
{
m_DisplayAdapter = 0;
}
return DetermineHardwareCaps( );
}
//-----------------------------------------------------------------------------
// Shutdown
//-----------------------------------------------------------------------------
void CShaderAPIDX8::Shutdown( )
{
if (m_pD3D)
{
ShutdownDevice();
m_pD3D->Release();
m_pD3D = 0;
}
}
//-----------------------------------------------------------------------------
// Gets the number of adapters...
//-----------------------------------------------------------------------------
int CShaderAPIDX8::GetDisplayAdapterCount() const
{
Assert( m_pD3D );
return m_pD3D->GetAdapterCount( );
}
//-----------------------------------------------------------------------------
// Returns info about each adapter
//-----------------------------------------------------------------------------
void CShaderAPIDX8::GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const
{
Assert( m_pD3D && (adapter < GetDisplayAdapterCount()) );
HRESULT hr;
D3DADAPTER_IDENTIFIER ident;
hr = m_pD3D->GetAdapterIdentifier( adapter, D3DENUM_WHQL_LEVEL, &ident );
Assert( !FAILED(hr) );
Q_strncpy( info.m_pDriverName, ident.Driver, MATERIAL_ADAPTER_NAME_LENGTH );
Q_strncpy( info.m_pDriverDescription, ident.Description, MATERIAL_ADAPTER_NAME_LENGTH );
}
//-----------------------------------------------------------------------------
// Returns the number of modes
//-----------------------------------------------------------------------------
int CShaderAPIDX8::GetModeCount( int adapter ) const
{
Assert( m_pD3D && (adapter < GetDisplayAdapterCount()) );
// fixme - what format should I use here?
return m_pD3D->GetAdapterModeCount( adapter, D3DFMT_X8R8G8B8 );
}
//-----------------------------------------------------------------------------
// Returns mode information..
//-----------------------------------------------------------------------------
void CShaderAPIDX8::GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const
{
Assert( m_pD3D && (adapter < GetDisplayAdapterCount()) );
Assert( mode < GetModeCount( adapter ) );
HRESULT hr;
D3DDISPLAYMODE d3dInfo;
// fixme - what format should I use here?
hr = m_pD3D->EnumAdapterModes( adapter, D3DFMT_X8R8G8B8, mode, &d3dInfo );
Assert( !FAILED(hr) );
info.m_Width = d3dInfo.Width;
info.m_Height = d3dInfo.Height;
info.m_Format = D3DFormatToImageFormat( d3dInfo.Format );
info.m_RefreshRate = d3dInfo.RefreshRate;
}
//-----------------------------------------------------------------------------
// Returns the mode info for the current display device
//-----------------------------------------------------------------------------
void CShaderAPIDX8::GetDisplayMode( MaterialVideoMode_t& info ) const
{
Assert( m_pD3D );
HRESULT hr;
D3DDISPLAYMODE mode;
hr = m_pD3D->GetAdapterDisplayMode( m_DisplayAdapter, &mode );
Assert( !FAILED(hr) );
info.m_Width = mode.Width;
info.m_Height = mode.Height;
info.m_Format = D3DFormatToImageFormat( mode.Format );
info.m_RefreshRate = mode.RefreshRate;
}
bool CShaderAPIDX8::Prefer16BitTextures( void ) const
{
return ::Prefer16BitTextures();
}
//-----------------------------------------------------------------------------
// Validates the mode...
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::ValidateMode( void* hwnd,
const MaterialVideoMode_t & mode, int flags ) const
{
// validate...
if (m_DisplayAdapter >= (int)m_pD3D->GetAdapterCount())
return false;
if (flags & MATERIAL_VIDEO_MODE_WINDOWED)
{
// make sure the window fits within the current video mode
MaterialVideoMode_t displayMode;
GetDisplayMode( displayMode );
if ((mode.m_Width >= displayMode.m_Width) ||
(mode.m_Height >= displayMode.m_Height))
return false;
}
else
{
// If the width and height == 0, then we just use whatever the current
// video mode is
if ((mode.m_Width == 0) && (mode.m_Height == 0))
return true;
// make sure we support that display mode
MaterialVideoMode_t testMode;
int count = GetModeCount( m_DisplayAdapter );
for (int i = 0; i < count; ++i)
{
GetModeInfo( m_DisplayAdapter, i, testMode );
// Found a match, we're ok
if ((testMode.m_Width == mode.m_Width) &&
(testMode.m_Height == mode.m_Height) &&
(testMode.m_Format == mode.m_Format) &&
((mode.m_RefreshRate == 0) || (testMode.m_RefreshRate == mode.m_RefreshRate)) )
{
return true;
}
}
// not found baby
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Do we have to change the device, or can we do something simpler...
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::DoesModeRequireDeviceChange( void* hwnd,
const MaterialVideoMode_t &mode, int flags ) const
{
if (m_HWnd != (HWND)hwnd)
return true;
if ((flags & MATERIAL_VIDEO_MODE_RESIZING) != (m_ModeFlags & MATERIAL_VIDEO_MODE_RESIZING))
return true;
return false;
}
//-----------------------------------------------------------------------------
// Can we render windowed?
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::CanRenderWindowed( ) const
{
// DX9 only supports dx7 drivers and above. All existing dx7 can render in windowed mode.
return true;
}
//-----------------------------------------------------------------------------
// Computes the supersample flags
//-----------------------------------------------------------------------------
static D3DMULTISAMPLE_TYPE ComputeMultisampleType( int nSampleCount )
{
switch (nSampleCount)
{
case 2: return D3DMULTISAMPLE_2_SAMPLES;
case 3: return D3DMULTISAMPLE_3_SAMPLES;
case 4: return D3DMULTISAMPLE_4_SAMPLES;
case 5: return D3DMULTISAMPLE_5_SAMPLES;
case 6: return D3DMULTISAMPLE_6_SAMPLES;
case 7: return D3DMULTISAMPLE_7_SAMPLES;
case 8: return D3DMULTISAMPLE_8_SAMPLES;
case 9: return D3DMULTISAMPLE_9_SAMPLES;
case 10: return D3DMULTISAMPLE_10_SAMPLES;
case 11: return D3DMULTISAMPLE_11_SAMPLES;
case 12: return D3DMULTISAMPLE_12_SAMPLES;
case 13: return D3DMULTISAMPLE_13_SAMPLES;
case 14: return D3DMULTISAMPLE_14_SAMPLES;
case 15: return D3DMULTISAMPLE_15_SAMPLES;
case 16: return D3DMULTISAMPLE_16_SAMPLES;
default:
case 0:
case 1:
return D3DMULTISAMPLE_NONE;
}
}
//-----------------------------------------------------------------------------
// Sets the present parameters
//-----------------------------------------------------------------------------
void CShaderAPIDX8::SetPresentParameters( const MaterialVideoMode_t &mode, int flags, int nSampleCount )
{
D3DDISPLAYMODE d3ddm;
HRESULT hr = m_pD3D->GetAdapterDisplayMode( m_DisplayAdapter, &d3ddm );
if (FAILED(hr))
return;
bool windowed = (flags & MATERIAL_VIDEO_MODE_WINDOWED) != 0;
bool resizing = (flags & MATERIAL_VIDEO_MODE_RESIZING) != 0;
ZeroMemory( &m_PresentParameters, sizeof(m_PresentParameters) );
m_PresentParameters.Windowed = windowed;
m_PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
// m_PresentParameters.SwapEffect = D3DSWAPEFFECT_FLIP;
// m_PresentParameters.SwapEffect = D3DSWAPEFFECT_COPY;
m_PresentParameters.EnableAutoDepthStencil = TRUE;
m_PresentParameters.AutoDepthStencilFormat = FindNearestSupportedDepthFormat( D3DFMT_D24S8 );
m_PresentParameters.hDeviceWindow = m_HWnd;
// If we can't use CreateQuery() to check for the end of a frame, then we have to lock the backbuffer
m_PresentParameters.Flags = 0;
#ifdef D3D_BUG_TRACKED_DOWN
if( m_DeviceSupportsCreateQuery == 0 )
#else
// NJS: Until we track down the D3D bug, basically force a lockable backbuffer unless createQuery is already detected.
if( m_DeviceSupportsCreateQuery != 1 )
#endif
{
m_PresentParameters.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
}
if (!windowed)
{
bool useDefault = (mode.m_Width == 0) || (mode.m_Height == 0);
m_PresentParameters.BackBufferWidth = useDefault ? d3ddm.Width : mode.m_Width;
m_PresentParameters.BackBufferHeight = useDefault ? d3ddm.Height : mode.m_Height;
if( g_pHardwareConfig->GetDXSupportLevel() >= 90 && g_pHardwareConfig->SupportsHDR() )
{
// hack to get dest alpha
m_PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8;
}
else
{
m_PresentParameters.BackBufferFormat = useDefault ? d3ddm.Format : ImageFormatToD3DFormat( mode.m_Format );
}
m_PresentParameters.BackBufferCount = 1;
if (flags & MATERIAL_VIDEO_MODE_NO_WAIT_FOR_VSYNC)
m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
else
m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
m_PresentParameters.FullScreen_RefreshRateInHz = useDefault || !mode.m_RefreshRate ?
D3DPRESENT_RATE_DEFAULT : mode.m_RefreshRate;
}
else
{
// NJS: We are seeing a lot of time spent in present in some cases when this isn't set.
m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
/*
if (flags & MATERIAL_VIDEO_MODE_NO_WAIT_FOR_VSYNC)
m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
else
m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
*/
if (resizing)
{
// When in resizing windowed mode,
// we want to allocate enough memory to deal with any resizing...
m_PresentParameters.BackBufferWidth = d3ddm.Width;
m_PresentParameters.BackBufferHeight = d3ddm.Height;
}
else
{
m_PresentParameters.BackBufferWidth = mode.m_Width;
m_PresentParameters.BackBufferHeight = mode.m_Height;
}
if( g_pHardwareConfig->GetDXSupportLevel() >= 90 && g_pHardwareConfig->SupportsHDR() )
{
// hack to get dest alpha
m_PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8;
}
else
{
m_PresentParameters.BackBufferFormat = d3ddm.Format;
}
m_PresentParameters.BackBufferCount = 1;
}
if (flags & MATERIAL_VIDEO_MODE_ANTIALIAS)
{
DWORD nQualityLevel;
D3DMULTISAMPLE_TYPE multiSampleType = ComputeMultisampleType( nSampleCount );
hr = m_pD3D->CheckDeviceMultiSampleType( m_DisplayAdapter, m_DeviceType,
m_PresentParameters.BackBufferFormat, m_PresentParameters.Windowed,
multiSampleType, &nQualityLevel
);
if (!FAILED(hr))
{
m_PresentParameters.MultiSampleType = multiSampleType;
m_PresentParameters.MultiSampleQuality = nQualityLevel - 1;
}
}
}
ImageFormat CShaderAPIDX8::GetBackBufferFormat() const
{
return D3DFormatToImageFormat( m_PresentParameters.BackBufferFormat );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -