Fix D3DDevice_SetPalette and D3DDevice_SetPalette_4 not calling to guest code

Fixes memory leaks in SetPalette functions, as they are now able
to reference count and destroy palette resources.
Also fixes a very poor SetPalette_4 LTCG function
This commit is contained in:
Silent 2020-11-24 20:04:53 +01:00
parent 36e6349de5
commit 4d8c4fbb68
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
2 changed files with 66 additions and 27 deletions

View File

@ -302,6 +302,8 @@ g_EmuCDPD = {0};
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTexture, (xbox::dword_xt, xbox::X_D3DBaseTexture*) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTexture, (xbox::dword_xt, xbox::X_D3DBaseTexture*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTexture_4__LTCG_eax_pTexture, (xbox::dword_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTexture_4__LTCG_eax_pTexture, (xbox::dword_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTexture_4, (xbox::X_D3DBaseTexture*) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTexture_4, (xbox::X_D3DBaseTexture*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetPalette, (xbox::dword_xt, xbox::X_D3DPalette*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetPalette_4, (xbox::X_D3DPalette*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShader, (xbox::dword_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShader, (xbox::dword_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShader_0, () ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShader_0, () ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShaderInput, (xbox::dword_xt, xbox::uint_xt, xbox::X_STREAMINPUT*) ); \ XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetVertexShaderInput, (xbox::dword_xt, xbox::uint_xt, xbox::X_STREAMINPUT*) ); \
@ -8008,27 +8010,67 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3D_CommonSetRenderTarget)
} }
} }
static void CxbxImpl_SetPalette
// LTCG specific D3DDevice_SetPalette function...
// This uses a custom calling convention where parameter is passed in EAX
// Test-case: Ninja Gaiden
xbox::void_xt __stdcall xbox::EMUPATCH(D3DDevice_SetPalette_4)
( (
xbox::dword_xt Stage,
xbox::X_D3DPalette *pPalette
) )
{ {
static uint32_t returnAddr; if (Stage >= xbox::X_D3DTS_STAGECOUNT) {
LOG_TEST_CASE("Stage out of bounds");
} else {
// Note : Actual update of paletized textures (X_D3DFMT_P8) happens in CxbxUpdateHostTextures!
g_pXbox_Palette_Data[Stage] = GetDataFromXboxResource(pPalette);
g_Xbox_Palette_Size[Stage] = pPalette ? XboxD3DPaletteSizeToBytes(GetXboxPaletteSize(pPalette)) : 0;
}
}
#ifdef _DEBUG_TRACE // Overload for logging
__asm add esp, 4 static void D3DDevice_SetPalette_4
#endif (
xbox::dword_xt Stage,
xbox::X_D3DPalette *pPalette
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Stage)
LOG_FUNC_ARG(pPalette)
LOG_FUNC_END;
}
// LTCG specific D3DDevice_SetPalette function...
// This uses a custom calling convention where Stage parameter is passed in EAX
// Test-case: Ninja Gaiden
__declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetPalette_4)
(
X_D3DPalette *pPalette
)
{
dword_xt Stage;
__asm { __asm {
pop returnAddr push ebp
push eax mov ebp, esp
call EmuPatch_D3DDevice_SetPalette sub esp, __LOCAL_SIZE
mov eax, 0 mov Stage, eax
push returnAddr }
ret
// Log
D3DDevice_SetPalette_4(Stage, pPalette);
// Call the Xbox implementation of this function, to properly handle reference counting for us
__asm {
push pPalette
mov eax, Stage
call XB_TRMP(D3DDevice_SetPalette_4)
}
CxbxImpl_SetPalette(Stage, pPalette);
__asm {
mov esp, ebp
pop ebp
ret 4
} }
} }
@ -8037,8 +8079,8 @@ xbox::void_xt __stdcall xbox::EMUPATCH(D3DDevice_SetPalette_4)
// ****************************************************************** // ******************************************************************
xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetPalette) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetPalette)
( (
dword_xt Stage, dword_xt Stage,
X_D3DPalette *pPalette X_D3DPalette *pPalette
) )
{ {
LOG_FUNC_BEGIN LOG_FUNC_BEGIN
@ -8046,16 +8088,10 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetPalette)
LOG_FUNC_ARG(pPalette) LOG_FUNC_ARG(pPalette)
LOG_FUNC_END; LOG_FUNC_END;
// g_pD3DDevice9->SetPaletteEntries(Stage?, (PALETTEENTRY*)pPalette->Data); // Call the Xbox implementation of this function, to properly handle reference counting for us
// g_pD3DDevice9->SetCurrentTexturePalette(Stage, Stage); XB_TRMP(D3DDevice_SetPalette)(Stage, pPalette);
if (Stage >= xbox::X_D3DTS_STAGECOUNT) { CxbxImpl_SetPalette(Stage, pPalette);
LOG_TEST_CASE("Stage out of bounds");
} else {
// Note : Actual update of paletized textures (X_D3DFMT_P8) happens in CxbxUpdateHostTextures!
g_pXbox_Palette_Data[Stage] = GetDataFromXboxResource(pPalette);
g_Xbox_Palette_Size[Stage] = pPalette ? XboxD3DPaletteSizeToBytes(GetXboxPaletteSize(pPalette)) : 0;
}
} }
// LTCG specific D3DDevice_SetFlickerFilter function... // LTCG specific D3DDevice_SetFlickerFilter function...

View File

@ -1547,7 +1547,10 @@ xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetPalette)
X_D3DPalette *pPalette X_D3DPalette *pPalette
); );
xbox::void_xt __stdcall EMUPATCH(D3DDevice_SetPalette_4)(); xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetPalette_4)
(
X_D3DPalette *pPalette
);
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_SetFlickerFilter // * patch: D3DDevice_SetFlickerFilter