123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- // Copyright 2019 Dolphin Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include "VideoBackends/D3DCommon/D3DCommon.h"
- #include <d3d11.h>
- #include <d3d12.h>
- #include <dxgi1_3.h>
- #include <wrl/client.h>
- #include "Common/Assert.h"
- #include "Common/DynamicLibrary.h"
- #include "Common/HRWrap.h"
- #include "Common/MsgHandler.h"
- #include "Common/StringUtil.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"))
- {
- PanicAlertFmtT("Failed to load dxgi.dll");
- return false;
- }
- if (!s_d3dcompiler_library.Open(D3DCOMPILER_DLL_A))
- {
- PanicAlertFmtT("Failed to load {0}. 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))
- {
- PanicAlertFmtT("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;
- }
- Microsoft::WRL::ComPtr<IDXGIFactory> CreateDXGIFactory(bool debug_device)
- {
- Microsoft::WRL::ComPtr<IDXGIFactory> 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.GetAddressOf()))))
- {
- return factory;
- }
- // Fallback to original version, without debug support.
- HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(factory.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- PanicAlertFmt("CreateDXGIFactory() failed: {}", Common::HRWrap(hr));
- return nullptr;
- }
- return factory;
- }
- std::vector<std::string> GetAdapterNames()
- {
- Microsoft::WRL::ComPtr<IDXGIFactory> factory;
- HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(factory.GetAddressOf()));
- if (FAILED(hr))
- return {};
- std::vector<std::string> adapters;
- Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
- while (factory->EnumAdapters(static_cast<UINT>(adapters.size()),
- adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND)
- {
- std::string name;
- DXGI_ADAPTER_DESC desc;
- if (SUCCEEDED(adapter->GetDesc(&desc)))
- name = WStringToUTF8(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::RGB10_A2:
- return typeless ? DXGI_FORMAT_R10G10B10A2_TYPELESS : DXGI_FORMAT_R10G10B10A2_UNORM;
- case AbstractTextureFormat::RGBA16F:
- return typeless ? DXGI_FORMAT_R16G16B16A16_TYPELESS : DXGI_FORMAT_R16G16B16A16_FLOAT;
- 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:
- PanicAlertFmt("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::RGB10_A2:
- return DXGI_FORMAT_R10G10B10A2_UNORM;
- case AbstractTextureFormat::RGBA16F:
- return DXGI_FORMAT_R16G16B16A16_FLOAT;
- 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:
- PanicAlertFmt("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::RGB10_A2:
- return DXGI_FORMAT_R10G10B10A2_UNORM;
- case AbstractTextureFormat::RGBA16F:
- return DXGI_FORMAT_R16G16B16A16_FLOAT;
- case AbstractTextureFormat::R16:
- return integer ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R16_UNORM;
- case AbstractTextureFormat::R32F:
- return DXGI_FORMAT_R32_FLOAT;
- default:
- PanicAlertFmt("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:
- PanicAlertFmt("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_R10G10B10A2_UNORM:
- case DXGI_FORMAT_R10G10B10A2_TYPELESS:
- return AbstractTextureFormat::RGB10_A2;
- case DXGI_FORMAT_R16G16B16A16_FLOAT:
- case DXGI_FORMAT_R16G16B16A16_TYPELESS:
- return AbstractTextureFormat::RGBA16F;
- 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, std::string_view name)
- {
- if (!g_ActiveConfig.bEnableValidationLayer)
- return;
- Microsoft::WRL::ComPtr<ID3D11DeviceChild> child11;
- Microsoft::WRL::ComPtr<ID3D12DeviceChild> child12;
- if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(child11.GetAddressOf()))))
- {
- child11->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()),
- name.data());
- }
- else if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(child12.GetAddressOf()))))
- {
- child12->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()),
- name.data());
- }
- }
- } // namespace D3DCommon
|