diff --git a/CMakeLists.txt b/CMakeLists.txt index 799ba0b..3a3892e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,3 +18,6 @@ endif() if (DESKTOP_APP_USE_ALLOCATION_TRACER) add_subdirectory(linux_allocation_tracer) endif() +if (WIN32) + add_subdirectory(win_directx_helper) +endif() diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 24b7a9a..118178c 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -11,6 +11,7 @@ macro(add_checked_subdirectory name) endif() endmacro() +add_checked_subdirectory(angle) add_checked_subdirectory(auto_updates) add_checked_subdirectory(crash_reports) if (LINUX AND NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION) diff --git a/external/angle/CMakeLists.txt b/external/angle/CMakeLists.txt new file mode 100644 index 0000000..5526582 --- /dev/null +++ b/external/angle/CMakeLists.txt @@ -0,0 +1,27 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +add_library(external_angle INTERFACE IMPORTED GLOBAL) +add_library(desktop-app::external_angle ALIAS external_angle) + +if (WIN32) + target_include_directories(external_angle + INTERFACE + ${libs_loc}/angle/include + ) + set(angle_libs_loc ${libs_loc}/angle/out/$,Debug,Release>/obj) + target_link_libraries(external_angle + INTERFACE + ${angle_libs_loc}/libANGLE_static.lib + ${angle_libs_loc}/libGLESv2_static.lib + ${angle_libs_loc}/libEGL_static.lib + dxguid.lib + ) + target_link_libraries(external_angle + INTERFACE + desktop-app::win_directx_helper + ) +endif() diff --git a/external/qt/CMakeLists.txt b/external/qt/CMakeLists.txt index 415f4d5..e7c78a8 100644 --- a/external/qt/CMakeLists.txt +++ b/external/qt/CMakeLists.txt @@ -158,20 +158,9 @@ else() list(APPEND qt_libs_list "${qt_loc}/${lib}${qt_lib_suffix}") endforeach() - target_include_directories(external_qt - INTERFACE - ${libs_loc}/angle/include - ) - set(angle_libs_loc ${libs_loc}/angle/out/$,Debug,Release>/obj) target_link_libraries(external_qt INTERFACE - ${angle_libs_loc}/libANGLE_static.lib - ${angle_libs_loc}/libGLESv2_static.lib - ${angle_libs_loc}/libEGL_static.lib - d3d9.lib - d3d11.lib - dxgi.lib - dxguid.lib + desktop-app::external_angle ) elseif (APPLE) if (NOT build_osx) diff --git a/linux_wayland_helper/linux_wayland_helper.cpp b/linux_wayland_helper/linux_wayland_helper.cpp index cbcbeaf..5d75469 100644 --- a/linux_wayland_helper/linux_wayland_helper.cpp +++ b/linux_wayland_helper/linux_wayland_helper.cpp @@ -200,7 +200,7 @@ inline bool LoadSymbol(const Handle &handle, const char *name, Function &func) { } bool Resolve() { - static const auto loaded = [&] { + static const auto loaded = [] { auto egl = Handle(); auto cursor = Handle(); auto client = Handle(); @@ -618,4 +618,5 @@ struct wl_proxy *wl_proxy_marshal_constructor_versioned( args, interface, version); } + } // extern "C" diff --git a/win_directx_helper/CMakeLists.txt b/win_directx_helper/CMakeLists.txt new file mode 100644 index 0000000..c98935c --- /dev/null +++ b/win_directx_helper/CMakeLists.txt @@ -0,0 +1,14 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +add_library(win_directx_helper STATIC) +init_target(win_directx_helper "(external)") +add_library(desktop-app::win_directx_helper ALIAS win_directx_helper) + +nice_target_sources(win_directx_helper ${CMAKE_CURRENT_SOURCE_DIR} +PRIVATE + win_directx_helper.cpp +) diff --git a/win_directx_helper/win_directx_helper.cpp b/win_directx_helper/win_directx_helper.cpp new file mode 100644 index 0000000..11590db --- /dev/null +++ b/win_directx_helper/win_directx_helper.cpp @@ -0,0 +1,200 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// + +#include +#include +#include + +#define LOAD_SYMBOL(handle, func) LoadSymbol(handle, #func, func) + +namespace DirectX { +namespace { + +using Handle = HINSTANCE; + +// d3d9.dll + +IDirect3D9 * (__stdcall *Direct3DCreate9)(UINT SDKVersion); +int (__stdcall *D3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName); +int (__stdcall *D3DPERF_EndEvent)(void); +void (__stdcall *D3DPERF_SetMarker)(D3DCOLOR col, LPCWSTR wszName); +DWORD (__stdcall *D3DPERF_GetStatus)(void); + +// d3d11.dll + +HRESULT (__stdcall *D3D11CreateDevice)( + _In_opt_ IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + _In_reads_opt_(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _COM_Outptr_opt_ ID3D11Device** ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, + _COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext); + +// dxgi.dll + +HRESULT (__stdcall *CreateDXGIFactory)( + REFIID riid, + _COM_Outptr_ void **ppFactory); + +HRESULT (__stdcall *CreateDXGIFactory1)( + REFIID riid, + _COM_Outptr_ void **ppFactory); + +Handle SafeLoadLibrary(const wchar_t *name) { + static const auto SystemPath = [] { + WCHAR buffer[MAX_PATH + 1] = { 0 }; + return GetSystemDirectory(buffer, MAX_PATH) + ? std::wstring(buffer) + : std::wstring(); + }(); + static const auto WindowsPath = [] { + WCHAR buffer[MAX_PATH + 1] = { 0 }; + return GetWindowsDirectory(buffer, MAX_PATH) + ? std::wstring(buffer) + : std::wstring(); + }(); + const auto tryPath = [&](const std::wstring &path) { + if (!path.empty()) { + const auto full = path + L'\\' + name; + if (const auto result = Handle(LoadLibrary(full.c_str()))) { + return result; + } + } + return Handle(); + }; + if (const auto result1 = tryPath(SystemPath)) { + return result1; + } else if (const auto result2 = tryPath(WindowsPath)) { + return result2; + } + return nullptr; +} + +template +inline bool LoadSymbol(Handle handle, const char *name, Function &func) { + func = handle + ? reinterpret_cast(GetProcAddress(handle, name)) + : nullptr; + return (func != nullptr); +} + +bool ResolveD3D9() { + static const auto loaded = [] { + const auto d3d9 = SafeLoadLibrary(L"d3d9.dll"); + LOAD_SYMBOL(d3d9, D3DPERF_BeginEvent); + LOAD_SYMBOL(d3d9, D3DPERF_EndEvent); + LOAD_SYMBOL(d3d9, D3DPERF_SetMarker); + LOAD_SYMBOL(d3d9, D3DPERF_GetStatus); + return true + && LOAD_SYMBOL(d3d9, Direct3DCreate9); + }(); + return loaded; +} + +bool ResolveD3D11() { + static const auto loaded = [] { + const auto d3d11 = SafeLoadLibrary(L"d3d11.dll"); + return true + && LOAD_SYMBOL(d3d11, D3D11CreateDevice); + }(); + return loaded; +} + +bool ResolveDXGI() { + static const auto loaded = [&] { + const auto dxgi = SafeLoadLibrary(L"dxgi.dll"); + LOAD_SYMBOL(dxgi, CreateDXGIFactory1); + return true + && LOAD_SYMBOL(dxgi, CreateDXGIFactory); + }(); + return loaded; +} + +} // namespace +} // namespace DirectX + +namespace D = DirectX; + +extern "C" { + +IDirect3D9 * WINAPI Direct3DCreate9(UINT SDKVersion) { + return D::ResolveD3D9() + ? D::Direct3DCreate9(SDKVersion) + : nullptr; +} + +int WINAPI D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName) { + return (D::ResolveD3D9() && D::D3DPERF_BeginEvent) + ? D::D3DPERF_BeginEvent(col, wszName) + : -1; +} + +int WINAPI D3DPERF_EndEvent(void) { + return (D::ResolveD3D9() && D::D3DPERF_EndEvent) + ? D::D3DPERF_EndEvent() + : -1; +} + +void WINAPI D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName) { + if (D::ResolveD3D9() && D::D3DPERF_SetMarker) { + D::D3DPERF_SetMarker(col, wszName); + } +} + +DWORD WINAPI D3DPERF_GetStatus(void) { + return (D::ResolveD3D9() && D::D3DPERF_GetStatus) + ? D::D3DPERF_GetStatus() + : 0; +} + +HRESULT WINAPI D3D11CreateDevice( + _In_opt_ IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + _In_reads_opt_(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _COM_Outptr_opt_ ID3D11Device** ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, + _COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext) { + return D::ResolveD3D11() + ? D::D3D11CreateDevice( + pAdapter, + DriverType, + Software, + Flags, + pFeatureLevels, + FeatureLevels, + SDKVersion, + ppDevice, + pFeatureLevel, + ppImmediateContext) + : CO_E_DLLNOTFOUND; +} + +HRESULT WINAPI CreateDXGIFactory( + REFIID riid, + _COM_Outptr_ void **ppFactory) { + return D::ResolveDXGI() + ? D::CreateDXGIFactory(riid, ppFactory) + : CO_E_DLLNOTFOUND; +} + +HRESULT WINAPI CreateDXGIFactory1( + REFIID riid, + _COM_Outptr_ void **ppFactory) { + return (D::ResolveDXGI() && D::CreateDXGIFactory1) + ? D::CreateDXGIFactory1(riid, ppFactory) + : CO_E_DLLNOTFOUND; +} + +} // extern "C"