Patch D3DDevice_SetRenderTarget_0 and factorize implementations

CreateDevice would try to call an inexistant guest trampoline,
but in fact we only needed to call the host implementation
This commit is contained in:
Silent 2020-10-27 20:23:17 +01:00
parent 38242d48f9
commit 8b7f4a5027
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
3 changed files with 67 additions and 13 deletions

View File

@ -204,6 +204,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wPara
static DWORD WINAPI EmuUpdateTickCount(LPVOID); static DWORD WINAPI EmuUpdateTickCount(LPVOID);
static inline void EmuVerifyResourceIsRegistered(xbox::X_D3DResource *pResource, DWORD D3DUsage, int iTextureStage, DWORD dwSize); static inline void EmuVerifyResourceIsRegistered(xbox::X_D3DResource *pResource, DWORD D3DUsage, int iTextureStage, DWORD dwSize);
static void UpdateCurrentMSpFAndFPS(); // Used for benchmarking/fps count static void UpdateCurrentMSpFAndFPS(); // Used for benchmarking/fps count
static void CxbxImpl_SetRenderTarget(xbox::X_D3DSurface *pRenderTarget, xbox::X_D3DSurface *pNewZStencil);
extern void UpdateFPSCounter(); extern void UpdateFPSCounter();
@ -293,6 +294,7 @@ g_EmuCDPD = {0};
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetPixelShader_0, () ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetPixelShader_0, () ); \
XB_MACRO(xbox::void_xt, __fastcall, D3DDevice_SetRenderState_Simple, (xbox::dword_xt, xbox::dword_xt) ); \ XB_MACRO(xbox::void_xt, __fastcall, D3DDevice_SetRenderState_Simple, (xbox::dword_xt, xbox::dword_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetRenderTarget, (xbox::X_D3DSurface*, xbox::X_D3DSurface*) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetRenderTarget, (xbox::X_D3DSurface*, xbox::X_D3DSurface*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetRenderTarget_0, () ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetStreamSource, (xbox::uint_xt, xbox::X_D3DVertexBuffer*, xbox::uint_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetStreamSource, (xbox::uint_xt, xbox::X_D3DVertexBuffer*, xbox::uint_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetStreamSource_4, (xbox::uint_xt, xbox::X_D3DVertexBuffer*, xbox::uint_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetStreamSource_4, (xbox::uint_xt, xbox::X_D3DVertexBuffer*, xbox::uint_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetStreamSource_8, (xbox::X_D3DVertexBuffer*, xbox::uint_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetStreamSource_8, (xbox::X_D3DVertexBuffer*, xbox::uint_xt) ); \
@ -3321,7 +3323,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(D3DDevice_Reset)
// Refresh the current render target and depth stencil, to apply changes made within D3DDevice_Reset // Refresh the current render target and depth stencil, to apply changes made within D3DDevice_Reset
// Some XDKs do this for us, but not all do! // Some XDKs do this for us, but not all do!
EMUPATCH(D3DDevice_SetRenderTarget)(g_pXbox_RenderTarget, g_pXbox_DepthStencil); CxbxImpl_SetRenderTarget(g_pXbox_RenderTarget, g_pXbox_DepthStencil);
return hRet; return hRet;
} }
@ -7774,25 +7776,17 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(D3DDevice_LightEnable)
return hRet; return hRet;
} }
// ****************************************************************** static void CxbxImpl_SetRenderTarget
// * patch: D3DDevice_SetRenderTarget
// ******************************************************************
xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
( (
X_D3DSurface *pRenderTarget, xbox::X_D3DSurface *pRenderTarget,
X_D3DSurface *pNewZStencil xbox::X_D3DSurface *pNewZStencil
) )
{ {
LOG_FUNC_BEGIN LOG_INIT;
LOG_FUNC_ARG(pRenderTarget)
LOG_FUNC_ARG(pNewZStencil)
LOG_FUNC_END;
IDirect3DSurface *pHostRenderTarget = nullptr; IDirect3DSurface *pHostRenderTarget = nullptr;
IDirect3DSurface *pHostDepthStencil = nullptr; IDirect3DSurface *pHostDepthStencil = nullptr;
XB_TRMP(D3DDevice_SetRenderTarget)(pRenderTarget, pNewZStencil);
// In Xbox titles, CreateDevice calls SetRenderTarget for the back buffer // In Xbox titles, CreateDevice calls SetRenderTarget for the back buffer
// We can use this to determine the Xbox backbuffer surface for later use! // We can use this to determine the Xbox backbuffer surface for later use!
if (g_pXbox_BackBufferSurface == xbox::zeroptr) { if (g_pXbox_BackBufferSurface == xbox::zeroptr) {
@ -7856,6 +7850,60 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
CalculateMultiSampleScaleForRenderTarget(pRenderTarget); CalculateMultiSampleScaleForRenderTarget(pRenderTarget);
} }
// ******************************************************************
// * patch: D3DDevice_SetRenderTarget
// ******************************************************************
xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
(
X_D3DSurface *pRenderTarget,
X_D3DSurface *pNewZStencil
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pRenderTarget)
LOG_FUNC_ARG(pNewZStencil)
LOG_FUNC_END;
XB_TRMP(D3DDevice_SetRenderTarget)(pRenderTarget, pNewZStencil);
CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil);
}
// LTCG specific D3DDevice_SetRenderTarget function...
// Passes pRenderTarget in ecx and pNewZStencil in eax
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pRenderTarget)
LOG_FUNC_ARG(pNewZStencil)
LOG_FUNC_END;
__declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget_0)
(
)
{
X_D3DSurface *pRenderTarget;
X_D3DSurface *pNewZStencil;
// prologue
__asm {
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov pRenderTarget, ecx
mov pNewZStencil, eax
call XB_TRMP(D3DDevice_SetRenderTarget_0)
}
CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil);
// epilogue
__asm {
mov esp, ebp
pop ebp
ret
}
}
// LTCG specific D3DDevice_SetPalette function... // LTCG specific D3DDevice_SetPalette function...
// This uses a custom calling convention where parameter is passed in EAX // This uses a custom calling convention where parameter is passed in EAX
// Test-case: Ninja Gaiden // Test-case: Ninja Gaiden

