1
0
Fork 0

Add dynamic DirectX loading helper.

This commit is contained in:
John Preston 2021-06-30 13:43:36 +03:00
parent fc4d02573c
commit e2455f3194
7 changed files with 248 additions and 13 deletions

View file

@ -18,3 +18,6 @@ endif()
if (DESKTOP_APP_USE_ALLOCATION_TRACER) if (DESKTOP_APP_USE_ALLOCATION_TRACER)
add_subdirectory(linux_allocation_tracer) add_subdirectory(linux_allocation_tracer)
endif() endif()
if (WIN32)
add_subdirectory(win_directx_helper)
endif()

View file

@ -11,6 +11,7 @@ macro(add_checked_subdirectory name)
endif() endif()
endmacro() endmacro()
add_checked_subdirectory(angle)
add_checked_subdirectory(auto_updates) add_checked_subdirectory(auto_updates)
add_checked_subdirectory(crash_reports) add_checked_subdirectory(crash_reports)
if (LINUX AND NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION) if (LINUX AND NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION)

27
external/angle/CMakeLists.txt vendored Normal file
View file

@ -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/$<IF:$<CONFIG:Debug>,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()

View file

@ -158,20 +158,9 @@ else()
list(APPEND qt_libs_list "${qt_loc}/${lib}${qt_lib_suffix}") list(APPEND qt_libs_list "${qt_loc}/${lib}${qt_lib_suffix}")
endforeach() endforeach()
target_include_directories(external_qt
INTERFACE
${libs_loc}/angle/include
)
set(angle_libs_loc ${libs_loc}/angle/out/$<IF:$<CONFIG:Debug>,Debug,Release>/obj)
target_link_libraries(external_qt target_link_libraries(external_qt
INTERFACE INTERFACE
${angle_libs_loc}/libANGLE_static.lib desktop-app::external_angle
${angle_libs_loc}/libGLESv2_static.lib
${angle_libs_loc}/libEGL_static.lib
d3d9.lib
d3d11.lib
dxgi.lib
dxguid.lib
) )
elseif (APPLE) elseif (APPLE)
if (NOT build_osx) if (NOT build_osx)

View file

@ -200,7 +200,7 @@ inline bool LoadSymbol(const Handle &handle, const char *name, Function &func) {
} }
bool Resolve() { bool Resolve() {
static const auto loaded = [&] { static const auto loaded = [] {
auto egl = Handle(); auto egl = Handle();
auto cursor = Handle(); auto cursor = Handle();
auto client = Handle(); auto client = Handle();
@ -618,4 +618,5 @@ struct wl_proxy *wl_proxy_marshal_constructor_versioned(
args, interface, args, interface,
version); version);
} }
} // extern "C" } // extern "C"

View file

@ -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
)

View file

@ -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 <d3d9.h>
#include <d3d11.h>
#include <string>
#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 <typename Function>
inline bool LoadSymbol(Handle handle, const char *name, Function &func) {
func = handle
? reinterpret_cast<Function>(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"