use core::ffi::CStr;
use std::sync::atomic::{AtomicUsize, Ordering};
use windows::Win32::Foundation::{E_NOTIMPL, HMODULE};
use windows::core::HRESULT;
use crate::log::log;
use crate::system::{export, system};
pub struct Slot {
dll: fn() -> HMODULE,
name: &'static CStr,
note: Option<&'static str>,
address: AtomicUsize,
}
fn d3d11() -> HMODULE {
system().d3d11
}
fn dxgi() -> HMODULE {
system().dxgi
}
extern "system" fn not_implemented() -> HRESULT {
E_NOTIMPL
}
extern "system" fn resolve(slot: &'static Slot) -> usize {
match slot.address.load(Ordering::Acquire) {
0 => {
if let Some(note) = slot.note {
crate::hello();
log!("{}: {note}", slot.name.to_string_lossy());
}
let address = unsafe { export::<usize>((slot.dll)(), slot.name) }.unwrap_or_else(|| {
log!(
"{}: not in the system DLL, so it fails (E_NOTIMPL)",
slot.name.to_string_lossy()
);
not_implemented as *const () as usize
});
slot.address.store(address, Ordering::Release);
address
}
address => address,
}
}
macro_rules! note {
() => {
None
};
($note:literal) => {
Some($note)
};
}
macro_rules! pass {
($($dll:ident $symbol:ident $name:literal $(note $note:literal)?;)*) => {$(
#[allow(non_snake_case)]
mod $symbol {
pub static SLOT: super::Slot = super::Slot {
dll: super::$dll,
name: $name,
note: note!($($note)?),
address: super::AtomicUsize::new(0),
};
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
pub unsafe extern "system" fn $symbol() {
core::arch::naked_asm!(
"push rcx", "push rdx", "push r8", "push r9", "sub rsp, 104",
"movdqu [rsp + 32], xmm0", "movdqu [rsp + 48], xmm1",
"movdqu [rsp + 64], xmm2", "movdqu [rsp + 80], xmm3",
"lea rcx, [rip + {slot}]", "call {resolve}",
"movdqu xmm0, [rsp + 32]", "movdqu xmm1, [rsp + 48]",
"movdqu xmm2, [rsp + 64]", "movdqu xmm3, [rsp + 80]",
"add rsp, 104", "pop r9", "pop r8", "pop rdx", "pop rcx", "jmp rax",
slot = sym $symbol::SLOT, resolve = sym resolve,
);
}
)*};
}
pass! {
d3d11 D3D11CoreCreateDevice c"D3D11CoreCreateDevice" note "passed through, device not wrapped";
d3d11 D3D11On12CreateDevice c"D3D11On12CreateDevice" note "passed through, device not wrapped";
d3d11 D3D11CreateDeviceForD3D12 c"D3D11CreateDeviceForD3D12" note "passed through, device not wrapped";
d3d11 CreateDirect3D11DeviceFromDXGIDevice c"CreateDirect3D11DeviceFromDXGIDevice"
note "passed through, device not wrapped";
d3d11 CreateDirect3D11SurfaceFromDXGISurface c"CreateDirect3D11SurfaceFromDXGISurface";
d3d11 D3D11CoreCreateLayeredDevice c"D3D11CoreCreateLayeredDevice";
d3d11 D3D11CoreGetLayeredDeviceSize c"D3D11CoreGetLayeredDeviceSize";
d3d11 D3D11CoreRegisterLayers c"D3D11CoreRegisterLayers";
d3d11 EnableFeatureLevelUpgrade c"EnableFeatureLevelUpgrade";
d3d11 OpenAdapter10 c"OpenAdapter10";
d3d11 OpenAdapter10_2 c"OpenAdapter10_2";
d3d11 D3DPerformance_BeginEvent c"D3DPerformance_BeginEvent";
d3d11 D3DPerformance_EndEvent c"D3DPerformance_EndEvent";
d3d11 D3DPerformance_GetStatus c"D3DPerformance_GetStatus";
d3d11 D3DPerformance_SetMarker c"D3DPerformance_SetMarker";
d3d11 D3DKMTCloseAdapter c"D3DKMTCloseAdapter";
d3d11 D3DKMTCreateAllocation c"D3DKMTCreateAllocation";
d3d11 D3DKMTCreateContext c"D3DKMTCreateContext";
d3d11 D3DKMTCreateDevice c"D3DKMTCreateDevice";
d3d11 D3DKMTCreateSynchronizationObject c"D3DKMTCreateSynchronizationObject";
d3d11 D3DKMTDestroyAllocation c"D3DKMTDestroyAllocation";
d3d11 D3DKMTDestroyContext c"D3DKMTDestroyContext";
d3d11 D3DKMTDestroyDevice c"D3DKMTDestroyDevice";
d3d11 D3DKMTDestroySynchronizationObject c"D3DKMTDestroySynchronizationObject";
d3d11 D3DKMTEscape c"D3DKMTEscape";
d3d11 D3DKMTGetContextSchedulingPriority c"D3DKMTGetContextSchedulingPriority";
d3d11 D3DKMTGetDeviceState c"D3DKMTGetDeviceState";
d3d11 D3DKMTGetDisplayModeList c"D3DKMTGetDisplayModeList";
d3d11 D3DKMTGetMultisampleMethodList c"D3DKMTGetMultisampleMethodList";
d3d11 D3DKMTGetRuntimeData c"D3DKMTGetRuntimeData";
d3d11 D3DKMTGetSharedPrimaryHandle c"D3DKMTGetSharedPrimaryHandle";
d3d11 D3DKMTLock c"D3DKMTLock";
d3d11 D3DKMTOpenAdapterFromHdc c"D3DKMTOpenAdapterFromHdc";
d3d11 D3DKMTOpenResource c"D3DKMTOpenResource";
d3d11 D3DKMTPresent c"D3DKMTPresent";
d3d11 D3DKMTQueryAdapterInfo c"D3DKMTQueryAdapterInfo";
d3d11 D3DKMTQueryAllocationResidency c"D3DKMTQueryAllocationResidency";
d3d11 D3DKMTQueryResourceInfo c"D3DKMTQueryResourceInfo";
d3d11 D3DKMTRender c"D3DKMTRender";
d3d11 D3DKMTSetAllocationPriority c"D3DKMTSetAllocationPriority";
d3d11 D3DKMTSetContextSchedulingPriority c"D3DKMTSetContextSchedulingPriority";
d3d11 D3DKMTSetDisplayMode c"D3DKMTSetDisplayMode";
d3d11 D3DKMTSetDisplayPrivateDriverFormat c"D3DKMTSetDisplayPrivateDriverFormat";
d3d11 D3DKMTSetGammaRamp c"D3DKMTSetGammaRamp";
d3d11 D3DKMTSetVidPnSourceOwner c"D3DKMTSetVidPnSourceOwner";
d3d11 D3DKMTSignalSynchronizationObject c"D3DKMTSignalSynchronizationObject";
d3d11 D3DKMTUnlock c"D3DKMTUnlock";
d3d11 D3DKMTWaitForSynchronizationObject c"D3DKMTWaitForSynchronizationObject";
d3d11 D3DKMTWaitForVerticalBlankEvent c"D3DKMTWaitForVerticalBlankEvent";
}
pass! {
dxgi ApplyCompatResolutionQuirking c"ApplyCompatResolutionQuirking";
dxgi CompatString c"CompatString";
dxgi CompatValue c"CompatValue";
dxgi DXGID3D10CreateDevice c"DXGID3D10CreateDevice";
dxgi DXGID3D10CreateLayeredDevice c"DXGID3D10CreateLayeredDevice";
dxgi DXGID3D10GetLayeredDeviceSize c"DXGID3D10GetLayeredDeviceSize";
dxgi DXGID3D10RegisterLayers c"DXGID3D10RegisterLayers";
dxgi DXGIDisableVBlankVirtualization c"DXGIDisableVBlankVirtualization";
dxgi DXGIDumpJournal c"DXGIDumpJournal";
dxgi DXGIReportAdapterConfiguration c"DXGIReportAdapterConfiguration";
dxgi PIXBeginCapture c"PIXBeginCapture";
dxgi PIXEndCapture c"PIXEndCapture";
dxgi PIXGetCaptureState c"PIXGetCaptureState";
dxgi DxgiSetAppCompatStringPointer c"SetAppCompatStringPointer";
dxgi UpdateHMDEmulationStatus c"UpdateHMDEmulationStatus";
}