Refactor LTCG versions of Direct3D_CreateDevice

* Make Direct3D_CreateDevice_4 naked to remove
   the risk of trashing parameters
* Split Direct3D_CreateDevice_16 into two separate functions
   with different calling convention
This commit is contained in:
Silent 2020-10-30 19:46:55 +01:00
parent cbe534cb54
commit feef6ffb3d
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
4 changed files with 179 additions and 34 deletions

@ -1 +1 @@
Subproject commit e6df7d42775fc35ae0dec546f94c5c40452cec02
Subproject commit b20e55df4087606e21a865a707c6fa4a5a01bd50

View File

@ -311,7 +311,8 @@ g_EmuCDPD = {0};
XB_MACRO(xbox::void_xt, WINAPI, D3D_DestroyResource, (xbox::X_D3DResource*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3D_DestroyResource__LTCG, (xbox::void_xt) ); \
XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice, (xbox::uint_xt, D3DDEVTYPE, HWND, xbox::dword_xt, xbox::X_D3DPRESENT_PARAMETERS*, IDirect3DDevice**) ); \
XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice_16, (xbox::uint_xt, D3DDEVTYPE, HWND, xbox::X_D3DPRESENT_PARAMETERS*) ); \
XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface, (xbox::uint_xt, D3DDEVTYPE, HWND, xbox::X_D3DPRESENT_PARAMETERS*) ); \
XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface, (xbox::uint_xt, D3DDEVTYPE, HWND, xbox::X_D3DPRESENT_PARAMETERS*) ); \
XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice_4, (xbox::X_D3DPRESENT_PARAMETERS*) ); \
XB_MACRO(xbox::void_xt, WINAPI, Lock2DSurface, (xbox::X_D3DPixelContainer*, D3DCUBEMAP_FACES, xbox::uint_xt, D3DLOCKED_RECT*, RECT*, xbox::dword_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, Lock3DSurface, (xbox::X_D3DPixelContainer*, xbox::uint_xt, D3DLOCKED_BOX*, D3DBOX*, xbox::dword_xt) ); \
@ -3146,10 +3147,25 @@ void Direct3D_CreateDevice_End()
}
}
// Overload for logging
static void Direct3D_CreateDevice_4
(
xbox::dword_xt BehaviorFlags,
xbox::X_D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice **ppReturnedDeviceInterface
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(BehaviorFlags)
LOG_FUNC_ARG(pPresentationParameters)
LOG_FUNC_ARG_OUT(ppReturnedDeviceInterface)
LOG_FUNC_END;
}
// LTCG specific Direct3D_CreateDevice function...
// This uses a custom calling with parameters passed in eax, ecx and the stack
// This uses a custom calling with parameters passed in EAX, ECX and the stack
// Test-case: Ninja Gaiden, Halo 2
xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice_4)
__declspec(naked) xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice_4)
(
X_D3DPRESENT_PARAMETERS *pPresentationParameters
)
@ -3158,58 +3174,178 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice_4)
IDirect3DDevice **ppReturnedDeviceInterface;
__asm {
mov BehaviorFlags, eax
mov ppReturnedDeviceInterface, ecx
}
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov BehaviorFlags, eax
mov ppReturnedDeviceInterface, ecx
}
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pPresentationParameters)
LOG_FUNC_END;
// Log
Direct3D_CreateDevice_4(BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
Direct3D_CreateDevice_Start(pPresentationParameters);
hresult_xt hRet = 0;
// Only then call Xbox CreateDevice function
__asm {
mov eax, BehaviorFlags
mov ecx, ppReturnedDeviceInterface
push pPresentationParameters
call XB_TRMP(Direct3D_CreateDevice_4)
mov hRet, eax
}
hresult_xt hRet;
__asm {
push pPresentationParameters
mov eax, BehaviorFlags
mov ecx, ppReturnedDeviceInterface
call XB_TRMP(Direct3D_CreateDevice_4)
mov hRet, eax
}
Direct3D_CreateDevice_End();
return hRet;
__asm {
mov eax, hRet
mov esp, ebp
pop ebp
ret 4
}
}
// LTCG specific Direct3D_CreateDevice function...
// This uses a custom calling convention passed unknown parameters
// Test-case: Battle Engine Aquila
xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice_16)
// Overload for logging
static void Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface
(
uint_xt Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
X_D3DPRESENT_PARAMETERS *pPresentationParameters
xbox::uint_xt Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
xbox::dword_xt BehaviorFlags,
xbox::X_D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice **ppReturnedDeviceInterface
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Adapter)
LOG_FUNC_ARG(DeviceType)
LOG_FUNC_ARG(hFocusWindow)
LOG_FUNC_ARG(BehaviorFlags)
LOG_FUNC_ARG(pPresentationParameters)
LOG_FUNC_ARG_OUT(ppReturnedDeviceInterface)
LOG_FUNC_END;
}
// LTCG specific Direct3D_CreateDevice function...
// This uses a custom calling convention passing parameters on stack, in EAX and ECX
// Test-case: Aggressive Inline, Midtown Madness 3
__declspec(naked) xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface)
(
uint_xt Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
X_D3DPRESENT_PARAMETERS *pPresentationParameters
)
{
dword_xt BehaviorFlags;
IDirect3DDevice **ppReturnedDeviceInterface;
__asm {
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov BehaviorFlags, eax
mov ppReturnedDeviceInterface, ecx
}
// Log
Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
Direct3D_CreateDevice_Start(pPresentationParameters);
// Only then call Xbox CreateDevice function
hresult_xt hRet = XB_TRMP(Direct3D_CreateDevice_16)(Adapter, DeviceType, hFocusWindow, pPresentationParameters);
hresult_xt hRet;
__asm {
push pPresentationParameters
push hFocusWindow
push DeviceType
push Adapter
mov eax, BehaviorFlags
mov ecx, ppReturnedDeviceInterface
call XB_TRMP(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface)
mov hRet, eax
}
Direct3D_CreateDevice_End();
return hRet;
__asm {
mov eax, hRet
mov esp, ebp
pop ebp
ret 10h
}
}
// Overload for logging
static void Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface
(
xbox::uint_xt Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
xbox::dword_xt BehaviorFlags,
xbox::X_D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice **ppReturnedDeviceInterface
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Adapter)
LOG_FUNC_ARG(DeviceType)
LOG_FUNC_ARG(hFocusWindow)
LOG_FUNC_ARG(BehaviorFlags)
LOG_FUNC_ARG(pPresentationParameters)
LOG_FUNC_ARG_OUT(ppReturnedDeviceInterface)
LOG_FUNC_END;
}
// LTCG specific Direct3D_CreateDevice function...
// This uses a custom calling convention passing parameters on stack, in EAX and EBX
// Test-case: NASCAR Heat 2002
__declspec(naked) xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface)
(
uint_xt Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
X_D3DPRESENT_PARAMETERS *pPresentationParameters
)
{
dword_xt BehaviorFlags;
IDirect3DDevice **ppReturnedDeviceInterface;
__asm {
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov BehaviorFlags, eax
mov ppReturnedDeviceInterface, ebx
}
// Log
Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
Direct3D_CreateDevice_Start(pPresentationParameters);
// Only then call Xbox CreateDevice function
hresult_xt hRet;
__asm {
push pPresentationParameters
push hFocusWindow
push DeviceType
push Adapter
mov eax, BehaviorFlags
mov ebx, ppReturnedDeviceInterface
call XB_TRMP(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface)
mov hRet, eax
}
Direct3D_CreateDevice_End();
__asm {
mov eax, hRet
mov esp, ebp
pop ebp
ret 10h
}
}
// ******************************************************************
@ -3277,9 +3413,9 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(Direct3D_CreateDevice)
LOG_FUNC_ARG(Adapter)
LOG_FUNC_ARG(DeviceType)
LOG_FUNC_ARG(hFocusWindow)
LOG_FUNC_ARG(BehaviorFlags) // Xbox ignores BehaviorFlags
LOG_FUNC_ARG(BehaviorFlags)
LOG_FUNC_ARG(pPresentationParameters)
LOG_FUNC_ARG(ppReturnedDeviceInterface)
LOG_FUNC_ARG_OUT(ppReturnedDeviceInterface)
LOG_FUNC_END;
Direct3D_CreateDevice_Start(pPresentationParameters);

