2015-05-23 22:55:12 -06:00
// Copyright 2010 Dolphin Emulator Project
2015-05-17 17:08:10 -06:00
// Licensed under GPLv2+
2013-04-17 21:29:41 -06:00
// Refer to the license.txt file included.
2010-06-13 13:50:06 -06:00
2014-02-17 03:18:15 -07:00
# include "Common/StringUtil.h"
# include "VideoBackends/D3D/D3DBase.h"
2014-06-23 00:11:07 -06:00
# include "VideoBackends/D3D/D3DState.h"
2014-02-17 03:18:15 -07:00
# include "VideoBackends/D3D/D3DTexture.h"
2014-02-19 04:14:09 -07:00
# include "VideoCommon/VideoConfig.h"
2010-06-13 13:50:06 -06:00
2011-01-29 13:16:51 -07:00
namespace DX11
{
2014-03-09 14:14:26 -06:00
HINSTANCE hD3DCompilerDll = nullptr ;
D3DREFLECT PD3DReflect = nullptr ;
pD3DCompile PD3DCompile = nullptr ;
2011-02-26 16:41:02 -07:00
int d3dcompiler_dll_ref = 0 ;
2014-03-09 14:14:26 -06:00
CREATEDXGIFACTORY PCreateDXGIFactory = nullptr ;
HINSTANCE hDXGIDll = nullptr ;
2010-12-29 06:07:00 -07:00
int dxgi_dll_ref = 0 ;
2010-11-21 08:34:04 -07:00
typedef HRESULT ( WINAPI * D3D11CREATEDEVICEANDSWAPCHAIN ) ( IDXGIAdapter * , D3D_DRIVER_TYPE , HMODULE , UINT , CONST D3D_FEATURE_LEVEL * , UINT , UINT , CONST DXGI_SWAP_CHAIN_DESC * , IDXGISwapChain * * , ID3D11Device * * , D3D_FEATURE_LEVEL * , ID3D11DeviceContext * * ) ;
2014-07-08 14:37:58 -06:00
static D3D11CREATEDEVICE PD3D11CreateDevice = nullptr ;
2014-03-09 14:14:26 -06:00
D3D11CREATEDEVICEANDSWAPCHAIN PD3D11CreateDeviceAndSwapChain = nullptr ;
HINSTANCE hD3DDll = nullptr ;
2010-12-29 06:07:00 -07:00
int d3d_dll_ref = 0 ;
2010-11-21 08:34:04 -07:00
2010-06-13 13:50:06 -06:00
namespace D3D
{
2014-03-09 14:14:26 -06:00
ID3D11Device * device = nullptr ;
ID3D11DeviceContext * context = nullptr ;
2014-07-26 05:00:49 -06:00
static IDXGISwapChain * swapchain = nullptr ;
2015-02-09 05:00:42 -07:00
static ID3D11Debug * debug = nullptr ;
2010-06-13 13:50:06 -06:00
D3D_FEATURE_LEVEL featlevel ;
2014-03-09 14:14:26 -06:00
D3DTexture2D * backbuf = nullptr ;
2010-06-13 13:50:06 -06:00
HWND hWnd ;
2011-06-11 13:37:21 -06:00
std : : vector < DXGI_SAMPLE_DESC > aa_modes ; // supported AA modes of the current adapter
2010-11-23 12:58:02 -07:00
2010-06-18 19:02:43 -06:00
bool bgra_textures_supported ;
2010-06-14 16:38:47 -06:00
# define NUM_SUPPORTED_FEATURE_LEVELS 3
const D3D_FEATURE_LEVEL supported_feature_levels [ NUM_SUPPORTED_FEATURE_LEVELS ] = {
D3D_FEATURE_LEVEL_11_0 ,
D3D_FEATURE_LEVEL_10_1 ,
D3D_FEATURE_LEVEL_10_0
} ;
2010-06-13 13:50:06 -06:00
unsigned int xres , yres ;
bool bFrameInProgress = false ;
2010-11-23 12:58:02 -07:00
HRESULT LoadDXGI ( )
2010-06-13 13:50:06 -06:00
{
2010-12-29 06:07:00 -07:00
if ( dxgi_dll_ref + + > 0 ) return S_OK ;
2010-11-23 12:58:02 -07:00
if ( hDXGIDll ) return S_OK ;
2010-11-21 08:34:04 -07:00
hDXGIDll = LoadLibraryA ( " dxgi.dll " ) ;
if ( ! hDXGIDll )
{
2014-03-09 14:14:26 -06:00
MessageBoxA ( nullptr , " Failed to load dxgi.dll " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2010-12-29 06:07:00 -07:00
- - dxgi_dll_ref ;
2010-11-21 08:34:04 -07:00
return E_FAIL ;
}
PCreateDXGIFactory = ( CREATEDXGIFACTORY ) GetProcAddress ( hDXGIDll , " CreateDXGIFactory " ) ;
2014-03-09 14:14:26 -06:00
if ( PCreateDXGIFactory = = nullptr ) MessageBoxA ( nullptr , " GetProcAddress failed for CreateDXGIFactory! " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2010-06-13 13:50:06 -06:00
2010-11-21 08:34:04 -07:00
return S_OK ;
}
2010-11-23 12:58:02 -07:00
HRESULT LoadD3D ( )
2010-11-21 08:34:04 -07:00
{
2011-06-11 13:37:21 -06:00
if ( d3d_dll_ref + + > 0 ) return S_OK ;
2010-12-29 06:07:00 -07:00
2011-06-11 13:37:21 -06:00
if ( hD3DDll ) return S_OK ;
hD3DDll = LoadLibraryA ( " d3d11.dll " ) ;
if ( ! hD3DDll )
2010-11-23 12:58:02 -07:00
{
2014-03-09 14:14:26 -06:00
MessageBoxA ( nullptr , " Failed to load d3d11.dll " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2010-12-29 06:07:00 -07:00
- - d3d_dll_ref ;
2010-11-23 12:58:02 -07:00
return E_FAIL ;
}
2011-06-11 13:37:21 -06:00
PD3D11CreateDevice = ( D3D11CREATEDEVICE ) GetProcAddress ( hD3DDll , " D3D11CreateDevice " ) ;
2014-03-09 14:14:26 -06:00
if ( PD3D11CreateDevice = = nullptr ) MessageBoxA ( nullptr , " GetProcAddress failed for D3D11CreateDevice! " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2010-11-23 12:58:02 -07:00
2011-06-11 13:37:21 -06:00
PD3D11CreateDeviceAndSwapChain = ( D3D11CREATEDEVICEANDSWAPCHAIN ) GetProcAddress ( hD3DDll , " D3D11CreateDeviceAndSwapChain " ) ;
2014-03-09 14:14:26 -06:00
if ( PD3D11CreateDeviceAndSwapChain = = nullptr ) MessageBoxA ( nullptr , " GetProcAddress failed for D3D11CreateDeviceAndSwapChain! " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2010-11-23 12:58:02 -07:00
return S_OK ;
2010-11-21 08:34:04 -07:00
}
2010-06-13 13:50:06 -06:00
2011-02-26 16:41:02 -07:00
HRESULT LoadD3DCompiler ( )
{
if ( d3dcompiler_dll_ref + + > 0 ) return S_OK ;
if ( hD3DCompilerDll ) return S_OK ;
// try to load D3DCompiler first to check whether we have proper runtime support
// try to use the dll the backend was compiled against first - don't bother about debug runtimes
hD3DCompilerDll = LoadLibraryA ( D3DCOMPILER_DLL_A ) ;
if ( ! hD3DCompilerDll )
{
// if that fails, use the dll which should be available in every SDK which officially supports DX11.
hD3DCompilerDll = LoadLibraryA ( " D3DCompiler_42.dll " ) ;
if ( ! hD3DCompilerDll )
{
2014-03-09 14:14:26 -06:00
MessageBoxA ( nullptr , " Failed to load D3DCompiler_42.dll, update your DX11 runtime, please " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2011-02-26 16:41:02 -07:00
return E_FAIL ;
}
else
{
NOTICE_LOG ( VIDEO , " Successfully loaded D3DCompiler_42.dll. If you're having trouble, try updating your DX runtime first. " ) ;
}
}
PD3DReflect = ( D3DREFLECT ) GetProcAddress ( hD3DCompilerDll , " D3DReflect " ) ;
2014-03-09 14:14:26 -06:00
if ( PD3DReflect = = nullptr ) MessageBoxA ( nullptr , " GetProcAddress failed for D3DReflect! " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2013-10-19 03:27:57 -06:00
PD3DCompile = ( pD3DCompile ) GetProcAddress ( hD3DCompilerDll , " D3DCompile " ) ;
2014-03-09 14:14:26 -06:00
if ( PD3DCompile = = nullptr ) MessageBoxA ( nullptr , " GetProcAddress failed for D3DCompile! " , " Critical error " , MB_OK | MB_ICONERROR ) ;
2011-02-26 16:41:02 -07:00
return S_OK ;
}
2010-11-23 12:58:02 -07:00
void UnloadDXGI ( )
{
2010-12-29 06:07:00 -07:00
if ( ! dxgi_dll_ref ) return ;
if ( - - dxgi_dll_ref ! = 0 ) return ;
2014-03-10 05:30:55 -06:00
if ( hDXGIDll ) FreeLibrary ( hDXGIDll ) ;
2014-03-09 14:14:26 -06:00
hDXGIDll = nullptr ;
PCreateDXGIFactory = nullptr ;
2010-11-23 12:58:02 -07:00
}
void UnloadD3D ( )
{
2011-06-11 13:37:21 -06:00
if ( ! d3d_dll_ref ) return ;
if ( - - d3d_dll_ref ! = 0 ) return ;
2010-12-29 06:07:00 -07:00
2014-03-10 05:30:55 -06:00
if ( hD3DDll ) FreeLibrary ( hD3DDll ) ;
2014-03-09 14:14:26 -06:00
hD3DDll = nullptr ;
PD3D11CreateDevice = nullptr ;
PD3D11CreateDeviceAndSwapChain = nullptr ;
2010-11-23 12:58:02 -07:00
}
2011-02-26 16:41:02 -07:00
void UnloadD3DCompiler ( )
{
if ( ! d3dcompiler_dll_ref ) return ;
if ( - - d3dcompiler_dll_ref ! = 0 ) return ;
if ( hD3DCompilerDll ) FreeLibrary ( hD3DCompilerDll ) ;
2014-03-09 14:14:26 -06:00
hD3DCompilerDll = nullptr ;
PD3DReflect = nullptr ;
2011-02-26 16:41:02 -07:00
}
2011-03-30 01:17:23 -06:00
std : : vector < DXGI_SAMPLE_DESC > EnumAAModes ( IDXGIAdapter * adapter )
2010-11-23 12:58:02 -07:00
{
2015-03-15 20:28:47 -06:00
std : : vector < DXGI_SAMPLE_DESC > _aa_modes ;
2011-06-11 13:37:21 -06:00
2010-11-28 08:23:51 -07:00
// NOTE: D3D 10.0 doesn't support multisampled resources which are bound as depth buffers AND shader resources.
// Thus, we can't have MSAA with 10.0 level hardware.
2015-03-15 20:28:47 -06:00
ID3D11Device * _device ;
ID3D11DeviceContext * _context ;
2010-11-23 12:58:02 -07:00
D3D_FEATURE_LEVEL feat_level ;
2015-03-15 20:28:47 -06:00
HRESULT hr = PD3D11CreateDevice ( adapter , D3D_DRIVER_TYPE_UNKNOWN , nullptr , D3D11_CREATE_DEVICE_SINGLETHREADED , supported_feature_levels , NUM_SUPPORTED_FEATURE_LEVELS , D3D11_SDK_VERSION , & _device , & feat_level , & _context ) ;
2010-11-28 08:23:51 -07:00
if ( FAILED ( hr ) | | feat_level = = D3D_FEATURE_LEVEL_10_0 )
{
2010-11-28 10:25:19 -07:00
DXGI_SAMPLE_DESC desc ;
desc . Count = 1 ;
desc . Quality = 0 ;
2015-03-15 20:28:47 -06:00
_aa_modes . push_back ( desc ) ;
SAFE_RELEASE ( _context ) ;
SAFE_RELEASE ( _device ) ;
2010-11-28 08:23:51 -07:00
}
2011-03-30 01:17:23 -06:00
else
2010-11-21 08:34:04 -07:00
{
2011-06-11 13:37:21 -06:00
for ( int samples = 0 ; samples < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT ; + + samples )
2011-03-30 01:17:23 -06:00
{
UINT quality_levels = 0 ;
2015-03-15 20:28:47 -06:00
_device - > CheckMultisampleQualityLevels ( DXGI_FORMAT_R8G8B8A8_UNORM , samples , & quality_levels ) ;
2014-08-30 14:54:18 -06:00
if ( quality_levels > 0 )
{
2011-03-30 01:17:23 -06:00
DXGI_SAMPLE_DESC desc ;
desc . Count = samples ;
2011-06-11 13:37:21 -06:00
for ( desc . Quality = 0 ; desc . Quality < quality_levels ; + + desc . Quality )
2015-03-15 20:28:47 -06:00
_aa_modes . push_back ( desc ) ;
2011-03-30 01:17:23 -06:00
}
2010-11-23 12:58:02 -07:00
}
2015-03-15 20:28:47 -06:00
_context - > Release ( ) ;
_device - > Release ( ) ;
2010-11-21 08:34:04 -07:00
}
2015-03-15 20:28:47 -06:00
return _aa_modes ;
2010-11-23 12:58:02 -07:00
}
2013-07-22 06:38:09 -06:00
D3D_FEATURE_LEVEL GetFeatureLevel ( IDXGIAdapter * adapter )
{
D3D_FEATURE_LEVEL feat_level = D3D_FEATURE_LEVEL_9_1 ;
2014-03-09 14:14:26 -06:00
PD3D11CreateDevice ( adapter , D3D_DRIVER_TYPE_UNKNOWN , nullptr , D3D11_CREATE_DEVICE_SINGLETHREADED , supported_feature_levels , NUM_SUPPORTED_FEATURE_LEVELS , D3D11_SDK_VERSION , nullptr , & feat_level , nullptr ) ;
2013-07-22 06:38:09 -06:00
return feat_level ;
}
2010-11-23 12:58:02 -07:00
DXGI_SAMPLE_DESC GetAAMode ( int index )
{
2011-06-11 13:37:21 -06:00
return aa_modes [ index ] ;
2010-11-21 08:34:04 -07:00
}
HRESULT Create ( HWND wnd )
{
hWnd = wnd ;
HRESULT hr ;
RECT client ;
GetClientRect ( hWnd , & client ) ;
xres = client . right - client . left ;
yres = client . bottom - client . top ;
2010-11-23 12:58:02 -07:00
hr = LoadDXGI ( ) ;
if ( SUCCEEDED ( hr ) ) hr = LoadD3D ( ) ;
2011-02-26 16:41:02 -07:00
if ( SUCCEEDED ( hr ) ) hr = LoadD3DCompiler ( ) ;
2010-11-23 12:58:02 -07:00
if ( FAILED ( hr ) )
{
UnloadDXGI ( ) ;
UnloadD3D ( ) ;
2011-02-26 16:41:02 -07:00
UnloadD3DCompiler ( ) ;
2010-11-23 12:58:02 -07:00
return hr ;
}
2010-11-21 08:34:04 -07:00
2010-06-14 13:20:41 -06:00
IDXGIFactory * factory ;
2011-06-11 13:37:21 -06:00
IDXGIAdapter * adapter ;
IDXGIOutput * output ;
2010-11-21 08:34:04 -07:00
hr = PCreateDXGIFactory ( __uuidof ( IDXGIFactory ) , ( void * * ) & factory ) ;
2011-06-11 13:37:21 -06:00
if ( FAILED ( hr ) ) MessageBox ( wnd , _T ( " Failed to create IDXGIFactory object " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
2010-06-14 13:20:41 -06:00
hr = factory - > EnumAdapters ( g_ActiveConfig . iAdapter , & adapter ) ;
if ( FAILED ( hr ) )
{
// try using the first one
hr = factory - > EnumAdapters ( 0 , & adapter ) ;
2011-06-11 13:37:21 -06:00
if ( FAILED ( hr ) ) MessageBox ( wnd , _T ( " Failed to enumerate adapters " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
2010-06-14 13:20:41 -06:00
}
// TODO: Make this configurable
hr = adapter - > EnumOutputs ( 0 , & output ) ;
if ( FAILED ( hr ) )
{
// try using the first one
2015-01-17 15:27:11 -07:00
IDXGIAdapter * firstadapter ;
hr = factory - > EnumAdapters ( 0 , & firstadapter ) ;
if ( ! FAILED ( hr ) )
hr = firstadapter - > EnumOutputs ( 0 , & output ) ;
if ( FAILED ( hr ) ) MessageBox ( wnd ,
_T ( " Failed to enumerate outputs! \n " )
_T ( " This usually happens when you've set your video adapter to the Nvidia GPU in an Optimus-equipped system. \n " )
_T ( " Set Dolphin to use the high-performance graphics in Nvidia's drivers instead and leave Dolphin's video adapter set to the Intel GPU. " ) ,
_T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
SAFE_RELEASE ( firstadapter ) ;
2010-06-14 13:20:41 -06:00
}
2010-11-23 12:58:02 -07:00
// get supported AA modes
2011-06-11 13:37:21 -06:00
aa_modes = EnumAAModes ( adapter ) ;
if ( g_Config . iMultisampleMode > = ( int ) aa_modes . size ( ) )
2010-11-28 08:23:51 -07:00
{
g_Config . iMultisampleMode = 0 ;
UpdateActiveConfig ( ) ;
}
2010-11-23 12:58:02 -07:00
2015-02-12 06:45:05 -07:00
DXGI_SWAP_CHAIN_DESC swap_chain_desc = { } ;
2010-06-14 13:20:41 -06:00
swap_chain_desc . BufferCount = 1 ;
swap_chain_desc . BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT ;
swap_chain_desc . OutputWindow = wnd ;
swap_chain_desc . SampleDesc . Count = 1 ;
swap_chain_desc . SampleDesc . Quality = 0 ;
2015-01-04 08:33:58 -07:00
swap_chain_desc . Windowed = ! g_Config . bFullscreen ;
2010-06-14 13:20:41 -06:00
2015-02-12 06:45:05 -07:00
DXGI_OUTPUT_DESC out_desc = { } ;
2014-06-18 07:02:42 -06:00
output - > GetDesc ( & out_desc ) ;
2015-02-12 06:45:05 -07:00
DXGI_MODE_DESC mode_desc = { } ;
2014-06-18 07:02:42 -06:00
mode_desc . Width = out_desc . DesktopCoordinates . right - out_desc . DesktopCoordinates . left ;
mode_desc . Height = out_desc . DesktopCoordinates . bottom - out_desc . DesktopCoordinates . top ;
2010-06-14 13:20:41 -06:00
mode_desc . Format = DXGI_FORMAT_R8G8B8A8_UNORM ;
mode_desc . Scaling = DXGI_MODE_SCALING_UNSPECIFIED ;
2014-03-09 14:14:26 -06:00
hr = output - > FindClosestMatchingMode ( & mode_desc , & swap_chain_desc . BufferDesc , nullptr ) ;
2011-06-11 13:37:21 -06:00
if ( FAILED ( hr ) ) MessageBox ( wnd , _T ( " Failed to find a supported video mode " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
2010-06-14 15:31:23 -06:00
2014-07-11 07:26:38 -06:00
if ( swap_chain_desc . Windowed )
{
// forcing buffer resolution to xres and yres..
// this is not a problem as long as we're in windowed mode
swap_chain_desc . BufferDesc . Width = xres ;
swap_chain_desc . BufferDesc . Height = yres ;
}
2010-06-13 13:50:06 -06:00
2013-08-15 08:07:52 -06:00
# if defined(_DEBUG) || defined(DEBUGFAST)
2013-08-15 08:19:14 -06:00
// Creating debug devices can sometimes fail if the user doesn't have the correct
// version of the DirectX SDK. If it does, simply fallback to a non-debug device.
{
2014-03-09 14:14:26 -06:00
hr = PD3D11CreateDeviceAndSwapChain ( adapter , D3D_DRIVER_TYPE_UNKNOWN , nullptr ,
2013-08-15 08:19:14 -06:00
D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG ,
supported_feature_levels , NUM_SUPPORTED_FEATURE_LEVELS ,
D3D11_SDK_VERSION , & swap_chain_desc , & swapchain , & device ,
& featlevel , & context ) ;
2015-02-09 05:00:42 -07:00
// Debugbreak on D3D error
if ( SUCCEEDED ( hr ) & & SUCCEEDED ( device - > QueryInterface ( __uuidof ( ID3D11Debug ) , ( void * * ) & debug ) ) )
{
ID3D11InfoQueue * infoQueue = nullptr ;
if ( SUCCEEDED ( debug - > QueryInterface ( __uuidof ( ID3D11InfoQueue ) , ( void * * ) & infoQueue ) ) )
{
infoQueue - > SetBreakOnSeverity ( D3D11_MESSAGE_SEVERITY_CORRUPTION , true ) ;
infoQueue - > SetBreakOnSeverity ( D3D11_MESSAGE_SEVERITY_ERROR , true ) ;
D3D11_MESSAGE_ID hide [ ] =
{
D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS
} ;
2015-02-12 06:45:05 -07:00
D3D11_INFO_QUEUE_FILTER filter = { } ;
2015-02-09 05:00:42 -07:00
filter . DenyList . NumIDs = sizeof ( hide ) / sizeof ( D3D11_MESSAGE_ID ) ;
filter . DenyList . pIDList = hide ;
infoQueue - > AddStorageFilterEntries ( & filter ) ;
infoQueue - > Release ( ) ;
}
}
2013-08-15 08:19:14 -06:00
}
if ( FAILED ( hr ) )
2013-08-15 08:07:52 -06:00
# endif
2013-08-15 08:19:14 -06:00
{
2014-03-09 14:14:26 -06:00
hr = PD3D11CreateDeviceAndSwapChain ( adapter , D3D_DRIVER_TYPE_UNKNOWN , nullptr ,
2013-08-15 08:19:14 -06:00
D3D11_CREATE_DEVICE_SINGLETHREADED ,
supported_feature_levels , NUM_SUPPORTED_FEATURE_LEVELS ,
D3D11_SDK_VERSION , & swap_chain_desc , & swapchain , & device ,
& featlevel , & context ) ;
}
if ( FAILED ( hr ) )
2010-06-13 13:50:06 -06:00
{
2011-06-11 13:37:21 -06:00
MessageBox ( wnd , _T ( " Failed to initialize Direct3D. \n Make sure your video card supports at least D3D 10.0 " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
SAFE_RELEASE ( device ) ;
SAFE_RELEASE ( context ) ;
SAFE_RELEASE ( swapchain ) ;
2010-06-13 13:50:06 -06:00
return E_FAIL ;
}
2014-06-17 03:15:56 -06:00
2014-07-16 14:13:13 -06:00
// prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER
// does not work so we disable all monitoring of window messages. However this
// may make it more difficult for DXGI to handle display mode changes.
2014-06-17 03:15:56 -06:00
hr = factory - > MakeWindowAssociation ( wnd , DXGI_MWA_NO_WINDOW_CHANGES ) ;
if ( FAILED ( hr ) ) MessageBox ( wnd , _T ( " Failed to associate the window " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
2011-06-11 13:37:21 -06:00
SetDebugObjectName ( ( ID3D11DeviceChild * ) context , " device context " ) ;
2010-07-17 05:42:28 -06:00
SAFE_RELEASE ( factory ) ;
SAFE_RELEASE ( output ) ;
SAFE_RELEASE ( adapter ) ;
2010-06-13 13:50:06 -06:00
2011-06-11 13:37:21 -06:00
ID3D11Texture2D * buf ;
hr = swapchain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & buf ) ;
if ( FAILED ( hr ) )
2010-06-13 13:50:06 -06:00
{
2011-02-13 19:18:03 -07:00
MessageBox ( wnd , _T ( " Failed to get swapchain buffer " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
2011-06-11 13:37:21 -06:00
SAFE_RELEASE ( device ) ;
SAFE_RELEASE ( context ) ;
SAFE_RELEASE ( swapchain ) ;
2010-06-13 13:50:06 -06:00
return E_FAIL ;
}
2011-06-11 13:37:21 -06:00
backbuf = new D3DTexture2D ( buf , D3D11_BIND_RENDER_TARGET ) ;
SAFE_RELEASE ( buf ) ;
2014-03-09 14:14:26 -06:00
CHECK ( backbuf ! = nullptr , " Create back buffer texture " ) ;
2011-06-11 13:37:21 -06:00
SetDebugObjectName ( ( ID3D11DeviceChild * ) backbuf - > GetTex ( ) , " backbuffer texture " ) ;
SetDebugObjectName ( ( ID3D11DeviceChild * ) backbuf - > GetRTV ( ) , " backbuffer render target view " ) ;
2010-06-13 13:50:06 -06:00
2014-03-09 14:14:26 -06:00
context - > OMSetRenderTargets ( 1 , & backbuf - > GetRTV ( ) , nullptr ) ;
2010-06-13 13:50:06 -06:00
2010-06-18 19:02:43 -06:00
// BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware
UINT format_support ;
device - > CheckFormatSupport ( DXGI_FORMAT_B8G8R8A8_UNORM , & format_support ) ;
bgra_textures_supported = ( format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D ) ! = 0 ;
2011-06-11 13:37:21 -06:00
stateman = new StateManager ;
2010-06-13 13:50:06 -06:00
return S_OK ;
}
void Close ( )
{
2014-06-19 19:45:42 -06:00
// we can't release the swapchain while in fullscreen.
swapchain - > SetFullscreenState ( false , nullptr ) ;
2010-06-13 13:50:06 -06:00
// release all bound resources
2011-06-11 13:37:21 -06:00
context - > ClearState ( ) ;
SAFE_RELEASE ( backbuf ) ;
SAFE_RELEASE ( swapchain ) ;
SAFE_DELETE ( stateman ) ;
context - > Flush ( ) ; // immediately destroy device objects
SAFE_RELEASE ( context ) ;
ULONG references = device - > Release ( ) ;
2015-02-09 05:00:42 -07:00
# if defined(_DEBUG) || defined(DEBUGFAST)
if ( debug )
{
2015-02-12 06:45:05 -07:00
- - references ; // the debug interface increases the refcount of the device, subtract that.
2015-02-09 05:00:42 -07:00
if ( references )
{
// print out alive objects, but only if we actually have pending references
// note this will also print out internal live objects to the debug console
debug - > ReportLiveDeviceObjects ( D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL ) ;
}
SAFE_RELEASE ( debug )
}
# endif
2011-06-11 13:37:21 -06:00
if ( references )
{
ERROR_LOG ( VIDEO , " Unreleased references: %i. " , references ) ;
}
else
{
NOTICE_LOG ( VIDEO , " Successfully released all device references! " ) ;
}
2014-03-09 14:14:26 -06:00
device = nullptr ;
2010-11-21 08:34:04 -07:00
// unload DLLs
2010-11-23 12:58:02 -07:00
UnloadD3D ( ) ;
2010-11-21 08:34:04 -07:00
UnloadDXGI ( ) ;
2010-06-13 13:50:06 -06:00
}
2010-11-27 04:11:05 -07:00
const char * VertexShaderVersionString ( )
{
2014-03-10 05:30:55 -06:00
if ( featlevel = = D3D_FEATURE_LEVEL_11_0 ) return " vs_5_0 " ;
else if ( featlevel = = D3D_FEATURE_LEVEL_10_1 ) return " vs_4_1 " ;
2010-11-27 04:11:05 -07:00
else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/ return " vs_4_0 " ;
}
2011-03-14 03:38:29 -06:00
const char * GeometryShaderVersionString ( )
{
2014-03-10 05:30:55 -06:00
if ( featlevel = = D3D_FEATURE_LEVEL_11_0 ) return " gs_5_0 " ;
else if ( featlevel = = D3D_FEATURE_LEVEL_10_1 ) return " gs_4_1 " ;
2011-03-14 03:38:29 -06:00
else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/ return " gs_4_0 " ;
}
2010-11-27 04:11:05 -07:00
const char * PixelShaderVersionString ( )
{
2014-03-10 05:30:55 -06:00
if ( featlevel = = D3D_FEATURE_LEVEL_11_0 ) return " ps_5_0 " ;
else if ( featlevel = = D3D_FEATURE_LEVEL_10_1 ) return " ps_4_1 " ;
2010-11-27 04:11:05 -07:00
else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/ return " ps_4_0 " ;
}
2010-06-13 13:50:06 -06:00
2011-06-11 13:37:21 -06:00
D3DTexture2D * & GetBackBuffer ( ) { return backbuf ; }
2010-06-13 13:50:06 -06:00
unsigned int GetBackBufferWidth ( ) { return xres ; }
unsigned int GetBackBufferHeight ( ) { return yres ; }
2010-06-18 19:02:43 -06:00
bool BGRATexturesSupported ( ) { return bgra_textures_supported ; }
2010-07-11 10:26:46 -06:00
// Returns the maximum width/height of a texture. This value only depends upon the feature level in DX11
unsigned int GetMaxTextureSize ( )
{
switch ( featlevel )
{
case D3D_FEATURE_LEVEL_11_0 :
2010-11-27 04:11:05 -07:00
return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION ;
2010-07-11 10:26:46 -06:00
case D3D_FEATURE_LEVEL_10_1 :
case D3D_FEATURE_LEVEL_10_0 :
2010-11-27 04:11:05 -07:00
return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION ;
2010-07-11 10:26:46 -06:00
case D3D_FEATURE_LEVEL_9_3 :
return 4096 ;
case D3D_FEATURE_LEVEL_9_2 :
case D3D_FEATURE_LEVEL_9_1 :
return 2048 ;
2010-07-17 05:42:28 -06:00
default :
return 0 ;
2010-07-11 10:26:46 -06:00
}
}
2010-06-13 13:50:06 -06:00
void Reset ( )
{
2010-06-17 04:42:57 -06:00
// release all back buffer references
2011-06-11 13:37:21 -06:00
SAFE_RELEASE ( backbuf ) ;
2010-06-17 04:42:57 -06:00
// resize swapchain buffers
RECT client ;
GetClientRect ( hWnd , & client ) ;
xres = client . right - client . left ;
yres = client . bottom - client . top ;
2011-06-11 13:37:21 -06:00
D3D : : swapchain - > ResizeBuffers ( 1 , xres , yres , DXGI_FORMAT_R8G8B8A8_UNORM , 0 ) ;
2010-06-17 04:42:57 -06:00
// recreate back buffer texture
2011-06-11 13:37:21 -06:00
ID3D11Texture2D * buf ;
HRESULT hr = swapchain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & buf ) ;
if ( FAILED ( hr ) )
2010-06-17 04:42:57 -06:00
{
2011-02-13 19:18:03 -07:00
MessageBox ( hWnd , _T ( " Failed to get swapchain buffer " ) , _T ( " Dolphin Direct3D 11 backend " ) , MB_OK | MB_ICONERROR ) ;
2011-06-11 13:37:21 -06:00
SAFE_RELEASE ( device ) ;
SAFE_RELEASE ( context ) ;
SAFE_RELEASE ( swapchain ) ;
2010-06-17 04:42:57 -06:00
return ;
}
2011-06-11 13:37:21 -06:00
backbuf = new D3DTexture2D ( buf , D3D11_BIND_RENDER_TARGET ) ;
SAFE_RELEASE ( buf ) ;
2014-03-09 14:14:26 -06:00
CHECK ( backbuf ! = nullptr , " Create back buffer texture " ) ;
2011-06-11 13:37:21 -06:00
SetDebugObjectName ( ( ID3D11DeviceChild * ) backbuf - > GetTex ( ) , " backbuffer texture " ) ;
SetDebugObjectName ( ( ID3D11DeviceChild * ) backbuf - > GetRTV ( ) , " backbuffer render target view " ) ;
2010-06-13 13:50:06 -06:00
}
bool BeginFrame ( )
{
if ( bFrameInProgress )
{
PanicAlert ( " BeginFrame called although a frame is already in progress " ) ;
return false ;
}
bFrameInProgress = true ;
2014-03-09 14:14:26 -06:00
return ( device ! = nullptr ) ;
2010-06-13 13:50:06 -06:00
}
void EndFrame ( )
{
if ( ! bFrameInProgress )
{
PanicAlert ( " EndFrame called although no frame is in progress " ) ;
return ;
}
bFrameInProgress = false ;
}
void Present ( )
{
// TODO: Is 1 the correct value for vsyncing?
2013-03-18 18:41:45 -06:00
swapchain - > Present ( ( UINT ) g_ActiveConfig . IsVSync ( ) , 0 ) ;
2010-06-13 13:50:06 -06:00
}
2014-07-26 05:00:49 -06:00
HRESULT SetFullscreenState ( bool enable_fullscreen )
{
return swapchain - > SetFullscreenState ( enable_fullscreen , nullptr ) ;
}
HRESULT GetFullscreenState ( bool * fullscreen_state )
{
if ( fullscreen_state = = nullptr )
{
return E_POINTER ;
}
BOOL state ;
HRESULT hr = swapchain - > GetFullscreenState ( & state , nullptr ) ;
* fullscreen_state = ! ! state ;
return hr ;
}
2011-01-29 13:16:51 -07:00
} // namespace D3D
2011-02-13 19:18:03 -07:00
} // namespace DX11