summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3DCommon/Common.cpp
diff options
context:
space:
mode:
authorConnor McLaughlin <stenzek@gmail.com>2019-03-29 20:40:06 +1000
committerGitHub <noreply@github.com>2019-03-29 20:40:06 +1000
commitf3fadd730218429a5f6472283d16d30d7e276f8d (patch)
treed1d6577cd52b2d3b3d7872aef4fac80dbd0ce563 /Source/Core/VideoBackends/D3DCommon/Common.cpp
parentfbe57e8dbef17e583f0ba0208af7bf414a3716bf (diff)
parentd0d010f8549cc902829f567b3b5127d9a0556ca5 (diff)
Merge pull request #7869 from stenzek/d3dcommon
D3D: Move sharable D3D11/D3D12 code to common library
Diffstat (limited to 'Source/Core/VideoBackends/D3DCommon/Common.cpp')
-rw-r--r--Source/Core/VideoBackends/D3DCommon/Common.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/Source/Core/VideoBackends/D3DCommon/Common.cpp b/Source/Core/VideoBackends/D3DCommon/Common.cpp
new file mode 100644
index 0000000000..f82c2d3f8c
--- /dev/null
+++ b/Source/Core/VideoBackends/D3DCommon/Common.cpp
@@ -0,0 +1,320 @@
+// Copyright 2019 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <d3d11.h>
+#include <d3d12.h>
+#include <dxgi1_3.h>
+#include <wrl/client.h>
+
+#include "Common/Assert.h"
+#include "Common/DynamicLibrary.h"
+#include "Common/MsgHandler.h"
+#include "Common/StringUtil.h"
+#include "VideoBackends/D3DCommon/Common.h"
+#include "VideoCommon/TextureConfig.h"
+#include "VideoCommon/VideoConfig.h"
+
+namespace D3DCommon
+{
+pD3DCompile d3d_compile;
+
+static Common::DynamicLibrary s_dxgi_library;
+static Common::DynamicLibrary s_d3dcompiler_library;
+static bool s_libraries_loaded = false;
+
+static HRESULT (*create_dxgi_factory)(REFIID riid, _COM_Outptr_ void** ppFactory);
+static HRESULT (*create_dxgi_factory2)(UINT Flags, REFIID riid, void** ppFactory);
+
+bool LoadLibraries()
+{
+ if (s_libraries_loaded)
+ return true;
+
+ if (!s_dxgi_library.Open("dxgi.dll"))
+ {
+ PanicAlertT("Failed to load dxgi.dll");
+ return false;
+ }
+
+ if (!s_d3dcompiler_library.Open(D3DCOMPILER_DLL_A))
+ {
+ PanicAlertT("Failed to load %s. If you are using Windows 7, try installing the "
+ "KB4019990 update package.",
+ D3DCOMPILER_DLL_A);
+ s_dxgi_library.Close();
+ return false;
+ }
+
+ // Required symbols.
+ if (!s_d3dcompiler_library.GetSymbol("D3DCompile", &d3d_compile) ||
+ !s_dxgi_library.GetSymbol("CreateDXGIFactory", &create_dxgi_factory))
+ {
+ PanicAlertT("Failed to find one or more D3D symbols");
+ s_d3dcompiler_library.Close();
+ s_dxgi_library.Close();
+ return false;
+ }
+
+ // Optional symbols.
+ s_dxgi_library.GetSymbol("CreateDXGIFactory2", &create_dxgi_factory2);
+ s_libraries_loaded = true;
+ return true;
+}
+
+void UnloadLibraries()
+{
+ create_dxgi_factory = nullptr;
+ create_dxgi_factory2 = nullptr;
+ d3d_compile = nullptr;
+ s_d3dcompiler_library.Close();
+ s_dxgi_library.Close();
+ s_libraries_loaded = false;
+}
+
+IDXGIFactory2* CreateDXGIFactory(bool debug_device)
+{
+ IDXGIFactory2* factory;
+
+ // Use Win8.1 version if available.
+ if (create_dxgi_factory2 &&
+ SUCCEEDED(create_dxgi_factory2(debug_device ? DXGI_CREATE_FACTORY_DEBUG : 0,
+ IID_PPV_ARGS(&factory))))
+ {
+ return factory;
+ }
+
+ // Fallback to original version, without debug support.
+ HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(&factory));
+ if (FAILED(hr))
+ {
+ PanicAlert("CreateDXGIFactory() failed with HRESULT %08X", hr);
+ return nullptr;
+ }
+
+ return factory;
+}
+
+std::vector<std::string> GetAdapterNames()
+{
+ Microsoft::WRL::ComPtr<IDXGIFactory> factory;
+ HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(&factory));
+ if (!SUCCEEDED(hr))
+ return {};
+
+ std::vector<std::string> adapters;
+ IDXGIAdapter* adapter;
+ while (factory->EnumAdapters(static_cast<UINT>(adapters.size()), &adapter) !=
+ DXGI_ERROR_NOT_FOUND)
+ {
+ std::string name;
+ DXGI_ADAPTER_DESC desc;
+ if (SUCCEEDED(adapter->GetDesc(&desc)))
+ name = UTF16ToUTF8(desc.Description);
+
+ adapters.push_back(std::move(name));
+ }
+
+ return adapters;
+}
+
+DXGI_FORMAT GetDXGIFormatForAbstractFormat(AbstractTextureFormat format, bool typeless)
+{
+ switch (format)
+ {
+ case AbstractTextureFormat::DXT1:
+ return DXGI_FORMAT_BC1_UNORM;
+ case AbstractTextureFormat::DXT3:
+ return DXGI_FORMAT_BC2_UNORM;
+ case AbstractTextureFormat::DXT5:
+ return DXGI_FORMAT_BC3_UNORM;
+ case AbstractTextureFormat::BPTC:
+ return DXGI_FORMAT_BC7_UNORM;
+ case AbstractTextureFormat::RGBA8:
+ return typeless ? DXGI_FORMAT_R8G8B8A8_TYPELESS : DXGI_FORMAT_R8G8B8A8_UNORM;
+ case AbstractTextureFormat::BGRA8:
+ return typeless ? DXGI_FORMAT_B8G8R8A8_TYPELESS : DXGI_FORMAT_B8G8R8A8_UNORM;
+ case AbstractTextureFormat::R16:
+ return typeless ? DXGI_FORMAT_R16_TYPELESS : DXGI_FORMAT_R16_UNORM;
+ case AbstractTextureFormat::R32F:
+ return typeless ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_R32_FLOAT;
+ case AbstractTextureFormat::D16:
+ return DXGI_FORMAT_R16_TYPELESS;
+ case AbstractTextureFormat::D24_S8:
+ return DXGI_FORMAT_R24G8_TYPELESS;
+ case AbstractTextureFormat::D32F:
+ return DXGI_FORMAT_R32_TYPELESS;
+ case AbstractTextureFormat::D32F_S8:
+ return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
+ default:
+ PanicAlert("Unhandled texture format.");
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ }
+}
+DXGI_FORMAT GetSRVFormatForAbstractFormat(AbstractTextureFormat format)
+{
+ switch (format)
+ {
+ case AbstractTextureFormat::DXT1:
+ return DXGI_FORMAT_BC1_UNORM;
+ case AbstractTextureFormat::DXT3:
+ return DXGI_FORMAT_BC2_UNORM;
+ case AbstractTextureFormat::DXT5:
+ return DXGI_FORMAT_BC3_UNORM;
+ case AbstractTextureFormat::BPTC:
+ return DXGI_FORMAT_BC7_UNORM;
+ case AbstractTextureFormat::RGBA8:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case AbstractTextureFormat::BGRA8:
+ return DXGI_FORMAT_B8G8R8A8_UNORM;
+ case AbstractTextureFormat::R16:
+ return DXGI_FORMAT_R16_UNORM;
+ case AbstractTextureFormat::R32F:
+ return DXGI_FORMAT_R32_FLOAT;
+ case AbstractTextureFormat::D16:
+ return DXGI_FORMAT_R16_UNORM;
+ case AbstractTextureFormat::D24_S8:
+ return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+ case AbstractTextureFormat::D32F:
+ return DXGI_FORMAT_R32_FLOAT;
+ case AbstractTextureFormat::D32F_S8:
+ return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
+ default:
+ PanicAlert("Unhandled SRV format");
+ return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+DXGI_FORMAT GetRTVFormatForAbstractFormat(AbstractTextureFormat format, bool integer)
+{
+ switch (format)
+ {
+ case AbstractTextureFormat::RGBA8:
+ return integer ? DXGI_FORMAT_R8G8B8A8_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
+ case AbstractTextureFormat::BGRA8:
+ return DXGI_FORMAT_B8G8R8A8_UNORM;
+ case AbstractTextureFormat::R16:
+ return integer ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R16_UNORM;
+ case AbstractTextureFormat::R32F:
+ return DXGI_FORMAT_R32_FLOAT;
+ default:
+ PanicAlert("Unhandled RTV format");
+ return DXGI_FORMAT_UNKNOWN;
+ }
+}
+DXGI_FORMAT GetDSVFormatForAbstractFormat(AbstractTextureFormat format)
+{
+ switch (format)
+ {
+ case AbstractTextureFormat::D16:
+ return DXGI_FORMAT_D16_UNORM;
+ case AbstractTextureFormat::D24_S8:
+ return DXGI_FORMAT_D24_UNORM_S8_UINT;
+ case AbstractTextureFormat::D32F:
+ return DXGI_FORMAT_D32_FLOAT;
+ case AbstractTextureFormat::D32F_S8:
+ return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
+ default:
+ PanicAlert("Unhandled DSV format");
+ return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+AbstractTextureFormat GetAbstractFormatForDXGIFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ return AbstractTextureFormat::RGBA8;
+
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ return AbstractTextureFormat::BGRA8;
+
+ case DXGI_FORMAT_R16_UINT:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16_TYPELESS:
+ return AbstractTextureFormat::R16;
+
+ case DXGI_FORMAT_R32_FLOAT:
+ case DXGI_FORMAT_R32_TYPELESS:
+ return AbstractTextureFormat::R32F;
+
+ case DXGI_FORMAT_D16_UNORM:
+ return AbstractTextureFormat::D16;
+
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ return AbstractTextureFormat::D24_S8;
+
+ case DXGI_FORMAT_D32_FLOAT:
+ return AbstractTextureFormat::D32F;
+
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ return AbstractTextureFormat::D32F_S8;
+
+ case DXGI_FORMAT_BC1_UNORM:
+ return AbstractTextureFormat::DXT1;
+ case DXGI_FORMAT_BC2_UNORM:
+ return AbstractTextureFormat::DXT3;
+ case DXGI_FORMAT_BC3_UNORM:
+ return AbstractTextureFormat::DXT5;
+ case DXGI_FORMAT_BC7_UNORM:
+ return AbstractTextureFormat::BPTC;
+
+ default:
+ return AbstractTextureFormat::Undefined;
+ }
+}
+
+void SetDebugObjectName(IUnknown* resource, const char* format, ...)
+{
+ if (!g_ActiveConfig.bEnableValidationLayer)
+ return;
+
+ std::va_list ap;
+ va_start(ap, format);
+ std::string name = StringFromFormatV(format, ap);
+ va_end(ap);
+
+ Microsoft::WRL::ComPtr<ID3D11DeviceChild> child11;
+ Microsoft::WRL::ComPtr<ID3D12DeviceChild> child12;
+ if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child11))))
+ {
+ child11->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()),
+ name.c_str());
+ }
+ else if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child12))))
+ {
+ child12->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()),
+ name.c_str());
+ }
+}
+
+std::string GetDebugObjectName(IUnknown* resource)
+{
+ if (!g_ActiveConfig.bEnableValidationLayer)
+ return {};
+
+ std::string name;
+ UINT size = 0;
+
+ Microsoft::WRL::ComPtr<ID3D11DeviceChild> child11;
+ Microsoft::WRL::ComPtr<ID3D12DeviceChild> child12;
+ if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child11))))
+ {
+ child11->GetPrivateData(WKPDID_D3DDebugObjectName, &size, nullptr);
+ name.resize(size);
+ child11->GetPrivateData(WKPDID_D3DDebugObjectName, &size, name.data());
+ }
+ else if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child12))))
+ {
+ child12->GetPrivateData(WKPDID_D3DDebugObjectName, &size, nullptr);
+ name.resize(size);
+ child12->GetPrivateData(WKPDID_D3DDebugObjectName, &size, name.data());
+ }
+
+ return name;
+}
+} // namespace D3DCommon