diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index 38ce76540..553e76634 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -78,6 +78,9 @@ #include #include + +#include "nv2a_vsh_emulator.h" + using namespace Microsoft::WRL; XboxRenderStateConverter XboxRenderStates; @@ -8660,6 +8663,8 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetVertexShaderInput) XB_TRMP(D3DDevice_SetVertexShaderInput)(Handle, StreamCount, pStreamInputs); } +extern xbox::dword_xt* GetCxbxVertexShaderSlotPtr(const DWORD SlotIndexAddress); // tmp glue + // ****************************************************************** // * patch: D3DDevice_RunVertexStateShader // ****************************************************************** @@ -8676,8 +8681,39 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_RunVertexStateShader) // If pData is assigned, pData[0..3] is pushed towards nv2a transform data registers // then sends the nv2a a command to launch the vertex shader function located at Address + NV2AState* dev = g_NV2A->GetDeviceState(); + PGRAPHState* pg = &(dev->pgraph); - LOG_UNIMPLEMENTED(); + float vertex_state_shader_v0[4]; + + for (int slot = 0; slot < 4; slot++) + { + if (pData != nullptr) + vertex_state_shader_v0[slot] = pData[slot]; + else + vertex_state_shader_v0[slot] = 0.0f; + } + + int shader_slot = Address; + Nv2aVshProgram program; + + Nv2aVshParseResult result = nv2a_vsh_parse_program( + &program, + //pg->program_data[shader_slot], + GetCxbxVertexShaderSlotPtr(shader_slot), + NV2A_MAX_TRANSFORM_PROGRAM_LENGTH - shader_slot); + assert(result == NV2AVPR_SUCCESS); + + Nv2aVshCPUXVSSExecutionState state_linkage; + Nv2aVshExecutionState state = nv2a_vsh_emu_initialize_xss_execution_state( + &state_linkage, (float*)pg->vsh_constants, pg->vsh_constants_dirty); + memcpy(state_linkage.input_regs, vertex_state_shader_v0, sizeof(vertex_state_shader_v0)); + + nv2a_vsh_emu_execute(&state, &program); + + nv2a_vsh_program_destroy(&program); + + //LOG_UNIMPLEMENTED(); } // ******************************************************************