mirror of
https://github.com/celisej567/cool-source-archive.git
synced 2026-01-04 14:11:16 +03:00
1155 lines
36 KiB
C++
1155 lines
36 KiB
C++
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//===========================================================================//
|
|
|
|
// HUH???
|
|
#define RAD_TELEMETRY_DISABLED
|
|
|
|
#include "Dx11Global.h"
|
|
#include "shaderdevicedx11.h"
|
|
#include "shaderapi/ishaderutil.h"
|
|
#include "shaderapidx11.h"
|
|
#include "shadershadowdx11.h"
|
|
#include "IndexBufferDx11.h"
|
|
#include "VertexBufferDx11.h"
|
|
#include "shaderapidx11_global.h"
|
|
#include "tier1/keyvalues.h"
|
|
#include "tier2/tier2.h"
|
|
#include "tier0/icommandline.h"
|
|
#include "inputlayoutdx11.h"
|
|
#include "shaderapidx9/shaderapibase.h"
|
|
#include "meshdx11.h"
|
|
#include "TextureDx11.h"
|
|
|
|
// NOTE: This has to be the last file included!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
// this is hooked into the engines convar
|
|
ConVar mat_debugalttab( "mat_debugalttab", "0", FCVAR_CHEAT );
|
|
|
|
// For testing Fast Clip
|
|
ConVar mat_fastclip("mat_fastclip", "0", FCVAR_CHEAT);
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Explicit instantiation of shader buffer implementation
|
|
//-----------------------------------------------------------------------------
|
|
template class CShaderBuffer< ID3DBlob >;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Globals
|
|
//-----------------------------------------------------------------------------
|
|
ID3D11Device *g_pD3DDevice = NULL;
|
|
ID3D11DeviceContext *g_pD3DDeviceContext = NULL;
|
|
IDXGISwapChain *g_pD3DSwapChain = NULL;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Device manager
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
static CShaderDeviceMgrDx11 g_ShaderDeviceMgrDx11;
|
|
|
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderDeviceMgrDx11, IShaderDeviceMgr,
|
|
SHADER_DEVICE_MGR_INTERFACE_VERSION, g_ShaderDeviceMgrDx11 )
|
|
|
|
static CShaderDeviceDx11 g_ShaderDeviceDx11;
|
|
CShaderDeviceDx11* g_pShaderDeviceDx11 = &g_ShaderDeviceDx11;
|
|
|
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderDeviceDx11, IShaderDevice,
|
|
SHADER_DEVICE_INTERFACE_VERSION, g_ShaderDeviceDx11 )
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// constructor, destructor
|
|
//-----------------------------------------------------------------------------
|
|
CShaderDeviceMgrDx11::CShaderDeviceMgrDx11()
|
|
{
|
|
m_pDXGIFactory = NULL;
|
|
m_bSetupAdapters = false;
|
|
m_bObeyDxCommandlineOverride = true;
|
|
}
|
|
|
|
CShaderDeviceMgrDx11::~CShaderDeviceMgrDx11()
|
|
{
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Connect, disconnect
|
|
//-----------------------------------------------------------------------------
|
|
bool CShaderDeviceMgrDx11::Connect( CreateInterfaceFn factory )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
|
|
Log("Connecting CShaderDeviceMgrDx11...\n");
|
|
|
|
if ( !BaseClass::Connect( factory ) )
|
|
return false;
|
|
|
|
HRESULT hr = CreateDXGIFactory1( __uuidof(IDXGIFactory1), (void**)(&m_pDXGIFactory) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
Warning( "Failed to create the DXGI Factory!\n" );
|
|
return false;
|
|
}
|
|
|
|
InitAdapterInfo();
|
|
return true;
|
|
}
|
|
|
|
void CShaderDeviceMgrDx11::Disconnect()
|
|
{
|
|
LOCK_SHADERAPI();
|
|
|
|
if ( m_pDXGIFactory )
|
|
{
|
|
m_pDXGIFactory->Release();
|
|
m_pDXGIFactory = NULL;
|
|
}
|
|
|
|
BaseClass::Disconnect();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Initialization
|
|
//-----------------------------------------------------------------------------
|
|
InitReturnVal_t CShaderDeviceMgrDx11::Init( )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
|
|
InitAdapterInfo();
|
|
|
|
return INIT_OK;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Shutdown
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceMgrDx11::Shutdown( )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
|
|
if ( g_pShaderDevice )
|
|
{
|
|
g_pShaderDevice->ShutdownDevice();
|
|
g_pShaderDevice = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Initialize adapter information
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceMgrDx11::InitAdapterInfo()
|
|
{
|
|
if ( m_bSetupAdapters )
|
|
return;
|
|
|
|
m_Adapters.RemoveAll();
|
|
|
|
IDXGIAdapter *pAdapter;
|
|
for( UINT nCount = 0; m_pDXGIFactory->EnumAdapters( nCount, &pAdapter ) != DXGI_ERROR_NOT_FOUND; ++nCount )
|
|
{
|
|
IDXGIOutput *pOutput = GetAdapterOutput( nCount );
|
|
//Log( "pOutput: %p\n", pAdapter );
|
|
if ( !pOutput )
|
|
break;
|
|
|
|
int j = m_Adapters.AddToTail();
|
|
AdapterInfo_t &info = m_Adapters[j];
|
|
|
|
#ifdef _DEBUG
|
|
memset( &info.m_ActualCaps, 0xDD, sizeof(info.m_ActualCaps) );
|
|
#endif
|
|
|
|
|
|
info.m_ActualCaps.m_bDeviceOk = ComputeCapsFromD3D( &info.m_ActualCaps, pAdapter, pOutput );
|
|
if ( !info.m_ActualCaps.m_bDeviceOk )
|
|
continue;
|
|
|
|
ReadDXSupportLevels( info.m_ActualCaps );
|
|
|
|
// Read dxsupport.cfg which has config overrides for particular cards.
|
|
ReadHardwareCaps( info.m_ActualCaps, info.m_ActualCaps.m_nMaxDXSupportLevel );
|
|
|
|
// What's in "-shader" overrides dxsupport.cfg
|
|
const char *pShaderParam = CommandLine()->ParmValue( "-shader" );
|
|
if ( pShaderParam )
|
|
{
|
|
Q_strncpy( info.m_ActualCaps.m_pShaderDLL, pShaderParam, sizeof( info.m_ActualCaps.m_pShaderDLL ) );
|
|
}
|
|
}
|
|
|
|
m_bSetupAdapters = true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Determines hardware caps from D3D
|
|
//-----------------------------------------------------------------------------
|
|
bool CShaderDeviceMgrDx11::ComputeCapsFromD3D( HardwareCaps_t *pCaps, IDXGIAdapter *pAdapter, IDXGIOutput *pOutput )
|
|
{
|
|
DXGI_ADAPTER_DESC desc;
|
|
HRESULT hr = pAdapter->GetDesc( &desc );
|
|
Assert( !FAILED( hr ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
Warning( "Dx11: Couldn't get adapter desc\n" );
|
|
return false;
|
|
}
|
|
|
|
|
|
bool bForceFloatHDR = ( CommandLine()->CheckParm( "-floathdr" ) != NULL );
|
|
|
|
// DX10 settings
|
|
// NOTE: We'll need to have different settings for dx10.1 and dx11
|
|
Q_UnicodeToUTF8( desc.Description, pCaps->m_pDriverName, MATERIAL_ADAPTER_NAME_LENGTH );
|
|
pCaps->m_VendorID = desc.VendorId;
|
|
pCaps->m_DeviceID = desc.DeviceId;
|
|
pCaps->m_SubSysID = desc.SubSysId;
|
|
pCaps->m_Revision = desc.Revision;
|
|
pCaps->m_NumSamplers = 16;
|
|
pCaps->m_NumTextureStages = 0;
|
|
pCaps->m_HasSetDeviceGammaRamp = true;
|
|
pCaps->m_bSoftwareVertexProcessing = false;
|
|
pCaps->m_SupportsVertexShaders = true;
|
|
pCaps->m_SupportsVertexShaders_2_0 = true;
|
|
pCaps->m_SupportsPixelShaders = true;
|
|
pCaps->m_SupportsPixelShaders_1_4 = true;
|
|
pCaps->m_SupportsPixelShaders_2_0 = true;
|
|
pCaps->m_SupportsPixelShaders_2_b = true;
|
|
pCaps->m_SupportsShaderModel_3_0 = true;
|
|
pCaps->m_SupportsCompressedTextures = COMPRESSED_TEXTURES_ON;
|
|
pCaps->m_SupportsCompressedVertices = VERTEX_COMPRESSION_NONE;
|
|
pCaps->m_bSupportsAnisotropicFiltering = true;
|
|
pCaps->m_bSupportsMagAnisotropicFiltering = true;
|
|
pCaps->m_bSupportsVertexTextures = true;
|
|
pCaps->m_nMaxAnisotropy = D3D11_REQ_MAXANISOTROPY;
|
|
pCaps->m_MaxTextureWidth = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
|
pCaps->m_MaxTextureHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
|
pCaps->m_MaxTextureDepth = D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
|
|
pCaps->m_MaxTextureAspectRatio = 1024; // FIXME
|
|
pCaps->m_MaxPrimitiveCount = 65536; // FIXME
|
|
pCaps->m_ZBiasAndSlopeScaledDepthBiasSupported = true;
|
|
pCaps->m_SupportsMipmapping = false; // FIXME
|
|
pCaps->m_SupportsOverbright = true;
|
|
pCaps->m_SupportsCubeMaps = true;
|
|
pCaps->m_NumPixelShaderConstants = 1024; // FIXME
|
|
pCaps->m_NumVertexShaderConstants = 1024; // FIXME
|
|
pCaps->m_TextureMemorySize = desc.DedicatedVideoMemory;
|
|
pCaps->m_MaxNumLights = 4;
|
|
pCaps->m_SupportsHardwareLighting = false;
|
|
pCaps->m_MaxBlendMatrices = 0;
|
|
pCaps->m_MaxBlendMatrixIndices = 0;
|
|
pCaps->m_MaxVertexShaderBlendMatrices = 53; // FIXME
|
|
pCaps->m_SupportsMipmappedCubemaps = true;
|
|
pCaps->m_SupportsNonPow2Textures = true;
|
|
pCaps->m_nDXSupportLevel = 110;
|
|
pCaps->m_PreferDynamicTextures = true;
|
|
pCaps->m_HasProjectedBumpEnv = true;
|
|
pCaps->m_MaxUserClipPlanes = 6; // FIXME
|
|
pCaps->m_HDRType = bForceFloatHDR ? HDR_TYPE_FLOAT : HDR_TYPE_INTEGER;
|
|
pCaps->m_MaxHDRType = HDR_TYPE_FLOAT;
|
|
pCaps->m_SupportsSRGB = true;
|
|
pCaps->m_bSupportsSpheremapping = true;
|
|
pCaps->m_UseFastClipping = false;
|
|
pCaps->m_pShaderDLL[0] = 0;
|
|
pCaps->m_bNeedsATICentroidHack = false;
|
|
pCaps->m_bColorOnSecondStream = true;
|
|
pCaps->m_bSupportsStreamOffset = true;
|
|
pCaps->m_nMaxDXSupportLevel = 110;
|
|
pCaps->m_bFogColorSpecifiedInLinearSpace = ( desc.VendorId == VENDORID_NVIDIA );
|
|
pCaps->m_nVertexTextureCount = 16;
|
|
pCaps->m_nMaxVertexTextureDimension = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
|
pCaps->m_bSupportsAlphaToCoverage = true; // FIXME
|
|
pCaps->m_bSupportsShadowDepthTextures = true;
|
|
pCaps->m_bSupportsFetch4 = ( desc.VendorId == VENDORID_ATI );
|
|
#if defined( COMPRESSED_NORMAL_FORMATS )
|
|
pCaps->m_bSupportsNormalMapCompression = true;
|
|
#else
|
|
pCaps->m_bSupportsNormalMapCompression = false;
|
|
#endif
|
|
pCaps->m_bSupportsBorderColor = true;
|
|
pCaps->m_ShadowDepthTextureFormat = IMAGE_FORMAT_UNKNOWN;
|
|
pCaps->m_nMaxViewports = 4;
|
|
|
|
//DXGI_GAMMA_CONTROL_CAPABILITIES gammaCaps;
|
|
//pOutput->GetGammaControlCapabilities( &gammaCaps );
|
|
//pCaps->m_flMinGammaControlPoint = gammaCaps.MinConvertedValue;
|
|
//pCaps->m_flMaxGammaControlPoint = gammaCaps.MaxConvertedValue;
|
|
//pCaps->m_nGammaControlPointCount = gammaCaps.NumGammaControlPoints;
|
|
pCaps->m_flMinGammaControlPoint = 0.0f;
|
|
pCaps->m_flMaxGammaControlPoint = 65535.0f;
|
|
pCaps->m_nGammaControlPointCount = 256;
|
|
Log( "Set gamma control capabilities %f %f %i\n", pCaps->m_flMaxGammaControlPoint, pCaps->m_flMaxGammaControlPoint, pCaps->m_nGammaControlPointCount );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets the number of adapters...
|
|
//-----------------------------------------------------------------------------
|
|
int CShaderDeviceMgrDx11::GetAdapterCount() const
|
|
{
|
|
return m_Adapters.Count();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns info about each adapter
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceMgrDx11::GetAdapterInfo( int nAdapter, MaterialAdapterInfo_t& info ) const
|
|
{
|
|
Assert( ( nAdapter >= 0 ) && ( nAdapter < m_Adapters.Count() ) );
|
|
const HardwareCaps_t &caps = m_Adapters[ nAdapter ].m_ActualCaps;
|
|
//Log( "Driver name: %s\n", caps.m_pDriverName );
|
|
memcpy( &info, &caps, sizeof(MaterialAdapterInfo_t) );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the adapter interface for a particular adapter
|
|
//-----------------------------------------------------------------------------
|
|
IDXGIAdapter* CShaderDeviceMgrDx11::GetAdapter( int nAdapter ) const
|
|
{
|
|
Assert( m_pDXGIFactory );
|
|
|
|
IDXGIAdapter *pAdapter;
|
|
HRESULT hr = m_pDXGIFactory->EnumAdapters( nAdapter, &pAdapter );
|
|
return ( FAILED(hr) ) ? NULL : pAdapter;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the amount of video memory in bytes for a particular adapter
|
|
//-----------------------------------------------------------------------------
|
|
int CShaderDeviceMgrDx11::GetVidMemBytes( int nAdapter ) const
|
|
{
|
|
LOCK_SHADERAPI();
|
|
IDXGIAdapter *pAdapter = GetAdapter( nAdapter );
|
|
if ( !pAdapter )
|
|
return 0;
|
|
|
|
DXGI_ADAPTER_DESC desc;
|
|
|
|
#ifdef _DEBUG
|
|
HRESULT hr =
|
|
#endif
|
|
pAdapter->GetDesc( &desc );
|
|
Assert( !FAILED( hr ) );
|
|
return desc.DedicatedVideoMemory;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the appropriate adapter output to use
|
|
//-----------------------------------------------------------------------------
|
|
IDXGIOutput* CShaderDeviceMgrDx11::GetAdapterOutput( int nAdapter ) const
|
|
{
|
|
LOCK_SHADERAPI();
|
|
IDXGIAdapter *pAdapter = GetAdapter( nAdapter );
|
|
if ( !pAdapter )
|
|
return 0;
|
|
|
|
IDXGIOutput *pOutput;
|
|
for( UINT i = 0; pAdapter->EnumOutputs( i, &pOutput ) != DXGI_ERROR_NOT_FOUND; ++i )
|
|
{
|
|
DXGI_OUTPUT_DESC desc;
|
|
HRESULT hr = pOutput->GetDesc( &desc );
|
|
if ( FAILED( hr ) )
|
|
continue;
|
|
|
|
// FIXME: Is this what I want? Or should I be looking at other fields,
|
|
// like DXGI_MODE_ROTATION_IDENTITY?
|
|
if ( !desc.AttachedToDesktop )
|
|
continue;
|
|
|
|
return pOutput;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the number of modes
|
|
//-----------------------------------------------------------------------------
|
|
int CShaderDeviceMgrDx11::GetModeCount( int nAdapter ) const
|
|
{
|
|
LOCK_SHADERAPI();
|
|
Assert( m_pDXGIFactory && ( nAdapter < GetAdapterCount() ) );
|
|
|
|
IDXGIOutput *pOutput = GetAdapterOutput( nAdapter );
|
|
if ( !pOutput )
|
|
return 0;
|
|
|
|
UINT num = 0;
|
|
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; //desired color format
|
|
UINT flags = DXGI_ENUM_MODES_INTERLACED; //desired scanline order and/or scaling
|
|
|
|
// get the number of available display mode for the given format and scanline order
|
|
HRESULT hr = pOutput->GetDisplayModeList( format, flags, &num, 0 );
|
|
return ( FAILED(hr) ) ? 0 : num;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns mode information..
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceMgrDx11::GetModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter, int nMode ) const
|
|
{
|
|
// Default error state
|
|
pInfo->m_nWidth = pInfo->m_nHeight = 0;
|
|
pInfo->m_Format = IMAGE_FORMAT_UNKNOWN;
|
|
pInfo->m_nRefreshRateNumerator = pInfo->m_nRefreshRateDenominator = 0;
|
|
|
|
LOCK_SHADERAPI();
|
|
Assert( m_pDXGIFactory && ( nAdapter < GetAdapterCount() ) );
|
|
|
|
IDXGIOutput *pOutput = GetAdapterOutput( nAdapter );
|
|
if ( !pOutput )
|
|
return;
|
|
|
|
UINT num = 0;
|
|
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; //desired color format
|
|
UINT flags = DXGI_ENUM_MODES_INTERLACED; //desired scanline order and/or scaling
|
|
|
|
// get the number of available display mode for the given format and scanline order
|
|
HRESULT hr = pOutput->GetDisplayModeList( format, flags, &num, 0 );
|
|
Assert( !FAILED( hr ) );
|
|
|
|
if ( (UINT)nMode >= num )
|
|
return;
|
|
|
|
DXGI_MODE_DESC *pDescs = (DXGI_MODE_DESC*)_alloca( num * sizeof( DXGI_MODE_DESC ) );
|
|
hr = pOutput->GetDisplayModeList( format, flags, &num, pDescs );
|
|
Assert( !FAILED( hr ) );
|
|
|
|
pInfo->m_nWidth = pDescs[nMode].Width;
|
|
pInfo->m_nHeight = pDescs[nMode].Height;
|
|
pInfo->m_Format = CTextureDx11::GetImageFormat( pDescs[nMode].Format );
|
|
pInfo->m_nRefreshRateNumerator = pDescs[nMode].RefreshRate.Numerator;
|
|
pInfo->m_nRefreshRateDenominator = pDescs[nMode].RefreshRate.Denominator;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the current mode for an adapter
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceMgrDx11::GetCurrentModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter ) const
|
|
{
|
|
// FIXME: Implement!
|
|
Assert( 0 );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Initialization, shutdown
|
|
//-----------------------------------------------------------------------------
|
|
bool CShaderDeviceMgrDx11::SetAdapter( int nAdapter, int nFlags )
|
|
{
|
|
Assert( m_bSetupAdapters && nAdapter < m_Adapters.Count() );
|
|
HardwareCaps_t &actualCaps = g_pHardwareConfig->ActualCapsForEdit();
|
|
ComputeCapsFromD3D( &actualCaps, GetAdapter( nAdapter ), GetAdapterOutput( nAdapter ) );
|
|
ReadDXSupportLevels( actualCaps );
|
|
ReadHardwareCaps( actualCaps, actualCaps.m_nMaxDXSupportLevel );
|
|
|
|
// What's in "-shader" overrides dxsupport.cfg
|
|
const char *pShaderParam = CommandLine()->ParmValue( "-shader" );
|
|
if ( pShaderParam )
|
|
{
|
|
Q_strncpy( actualCaps.m_pShaderDLL, pShaderParam, sizeof( actualCaps.m_pShaderDLL ) );
|
|
}
|
|
|
|
g_pHardwareConfig->SetupHardwareCaps( actualCaps.m_nDXSupportLevel, actualCaps );
|
|
|
|
g_pShaderDevice = g_pShaderDeviceDx11;
|
|
g_pShaderDeviceDx11->m_nAdapter = nAdapter;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Sets the mode
|
|
//-----------------------------------------------------------------------------
|
|
CreateInterfaceFn CShaderDeviceMgrDx11::SetMode( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
|
|
//Log("Calling CShaderDeviceMgrDx11::SetMode()\n");
|
|
|
|
Assert( nAdapter < GetAdapterCount() );
|
|
int nDXLevel = mode.m_nDXLevel != 0 ? mode.m_nDXLevel : m_Adapters[nAdapter].m_ActualCaps.m_nDXSupportLevel;
|
|
if ( m_bObeyDxCommandlineOverride )
|
|
{
|
|
nDXLevel = CommandLine()->ParmValue( "-dxlevel", nDXLevel );
|
|
m_bObeyDxCommandlineOverride = false;
|
|
}
|
|
if ( nDXLevel > m_Adapters[nAdapter].m_ActualCaps.m_nMaxDXSupportLevel )
|
|
{
|
|
nDXLevel = m_Adapters[nAdapter].m_ActualCaps.m_nMaxDXSupportLevel;
|
|
}
|
|
nDXLevel = GetClosestActualDXLevel( nDXLevel );
|
|
Log("nDXLevel: %i\n", nDXLevel);
|
|
if ( nDXLevel < 110 )
|
|
{
|
|
// Fall back to the Dx9 implementations
|
|
//return g_pShaderDeviceMgrDx8->SetMode( hWnd, nAdapter, mode );
|
|
Error( "DirectX 11 unsupported!" );
|
|
Assert( 0 );
|
|
return NULL;
|
|
}
|
|
|
|
if ( g_pShaderAPI )
|
|
{
|
|
g_pShaderAPI->OnDeviceShutdown();
|
|
g_pShaderAPI = NULL;
|
|
}
|
|
|
|
if ( g_pShaderDevice )
|
|
{
|
|
g_pShaderDevice->ShutdownDevice();
|
|
g_pShaderDevice = NULL;
|
|
}
|
|
|
|
g_pShaderShadow = NULL;
|
|
|
|
ShaderDeviceInfo_t adjustedMode = mode;
|
|
adjustedMode.m_nDXLevel = nDXLevel;
|
|
if ( !g_pShaderDeviceDx11->InitDevice( hWnd, nAdapter, adjustedMode ) )
|
|
return NULL;
|
|
|
|
if ( !g_pShaderAPIDx11->OnDeviceInit() )
|
|
return NULL;
|
|
|
|
g_pShaderDevice = g_pShaderDeviceDx11;
|
|
g_pShaderAPI = g_pShaderAPIDx11;
|
|
g_pShaderShadow = g_pShaderShadowDx11;
|
|
|
|
return ShaderInterfaceFactory;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Device
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// constructor, destructor
|
|
//-----------------------------------------------------------------------------
|
|
CShaderDeviceDx11::CShaderDeviceDx11()
|
|
{
|
|
m_pDevice = NULL;
|
|
m_pDeviceContext = NULL;
|
|
m_pOutput = NULL;
|
|
m_pSwapChain = NULL;
|
|
m_bDeviceInitialized = false;
|
|
}
|
|
|
|
CShaderDeviceDx11::~CShaderDeviceDx11()
|
|
{
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Sets the mode
|
|
//-----------------------------------------------------------------------------
|
|
bool CShaderDeviceDx11::InitDevice( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode )
|
|
{
|
|
// Make sure we've been shutdown previously
|
|
if ( m_bDeviceInitialized )
|
|
{
|
|
Warning( "CShaderDeviceDx11::SetMode: Previous mode has not been shut down!\n" );
|
|
return false;
|
|
}
|
|
|
|
LOCK_SHADERAPI();
|
|
IDXGIAdapter *pAdapter = g_ShaderDeviceMgrDx11.GetAdapter( nAdapter );
|
|
if ( !pAdapter )
|
|
return false;
|
|
|
|
m_pOutput = g_ShaderDeviceMgrDx11.GetAdapterOutput( nAdapter );
|
|
if ( !m_pOutput )
|
|
return false;
|
|
m_pOutput->AddRef();
|
|
|
|
DXGI_SWAP_CHAIN_DESC sd;
|
|
ZeroMemory( &sd, sizeof(sd) );
|
|
sd.BufferDesc.Width = mode.m_DisplayMode.m_nWidth;
|
|
sd.BufferDesc.Height = mode.m_DisplayMode.m_nHeight;
|
|
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
|
sd.BufferDesc.RefreshRate.Numerator = mode.m_DisplayMode.m_nRefreshRateNumerator;
|
|
sd.BufferDesc.RefreshRate.Denominator = mode.m_DisplayMode.m_nRefreshRateDenominator;
|
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
|
|
sd.BufferCount = mode.m_nBackBufferCount;
|
|
sd.OutputWindow = (HWND)hWnd;
|
|
sd.Windowed = mode.m_bWindowed ? TRUE : FALSE;
|
|
sd.Flags = mode.m_bWindowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
|
|
|
// NOTE: Having more than 1 back buffer disables MSAA!
|
|
sd.SwapEffect = mode.m_nBackBufferCount > 1 ? DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD;
|
|
|
|
// FIXME: Chicken + egg problem with SampleDesc.
|
|
sd.SampleDesc.Count = mode.m_nAASamples ? mode.m_nAASamples : 1;
|
|
sd.SampleDesc.Quality = mode.m_nAAQuality;
|
|
|
|
UINT nDeviceFlags = 0;
|
|
#ifdef _DEBUG
|
|
nDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
|
#endif
|
|
|
|
HRESULT hr = D3D11CreateDeviceAndSwapChain( pAdapter, D3D_DRIVER_TYPE_UNKNOWN,
|
|
NULL, nDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &sd, &m_pSwapChain,
|
|
&m_pDevice, NULL, &m_pDeviceContext );
|
|
|
|
if ( FAILED( hr ) )
|
|
return false;
|
|
|
|
g_pD3DDevice = m_pDevice;
|
|
g_pD3DDeviceContext = m_pDeviceContext;
|
|
g_pD3DSwapChain = m_pSwapChain;
|
|
|
|
m_hWnd = hWnd;
|
|
m_nAdapter = nAdapter;
|
|
|
|
// This is our current view.
|
|
m_ViewHWnd = hWnd;
|
|
GetWindowSize( m_nWindowWidth, m_nWindowHeight );
|
|
|
|
Log( "InitDevice: setupHardwareCaps\n" );
|
|
const HardwareCaps_t &caps = g_ShaderDeviceMgrDx11.GetHardwareCaps( nAdapter );
|
|
g_pHardwareConfig->SetupHardwareCaps( mode, caps );
|
|
|
|
m_bDeviceInitialized = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Shuts down the mode
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceDx11::ShutdownDevice()
|
|
{
|
|
if ( m_pDeviceContext )
|
|
{
|
|
m_pDeviceContext->Release();
|
|
m_pDeviceContext = NULL;
|
|
}
|
|
|
|
if ( m_pDevice )
|
|
{
|
|
m_pDevice->Release();
|
|
m_pDevice = NULL;
|
|
}
|
|
|
|
if ( m_pSwapChain )
|
|
{
|
|
m_pSwapChain->Release();
|
|
m_pSwapChain = NULL;
|
|
}
|
|
|
|
if ( m_pOutput )
|
|
{
|
|
m_pOutput->Release();
|
|
m_pOutput = NULL;
|
|
}
|
|
|
|
m_hWnd = NULL;
|
|
//m_nAdapter = -1;
|
|
m_bDeviceInitialized = false;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Are we using graphics?
|
|
//-----------------------------------------------------------------------------
|
|
bool CShaderDeviceDx11::IsUsingGraphics() const
|
|
{
|
|
return m_bDeviceInitialized;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the adapter
|
|
//-----------------------------------------------------------------------------
|
|
int CShaderDeviceDx11::GetCurrentAdapter() const
|
|
{
|
|
return m_nAdapter;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get back buffer information
|
|
//-----------------------------------------------------------------------------
|
|
ImageFormat CShaderDeviceDx11::GetBackBufferFormat() const
|
|
{
|
|
return IMAGE_FORMAT_RGB888;
|
|
}
|
|
|
|
void CShaderDeviceDx11::GetBackBufferDimensions( int& width, int& height ) const
|
|
{
|
|
//width = 1024;
|
|
//height = 768;
|
|
DXGI_SWAP_CHAIN_DESC desc;
|
|
m_pSwapChain->GetDesc( &desc );
|
|
width = desc.BufferDesc.Width;
|
|
height = desc.BufferDesc.Height;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Use this to spew information about the 3D layer
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceDx11::SpewDriverInfo() const
|
|
{
|
|
Warning( "Dx11 Driver!\n" );
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Swap buffers
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceDx11::Present()
|
|
{
|
|
// Draw buffered primitives
|
|
g_pShaderAPIDx11->FlushBufferedPrimitives();
|
|
|
|
// FIXME: Deal with window occlusion, alt-tab, etc.
|
|
HRESULT hr = m_pSwapChain->Present( 0, 0 );
|
|
if ( FAILED(hr) )
|
|
{
|
|
D3D11Device()->GetDeviceRemovedReason();
|
|
Assert( 0 );
|
|
}
|
|
|
|
// Make all vertex and index buffers flush
|
|
// the next time they are locked.
|
|
MeshMgr()->DiscardVertexBuffers();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Camma ramp
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceDx11::SetHardwareGammaRamp( float fGamma, float fGammaTVRangeMin, float fGammaTVRangeMax, float fGammaTVExponent, bool bTVEnabled )
|
|
{
|
|
DevMsg( "SetHardwareGammaRamp( %f )\n", fGamma );
|
|
|
|
Assert( m_pOutput );
|
|
if( !m_pOutput )
|
|
return;
|
|
|
|
float flMin = g_pHardwareConfig->Caps().m_flMinGammaControlPoint;
|
|
float flMax = g_pHardwareConfig->Caps().m_flMaxGammaControlPoint;
|
|
int nGammaPoints = g_pHardwareConfig->Caps().m_nGammaControlPointCount;
|
|
|
|
DXGI_GAMMA_CONTROL gammaControl;
|
|
gammaControl.Scale.Red = gammaControl.Scale.Green = gammaControl.Scale.Blue = 1.0f;
|
|
gammaControl.Offset.Red = gammaControl.Offset.Green = gammaControl.Offset.Blue = 0.0f;
|
|
float flOOCount = 1.0f / ( nGammaPoints - 1 );
|
|
for ( int i = 0; i < nGammaPoints; i++ )
|
|
{
|
|
float flGamma22 = i * flOOCount;
|
|
float flCorrection = pow( flGamma22, fGamma / 2.2f );
|
|
flCorrection = clamp( flCorrection, flMin, flMax );
|
|
|
|
gammaControl.GammaCurve[i].Red = flCorrection;
|
|
gammaControl.GammaCurve[i].Green = flCorrection;
|
|
gammaControl.GammaCurve[i].Blue = flCorrection;
|
|
}
|
|
|
|
HRESULT hr = m_pOutput->SetGammaControl( &gammaControl );
|
|
if ( FAILED(hr) )
|
|
{
|
|
Warning( "CShaderDeviceDx11::SetHardwareGammaRamp: Unable to set gamma controls!\n" );
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Compiles all manner of shaders
|
|
//-----------------------------------------------------------------------------
|
|
IShaderBuffer* CShaderDeviceDx11::CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion )
|
|
{
|
|
int nCompileFlags = D3DCOMPILE_AVOID_FLOW_CONTROL;
|
|
nCompileFlags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
|
|
|
|
#ifdef _DEBUG
|
|
nCompileFlags |= D3DCOMPILE_DEBUG;
|
|
#endif
|
|
|
|
ID3DBlob *pCompiledShader, *pErrorMessages;
|
|
HRESULT hr = D3DCompile( pProgram, nBufLen, "",
|
|
NULL, NULL, "main", pShaderVersion, nCompileFlags, 0, &pCompiledShader,
|
|
&pErrorMessages );
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
if ( pErrorMessages )
|
|
{
|
|
const char *pErrorMessage = (const char *)pErrorMessages->GetBufferPointer();
|
|
Warning( "Vertex shader compilation failed! Reported the following errors:\n%s\n", pErrorMessage );
|
|
pErrorMessages->Release();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// NOTE: This uses small block heap allocator; so I'm not going
|
|
// to bother creating a memory pool.
|
|
CShaderBuffer< ID3DBlob > *pShaderBuffer = new CShaderBuffer< ID3DBlob >( pCompiledShader );
|
|
if ( pErrorMessages )
|
|
{
|
|
pErrorMessages->Release();
|
|
}
|
|
|
|
return pShaderBuffer;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Release input layouts
|
|
//-----------------------------------------------------------------------------
|
|
void CShaderDeviceDx11::ReleaseInputLayouts( VertexShaderIndex_t nIndex )
|
|
{
|
|
InputLayoutDict_t &dict = m_VertexShaderDict[nIndex].m_InputLayouts;
|
|
unsigned short hCurr = dict.FirstInorder();
|
|
while( hCurr != dict.InvalidIndex() )
|
|
{
|
|
if ( dict[hCurr].m_pInputLayout )
|
|
{
|
|
dict[hCurr].m_pInputLayout->Release();
|
|
dict[hCurr].m_pInputLayout = NULL;
|
|
}
|
|
hCurr = dict.NextInorder( hCurr );
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Create, destroy vertex shader
|
|
//-----------------------------------------------------------------------------
|
|
VertexShaderHandle_t CShaderDeviceDx11::CreateVertexShader( IShaderBuffer* pShaderBuffer )
|
|
{
|
|
return CreateVertexShader( pShaderBuffer->GetBits(), pShaderBuffer->GetSize() );
|
|
}
|
|
|
|
VertexShaderHandle_t CShaderDeviceDx11::CreateVertexShader( const void* pBuffer, size_t nBufLen )
|
|
{
|
|
// Create the vertex shader
|
|
ID3D11VertexShader* pShader = NULL;
|
|
HRESULT hr = m_pDevice->CreateVertexShader( pBuffer, nBufLen, NULL, &pShader );
|
|
|
|
if ( FAILED( hr ) || !pShader )
|
|
{
|
|
Log( "D3D11Device->CreateVertexShader() failed: error %i\n", hr );
|
|
return VERTEX_SHADER_HANDLE_INVALID;
|
|
}
|
|
|
|
ID3D11ShaderReflection* pInfo;
|
|
hr = D3DReflect( pBuffer, nBufLen, IID_ID3D11ShaderReflection, (void**)&pInfo );
|
|
if ( FAILED( hr ) || !pInfo )
|
|
{
|
|
pShader->Release();
|
|
return VERTEX_SHADER_HANDLE_INVALID;
|
|
}
|
|
|
|
// Insert the shader into the dictionary of shaders
|
|
VertexShaderIndex_t i = m_VertexShaderDict.AddToTail();
|
|
VertexShader_t& dict = m_VertexShaderDict[i];
|
|
dict.m_pShader = pShader;
|
|
dict.m_pInfo = pInfo;
|
|
dict.m_nByteCodeLen = nBufLen;
|
|
dict.m_pByteCode = new unsigned char[dict.m_nByteCodeLen];
|
|
memcpy( dict.m_pByteCode, pBuffer, dict.m_nByteCodeLen );
|
|
return (VertexShaderHandle_t)i;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyVertexShader( VertexShaderHandle_t hShader )
|
|
{
|
|
if ( hShader == VERTEX_SHADER_HANDLE_INVALID )
|
|
return;
|
|
|
|
g_pShaderAPIDx11->Unbind( hShader );
|
|
|
|
VertexShaderIndex_t i = (VertexShaderIndex_t)hShader;
|
|
VertexShader_t &dict = m_VertexShaderDict[i];
|
|
VerifyEquals( dict.m_pShader->Release(), 0 );
|
|
VerifyEquals( dict.m_pInfo->Release(), 0 );
|
|
delete[] dict.m_pByteCode;
|
|
ReleaseInputLayouts( i );
|
|
m_VertexShaderDict.Remove( i );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Create, destroy geometry shader
|
|
//-----------------------------------------------------------------------------
|
|
GeometryShaderHandle_t CShaderDeviceDx11::CreateGeometryShader( IShaderBuffer* pShaderBuffer )
|
|
{
|
|
return CreateGeometryShader( pShaderBuffer->GetBits(), pShaderBuffer->GetSize() );
|
|
}
|
|
|
|
GeometryShaderHandle_t CShaderDeviceDx11::CreateGeometryShader( const void* pBuffer, size_t nBufLen )
|
|
{
|
|
// Create the geometry shader
|
|
ID3D11GeometryShader* pShader = NULL;
|
|
HRESULT hr = m_pDevice->CreateGeometryShader( pBuffer,
|
|
nBufLen, NULL, &pShader );
|
|
|
|
if ( FAILED( hr ) || !pShader )
|
|
return GEOMETRY_SHADER_HANDLE_INVALID;
|
|
|
|
ID3D11ShaderReflection* pInfo;
|
|
hr = D3DReflect( pBuffer, nBufLen, IID_ID3D11ShaderReflection, (void**)&pInfo );
|
|
if ( FAILED( hr ) || !pInfo )
|
|
{
|
|
pShader->Release();
|
|
return GEOMETRY_SHADER_HANDLE_INVALID;
|
|
}
|
|
|
|
// Insert the shader into the dictionary of shaders
|
|
GeometryShaderIndex_t i = m_GeometryShaderDict.AddToTail();
|
|
m_GeometryShaderDict[i].m_pShader = pShader;
|
|
m_GeometryShaderDict[i].m_pInfo = pInfo;
|
|
return (GeometryShaderHandle_t)i;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyGeometryShader( GeometryShaderHandle_t hShader )
|
|
{
|
|
if ( hShader == GEOMETRY_SHADER_HANDLE_INVALID )
|
|
return;
|
|
|
|
g_pShaderAPIDx11->Unbind( hShader );
|
|
|
|
GeometryShaderIndex_t i = (GeometryShaderIndex_t)hShader;
|
|
VerifyEquals( m_GeometryShaderDict[ i ].m_pShader->Release(), 0 );
|
|
VerifyEquals( m_GeometryShaderDict[ i ].m_pInfo->Release(), 0 );
|
|
m_GeometryShaderDict.Remove( i );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Create, destroy pixel shader
|
|
//-----------------------------------------------------------------------------
|
|
PixelShaderHandle_t CShaderDeviceDx11::CreatePixelShader( IShaderBuffer* pShaderBuffer )
|
|
{
|
|
return CreatePixelShader( pShaderBuffer->GetBits(), pShaderBuffer->GetSize() );
|
|
}
|
|
|
|
PixelShaderHandle_t CShaderDeviceDx11::CreatePixelShader( const void* pBuffer, size_t nBufLen )
|
|
{
|
|
// Create the pixel shader
|
|
ID3D11PixelShader* pShader = NULL;
|
|
HRESULT hr = m_pDevice->CreatePixelShader( pBuffer,
|
|
nBufLen, NULL, &pShader );
|
|
|
|
if ( FAILED( hr ) || !pShader )
|
|
return PIXEL_SHADER_HANDLE_INVALID;
|
|
|
|
ID3D11ShaderReflection* pInfo;
|
|
hr = D3DReflect( pBuffer, nBufLen, IID_ID3D11ShaderReflection, (void**)&pInfo );
|
|
if ( FAILED( hr ) || !pInfo )
|
|
{
|
|
pShader->Release();
|
|
return PIXEL_SHADER_HANDLE_INVALID;
|
|
}
|
|
|
|
// Insert the shader into the dictionary of shaders
|
|
PixelShaderIndex_t i = m_PixelShaderDict.AddToTail();
|
|
m_PixelShaderDict[i].m_pShader = pShader;
|
|
m_PixelShaderDict[i].m_pInfo = pInfo;
|
|
return (PixelShaderHandle_t)i;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyPixelShader( PixelShaderHandle_t hShader )
|
|
{
|
|
if ( hShader == PIXEL_SHADER_HANDLE_INVALID )
|
|
return;
|
|
|
|
g_pShaderAPIDx11->Unbind( hShader );
|
|
|
|
PixelShaderIndex_t i = (PixelShaderIndex_t)hShader;
|
|
VerifyEquals( m_PixelShaderDict[ i ].m_pShader->Release(), 0 );
|
|
VerifyEquals( m_PixelShaderDict[ i ].m_pInfo->Release(), 0 );
|
|
m_PixelShaderDict.Remove( i );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Finds or creates an input layout for a given vertex shader + stream format
|
|
//-----------------------------------------------------------------------------
|
|
ID3D11InputLayout* CShaderDeviceDx11::GetInputLayout( VertexShaderHandle_t hShader, VertexFormat_t format,
|
|
bool bStaticLit, bool bUsingFlex, bool bUsingMorph )
|
|
{
|
|
if ( hShader == VERTEX_SHADER_HANDLE_INVALID )
|
|
return NULL;
|
|
|
|
// FIXME: VertexFormat_t is not the appropriate way of specifying this
|
|
// because it has no stream information
|
|
InputLayout_t insert;
|
|
insert.m_VertexFormat = format;
|
|
insert.m_bStaticLit = bStaticLit;
|
|
insert.m_bUsingFlex = bUsingFlex;
|
|
insert.m_bUsingMorph = bUsingMorph;
|
|
|
|
VertexShaderIndex_t i = (VertexShaderIndex_t)hShader;
|
|
InputLayoutDict_t &dict = m_VertexShaderDict[i].m_InputLayouts;
|
|
unsigned short hIndex = dict.Find( insert );
|
|
if ( hIndex != dict.InvalidIndex() )
|
|
return dict[hIndex].m_pInputLayout;
|
|
|
|
VertexShader_t &shader = m_VertexShaderDict[i];
|
|
insert.m_pInputLayout = CreateInputLayout( format, bStaticLit, bUsingFlex, bUsingMorph, shader.m_pInfo, shader.m_pByteCode, shader.m_nByteCodeLen );
|
|
dict.Insert( insert );
|
|
return insert.m_pInputLayout;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates/destroys Mesh
|
|
//-----------------------------------------------------------------------------
|
|
IMesh* CShaderDeviceDx11::CreateStaticMesh( VertexFormat_t vertexFormat, const char *pBudgetGroup, IMaterial * pMaterial )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
return g_pShaderAPIDx11->CreateStaticMesh( vertexFormat, pBudgetGroup, pMaterial );
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyStaticMesh( IMesh* pMesh )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
g_pShaderAPIDx11->DestroyStaticMesh( pMesh );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates/destroys vertex buffers + index buffers
|
|
//-----------------------------------------------------------------------------
|
|
IVertexBuffer *CShaderDeviceDx11::CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
CVertexBufferDx11 *pVertexBuffer = new CVertexBufferDx11( type, fmt, nVertexCount, pBudgetGroup );
|
|
return pVertexBuffer;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyVertexBuffer( IVertexBuffer *pVertexBuffer )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
if ( pVertexBuffer )
|
|
{
|
|
CVertexBufferDx11 *pVertexBufferBase = assert_cast<CVertexBufferDx11*>( pVertexBuffer );
|
|
g_pShaderAPIDx11->UnbindVertexBuffer( pVertexBufferBase->GetDx11Buffer() );
|
|
delete pVertexBufferBase;
|
|
}
|
|
}
|
|
|
|
IIndexBuffer *CShaderDeviceDx11::CreateIndexBuffer( ShaderBufferType_t type, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
CIndexBufferDx11 *pIndexBuffer = new CIndexBufferDx11( type, fmt, nIndexCount, pBudgetGroup );
|
|
return pIndexBuffer;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyIndexBuffer( IIndexBuffer *pIndexBuffer )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
if ( pIndexBuffer )
|
|
{
|
|
CIndexBufferDx11 *pIndexBufferBase = assert_cast<CIndexBufferDx11*>( pIndexBuffer );
|
|
g_pShaderAPIDx11->UnbindIndexBuffer( pIndexBufferBase->GetDx11Buffer() );
|
|
delete pIndexBufferBase;
|
|
}
|
|
}
|
|
|
|
ConstantBufferHandle_t CShaderDeviceDx11::CreateConstantBuffer( size_t nBufLen )
|
|
{
|
|
CShaderConstantBufferDx11 *pBuf = new CShaderConstantBufferDx11;
|
|
pBuf->Create( nBufLen );
|
|
return (ConstantBufferHandle_t)pBuf;
|
|
}
|
|
|
|
void CShaderDeviceDx11::UpdateConstantBuffer( ConstantBufferHandle_t hBuffer, void *pData )
|
|
{
|
|
( (IShaderConstantBuffer *)hBuffer )->Update( pData );
|
|
}
|
|
|
|
void CShaderDeviceDx11::UploadConstantBuffers( ConstantBufferHandle_t *pBuffers, int nBuffers )
|
|
{
|
|
for ( int i = 0; i < nBuffers; i++ )
|
|
{
|
|
( (IShaderConstantBuffer *)pBuffers[i] )->UploadToGPU();
|
|
}
|
|
}
|
|
|
|
ConstantBufferHandle_t CShaderDeviceDx11::GetInternalConstantBuffer( int buffer )
|
|
{
|
|
return CONSTANT_BUFFER_HANDLE_INVALID;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyConstantBuffer( ConstantBufferHandle_t hBuffer )
|
|
{
|
|
if ( hBuffer != CONSTANT_BUFFER_HANDLE_INVALID )
|
|
{
|
|
IShaderConstantBuffer *pBuffer = (IShaderConstantBuffer *)hBuffer;
|
|
pBuffer->Destroy();
|
|
}
|
|
}
|
|
|
|
// NOTE: I don't see these functions being called by anybody. I think they should be removed.
|
|
IVertexBuffer *CShaderDeviceDx11::GetDynamicVertexBuffer( int nStreamID, VertexFormat_t vertexFormat, bool bBuffered )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
return NULL;
|
|
}
|
|
|
|
IIndexBuffer *CShaderDeviceDx11::GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered )
|
|
{
|
|
LOCK_SHADERAPI();
|
|
return NULL;
|
|
}
|
|
|
|
char* CShaderDeviceDx11::GetDisplayDeviceName()
|
|
{
|
|
if (m_sDisplayDeviceName.IsEmpty())
|
|
{
|
|
DXGI_ADAPTER_DESC desc;
|
|
g_ShaderDeviceMgrDx11.GetAdapter(m_nAdapter)->GetDesc(&desc);
|
|
m_sDisplayDeviceName = (char*)desc.Description;
|
|
}
|
|
return m_sDisplayDeviceName.GetForModify();
|
|
}
|
|
|
|
ShaderAPIOcclusionQuery_t CShaderDeviceDx11::CreateOcclusionQuery()
|
|
{
|
|
CD3D11_QUERY_DESC desc;
|
|
desc.Query = D3D11_QUERY_OCCLUSION;
|
|
desc.MiscFlags = 0;
|
|
ID3D11Query *pQuery = NULL;
|
|
HRESULT hr = D3D11Device()->CreateQuery( &desc, &pQuery );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE;
|
|
}
|
|
return (ShaderAPIOcclusionQuery_t)pQuery;
|
|
}
|
|
|
|
void CShaderDeviceDx11::DestroyOcclusionQuery( ShaderAPIOcclusionQuery_t hQuery )
|
|
{
|
|
if ( hQuery != INVALID_SHADERAPI_OCCLUSION_QUERY_HANDLE )
|
|
{
|
|
( (ID3D11Query *)hQuery )->Release();
|
|
}
|
|
}
|