View File

@ -1512,6 +1512,11 @@ xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetRenderTarget)
X_D3DSurface *pNewZStencil X_D3DSurface *pNewZStencil
); );
// ******************************************************************
// * patch: D3DDevice_SetRenderTarget_0
// ******************************************************************
xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetRenderTarget_0)();
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_SetPalette // * patch: D3DDevice_SetPalette
// ****************************************************************** // ******************************************************************

View File

@ -138,6 +138,7 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
PATCH_ENTRY("D3DDevice_SetRenderState_Simple", xbox::EMUPATCH(D3DDevice_SetRenderState_Simple), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_SetRenderState_Simple", xbox::EMUPATCH(D3DDevice_SetRenderState_Simple), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_SetRenderTarget", xbox::EMUPATCH(D3DDevice_SetRenderTarget), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_SetRenderTarget", xbox::EMUPATCH(D3DDevice_SetRenderTarget), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_SetRenderTargetFast", xbox::EMUPATCH(D3DDevice_SetRenderTargetFast), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_SetRenderTargetFast", xbox::EMUPATCH(D3DDevice_SetRenderTargetFast), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_SetRenderTarget_0", xbox::EMUPATCH(D3DDevice_SetRenderTarget_0), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_SetScreenSpaceOffset", xbox::EMUPATCH(D3DDevice_SetScreenSpaceOffset), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_SetScreenSpaceOffset", xbox::EMUPATCH(D3DDevice_SetScreenSpaceOffset), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_SetShaderConstantMode", xbox::EMUPATCH(D3DDevice_SetShaderConstantMode), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_SetShaderConstantMode", xbox::EMUPATCH(D3DDevice_SetShaderConstantMode), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_SetShaderConstantMode_0", xbox::EMUPATCH(D3DDevice_SetShaderConstantMode_0), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_SetShaderConstantMode_0", xbox::EMUPATCH(D3DDevice_SetShaderConstantMode_0), PATCH_HLE_D3D),