summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3DBase
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-01 21:29:40 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-01 21:29:40 +0000
commit6438621293a4dc5b12def1954375aa41e661bba4 (patch)
tree39660542c2d1d63fb1d2db26cb911f88b759b2fc /Graphics/GraphicsEngineD3DBase
parentImplementing texture views in Vulkan (diff)
parentAdded comment (diff)
downloadDiligentCore-6438621293a4dc5b12def1954375aa41e661bba4.tar.gz
DiligentCore-6438621293a4dc5b12def1954375aa41e661bba4.zip
Merge branch 'master'
Diffstat (limited to 'Graphics/GraphicsEngineD3DBase')
-rw-r--r--Graphics/GraphicsEngineD3DBase/CMakeLists.txt5
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/D3DErrors.h18
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h205
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh1
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh1
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h206
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp79
7 files changed, 478 insertions, 37 deletions
diff --git a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt
index ee5066ba..7b85ad3a 100644
--- a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt
+++ b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt
@@ -8,11 +8,13 @@ set(INCLUDE
include/D3DTypeConversionImpl.h
include/D3DViewDescConversionImpl.h
include/DXGITypeConversions.h
+ include/EngineFactoryD3DBase.h
include/HLSLDefinitions.fxh
include/RenderDeviceD3DBase.h
include/ShaderD3DBase.h
include/ShaderResources.h
include/ShaderVariableD3DBase.h
+ include/SwapChainD3DBase.h
)
set(SOURCE
@@ -58,6 +60,9 @@ PUBLIC
BuildSettings
GraphicsEngine
)
+if(D3D12_SUPPORTED)
+ target_link_libraries(GraphicsEngineD3DBase PRIVATE D3D12.lib)
+endif()
set_common_target_properties(GraphicsEngineD3DBase)
source_group("src" FILES ${SOURCE})
diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h
index 0a9233e4..b1d1e068 100644
--- a/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h
+++ b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h
@@ -67,17 +67,17 @@ private:
#define CHECK_D3D_RESULT_THROW(Expr, Message)\
-{ \
+do{ \
HRESULT _hr_ = Expr; \
if(FAILED(_hr_)) \
{ \
ComErrorDesc ErrDesc( _hr_ ); \
LOG_ERROR_AND_THROW( Message, "\nHRESULT Desc: ", ErrDesc.Get());\
} \
-}
+}while(false)
#define CHECK_D3D_RESULT_THROW_EX(Expr, ...)\
-{ \
+do{ \
HRESULT _hr_ = Expr; \
if(FAILED(_hr_)) \
{ \
@@ -86,4 +86,14 @@ private:
ComErrorDesc ErrDesc( _hr_ ); \
LOG_ERROR_AND_THROW( ms.str(), "\nHRESULT Desc: ", ErrDesc.Get());\
} \
-}
+}while(false)
+
+#define LOG_D3D_ERROR(Expr, Message)\
+do{ \
+ HRESULT _hr_ = Expr; \
+ if(FAILED(_hr_)) \
+ { \
+ ComErrorDesc ErrDesc( _hr_ ); \
+ LOG_ERROR_MESSAGE( Message, "\nHRESULT Desc: ", ErrDesc.Get());\
+ } \
+}while(false)
diff --git a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h
new file mode 100644
index 00000000..934b8974
--- /dev/null
+++ b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h
@@ -0,0 +1,205 @@
+/* Copyright 2015-2018 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#pragma once
+
+#include "DXGITypeConversions.h"
+
+/// \file
+/// Implementation of the Diligent::EngineFactoryD3DBase template class
+
+namespace Diligent
+{
+
+template<typename BaseInterface, DeviceType DevType>
+class EngineFactoryD3DBase : public BaseInterface
+{
+public:
+ /// Enumerates hardware adapters available on this machine
+
+ /// \param [in,out] NumAdapters - Number of adapters. If Adapters is null, this value
+ /// will be overwritten with the number of adapters available
+ /// on this system. If Adapters is not null, this value should
+ /// contain maximum number of elements reserved in the array
+ /// pointed to by Adapters. In the latter case, this value
+ /// is overwritten with the actual number of elements written to
+ /// Adapters.
+ /// \param [out] Adapters - Pointer to the array conataining adapter information. If
+ /// null is provided, the number of available adapters is written to
+ /// NumAdapters
+ virtual void EnumerateHardwareAdapters(Uint32 &NumAdapters,
+ HardwareAdapterAttribs *Adapters)override final
+ {
+ auto DXGIAdapters = FindCompatibleAdapters();
+
+ if (Adapters == nullptr)
+ NumAdapters = static_cast<Uint32>(DXGIAdapters.size());
+ else
+ {
+ NumAdapters = std::min(NumAdapters, static_cast<Uint32>(DXGIAdapters.size()));
+ for (Uint32 adapter = 0; adapter < NumAdapters; ++adapter)
+ {
+ IDXGIAdapter1 *pDXIAdapter = DXGIAdapters[adapter];
+ DXGI_ADAPTER_DESC1 AdapterDesc;
+ pDXIAdapter->GetDesc1(&AdapterDesc);
+
+ auto &Attribs = Adapters[adapter];
+ WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, Attribs.Description, _countof(Attribs.Description), NULL, FALSE);
+ Attribs.DedicatedVideoMemory = AdapterDesc.DedicatedVideoMemory;
+ Attribs.DedicatedSystemMemory = AdapterDesc.DedicatedSystemMemory;
+ Attribs.SharedSystemMemory = AdapterDesc.SharedSystemMemory;
+ Attribs.VendorId = AdapterDesc.VendorId;
+ Attribs.DeviceId = AdapterDesc.DeviceId;
+
+ Attribs.NumOutputs = 0;
+ CComPtr<IDXGIOutput> pOutput;
+ while (pDXIAdapter->EnumOutputs(Attribs.NumOutputs, &pOutput) != DXGI_ERROR_NOT_FOUND)
+ {
+ ++Attribs.NumOutputs;
+ pOutput.Release();
+ };
+ }
+ }
+ }
+
+ /// Enumerates available display modes for the specified output of the specified adapter
+
+ /// \param [in] AdapterId - Id of the adapter enumerated by EnumerateHardwareAdapters().
+ /// \param [in] OutputId - Adapter output id
+ /// \param [in] Format - Display mode format
+ /// \param [in, out] NumDisplayModes - Number of display modes. If DisplayModes is null, this
+ /// value is overwritten with the number of display modes
+ /// available for this output. If DisplayModes is not null,
+ /// this value should contain the maximum number of elements
+ /// to be written to DisplayModes array. It is overwritten with
+ /// the actual number of display modes written.
+ virtual void EnumerateDisplayModes(Uint32 AdapterId,
+ Uint32 OutputId,
+ TEXTURE_FORMAT Format,
+ Uint32 &NumDisplayModes,
+ DisplayModeAttribs *DisplayModes)override final
+ {
+ auto DXGIAdapters = FindCompatibleAdapters();
+ if(AdapterId >= DXGIAdapters.size())
+ {
+ LOG_ERROR("Incorrect adapter id ", AdapterId);
+ return;
+ }
+
+ IDXGIAdapter1 *pDXIAdapter = DXGIAdapters[AdapterId];
+
+ DXGI_FORMAT DXIGFormat = TexFormatToDXGI_Format(Format);
+ CComPtr<IDXGIOutput> pOutput;
+ if (pDXIAdapter->EnumOutputs(OutputId, &pOutput) == DXGI_ERROR_NOT_FOUND)
+ {
+ DXGI_ADAPTER_DESC1 AdapterDesc;
+ pDXIAdapter->GetDesc1(&AdapterDesc);
+ char DescriptionMB[_countof(AdapterDesc.Description)];
+ WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, DescriptionMB, _countof(DescriptionMB), NULL, FALSE);
+ LOG_ERROR_MESSAGE("Failed to enumerate output ", OutputId, " for adapter ", AdapterId, " (", DescriptionMB, ')');
+ return;
+ }
+
+ UINT numModes = 0;
+ // Get the number of elements
+ auto hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, NULL);
+ if (DisplayModes != nullptr)
+ {
+ // Get the list
+ std::vector<DXGI_MODE_DESC> DXIDisplayModes(numModes);
+ hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, DXIDisplayModes.data());
+ for (Uint32 m = 0; m < std::min(NumDisplayModes, numModes); ++m)
+ {
+ const auto &SrcMode = DXIDisplayModes[m];
+ auto &DstMode = DisplayModes[m];
+ DstMode.Width = SrcMode.Width;
+ DstMode.Height = SrcMode.Height;
+ DstMode.Format = DXGI_FormatToTexFormat(SrcMode.Format);
+ DstMode.RefreshRateNumerator = SrcMode.RefreshRate.Numerator;
+ DstMode.RefreshRateDenominator = SrcMode.RefreshRate.Denominator;
+ DstMode.Scaling = static_cast<DisplayModeAttribs::SCALING>(SrcMode.Scaling);
+ DstMode.ScanlineOrder = static_cast<DisplayModeAttribs::SCANLINE_ORDER>(SrcMode.ScanlineOrdering);
+ }
+ NumDisplayModes = std::min(NumDisplayModes, numModes);
+ }
+ else
+ {
+ NumDisplayModes = numModes;
+ }
+ }
+
+
+ std::vector<CComPtr<IDXGIAdapter1>> FindCompatibleAdapters()
+ {
+ std::vector<CComPtr<IDXGIAdapter1>> DXGIAdapters;
+
+ CComPtr<IDXGIFactory2> pFactory;
+ if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&pFactory)))
+ {
+ LOG_ERROR_MESSAGE("Failed to create DXGI Factory");
+ return std::move(DXGIAdapters);
+ }
+
+ CComPtr<IDXGIAdapter1> pDXIAdapter;
+ UINT adapter = 0;
+ for (; pFactory->EnumAdapters1(adapter, &pDXIAdapter) != DXGI_ERROR_NOT_FOUND; ++adapter, pDXIAdapter.Release())
+ {
+ DXGI_ADAPTER_DESC1 AdapterDesc;
+ pDXIAdapter->GetDesc1(&AdapterDesc);
+ if (AdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
+ {
+ // Skip software devices
+ continue;
+ }
+
+ bool IsCompatibleAdapter = CheckAdapterCompatibility<DevType>(pDXIAdapter);
+
+ if (IsCompatibleAdapter)
+ {
+ DXGIAdapters.emplace_back(std::move(pDXIAdapter));
+ }
+ }
+
+ return std::move(DXGIAdapters);
+ }
+
+private:
+
+ template<DeviceType DevType>
+ bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter);
+
+ template<>
+ bool CheckAdapterCompatibility<DeviceType::D3D11>(IDXGIAdapter1 *pDXGIAdapter)
+ {
+ return true;
+ }
+
+ template<>
+ bool CheckAdapterCompatibility<DeviceType::D3D12>(IDXGIAdapter1 *pDXGIAdapter)
+ {
+ auto hr = D3D12CreateDevice(pDXGIAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
+ return SUCCEEDED(hr);
+ }
+};
+
+}
diff --git a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh
index df6edfa0..44ed3641 100644
--- a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh
+++ b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh
@@ -74,3 +74,4 @@ float2x2 MatrixFromRows(float2 row0, float2 row1)
}
#endif // _HLSL_DEFINITIONS_
+
diff --git a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh
index 3eb36067..72bfc1f8 100644
--- a/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh
+++ b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh
@@ -74,3 +74,4 @@
"}\n"
"\n"
"#endif // _HLSL_DEFINITIONS_\n"
+"\n"
diff --git a/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h
new file mode 100644
index 00000000..9f69d55b
--- /dev/null
+++ b/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h
@@ -0,0 +1,206 @@
+/* Copyright 2015-2018 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#pragma once
+
+#include "SwapChainBase.h"
+
+/// \file
+/// Base implementation of a D3D swap chain
+
+namespace Diligent
+{
+ /// Base implementation of a D3D swap chain
+ template<class BaseInterface, typename DXGISwapChainType>
+ class SwapChainD3DBase : public SwapChainBase<BaseInterface>
+ {
+ public:
+ using TBase = SwapChainBase<BaseInterface>;
+ SwapChainD3DBase(IReferenceCounters *pRefCounters,
+ IRenderDevice *pDevice,
+ IDeviceContext *pDeviceContext,
+ const SwapChainDesc& SCDesc,
+ const FullScreenModeDesc& FSDesc,
+ void* pNativeWndHandle) :
+ TBase(pRefCounters, pDevice, pDeviceContext, SCDesc),
+ m_FSDesc(FSDesc),
+ m_pNativeWndHandle(pNativeWndHandle)
+ {}
+
+ ~SwapChainD3DBase()
+ {
+ if (m_pSwapChain)
+ {
+ // Swap chain must be in windowed mode when it is destroyed
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075(v=vs.85).aspx#Destroying
+ BOOL IsFullScreen = FALSE;
+ m_pSwapChain->GetFullscreenState(&IsFullScreen, nullptr);
+ if (IsFullScreen)
+ m_pSwapChain->SetFullscreenState(FALSE, nullptr);
+ }
+ }
+
+ protected:
+ virtual void UpdateSwapChain(bool CreateNew) = 0;
+
+ void CreateDXGISwapChain(IUnknown *pD3D11DeviceOrD3D12CmdQueue)
+ {
+#if PLATFORM_WIN32
+ auto hWnd = reinterpret_cast<HWND>(m_pNativeWndHandle);
+ if (m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0)
+ {
+ RECT rc;
+ if (m_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;
+
+ // DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is the flip presentation model, where the contents of the back
+ // buffer is preserved after the call to Present. This flag cannot be used with multisampling.
+ // The only swap effect that supports multisampling is DXGI_SWAP_EFFECT_DISCARD.
+ // 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; // Transparency behavior is not specified
+
+ // DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH enables an application to switch modes by calling
+ // IDXGISwapChain::ResizeTarget(). When switching from windowed to fullscreen mode, the display
+ // mode (or monitor resolution) will be changed to match the dimensions of the application window.
+ swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+ CComPtr<IDXGISwapChain1> pSwapChain1;
+ CComPtr<IDXGIFactory2> factory;
+ HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory2**>(&factory)));
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory");
+
+#if PLATFORM_WIN32
+
+ DXGI_SWAP_CHAIN_FULLSCREEN_DESC FullScreenDesc = {};
+ FullScreenDesc.Windowed = m_FSDesc.Fullscreen ? FALSE : TRUE;
+ FullScreenDesc.RefreshRate.Numerator = m_FSDesc.RefreshRateNumerator;
+ FullScreenDesc.RefreshRate.Denominator = m_FSDesc.RefreshRateDenominator;
+ FullScreenDesc.Scaling = static_cast<DXGI_MODE_SCALING>(m_FSDesc.Scaling);
+ FullScreenDesc.ScanlineOrdering = static_cast<DXGI_MODE_SCANLINE_ORDER>(m_FSDesc.ScanlineOrder);
+ hr = factory->CreateSwapChainForHwnd(pD3D11DeviceOrD3D12CmdQueue, hWnd, &swapChainDesc, &FullScreenDesc, nullptr, &pSwapChain1);
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create Swap Chain");
+
+ {
+ // This is silly, but IDXGIFactory used for MakeWindowAssociation must be retrieved via
+ // calling IDXGISwapchain::GetParent first, otherwise it won't work
+ // https://www.gamedev.net/forums/topic/634235-dxgidisabling-altenter/?do=findComment&comment=4999990
+ CComPtr<IDXGIFactory1> pFactoryFromSC;
+ if (SUCCEEDED(pSwapChain1->GetParent(__uuidof(pFactoryFromSC), (void **)&pFactoryFromSC)))
+ {
+ // Do not allow the swap chain to handle Alt+Enter
+ pFactoryFromSC->MakeWindowAssociation(hWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);
+ }
+ }
+
+#elif PLATFORM_UNIVERSAL_WINDOWS
+
+ if (m_FSDesc.Fullscreen)
+ LOG_WARNING_MESSAGE("UWP applications do not support fullscreen mode");
+
+ hr = factory->CreateSwapChainForCoreWindow(
+ pD3D11DeviceOrD3D12CmdQueue,
+ reinterpret_cast<IUnknown*>(m_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<DXGISwapChainType**>(&m_pSwapChain)));
+
+ }
+
+ virtual void SetFullscreenMode(const DisplayModeAttribs &DisplayMode)override final
+ {
+ if (m_pSwapChain)
+ {
+ // If we are already in fullscreen mode, we need to switch to windowed mode first,
+ // because a swap chain must be in windowed mode when it is released.
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075(v=vs.85).aspx#Destroying
+ if (m_FSDesc.Fullscreen)
+ m_pSwapChain->SetFullscreenState(FALSE, nullptr);
+ m_FSDesc.Fullscreen = True;
+ m_FSDesc.RefreshRateNumerator = DisplayMode.RefreshRateNumerator;
+ m_FSDesc.RefreshRateDenominator = DisplayMode.RefreshRateDenominator;
+ m_FSDesc.Scaling = DisplayMode.Scaling;
+ m_FSDesc.ScanlineOrder = DisplayMode.ScanlineOrder;
+ m_SwapChainDesc.Width = DisplayMode.Width;
+ m_SwapChainDesc.Height = DisplayMode.Height;
+ if (DisplayMode.Format != TEX_FORMAT_UNKNOWN)
+ m_SwapChainDesc.ColorBufferFormat = DisplayMode.Format;
+ UpdateSwapChain(true);
+ }
+ }
+
+ virtual void SetWindowedMode()override final
+ {
+ if (m_FSDesc.Fullscreen)
+ {
+ m_FSDesc.Fullscreen = False;
+ m_pSwapChain->SetFullscreenState(FALSE, nullptr);
+ }
+ }
+
+ FullScreenModeDesc m_FSDesc;
+ CComPtr<DXGISwapChainType> m_pSwapChain;
+ void* m_pNativeWndHandle;
+ };
+}
diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
index 31332e3e..0e70d7fa 100644
--- a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
+++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
@@ -57,7 +57,7 @@ public:
return E_FAIL;
}
- RefCntAutoPtr<Diligent::IDataBlob> pFileData( MakeNewRCObj<Diligent::DataBlobImpl>()(0) );
+ RefCntAutoPtr<IDataBlob> pFileData( MakeNewRCObj<DataBlobImpl>()(0) );
pSourceStream->Read( pFileData );
*ppData = pFileData->GetDataPtr();
*pBytes = static_cast<UINT>( pFileData->GetSize() );
@@ -75,7 +75,7 @@ public:
private:
IShaderSourceInputStreamFactory *m_pStreamFactory;
- std::unordered_map< LPCVOID, RefCntAutoPtr<Diligent::IDataBlob> > m_DataBlobs;
+ std::unordered_map< LPCVOID, RefCntAutoPtr<IDataBlob> > m_DataBlobs;
};
HRESULT CompileShader( const char* Source,
@@ -83,7 +83,8 @@ HRESULT CompileShader( const char* Source,
const D3D_SHADER_MACRO* pDefines,
IShaderSourceInputStreamFactory *pIncludeStreamFactory,
LPCSTR profile,
- ID3DBlob **ppBlobOut )
+ ID3DBlob **ppBlobOut,
+ ID3DBlob **ppCompilerOutput)
{
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
@@ -98,37 +99,25 @@ HRESULT CompileShader( const char* Source,
// dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3;
#endif
HRESULT hr;
- do
- {
- CComPtr<ID3DBlob> errors;
+// do
+// {
auto SourceLen = strlen(Source);
D3DIncludeImpl IncludeImpl(pIncludeStreamFactory);
- hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, &errors );
+ hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, ppCompilerOutput);
- if( FAILED(hr) || errors )
- {
- std::wstringstream errorss;
- ComErrorDesc ErrDesc(hr);
- if( FAILED(hr) )
- Diligent::FormatMsg( errorss, "Failed to compile shader\n" );
- else
- Diligent::FormatMsg( errorss, "Shader compiler output:\n" );
- Diligent::FormatMsg( errorss, ErrDesc.Get(), "\n" );
- if( errors )
- Diligent::FormatMsg( errorss, (char*)errors->GetBufferPointer() );
- auto ErrorDesc = errorss.str();
- OutputDebugStringW( ErrorDesc.c_str() );
- if( FAILED(hr)
-#if PLATFORM_WIN32
- && IDRETRY != MessageBoxW( NULL, ErrorDesc.c_str() , L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) )
-#endif
- )
- {
- break;
- }
- }
- } while( FAILED(hr) );
+// if( FAILED(hr) || errors )
+// {
+// if( FAILED(hr)
+//#if PLATFORM_WIN32
+// && IDRETRY != MessageBoxW( NULL, L"Failed to compile shader", L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) )
+//#endif
+// )
+// {
+// break;
+// }
+// }
+// } while( FAILED(hr) );
return hr;
}
@@ -178,7 +167,7 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs)
VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null");
RefCntAutoPtr<IFileStream> pSourceStream;
CreationAttribs.pShaderSourceStreamFactory->CreateInputStream(CreationAttribs.FilePath, &pSourceStream);
- RefCntAutoPtr<Diligent::IDataBlob> pFileData(MakeNewRCObj<Diligent::DataBlobImpl>()(0));
+ RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0));
if (pSourceStream == nullptr)
LOG_ERROR_AND_THROW("Failed to open shader source file");
pSourceStream->Read(pFileData);
@@ -201,8 +190,32 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs)
}
VERIFY(CreationAttribs.EntryPoint != nullptr, "Entry point must not be null");
- CHECK_D3D_RESULT_THROW(CompileShader(ShaderSource.c_str(), CreationAttribs.EntryPoint, pDefines, CreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode),
- "Failed to compile the shader");
+ CComPtr<ID3DBlob> errors;
+ auto hr = CompileShader(ShaderSource.c_str(), CreationAttribs.EntryPoint, pDefines, CreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode, &errors);
+
+ const char *CompilerMsg = errors ? reinterpret_cast<const char*>(errors->GetBufferPointer()) : nullptr;
+ if(CompilerMsg != nullptr && CreationAttribs.ppCompilerOutput != nullptr)
+ {
+ auto ErrorMsgLen = strlen(CompilerMsg);
+ auto *pOutputDataBlob = MakeNewRCObj<DataBlobImpl>()(ErrorMsgLen + 1 + ShaderSource.length() + 1);
+ char* DataPtr = reinterpret_cast<char*>(pOutputDataBlob->GetDataPtr());
+ memcpy(DataPtr, CompilerMsg, ErrorMsgLen+1);
+ memcpy(DataPtr + ErrorMsgLen + 1, ShaderSource.data(), ShaderSource.length() + 1);
+ pOutputDataBlob->QueryInterface(IID_DataBlob, reinterpret_cast<IObject**>(CreationAttribs.ppCompilerOutput));
+ }
+
+ if(FAILED(hr))
+ {
+ ComErrorDesc ErrDesc(hr);
+ if(CreationAttribs.ppCompilerOutput != nullptr)
+ {
+ LOG_ERROR_AND_THROW("Failed to compile D3D shader \"", (CreationAttribs.Desc.Name != nullptr ? CreationAttribs.Desc.Name : ""), "\" (", ErrDesc.Get(), ").");
+ }
+ else
+ {
+ LOG_ERROR_AND_THROW("Failed to compile D3D shader \"", (CreationAttribs.Desc.Name != nullptr ? CreationAttribs.Desc.Name : ""), "\" (", ErrDesc.Get(), "):\n", (CompilerMsg != nullptr ? CompilerMsg : "<no compiler log available>") );
+ }
+ }
}
else if (CreationAttribs.ByteCode)
{