View File

@ -92,7 +92,15 @@ xbox::hresult_xt WINAPI EMUPATCH(Direct3D_CreateDevice)
IDirect3DDevice **ppReturnedDeviceInterface
);
xbox::hresult_xt WINAPI EMUPATCH(Direct3D_CreateDevice_16)
xbox::hresult_xt WINAPI EMUPATCH(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface)
(
uint_xt Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
X_D3DPRESENT_PARAMETERS *pPresentationParameters
);
xbox::hresult_xt WINAPI EMUPATCH(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface)
(
uint_xt Adapter,
D3DDEVTYPE DeviceType,

View File

@ -189,7 +189,8 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
PATCH_ENTRY("D3D_LazySetPointParams", xbox::EMUPATCH(D3D_LazySetPointParams), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_SetCommonDebugRegisters", xbox::EMUPATCH(D3D_SetCommonDebugRegisters), PATCH_HLE_D3D),
PATCH_ENTRY("Direct3D_CreateDevice", xbox::EMUPATCH(Direct3D_CreateDevice), PATCH_HLE_D3D),
PATCH_ENTRY("Direct3D_CreateDevice_16", xbox::EMUPATCH(Direct3D_CreateDevice_16), PATCH_HLE_D3D),
PATCH_ENTRY("Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface", xbox::EMUPATCH(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ebx_ppReturnedDeviceInterface), PATCH_HLE_D3D),
PATCH_ENTRY("Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface", xbox::EMUPATCH(Direct3D_CreateDevice_16__LTCG_eax_BehaviorFlags_ecx_ppReturnedDeviceInterface), PATCH_HLE_D3D),
PATCH_ENTRY("Direct3D_CreateDevice_4", xbox::EMUPATCH(Direct3D_CreateDevice_4), PATCH_HLE_D3D),
PATCH_ENTRY("Lock2DSurface", xbox::EMUPATCH(Lock2DSurface), PATCH_HLE_D3D),
PATCH_ENTRY("Lock3DSurface", xbox::EMUPATCH(Lock3DSurface), PATCH_HLE_D3D),