summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-03-31 18:55:55 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-03-31 18:55:55 +0000
commitf88358621a3a2ffa1a9b7a87baa84695075337bd (patch)
treebb555200a0d97d473744faf83e63834c742d0286 /Graphics/GraphicsEngineD3D12
parentImplemented initialization in fullscreen mode on Win32 (diff)
downloadDiligentCore-f88358621a3a2ffa1a9b7a87baa84695075337bd.tar.gz
DiligentCore-f88358621a3a2ffa1a9b7a87baa84695075337bd.zip
Implemented switching to a fullscreen mode in d3d on Win32
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h10
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp184
5 files changed, 67 insertions, 143 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h
index 3b75be44..01d814b8 100644
--- a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h
@@ -28,7 +28,7 @@
#include <dxgi1_4.h>
#include "SwapChainD3D12.h"
-#include "SwapChainBase.h"
+#include "SwapChainD3DBase.h"
namespace Diligent
{
@@ -36,10 +36,10 @@ namespace Diligent
class ITextureViewD3D12;
class IMemoryAllocator;
/// Implementation of the Diligent::ISwapChainD3D12 interface
-class SwapChainD3D12Impl : public SwapChainBase<ISwapChainD3D12>
+class SwapChainD3D12Impl : public SwapChainD3DBase<ISwapChainD3D12, IDXGISwapChain3>
{
public:
- typedef SwapChainBase<ISwapChainD3D12> TSwapChainBase;
+ using TSwapChainBase = SwapChainD3DBase<ISwapChainD3D12, IDXGISwapChain3>;
SwapChainD3D12Impl(IReferenceCounters *pRefCounters,
const SwapChainDesc& SwapChainDesc,
const FullScreenModeDesc& FSDesc,
@@ -58,11 +58,9 @@ public:
virtual ITextureViewD3D12* GetDepthBufferDSV()override final{return m_pDepthBufferDSV;}
private:
+ virtual void UpdateSwapChain(bool CreateNew)override final;
void InitBuffersAndViews();
- /// DXGI swap chain
- CComPtr<IDXGISwapChain3> m_pSwapChain;
-
std::vector< RefCntAutoPtr<ITextureViewD3D12>, STDAllocatorRawMem<RefCntAutoPtr<ITextureViewD3D12>> > m_pBackBufferRTV;
RefCntAutoPtr<ITextureViewD3D12> m_pDepthBufferDSV;
};
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 3753a0a9..513f2907 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -61,17 +61,17 @@ namespace Diligent
CmdSignatureDesc.ByteStride = sizeof(UINT)*4;
IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
auto hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDrawIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDrawIndirectSignature)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to create indirect draw command signature")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create indirect draw command signature");
CmdSignatureDesc.ByteStride = sizeof(UINT)*5;
IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDrawIndexedIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDrawIndexedIndirectSignature)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to create draw indexed indirect command signature")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create draw indexed indirect command signature");
CmdSignatureDesc.ByteStride = sizeof(UINT)*3;
IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;
hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDispatchIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDispatchIndirectSignature)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to create dispatch indirect command signature")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create dispatch indirect command signature");
}
DeviceContextD3D12Impl::~DeviceContextD3D12Impl()
diff --git a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp
index 70aaff66..12b64835 100644
--- a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp
@@ -79,7 +79,7 @@ namespace Diligent
CComPtr<ID3DBlob> error;
HRESULT hr = D3D12SerializeRootSignature(&RootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pGenerateMipsRS), reinterpret_cast<void**>( static_cast<ID3D12RootSignature**>(&m_pGenerateMipsRS)));
- CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature for mipmap generation")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature for mipmap generation");
D3D12_COMPUTE_PIPELINE_STATE_DESC PSODesc = {};
PSODesc.pRootSignature = m_pGenerateMipsRS;
@@ -90,7 +90,7 @@ namespace Diligent
PSODesc.CS.pShaderBytecode = ShaderByteCode;\
PSODesc.CS.BytecodeLength = sizeof(ShaderByteCode);\
hr = pd3d12Device->CreateComputePipelineState(&PSODesc, __uuidof(PSO), reinterpret_cast<void**>( static_cast<ID3D12PipelineState**>(&PSO))); \
- CHECK_D3D_RESULT_THROW(hr, "Failed to create Pipeline state for mipmap generation") \
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create Pipeline state for mipmap generation"); \
PSO->SetName(L"Generate mips PSO");
CreatePSO(m_pGenerateMipsLinearPSO[0], g_pGenerateMipsLinearCS);
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp
index 2fdbe59b..8f05e917 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp
@@ -159,7 +159,7 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12( const EngineD3D12Attr
CComPtr<IDXGIFactory4> factory;
HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory4**>(&factory)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory");
CComPtr<IDXGIAdapter1> hardwareAdapter;
if(CreationAttribs.AdapterId == EngineD3D12Attribs::DefaultAdapterId)
@@ -192,10 +192,10 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12( const EngineD3D12Attr
CComPtr<IDXGIAdapter> warpAdapter;
hr = factory->EnumWarpAdapter( __uuidof(warpAdapter), reinterpret_cast<void**>(static_cast<IDXGIAdapter**>(&warpAdapter)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to enum warp adapter")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to enum warp adapter");
hr = D3D12CreateDevice( warpAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(d3d12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&d3d12Device)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to crate warp device")
+ CHECK_D3D_RESULT_THROW(hr, "Failed to crate warp device");
}
#if _DEBUG
diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp
index 6add53b8..6078f6a2 100644
--- a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp
@@ -38,108 +38,16 @@ SwapChainD3D12Impl::SwapChainD3D12Impl(IReferenceCounters *pRefCounters,
RenderDeviceD3D12Impl* pRenderDeviceD3D12,
DeviceContextD3D12Impl* pDeviceContextD3D12,
void* pNativeWndHandle) :
- TSwapChainBase(pRefCounters, pRenderDeviceD3D12, pDeviceContextD3D12, SCDesc),
+ TSwapChainBase(pRefCounters, pRenderDeviceD3D12, pDeviceContextD3D12, SCDesc, FSDesc, pNativeWndHandle),
m_pBackBufferRTV(STD_ALLOCATOR_RAW_MEM(RefCntAutoPtr<ITextureView>, GetRawAllocator(), "Allocator for vector<RefCntAutoPtr<ITextureView>>"))
{
-
-#if PLATFORM_WIN32
- auto hWnd = reinterpret_cast<HWND>(pNativeWndHandle);
-
- if( m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 )
- {
- RECT rc;
- if (FSDesc.Fullscreen)
- {
- const HWND hDesktop = GetDesktopWindow();
- GetWindowRect(hDesktop, &rc);
- }
- else
- {
- GetClientRect(hWnd, &rc);
- }
- m_SwapChainDesc.Width = rc.right - rc.left;
- m_SwapChainDesc.Height = rc.bottom - rc.top;
- }
-#endif
-
- auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat);
-
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
- swapChainDesc.Width = m_SwapChainDesc.Width;
- swapChainDesc.Height = m_SwapChainDesc.Height;
- // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats:
- // - DXGI_FORMAT_R16G16B16A16_FLOAT
- // - DXGI_FORMAT_B8G8R8A8_UNORM
- // - DXGI_FORMAT_R8G8B8A8_UNORM
- // - DXGI_FORMAT_R10G10B10A2_UNORM
- // If RGBA8_UNORM_SRGB swap chain is required, we will create RGBA8_UNORM swap chain, but
- // create RGBA8_UNORM_SRGB render target view
- swapChainDesc.Format = DXGIColorBuffFmt == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGIColorBuffFmt;
- swapChainDesc.Stereo = FALSE;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount;
- swapChainDesc.Scaling = DXGI_SCALING_NONE;
- // Windows Store apps must use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL or DXGI_SWAP_EFFECT_FLIP_DISCARD.
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
- swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used
- swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
-
- CComPtr<IDXGISwapChain1> pSwapChain1;
- CComPtr<IDXGIFactory4> factory;
- HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory4**>(&factory)) );
- CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory")
-
auto *pd3d12CmdQueue = pRenderDeviceD3D12->GetCmdQueue()->GetD3D12CommandQueue();
-
-#if PLATFORM_WIN32
-
- DXGI_SWAP_CHAIN_FULLSCREEN_DESC FullScreenDesc = {};
- FullScreenDesc.Windowed = FSDesc.Fullscreen ? FALSE : TRUE;
- FullScreenDesc.RefreshRate.Numerator = FSDesc.RefreshRateNumerator;
- FullScreenDesc.RefreshRate.Denominator = FSDesc.RefreshRateDenominator;
- FullScreenDesc.Scaling = static_cast<DXGI_MODE_SCALING>(FSDesc.Scaling);
- FullScreenDesc.ScanlineOrdering = static_cast<DXGI_MODE_SCANLINE_ORDER>(FSDesc.ScanlineOrder);
- hr = factory->CreateSwapChainForHwnd(pd3d12CmdQueue, hWnd, &swapChainDesc, &FullScreenDesc, nullptr, &pSwapChain1);
- CHECK_D3D_RESULT_THROW( hr, "Failed to create Swap Chain" );
-
- // This sample does not support fullscreen transitions.
- hr = factory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);
-
-#elif PLATFORM_UNIVERSAL_WINDOWS
-
- if (FSDesc.Fullscreen)
- LOG_WARNING_MESSAGE("UWP applications do not support fullscreen mode");
-
- hr = factory->CreateSwapChainForCoreWindow(
- pd3d12CmdQueue,
- reinterpret_cast<IUnknown*>(pNativeWndHandle),
- &swapChainDesc,
- nullptr,
- &pSwapChain1);
- CHECK_D3D_RESULT_THROW( hr, "Failed to create DXGI swap chain" );
-
- // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
- // ensures that the application will only render after each VSync, minimizing power consumption.
- //pDXGIDevice->SetMaximumFrameLatency( 1 );
-
-#endif
-
- pSwapChain1->QueryInterface(__uuidof(m_pSwapChain), reinterpret_cast<void**>( static_cast<IDXGISwapChain3**>(&m_pSwapChain) ));
-
+ CreateDXGISwapChain(pd3d12CmdQueue);
InitBuffersAndViews();
}
SwapChainD3D12Impl::~SwapChainD3D12Impl()
{
- if (m_pSwapChain)
- {
- BOOL IsFullScreen = FALSE;
- m_pSwapChain->GetFullscreenState(&IsFullScreen, nullptr);
- if (IsFullScreen)
- m_pSwapChain->SetFullscreenState(FALSE, nullptr);
- }
}
void SwapChainD3D12Impl::InitBuffersAndViews()
@@ -233,53 +141,71 @@ void SwapChainD3D12Impl::Present()
#endif
}
-void SwapChainD3D12Impl::Resize( Uint32 NewWidth, Uint32 NewHeight )
+void SwapChainD3D12Impl::UpdateSwapChain(bool CreateNew)
{
- if( TSwapChainBase::Resize(NewWidth, NewHeight) )
+ // When switching to full screen mode, WM_SIZE is send to the window
+ // and Resize() is called before the new swap chain is created
+ if (!m_pSwapChain)
+ return;
+
+ auto pDeviceContext = m_wpDeviceContext.Lock();
+ VERIFY(pDeviceContext, "Immediate context has been released");
+ if (pDeviceContext)
{
- auto pDeviceContext = m_wpDeviceContext.Lock();
- VERIFY( pDeviceContext, "Immediate context has been released" );
- if( pDeviceContext )
- {
- RenderDeviceD3D12Impl *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>(m_pRenderDevice.RawPtr());
- pDeviceContext->Flush();
+ RenderDeviceD3D12Impl *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>(m_pRenderDevice.RawPtr());
+ pDeviceContext->Flush();
- try
- {
- auto *pImmediateCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pDeviceContext.RawPtr());
- bool bIsDefaultFBBound = pImmediateCtxD3D12->IsDefaultFBBound();
+ try
+ {
+ auto *pImmediateCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pDeviceContext.RawPtr());
+ bool bIsDefaultFBBound = pImmediateCtxD3D12->IsDefaultFBBound();
- // All references to the swap chain must be released before it can be resized
- m_pBackBufferRTV.clear();
- m_pDepthBufferDSV.Release();
+ // All references to the swap chain must be released before it can be resized
+ m_pBackBufferRTV.clear();
+ m_pDepthBufferDSV.Release();
- // This will release references to D3D12 swap chain buffers hold by
- // m_pBackBufferRTV[]
- pDeviceD3D12->IdleGPU(true);
+ // This will release references to D3D12 swap chain buffers hold by
+ // m_pBackBufferRTV[]
+ pDeviceD3D12->IdleGPU(true);
+ if(CreateNew)
+ {
+ m_pSwapChain.Release();
+ auto *pd3d12CmdQueue = ValidatedCast<RenderDeviceD3D12Impl>(m_pRenderDevice.RawPtr())->GetCmdQueue()->GetD3D12CommandQueue();
+ CreateDXGISwapChain(pd3d12CmdQueue);
+ }
+ else
+ {
DXGI_SWAP_CHAIN_DESC SCDes;
- memset( &SCDes, 0, sizeof( SCDes ) );
- m_pSwapChain->GetDesc( &SCDes );
- CHECK_D3D_RESULT_THROW( m_pSwapChain->ResizeBuffers(SCDes.BufferCount, m_SwapChainDesc.Width,
- m_SwapChainDesc.Height, SCDes.BufferDesc.Format,
- SCDes.Flags),
- "Failed to resize the DXGI swap chain" );
+ memset(&SCDes, 0, sizeof(SCDes));
+ m_pSwapChain->GetDesc(&SCDes);
+ CHECK_D3D_RESULT_THROW(m_pSwapChain->ResizeBuffers(SCDes.BufferCount, m_SwapChainDesc.Width,
+ m_SwapChainDesc.Height, SCDes.BufferDesc.Format,
+ SCDes.Flags),
+ "Failed to resize the DXGI swap chain");
+ }
+ InitBuffersAndViews();
- InitBuffersAndViews();
-
- if( bIsDefaultFBBound )
- {
- // Set default render target and viewport
- pDeviceContext->SetRenderTargets( 0, nullptr, nullptr );
- pDeviceContext->SetViewports( 1, nullptr, 0, 0 );
- }
- }
- catch( const std::runtime_error & )
+ if (bIsDefaultFBBound)
{
- LOG_ERROR( "Failed to resize the swap chain" );
+ // Set default render target and viewport
+ pDeviceContext->SetRenderTargets(0, nullptr, nullptr);
+ pDeviceContext->SetViewports(1, nullptr, 0, 0);
}
}
+ catch (const std::runtime_error &)
+ {
+ LOG_ERROR("Failed to resize the swap chain");
+ }
+ }
+}
+
+void SwapChainD3D12Impl::Resize( Uint32 NewWidth, Uint32 NewHeight )
+{
+ if( TSwapChainBase::Resize(NewWidth, NewHeight) )
+ {
+ UpdateSwapChain(false);
}
}