FF13Fix/d3d9ex/Wrapper.h
Robert Krawczyk 3a844cc3ca Changes:
Fixed DXVK window starting in background and required clicking to activate
Added experimental (disabled by default) DiscardUIVertexBuffer option
Improved D3D9 reference counting
Two step initialization, check is correct window was created, then initialize 2s after IDirect3D9::CreateDevice call

Other:
Fix some include hell
Settings.h now include all comments so it will autogenerated ini file
Deleted IDirect3DVertexBuffer9.cpp/h
2021-03-13 03:54:05 +01:00

150 lines
3.7 KiB
C++

#pragma once
#include "comdef.h"
#include <d3d9.h>
template <class T>
class WrapperBase
{
public:
WrapperBase(const WrapperBase&) = delete;
const WrapperBase& operator=(WrapperBase& other) = delete;
WrapperBase(): m_module(nullptr) {}
~WrapperBase()
{
if (m_module)
{
FreeLibrary(m_module);
PrintLog("Unloaded %s", module_path.c_str());
}
}
static T& Get()
{
static T instance;
return instance;
}
protected:
bool WrapperLoad(const char* module_name, bool use_system_dir = true, bool fail_is_critical = true)
{
use_system_dir ? module_path = CreateSystemModulePath(module_name) : module_path = module_name;
m_module = LoadLibraryA(module_path.c_str());
if (m_module) {
PrintLog("Loaded %s", module_path.c_str());
return true;
}
else if(fail_is_critical) {
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
_com_error err(hr);
std::string msg = StringFromFormat("Cannot load %s\nHRESULT 0x%08X: \"%s\"", module_path.c_str(), err.Error(), err.ErrorMessage());
PrintLog(msg.c_str());
MessageBoxA(NULL, msg.c_str(), "Error", MB_ICONERROR);
ExitProcess(hr);
}
return false;
}
template<typename T>
void StoreAddress(T* dest, const char* name)
{
*dest = reinterpret_cast<T>(::GetProcAddress(m_module, name));
}
private:
HMODULE m_module;
std::string module_path;
};
class D3D9DLL : public WrapperBase<D3D9DLL>
{
public:
IDirect3D9* (WINAPI* Direct3DCreate9)(UINT SDKVersion);
HRESULT(WINAPI* Direct3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **ppD3D);
int (WINAPI* D3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName);
int (WINAPI* D3DPERF_EndEvent)(void);
DWORD(WINAPI* D3DPERF_GetStatus)();
BOOL(WINAPI* D3DPERF_QueryRepeatFrame)();
void (WINAPI* D3DPERF_SetMarker)(D3DCOLOR col, LPCWSTR wszName);
void (WINAPI* D3DPERF_SetOptions)(DWORD dwOptions);
void (WINAPI* D3DPERF_SetRegion)(D3DCOLOR col, LPCWSTR wszName);
bool IsDXVK() { return m_isdxvk; }
D3D9DLL()
{
WrapperLoad("dxvk.dll", false, false) ? m_isdxvk = true : WrapperLoad("d3d9.dll");
StoreAddress(&Direct3DCreate9, "Direct3DCreate9");
StoreAddress(&Direct3DCreate9Ex, "Direct3DCreate9Ex");
StoreAddress(&D3DPERF_BeginEvent, "D3DPERF_BeginEvent");
StoreAddress(&D3DPERF_EndEvent, "D3DPERF_EndEvent");
StoreAddress(&D3DPERF_GetStatus, "D3DPERF_GetStatus");
StoreAddress(&D3DPERF_QueryRepeatFrame, "D3DPERF_QueryRepeatFrame");
StoreAddress(&D3DPERF_SetMarker, "D3DPERF_SetMarker");
StoreAddress(&D3DPERF_SetOptions, "D3DPERF_SetOptions");
StoreAddress(&D3DPERF_SetRegion, "D3DPERF_SetRegion");
}
private:
bool m_isdxvk = false;
};
extern "C"
{
IDirect3D9* WINAPI _Direct3DCreate9(UINT SDKVersion)
{
return D3D9DLL::Get().Direct3DCreate9(SDKVersion);
}
HRESULT WINAPI _Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
{
return D3D9DLL::Get().Direct3DCreate9Ex(SDKVersion, ppD3D);
}
int WINAPI _D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName)
{
return D3D9DLL::Get().D3DPERF_BeginEvent(col, wszName);
}
int WINAPI _D3DPERF_EndEvent()
{
return D3D9DLL::Get().D3DPERF_EndEvent();
}
DWORD WINAPI _D3DPERF_GetStatus()
{
return D3D9DLL::Get().D3DPERF_GetStatus();
}
BOOL WINAPI _D3DPERF_QueryRepeatFrame()
{
return D3D9DLL::Get().D3DPERF_QueryRepeatFrame();
}
void WINAPI _D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName)
{
return D3D9DLL::Get().D3DPERF_SetMarker(col, wszName);
}
void WINAPI _D3DPERF_SetOptions(DWORD dwOptions)
{
return D3D9DLL::Get().D3DPERF_SetOptions(dwOptions);
}
void WINAPI _D3DPERF_SetRegion(D3DCOLOR col, LPCWSTR wszName)
{
return D3D9DLL::Get().D3DPERF_SetRegion(col, wszName);
}
}