Merge pull request #2031 from CookiePLMonster/xdk-3911-ltcg-fixes

Misc fixes after the vertex declaration changes
This commit is contained in:
PatrickvL 2020-11-15 22:20:51 +01:00 committed by GitHub
commit 7e0f8f4b30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 16 deletions

View File

@ -301,6 +301,7 @@ g_EmuCDPD = {0};
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_SetVertexShader, (xbox::dword_xt) ); \
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_SetViewport, (CONST xbox::X_D3DVIEWPORT8*) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3DDevice_SetTransform, (D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) ); \
@ -3060,6 +3061,8 @@ void Direct3D_CreateDevice_Start
xbox::X_D3DPRESENT_PARAMETERS *pPresentationParameters
)
{
CxbxVertexShaderSetFlags();
if (!XboxRenderStates.Init()) {
CxbxKrnlCleanup("Failed to init XboxRenderStates");
}
@ -4301,8 +4304,6 @@ void CxbxImpl_SetViewPort(xbox::X_D3DVIEWPORT8* pViewport)
HostViewPort.Y = static_cast<DWORD>(HostViewPort.Y * g_Xbox_MultiSampleYScale);
HostViewPort.Width = static_cast<DWORD>(HostViewPort.Width * g_Xbox_MultiSampleXScale);
HostViewPort.Height = static_cast<DWORD>(HostViewPort.Height * g_Xbox_MultiSampleYScale);
HostViewPort.X = static_cast<DWORD>(HostViewPort.X * g_Xbox_MultiSampleXScale);
HostViewPort.Y = static_cast<DWORD>(HostViewPort.Y * g_Xbox_MultiSampleYScale);
// Since Width and Height are DWORD, adding GetMultiSampleOffset 0.0f or 0.5f makes no sense
HRESULT hRet = g_pD3DDevice->SetViewport(&HostViewPort);
@ -6604,22 +6605,51 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetVertexShader)
{
LOG_FUNC_ONE_ARG(Handle);
if (XB_TRMP(D3DDevice_SetVertexShader))
XB_TRMP(D3DDevice_SetVertexShader)(Handle);
// This trampoline leads to calling D3DDevice_LoadVertexShader and D3DDevice_SelectVertexShader
// Please raise the alarm if this is ever not the case
XB_TRMP(D3DDevice_SetVertexShader)(Handle);
CxbxImpl_SetVertexShader(Handle);
}
// Overload for logging
static void D3DDevice_SetVertexShader_0
(
xbox::dword_xt Handle
)
{
LOG_FUNC_ONE_ARG(Handle);
}
// This uses a custom calling convention where Handle is passed in EBX
// Test-case: NASCAR Heat 2002
xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetVertexShader_0)()
__declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetVertexShader_0)()
{
dword_xt Handle;
__asm mov Handle, ebx
__asm {
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov Handle, ebx
}
LOG_FUNC_ONE_ARG(Handle);
// Log
D3DDevice_SetVertexShader_0(Handle);
// This trampoline leads to calling D3DDevice_LoadVertexShader and D3DDevice_SelectVertexShader
// Please raise the alarm if this is ever not the case
__asm {
mov ebx, Handle
call XB_TRMP(D3DDevice_SetVertexShader_0)
}
CxbxImpl_SetVertexShader(Handle);
__asm {
mov esp, ebp
pop ebp
ret
}
}
// TODO : Move to own file

View File

@ -1149,14 +1149,16 @@ struct X_D3DVertexShader
// X_D3DVertexShader.Flags values :
#define X_VERTEXSHADER_FLAG_WRITE (1 << 0) // = 0x0001 // Set for Xbox ShaderType != X_VST_NORMAL
#define X_VERTEXSHADER_FLAG_PASSTHROUGH (1 << 1) // = 0x0002
#define X_VERTEXSHADER_FLAG_UNKNOWN (1 << 2) // = 0x0004 // Test case: Amped
#define X_VERTEXSHADER_FLAG_STATE (1 << 3) // = 0x0008 // Set for Xbox ShaderType == X_VST_STATE
#define X_VERTEXSHADER_FLAG_PROGRAM (1 << 4) // = 0x0010 // Set when X_D3DVertexShader was created with assigned function data
#define X_VERTEXSHADER_FLAG_PROGRAM (1 << 4) // = 0x0010 // Set when X_D3DVertexShader was created with assigned function data; introduced after XDK 3948; don't use directly, use g_X_VERTEXSHADER_FLAG_PROGRAM instead
#define X_VERTEXSHADER_FLAG_HASDIFFUSE (1 << 10) // = 0x0400 Corresponds to X_D3DUSAGE_PERSISTENTDIFFUSE
#define X_VERTEXSHADER_FLAG_HASSPECULAR (1 << 11) // = 0x0800 Corresponds to X_D3DUSAGE_PERSISTENTSPECULAR
#define X_VERTEXSHADER_FLAG_HASBACKDIFFUSE (1 << 12) // = 0x1000 Corresponds to X_D3DUSAGE_PERSISTENTBACKDIFFUSE
#define X_VERTEXSHADER_FLAG_HASBACKSPECULAR (1 << 13) // = 0x2000 Corresponds to X_D3DUSAGE_PERSISTENTBACKSPECULAR
// X_D3DVertexShader3948.Flags values, only those which differ from the above :
#define X_VERTEXSHADER3948_FLAG_PROGRAM (1 << 2) // = 0x0004 // Test case: Amped, NASCAR Heat 2002; don't use directly, use g_X_VERTEXSHADER_FLAG_PROGRAM instead
// vertex shader input registers for fixed function vertex shader
// Name Register number D3DFVF

View File

