From 5592f81c020ec9a4cc97b76c47bdfc6717fed15f Mon Sep 17 00:00:00 2001 From: Silent Date: Sun, 25 Oct 2020 16:58:09 +0100 Subject: [PATCH 1/2] Implement D3D_BlockOnTime_4 --- src/core/hle/D3D8/Direct3D9/Direct3D9.cpp | 27 +++++++++++++++++++++++ src/core/hle/D3D8/Direct3D9/Direct3D9.h | 6 +++++ src/core/hle/Patches.cpp | 1 + 3 files changed, 34 insertions(+) diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index 492df0e19..ce228c265 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -8608,6 +8608,33 @@ void WINAPI xbox::EMUPATCH(D3D_BlockOnTime)( dword_xt Unknown1, int Unknown2 ) LOG_UNIMPLEMENTED(); } +// LTCG specific D3D_BlockOnTime function +// This uses a custom calling convention where parameter is passed in EAX +// Test case: Burnout 3 +__declspec(naked) void WINAPI xbox::EMUPATCH(D3D_BlockOnTime_4)( dword_xt Unknown1 ) +{ + int Unknown2; + + // prologue + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + mov Unknown2, eax // get parameter from eax + } + + // LOG_FORWARD requires unwinding, so carry on without it + EMUPATCH(D3D_BlockOnTime)(Unknown1, Unknown2); + + // epilogue + __asm { + mov esp, ebp + pop ebp + ret 4 + } +} + + bool DestroyResource_Common(xbox::X_D3DResource* pResource) { if (pResource == g_pXbox_RenderTarget) { diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.h b/src/core/hle/D3D8/Direct3D9/Direct3D9.h index 9232494c3..b00c54d37 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.h +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.h @@ -2068,6 +2068,12 @@ void WINAPI EMUPATCH(D3D_SetCommonDebugRegisters)(); // ****************************************************************** void WINAPI EMUPATCH(D3D_BlockOnTime)( dword_xt Unknown1, int Unknown2 ); +// ****************************************************************** +// * patch: D3D_BlockOnTime_4 +// One of the parameters (unknown which) passed in EAX +// ****************************************************************** +void WINAPI EMUPATCH(D3D_BlockOnTime_4)( dword_xt Unknown1 ); + // ****************************************************************** // * patch: D3D_BlockOnResource // ****************************************************************** diff --git a/src/core/hle/Patches.cpp b/src/core/hle/Patches.cpp index 3fef16dfa..11b43665a 100644 --- a/src/core/hle/Patches.cpp +++ b/src/core/hle/Patches.cpp @@ -181,6 +181,7 @@ std::map g_PatchTable = { PATCH_ENTRY("D3DDevice_UpdateOverlay", xbox::EMUPATCH(D3DDevice_UpdateOverlay), PATCH_HLE_D3D), PATCH_ENTRY("D3DResource_BlockUntilNotBusy", xbox::EMUPATCH(D3DResource_BlockUntilNotBusy), PATCH_HLE_D3D), PATCH_ENTRY("D3D_BlockOnTime", xbox::EMUPATCH(D3D_BlockOnTime), PATCH_HLE_D3D), + PATCH_ENTRY("D3D_BlockOnTime_4", xbox::EMUPATCH(D3D_BlockOnTime_4), PATCH_HLE_D3D), PATCH_ENTRY("D3D_DestroyResource", xbox::EMUPATCH(D3D_DestroyResource), PATCH_HLE_D3D), PATCH_ENTRY("D3D_DestroyResource__LTCG", xbox::EMUPATCH(D3D_DestroyResource__LTCG), PATCH_HLE_D3D), PATCH_ENTRY("D3D_LazySetPointParams", xbox::EMUPATCH(D3D_LazySetPointParams), PATCH_HLE_D3D), From e81c9fecb89b6da72364b3ee42083cb575296efd Mon Sep 17 00:00:00 2001 From: Silent Date: Sun, 25 Oct 2020 18:51:40 +0100 Subject: [PATCH 2/2] Unpatch D3DDevice_GetTransform and call to guest in SetTransform and MultiplyTransform Fixes (not yet visible) rendering in Burnout 3, possibly because to it having an unpatched LTCG-specific GetTransform or reading from the D3D state directly. --- src/core/hle/D3D8/Direct3D9/Direct3D9.cpp | 103 ++++++++---------- .../Direct3D9/Direct3D9.cpp.unused-patches | 20 ++++ src/core/hle/D3D8/Direct3D9/Direct3D9.h | 2 +- src/core/hle/Patches.cpp | 2 +- 4 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index ce228c265..9cdffa0ef 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -303,6 +303,9 @@ g_EmuCDPD = {0}; /*XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShader, (xbox::dword_xt) );*/\ /*XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShaderInput, (xbox::dword_xt, xbox::uint_xt, xbox::X_STREAMINPUT*) );*/\ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetViewport, (CONST xbox::X_D3DVIEWPORT8*) ); \ + XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTransform, (D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) ); \ + XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTransform_0, () ); \ + XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_MultiplyTransform, (D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) ); \ 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**) ); \ @@ -6445,21 +6448,51 @@ xbox::void_xt __fastcall xbox::EMUPATCH(D3DDevice_SetRenderState_Simple) XboxRenderStates.SetXboxRenderState(XboxRenderStateIndex, Value); } +void CxbxImpl_SetTransform +( + D3DTRANSFORMSTATETYPE State, + CONST D3DMATRIX *pMatrix +) +{ + LOG_FUNC_BEGIN + LOG_FUNC_ARG(State) + LOG_FUNC_ARG(pMatrix) + LOG_FUNC_END; + + State = EmuXB2PC_D3DTS(State); + + HRESULT hRet = g_pD3DDevice->SetTransform(State, pMatrix); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetTransform"); +} + // LTCG specific D3DDevice_SetTransform function... // This uses a custom calling convention where parameter is passed in EAX, EDX -xbox::void_xt __stdcall xbox::EMUPATCH(D3DDevice_SetTransform_0) +__declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetTransform_0) ( ) { - D3DTRANSFORMSTATETYPE param1; - CONST D3DMATRIX *param2; + D3DTRANSFORMSTATETYPE State; + CONST D3DMATRIX *pMatrix; + // prologue __asm { - mov param1, eax - mov param2, edx + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + mov State, eax + mov pMatrix, edx + // Trampoline to guest code to remove the need for a GetTransform patch + call XB_TRMP(D3DDevice_SetTransform_0) } - return EMUPATCH(D3DDevice_SetTransform)(param1, param2); + CxbxImpl_SetTransform(State, pMatrix); + + // epilogue + __asm { + mov esp, ebp + pop ebp + ret + } } // ****************************************************************** @@ -6471,36 +6504,9 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetTransform) CONST D3DMATRIX *pMatrix ) { - LOG_FUNC_BEGIN - LOG_FUNC_ARG(State) - LOG_FUNC_ARG(pMatrix) - LOG_FUNC_END; - - /* - printf("pMatrix (%d)\n", State); - printf("{\n"); - printf(" %.08f,%.08f,%.08f,%.08f\n", pMatrix->_11, pMatrix->_12, pMatrix->_13, pMatrix->_14); - printf(" %.08f,%.08f,%.08f,%.08f\n", pMatrix->_21, pMatrix->_22, pMatrix->_23, pMatrix->_24); - printf(" %.08f,%.08f,%.08f,%.08f\n", pMatrix->_31, pMatrix->_32, pMatrix->_33, pMatrix->_34); - printf(" %.08f,%.08f,%.08f,%.08f\n", pMatrix->_41, pMatrix->_42, pMatrix->_43, pMatrix->_44); - printf("}\n"); - - if(State == 6 && (pMatrix->_11 == 1.0f) && (pMatrix->_22 == 1.0f) && (pMatrix->_33 == 1.0f) && (pMatrix->_44 == 1.0f)) - { - g_bSkipPush = TRUE; - printf("SkipPush ON\n"); - } - else - { - g_bSkipPush = FALSE; - printf("SkipPush OFF\n"); - } - */ - - State = EmuXB2PC_D3DTS(State); - - HRESULT hRet = g_pD3DDevice->SetTransform(State, pMatrix); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetTransform"); + // Trampoline to guest code to remove the need for a GetTransform patch + XB_TRMP(D3DDevice_SetTransform)(State, pMatrix); + CxbxImpl_SetTransform(State, pMatrix); } // ****************************************************************** @@ -6517,33 +6523,16 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_MultiplyTransform) LOG_FUNC_ARG(pMatrix) LOG_FUNC_END; + + // Trampoline to guest code to remove the need for a GetTransform patch + XB_TRMP(D3DDevice_MultiplyTransform)(State, pMatrix); + State = EmuXB2PC_D3DTS(State); HRESULT hRet = g_pD3DDevice->MultiplyTransform(State, pMatrix); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->MultiplyTransform"); } - -// ****************************************************************** -// * patch: D3DDevice_GetTransform -// ****************************************************************** -xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_GetTransform) -( - D3DTRANSFORMSTATETYPE State, - D3DMATRIX *pMatrix -) -{ - LOG_FUNC_BEGIN - LOG_FUNC_ARG(State) - LOG_FUNC_ARG(pMatrix) - LOG_FUNC_END; - - State = EmuXB2PC_D3DTS(State); - - HRESULT hRet = g_pD3DDevice->GetTransform(State, pMatrix); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetTransform"); -} - // ****************************************************************** // * patch: Lock2DSurface // ****************************************************************** diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp.unused-patches b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp.unused-patches index 45f1e5c91..2f72e5d08 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp.unused-patches +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp.unused-patches @@ -4135,3 +4135,23 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderFunction) return hRet; } + +// ****************************************************************** +// * patch: D3DDevice_GetTransform +// ****************************************************************** +xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_GetTransform) +( + D3DTRANSFORMSTATETYPE State, + D3DMATRIX *pMatrix +) +{ + LOG_FUNC_BEGIN + LOG_FUNC_ARG(State) + LOG_FUNC_ARG(pMatrix) + LOG_FUNC_END; + + State = EmuXB2PC_D3DTS(State); + + HRESULT hRet = g_pD3DDevice->GetTransform(State, pMatrix); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetTransform"); +} diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.h b/src/core/hle/D3D8/Direct3D9/Direct3D9.h index b00c54d37..6e7842c08 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.h +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.h @@ -1313,7 +1313,7 @@ xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetTransform) CONST D3DMATRIX *pMatrix ); -xbox::void_xt __stdcall EMUPATCH(D3DDevice_SetTransform_0)(); +xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetTransform_0)(); // ****************************************************************** // * patch: D3DDevice_MultiplyTransform diff --git a/src/core/hle/Patches.cpp b/src/core/hle/Patches.cpp index 11b43665a..cc9634814 100644 --- a/src/core/hle/Patches.cpp +++ b/src/core/hle/Patches.cpp @@ -90,7 +90,7 @@ std::map g_PatchTable = { PATCH_ENTRY("D3DDevice_GetOverlayUpdateStatus", xbox::EMUPATCH(D3DDevice_GetOverlayUpdateStatus), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetProjectionViewportMatrix", xbox::EMUPATCH(D3DDevice_GetProjectionViewportMatrix), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetShaderConstantMode", xbox::EMUPATCH(D3DDevice_GetShaderConstantMode), PATCH_HLE_D3D), - PATCH_ENTRY("D3DDevice_GetTransform", xbox::EMUPATCH(D3DDevice_GetTransform), PATCH_HLE_D3D), + //PATCH_ENTRY("D3DDevice_GetTransform", xbox::EMUPATCH(D3DDevice_GetTransform), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetVertexShader", xbox::EMUPATCH(D3DDevice_GetVertexShader), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetVertexShaderConstant", xbox::EMUPATCH(D3DDevice_GetVertexShaderConstant), PATCH_HLE_D3D), //PATCH_ENTRY("D3DDevice_GetVertexShaderDeclaration", xbox::EMUPATCH(D3DDevice_GetVertexShaderDeclaration), PATCH_HLE_D3D),