mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
overlay: remove dependency on d3dcompiler (#738)
## Link to GitHub Issue or related Pull Request, if one exists Fixes #737, regressed by #707 ## Description of change ImGui backend for DX11 pulled in dependency on a specific version of `d3dcompiler_47.dll` which is not present on stock Win7 OS image. Change this to a runtime load of the DLL and disable the overlay if we can't find one. ## Testing - [x] Win11, DX11 overlay - [x] Win11, DX9 overlay - [x] Win7, DX9 overlay
This commit is contained in:
@@ -236,7 +236,7 @@ add_compile_definitions(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# SPICE_XP: set by build_all.sh for the WinXP-compat toolchains. Gates out
|
# SPICE_XP: set by build_all.sh for the WinXP-compat toolchains. Gates out
|
||||||
# the DX11 overlay backend (WinXP lacks D3DCOMPILER_47.dll).
|
# the DX11 overlay backend
|
||||||
option(SPICE_XP "Build for the WinXP-compat toolchain" OFF)
|
option(SPICE_XP "Build for the WinXP-compat toolchain" OFF)
|
||||||
if(SPICE_XP)
|
if(SPICE_XP)
|
||||||
add_compile_definitions(SPICE_XP=1)
|
add_compile_definitions(SPICE_XP=1)
|
||||||
@@ -734,7 +734,7 @@ set_target_properties(spicetools_spice64 PROPERTIES PREFIX "")
|
|||||||
set_target_properties(spicetools_spice64 PROPERTIES OUTPUT_NAME "spice64")
|
set_target_properties(spicetools_spice64 PROPERTIES OUTPUT_NAME "spice64")
|
||||||
target_compile_definitions(spicetools_spice64 PRIVATE SPICE64=1)
|
target_compile_definitions(spicetools_spice64 PRIVATE SPICE64=1)
|
||||||
if(NOT SPICE_XP)
|
if(NOT SPICE_XP)
|
||||||
target_link_libraries(spicetools_spice64 PUBLIC d3d11 dxgi d3dcompiler)
|
target_link_libraries(spicetools_spice64 PUBLIC d3d11 dxgi)
|
||||||
target_compile_definitions(spicetools_spice64 PRIVATE SPICE_D3D11=1)
|
target_compile_definitions(spicetools_spice64 PRIVATE SPICE_D3D11=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -757,7 +757,7 @@ set_target_properties(spicetools_spice64_linux PROPERTIES OUTPUT_NAME "spice64_l
|
|||||||
target_compile_definitions(spicetools_spice64_linux PRIVATE SPICE64=1)
|
target_compile_definitions(spicetools_spice64_linux PRIVATE SPICE64=1)
|
||||||
target_compile_definitions(spicetools_spice64_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1)
|
target_compile_definitions(spicetools_spice64_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1)
|
||||||
# spice64_linux is never built under the WinXP toolchain, so dx11 is always on.
|
# spice64_linux is never built under the WinXP toolchain, so dx11 is always on.
|
||||||
target_link_libraries(spicetools_spice64_linux PUBLIC d3d11 dxgi d3dcompiler)
|
target_link_libraries(spicetools_spice64_linux PUBLIC d3d11 dxgi)
|
||||||
target_compile_definitions(spicetools_spice64_linux PRIVATE SPICE_D3D11=1)
|
target_compile_definitions(spicetools_spice64_linux PRIVATE SPICE_D3D11=1)
|
||||||
|
|
||||||
IF(NOT MSVC)
|
IF(NOT MSVC)
|
||||||
|
|||||||
+1
-2
@@ -21,8 +21,7 @@ set(IMGUI_SOURCES
|
|||||||
misc/cpp/imgui_stdlib.cpp
|
misc/cpp/imgui_stdlib.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# spice2x: DX11 backend is only built for non-XP toolchains. WinXP lacks
|
# spice2x: DX11 backend is only built for non-XP toolchains
|
||||||
# D3DCOMPILER_47.dll, and including this TU would pull in D3DCompile imports.
|
|
||||||
if(NOT SPICE_XP)
|
if(NOT SPICE_XP)
|
||||||
list(APPEND IMGUI_HEADERS backends/imgui_impl_dx11.h)
|
list(APPEND IMGUI_HEADERS backends/imgui_impl_dx11.h)
|
||||||
list(APPEND IMGUI_SOURCES backends/imgui_impl_dx11.cpp)
|
list(APPEND IMGUI_SOURCES backends/imgui_impl_dx11.cpp)
|
||||||
|
|||||||
+37
-5
@@ -50,9 +50,35 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
#ifdef _MSC_VER
|
// #ifdef _MSC_VER
|
||||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
// #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
#endif
|
// #endif
|
||||||
|
|
||||||
|
// spice2x: resolve D3DCompile at runtime rather than static-linking d3dcompiler,
|
||||||
|
// which would hardwire an import on d3dcompiler_47.dll (absent on stock Win7).
|
||||||
|
static pD3DCompile ImGui_ImplDX11_GetD3DCompile()
|
||||||
|
{
|
||||||
|
static pD3DCompile fn = []() -> pD3DCompile {
|
||||||
|
static const char *dlls[] = {
|
||||||
|
"d3dcompiler_47.dll",
|
||||||
|
"d3dcompiler_46.dll",
|
||||||
|
"d3dcompiler_43.dll" };
|
||||||
|
|
||||||
|
for (const char *dll : dlls) {
|
||||||
|
HMODULE mod = GetModuleHandleA(dll);
|
||||||
|
if (!mod) {
|
||||||
|
mod = LoadLibraryA(dll);
|
||||||
|
}
|
||||||
|
if (mod) {
|
||||||
|
if (auto p = (pD3DCompile) GetProcAddress(mod, "D3DCompile")) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
@@ -442,6 +468,12 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||||
|
|
||||||
|
// spice2x: dynamically resolved; see ImGui_ImplDX11_GetD3DCompile.
|
||||||
|
pD3DCompile D3DCompile_fn = ImGui_ImplDX11_GetD3DCompile();
|
||||||
|
if (!D3DCompile_fn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the vertex shader
|
// Create the vertex shader
|
||||||
{
|
{
|
||||||
static const char* vertexShader =
|
static const char* vertexShader =
|
||||||
@@ -473,7 +505,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
}";
|
}";
|
||||||
|
|
||||||
ID3DBlob* vertexShaderBlob;
|
ID3DBlob* vertexShaderBlob;
|
||||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
if (FAILED(D3DCompile_fn(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
||||||
{
|
{
|
||||||
@@ -530,7 +562,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
}";
|
}";
|
||||||
|
|
||||||
ID3DBlob* pixelShaderBlob;
|
ID3DBlob* pixelShaderBlob;
|
||||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
if (FAILED(D3DCompile_fn(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -213,6 +213,27 @@ void poll_thread() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the overlay's imgui dx11 backend needs D3DCompile (d3dcompiler_XX.dll) to
|
||||||
|
// build its shaders. _43 ships with the DX June 2010 redist on stock Win7;
|
||||||
|
// _46/_47 come with newer Windows.
|
||||||
|
bool d3dcompiler_available() {
|
||||||
|
static const wchar_t *names[] = {
|
||||||
|
L"d3dcompiler_47.dll",
|
||||||
|
L"d3dcompiler_46.dll",
|
||||||
|
L"d3dcompiler_43.dll",
|
||||||
|
};
|
||||||
|
for (auto name : names) {
|
||||||
|
HMODULE mod = GetModuleHandleW(name);
|
||||||
|
if (!mod) {
|
||||||
|
mod = LoadLibraryW(name);
|
||||||
|
}
|
||||||
|
if (mod && GetProcAddress(mod, "D3DCompile")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void graphics_d3d11_init() {
|
void graphics_d3d11_init() {
|
||||||
@@ -223,6 +244,14 @@ void graphics_d3d11_init() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no d3dcompiler -> overlay can't build shaders; skip dx11 overlay
|
||||||
|
if (!d3dcompiler_available()) {
|
||||||
|
log_warning(
|
||||||
|
"graphics::d3d11",
|
||||||
|
"d3dcompiler not found; dx11 overlay disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(g_init_mutex);
|
std::lock_guard<std::mutex> lock(g_init_mutex);
|
||||||
if (g_poll_thread.joinable()) {
|
if (g_poll_thread.joinable()) {
|
||||||
return; // already initialized
|
return; // already initialized
|
||||||
|
|||||||
Reference in New Issue
Block a user