@ -77,6 +77,23 @@ extern XboxRenderStateConverter XboxRenderStates; // Declared in Direct3D9.cpp
static xbox::X_D3DVertexShader g_Xbox_VertexShader_ForFVF = {};
static uint32_t g_X_VERTEXSHADER_FLAG_PROGRAM; // X_VERTEXSHADER_FLAG_PROGRAM flag varies per XDK, so it is set on runtime
static uint32_t g_X_VERTEXSHADER_FLAG_VALID_MASK; // For a test case
void CxbxVertexShaderSetFlags()
{
// Set an appropriate X_VERTEXSHADER_FLAG_PROGRAM version and mask off the "wrong" one
// to allow the test case to spot it
if (g_LibVersion_D3D8 <= 3948) {
g_X_VERTEXSHADER_FLAG_PROGRAM = X_VERTEXSHADER3948_FLAG_PROGRAM;
g_X_VERTEXSHADER_FLAG_VALID_MASK = ~X_VERTEXSHADER_FLAG_PROGRAM;
}
else {
g_X_VERTEXSHADER_FLAG_PROGRAM = X_VERTEXSHADER_FLAG_PROGRAM;
g_X_VERTEXSHADER_FLAG_VALID_MASK = ~X_VERTEXSHADER3948_FLAG_PROGRAM;
}
}
// Converts an Xbox FVF shader handle to X_D3DVertexShader
// Note : Temporary, until we reliably locate the Xbox internal state for this
// See D3DXDeclaratorFromFVF docs https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxdeclaratorfromfvf
@ -272,7 +289,7 @@ xbox::X_D3DVertexShader* GetXboxVertexShader()
return pXboxVertexShader;
}
static bool UseXboxD3DVertexShaderTypeForVersion3948(xbox::X_D3DVertexShader* pXboxVertexShader)
static bool UseXboxD3DVertexShaderTypeForVersion3948(const xbox::X_D3DVertexShader* pXboxVertexShader)
{
// Don't check XDK version for our internal FVF vertex shader
// because g_Xbox_VertexShader_ForFVF is an internal variable
@ -287,7 +304,7 @@ static bool UseXboxD3DVertexShaderTypeForVersion3948(xbox::X_D3DVertexShader* pX
static xbox::X_VERTEXATTRIBUTEFORMAT* CxbxGetVertexShaderAttributes(xbox::X_D3DVertexShader* pXboxVertexShader)
{
if (UseXboxD3DVertexShaderTypeForVersion3948(pXboxVertexShader)) {
auto pXboxVertexShader3948 = (xbox::X_D3DVertexShader3948*)pXboxVertexShader;
auto pXboxVertexShader3948 = reinterpret_cast<xbox::X_D3DVertexShader3948*>(pXboxVertexShader);
return &(pXboxVertexShader3948->VertexAttribute);
}
@ -297,7 +314,7 @@ static xbox::X_VERTEXATTRIBUTEFORMAT* CxbxGetVertexShaderAttributes(xbox::X_D3DV
static DWORD* CxbxGetVertexShaderTokens(xbox::X_D3DVertexShader* pXboxVertexShader, DWORD* pNrTokens)
{
if (UseXboxD3DVertexShaderTypeForVersion3948(pXboxVertexShader)) {
auto pXboxVertexShader3948 = (xbox::X_D3DVertexShader3948*)pXboxVertexShader;
auto pXboxVertexShader3948 = reinterpret_cast<xbox::X_D3DVertexShader3948*>(pXboxVertexShader);
*pNrTokens = pXboxVertexShader3948->ProgramAndConstantsDwords;
return &pXboxVertexShader3948->ProgramAndConstants[0];
}
@ -1408,7 +1425,12 @@ void CxbxImpl_SetVertexShader(DWORD Handle)
xbox::X_D3DVertexShader* pXboxVertexShader = CxbxGetXboxVertexShaderForHandle(Handle);
g_Xbox_VertexShader_IsPassthrough = false;
if (pXboxVertexShader->Flags & X_VERTEXSHADER_FLAG_PROGRAM) {
if ((pXboxVertexShader->Flags & g_X_VERTEXSHADER_FLAG_VALID_MASK) != pXboxVertexShader->Flags) {
LOG_TEST_CASE("Unknown vertex shader flag");
}
if (pXboxVertexShader->Flags & g_X_VERTEXSHADER_FLAG_PROGRAM) { // Global variable set from CxbxVertexShaderSetFlags
#if 0 // Since the D3DDevice_SetVertexShader patch already called it's trampoline, these calls have already been executed :
CxbxImpl_LoadVertexShader(Handle, 0);
CxbxImpl_SelectVertexShader(Handle, 0);
@ -1465,9 +1487,6 @@ void CxbxImpl_SetVertexShader(DWORD Handle)
CxbxSetVertexShaderPassthroughProgram();
g_Xbox_VertexShader_IsFixedFunction = false;
g_Xbox_VertexShader_IsPassthrough = true;
} else if (pXboxVertexShader->Flags & X_VERTEXSHADER_FLAG_UNKNOWN) {
// Test-case : Amped
LOG_TEST_CASE("unknown vertex shader flag (4)");
} else {
// Test-case : Many XDK samples, Crazy taxi 3
//LOG_TEST_CASE("Other or no vertex shader flags");

View File

@ -213,5 +213,6 @@ extern void CxbxImpl_SelectVertexShader(DWORD Handle, DWORD Address);
extern void CxbxImpl_SetVertexShaderInput(DWORD Handle, UINT StreamCount, xbox::X_STREAMINPUT* pStreamInputs);
extern void CxbxImpl_SetVertexShaderConstant(INT Register, PVOID pConstantData, DWORD ConstantCount);
extern void CxbxImpl_DeleteVertexShader(DWORD Handle);
extern void CxbxVertexShaderSetFlags();
#endif