Add dynamic DirectX loading helper.
This commit is contained in:
parent
fc4d02573c
commit
e2455f3194
7 changed files with 248 additions and 13 deletions
|
|
@ -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()
|
||||||
|
|
|
||||||
1
external/CMakeLists.txt
vendored
1
external/CMakeLists.txt
vendored
|
|
@ -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
27
external/angle/CMakeLists.txt
vendored
Normal 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()
|
||||||
13
external/qt/CMakeLists.txt
vendored
13
external/qt/CMakeLists.txt
vendored
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
14
win_directx_helper/CMakeLists.txt
Normal file
14
win_directx_helper/CMakeLists.txt
Normal 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
|
||||||
|
)
|
||||||
200
win_directx_helper/win_directx_helper.cpp
Normal file
200
win_directx_helper/win_directx_helper.cpp
Normal 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"
|
||||||
Loading…
Add table
Reference in a new issue