mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 23:00:42 -07:00
overlay: implement dx11 backend (#707)
## Link to GitHub Issue or related Pull Request, if one exists Fixes #134 ## Description of change Add ImGui DX11 backend implementation, and integrate into the spice overlay. The tricky part is that some of the Unity games: 1. Launch multiple windows, and 2. Can be resized (even full screen games launch at a certain resolution and then expand to fit desktop resolution) 3. lazy load DX11 DLLs This PR also adds screenshot functionality, but screen resize is not implemented. ## Testing Seems to be working for most games. Need to do final tests for: - [x] CCJ (attract movie plays as well) - [x] Busou Shinki (title movie plays) - [x] MFG - [x] QuizKnock - [x] Polaris Chord - [x] check dx9 for regression
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
// internal glue for the dx11 backend. all symbols gated on SPICE_D3D11.
|
||||
|
||||
#include "overlay/overlay.h"
|
||||
|
||||
#ifdef SPICE_D3D11
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "util/detour.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
struct HWND__; typedef HWND__ *HWND;
|
||||
struct IUnknown;
|
||||
struct IDXGISwapChain;
|
||||
|
||||
namespace d3d11_hooks {
|
||||
|
||||
void install_swapchain_hooks(IDXGISwapChain *swapchain);
|
||||
void install_factory_hooks(IUnknown *factory);
|
||||
void try_capture_vtables();
|
||||
|
||||
// first non-null swapchain HWND wins; later ones (sub-screens, IME
|
||||
// helpers) are ignored. the dummy capture window is exempted via
|
||||
// ignore_hwnd.
|
||||
void note_main_hwnd(HWND hwnd);
|
||||
HWND main_hwnd();
|
||||
void ignore_hwnd(HWND hwnd);
|
||||
|
||||
// capture backbuffer to PNG if a screenshot was requested.
|
||||
void try_screenshot(IDXGISwapChain *swapchain);
|
||||
|
||||
// trampoline a virtual method by vtable index. on failure *orig is null.
|
||||
inline bool hook_vtbl(void *iface, size_t index,
|
||||
void *hook, void **orig, const char *name)
|
||||
{
|
||||
void **vtbl = *reinterpret_cast<void ***>(iface);
|
||||
void *target = vtbl[index];
|
||||
// trampoline_try reads *orig before overwriting it.
|
||||
*orig = target;
|
||||
if (!detour::trampoline_try(target, hook, orig)) {
|
||||
*orig = nullptr;
|
||||
log_warning("graphics::d3d11", "failed to hook {}", name);
|
||||
return false;
|
||||
}
|
||||
log_info("graphics::d3d11", "hooked {}", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
// minimal COM RAII used by capture / screenshot paths.
|
||||
struct com_release {
|
||||
void operator()(IUnknown *p) const { if (p) p->Release(); }
|
||||
};
|
||||
template<typename T> using com_ptr = std::unique_ptr<T, com_release>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user