Move implementation of D3DDevice_LoadVertexShader towards XbVertexShader.cpp

This commit is contained in:
patrickvl 2020-04-30 13:58:27 +02:00
parent 848f4eeee3
commit 3db98e4e90
3 changed files with 28 additions and 21 deletions

View File

@ -3528,27 +3528,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_LoadVertexShader)
LOG_FUNC_ARG(Address)
LOG_FUNC_END;
// Handle is always address of an X_D3DVertexShader struct, thus always or-ed with 1 (X_D3DFVF_RESERVED0)
// Address is the slot (offset) from which the program must be written onwards (as whole DWORDS)
// D3DDevice_LoadVertexShader pushes the program contained in the Xbox VertexShader struct to the NV2A
auto CxbxVertexShaderSlotPtr = GetCxbxVertexShaderSlotPtr(Address);
if(CxbxVertexShaderSlotPtr) {
CxbxVertexShader * pCxbxVertexShader = GetCxbxVertexShader(Handle);
if (pCxbxVertexShader) {
int upToSlot = Address + pCxbxVertexShader->XboxNrAddressSlots;
if (upToSlot > X_VSH_MAX_INSTRUCTION_COUNT) {
LOG_TEST_CASE("Shader does not fit in vertex shader slots");
return;
}
// Skip the header DWORD at the beginning
auto pTokens = &pCxbxVertexShader->pXboxFunctionCopy[1];
memcpy(CxbxVertexShaderSlotPtr, pTokens, pCxbxVertexShader->XboxNrAddressSlots * X_VSH_INSTRUCTION_SIZE_BYTES);
}
else {
LOG_TEST_CASE("LoadVertexShader called with unrecognized handle %d", Handle);
}
}
CxbxImpl_LoadVertexShader(Handle, Address);
}
// LTCG specific D3DDevice_SelectVertexShader function...

View File

@ -1326,6 +1326,31 @@ void CxbxImpl_SelectVertexShaderDirect
// When pVAF is non-null, this vertex attribute format takes precedence over the the one
LOG_UNIMPLEMENTED();
}
void CxbxImpl_LoadVertexShader(DWORD Handle, DWORD Address)
{
// Handle is always address of an X_D3DVertexShader struct, thus always or-ed with 1 (X_D3DFVF_RESERVED0)
// Address is the slot (offset) from which the program must be written onwards (as whole DWORDS)
// D3DDevice_LoadVertexShader pushes the program contained in the Xbox VertexShader struct to the NV2A
auto CxbxVertexShaderSlotPtr = GetCxbxVertexShaderSlotPtr(Address);
if (CxbxVertexShaderSlotPtr) {
CxbxVertexShader* pCxbxVertexShader = GetCxbxVertexShader(Handle);
if (pCxbxVertexShader) {
int upToSlot = Address + pCxbxVertexShader->XboxNrAddressSlots;
if (upToSlot > X_VSH_MAX_INSTRUCTION_COUNT) {
LOG_TEST_CASE("Shader does not fit in vertex shader slots");
return;
}
// Skip the header DWORD at the beginning
auto pTokens = &pCxbxVertexShader->pXboxFunctionCopy[1];
memcpy(CxbxVertexShaderSlotPtr, pTokens, pCxbxVertexShader->XboxNrAddressSlots * X_VSH_INSTRUCTION_SIZE_BYTES);
}
else {
LOG_TEST_CASE("LoadVertexShader called with unrecognized handle %d", Handle);
}
}
}
// parse xbox vertex shader function into an intermediate format
extern void EmuParseVshFunction

View File

@ -236,5 +236,7 @@ inline XTL::X_D3DVertexShader *VshHandleToXboxVertexShader(DWORD Handle) { retur
extern DWORD* GetCxbxVertexShaderSlotPtr(const DWORD SlotIndexAddress);
extern CxbxVertexShader* GetCxbxVertexShader(DWORD XboxVertexShaderHandle);
extern void SetCxbxVertexShader(DWORD XboxVertexShaderHandle, CxbxVertexShader* shader);
extern void CxbxImpl_LoadVertexShader(DWORD Handle, DWORD Address);
#endif