diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index e5923641e..76be70d73 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -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... diff --git a/src/core/hle/D3D8/XbVertexShader.cpp b/src/core/hle/D3D8/XbVertexShader.cpp index af5ce8e30..7e604e163 100644 --- a/src/core/hle/D3D8/XbVertexShader.cpp +++ b/src/core/hle/D3D8/XbVertexShader.cpp @@ -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 diff --git a/src/core/hle/D3D8/XbVertexShader.h b/src/core/hle/D3D8/XbVertexShader.h index 13347854c..45260db57 100644 --- a/src/core/hle/D3D8/XbVertexShader.h +++ b/src/core/hle/D3D8/XbVertexShader.h @@ -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