Merge pull request #2382 from jackchentwkh/vsh_cpu_2

Implement HLE D3DDevice_RunVertexStateShader()
This commit is contained in:
Luke Usher 2022-07-05 15:57:43 +01:00 committed by GitHub
commit b2f63918de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 1 deletions

3
.gitmodules vendored
View File

@ -39,3 +39,6 @@
path = import/libusb
url = https://github.com/libusb/libusb
shallow = true
[submodule "import/nv2a_vsh_cpu"]
path = import/nv2a_vsh_cpu
url = https://github.com/abaire/nv2a_vsh_cpu.git

View File

@ -39,6 +39,9 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/imgui")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/libusb")
set(nv2a_vsh_cpu_UNIT_TEST OFF)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/nv2a_vsh_cpu" EXCLUDE_FROM_ALL)
# Split the files into group for which project is likely
# going to be used for both header and source files.
# Then move only specific project files into their
@ -437,6 +440,10 @@ set_target_properties(cxbx cxbxr-ldr cxbxr-emu misc-batch SDL2 subhook libXbSymb
PROPERTIES FOLDER Cxbx-Reloaded
)
set_target_properties(nv2a_vsh_emulator nv2a_vsh_disassembler nv2a_vsh_cpu
PROPERTIES FOLDER Cxbx-Reloaded/nv2a_vsh
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# Configure startup project
set_property(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" PROPERTY VS_STARTUP_PROJECT cxbx)

1
import/nv2a_vsh_cpu vendored Submodule

@ -0,0 +1 @@
Subproject commit ead0af5dee49e408c005151393f8a7dbcd27026c

View File

@ -171,6 +171,7 @@ target_link_libraries(cxbxr-emu
SDL2
imgui
libusb
nv2a_vsh_emulator
${WINS_LIB}
)

View File

@ -78,6 +78,9 @@
#include <thread>
#include <wrl/client.h>
#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,41 @@ 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
if (Address >= NV2A_MAX_TRANSFORM_PROGRAM_LENGTH) {
LOG_TEST_CASE("Address out of bounds");
return;
}
LOG_UNIMPLEMENTED();
NV2AState* dev = g_NV2A->GetDeviceState();
PGRAPHState* pg = &(dev->pgraph);
Nv2aVshProgram program = {}; // Note: This nulls program.steps
// TODO : Retain program globally and perform nv2a_vsh_parse_program only when
// the address-range we're about to emulate was modified since last parse.
// TODO : As a suggestion for this, parse all NV2A_MAX_TRANSFORM_PROGRAM_LENGTH slots,
// and here just point program.steps to global vsh_program_steps[Address].
Nv2aVshParseResult result = nv2a_vsh_parse_program(
&program, // Note : program.steps will be malloc'ed
GetCxbxVertexShaderSlotPtr(Address), // TODO : At some point, use pg->program_data[Address] here instead
NV2A_MAX_TRANSFORM_PROGRAM_LENGTH - Address);
if (result != NV2AVPR_SUCCESS) {
LOG_TEST_CASE("nv2a_vsh_parse_program failed");
// TODO : Dump Nv2aVshParseResult as string and program for debugging purposes
return;
}
Nv2aVshCPUXVSSExecutionState state_linkage;
Nv2aVshExecutionState state = nv2a_vsh_emu_initialize_xss_execution_state(
&state_linkage, (float*)pg->vsh_constants); // Note : This wil memset(state_linkage, 0)
if (pData != nullptr)
//if pData != nullptr, then it contains v0.xyzw, we shall copy the binary content directly.
memcpy(state_linkage.input_regs, pData, sizeof(state_linkage.input_regs));
nv2a_vsh_emu_execute_track_context_writes(&state, &program, pg->vsh_constants_dirty);
// Note: Above emulation's primary purpose is to update pg->vsh_constants and pg->vsh_constants_dirty
// therefor, nothing else needs to be done here, other than to cleanup
nv2a_vsh_program_destroy(&program); // Note: program.steps will be free'ed
}
// ******************************************************************