diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index 72c68d187..a0732340b 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -3563,43 +3563,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader) LOG_FUNC_ARG(Address) LOG_FUNC_END; - HRESULT hRet = D3D_OK; - - // Address always indicates a previously loaded vertex shader slot (from where the program is used). - // Handle can be null if the current Xbox VertexShader is assigned - // Handle can be an address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0) - // If Handle is assigned, it becomes the new current Xbox VertexShader, - // which resets a bit of state (nv2a execution mode, viewport, ?) - // Either way, the given address slot is selected as the start of the current vertex shader program - g_Xbox_VertexShader_Handle = Handle; - - CxbxVertexShader *pCxbxVertexShader = nullptr; - - if(VshHandleIsVertexShader(Handle)) - { - pCxbxVertexShader = GetCxbxVertexShader(Handle); - if (pCxbxVertexShader == nullptr) { - LOG_TEST_CASE("Shader handle has not been created"); - } - - // TODO we should only set the vertex declaration here? - SetCxbxVertexShader(pCxbxVertexShader); - } - - auto pTokens = GetCxbxVertexShaderSlotPtr(Address); - if (pTokens) { - // Create a vertex shader from the tokens - DWORD shaderSize; - auto shaderKey = g_VertexShaderSource.CreateShader(pTokens, &shaderSize); - g_pD3DDevice->SetVertexShader(g_VertexShaderSource.GetShader(shaderKey)); - } - - if (FAILED(hRet)) - { - EmuLog(LOG_LEVEL::WARNING, "We're lying about setting a vertext shader!"); - - hRet = D3D_OK; - } + CxbxImpl_SelectVertexShader(Handle, Address); } // ****************************************************************** diff --git a/src/core/hle/D3D8/XbVertexShader.cpp b/src/core/hle/D3D8/XbVertexShader.cpp index b20a1e998..e1687a2b6 100644 --- a/src/core/hle/D3D8/XbVertexShader.cpp +++ b/src/core/hle/D3D8/XbVertexShader.cpp @@ -32,6 +32,7 @@ #include "core\kernel\init\CxbxKrnl.h" #include "core\kernel\support\Emu.h" #include "core\hle\D3D8\Direct3D9\Direct3D9.h" // For g_Xbox_VertexShader_Handle +#include "core\hle\D3D8\Direct3D9\VertexShaderSource.h" // For g_VertexShaderSource #include "core\hle\D3D8\XbVertexShader.h" #include "core\hle\D3D8\XbD3D8Logging.h" // For DEBUG_D3DRESULT #include "common\Logging.h" // For LOG_INIT @@ -1329,6 +1330,47 @@ void CxbxImpl_SelectVertexShaderDirect LOG_UNIMPLEMENTED(); } +void CxbxImpl_SelectVertexShader(DWORD Handle, DWORD Address) +{ + HRESULT hRet = D3D_OK; + + // Address always indicates a previously loaded vertex shader slot (from where the program is used). + // Handle can be null if the current Xbox VertexShader is assigned + // Handle can be an address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0) + // If Handle is assigned, it becomes the new current Xbox VertexShader, + // which resets a bit of state (nv2a execution mode, viewport, ?) + // Either way, the given address slot is selected as the start of the current vertex shader program + g_Xbox_VertexShader_Handle = Handle; + + CxbxVertexShader* pCxbxVertexShader = nullptr; + + if (VshHandleIsVertexShader(Handle)) + { + pCxbxVertexShader = GetCxbxVertexShader(Handle); + if (pCxbxVertexShader == nullptr) { + LOG_TEST_CASE("Shader handle has not been created"); + } + + // TODO we should only set the vertex declaration here? + SetCxbxVertexShader(pCxbxVertexShader); + } + + auto pTokens = GetCxbxVertexShaderSlotPtr(Address); + if (pTokens) { + // Create a vertex shader from the tokens + DWORD shaderSize; + auto shaderKey = g_VertexShaderSource.CreateShader(pTokens, &shaderSize); + g_pD3DDevice->SetVertexShader(g_VertexShaderSource.GetShader(shaderKey)); + } + + if (FAILED(hRet)) + { + EmuLog(LOG_LEVEL::WARNING, "We're lying about setting a vertext shader!"); + + hRet = D3D_OK; + } +} + 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) diff --git a/src/core/hle/D3D8/XbVertexShader.h b/src/core/hle/D3D8/XbVertexShader.h index bdb4b1361..a84d0be9b 100644 --- a/src/core/hle/D3D8/XbVertexShader.h +++ b/src/core/hle/D3D8/XbVertexShader.h @@ -240,6 +240,7 @@ extern void SetCxbxVertexShader(CxbxVertexShader* pCxbxVertexShader); // Impleme extern void CxbxImpl_LoadVertexShader(DWORD Handle, DWORD Address); extern void CxbxImpl_SetVertexShader(DWORD Handle); extern void CxbxImpl_SelectVertexShaderDirect(XTL::X_VERTEXATTRIBUTEFORMAT* pVAF, DWORD Address); +extern void CxbxImpl_SelectVertexShader(DWORD Handle, DWORD Address); extern void CxbxImpl_SetVertexShaderInput(DWORD Handle, UINT StreamCount, XTL::X_STREAMINPUT* pStreamInputs); extern void CxbxImpl_SetVertexShaderConstant(INT Register, PVOID pConstantData, DWORD ConstantCount);