From 9d2d8691b5d837f08ee5919957b0c404aa4bba2d Mon Sep 17 00:00:00 2001 From: Erik Abair Date: Fri, 17 Jun 2022 19:25:46 -0700 Subject: [PATCH] nv2a: Implement NV097_LAUNCH_TRANSFORM_PROGRAM --- hw/xbox/nv2a/nv2a.c | 1 + hw/xbox/nv2a/nv2a_int.h | 1 + hw/xbox/nv2a/nv2a_regs.h | 2 ++ hw/xbox/nv2a/pgraph.c | 28 ++++++++++++++++++++++++++++ hw/xbox/nv2a/pgraph_methods.h | 2 ++ hw/xbox/nv2a/thirdparty/nv2a_vsh_cpu | 2 +- 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/hw/xbox/nv2a/nv2a.c b/hw/xbox/nv2a/nv2a.c index aa75cdaa38..d862bd951c 100644 --- a/hw/xbox/nv2a/nv2a.c +++ b/hw/xbox/nv2a/nv2a.c @@ -487,6 +487,7 @@ static const VMStateDescription vmstate_nv2a = { VMSTATE_UINT64(pgraph.dma_vertex_a, NV2AState), VMSTATE_UINT64(pgraph.dma_vertex_b, NV2AState), VMSTATE_UINT32(pgraph.primitive_mode, NV2AState), + VMSTATE_UINT32_ARRAY(pgraph.vertex_state_shader_v0, NV2AState, 4), VMSTATE_UINT32_2DARRAY(pgraph.program_data, NV2AState, NV2A_MAX_TRANSFORM_PROGRAM_LENGTH, VSH_TOKEN_SIZE), VMSTATE_UINT32_2DARRAY(pgraph.vsh_constants, NV2AState, NV2A_VERTEXSHADER_CONSTANTS, 4), VMSTATE_BOOL_ARRAY(pgraph.vsh_constants_dirty, NV2AState, NV2A_VERTEXSHADER_CONSTANTS), diff --git a/hw/xbox/nv2a/nv2a_int.h b/hw/xbox/nv2a/nv2a_int.h index a09ed29e0b..c46a42db05 100644 --- a/hw/xbox/nv2a/nv2a_int.h +++ b/hw/xbox/nv2a/nv2a_int.h @@ -331,6 +331,7 @@ typedef struct PGRAPHState { bool enable_vertex_program_write; + uint32_t vertex_state_shader_v0[4]; uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE]; bool program_data_dirty; diff --git a/hw/xbox/nv2a/nv2a_regs.h b/hw/xbox/nv2a/nv2a_regs.h index 40e324f558..252b89c83e 100644 --- a/hw/xbox/nv2a/nv2a_regs.h +++ b/hw/xbox/nv2a/nv2a_regs.h @@ -1241,6 +1241,8 @@ # define NV097_SET_SHADER_STAGE_PROGRAM 0x00001E70 # define NV097_SET_DOT_RGBMAPPING 0X00001E74 # define NV097_SET_SHADER_OTHER_STAGE_INPUT 0x00001E78 +# define NV097_SET_TRANSFORM_DATA 0x00001E80 +# define NV097_LAUNCH_TRANSFORM_PROGRAM 0x00001E90 # define NV097_SET_TRANSFORM_EXECUTION_MODE 0x00001E94 # define NV097_SET_TRANSFORM_EXECUTION_MODE_MODE 0x00000003 # define NV097_SET_TRANSFORM_EXECUTION_MODE_RANGE_MODE 0xFFFFFFFC diff --git a/hw/xbox/nv2a/pgraph.c b/hw/xbox/nv2a/pgraph.c index 4fd01b781c..9f7ccfb33d 100644 --- a/hw/xbox/nv2a/pgraph.c +++ b/hw/xbox/nv2a/pgraph.c @@ -21,6 +21,7 @@ #include "nv2a_int.h" +#include "nv2a_vsh_emulator.h" #include "s3tc.h" #include "ui/xemu-settings.h" #include "qemu/fast-hash.h" @@ -3689,6 +3690,33 @@ DEF_METHOD(NV097, SET_SHADER_OTHER_STAGE_INPUT) GET_MASK(parameter, 0xFFFF000)); } +DEF_METHOD_INC(NV097, SET_TRANSFORM_DATA) +{ + int slot = (method - NV097_SET_TRANSFORM_DATA) / 4; + pg->vertex_state_shader_v0[slot] = parameter; +} + +DEF_METHOD(NV097, LAUNCH_TRANSFORM_PROGRAM) +{ + unsigned int program_start = parameter; + assert(program_start < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH); + Nv2aVshProgram program; + Nv2aVshParseResult result = nv2a_vsh_parse_program( + &program, + pg->program_data[program_start], + NV2A_MAX_TRANSFORM_PROGRAM_LENGTH - program_start); + assert(result == NV2AVPR_SUCCESS); + + Nv2aVshCPUXVSSExecutionState state_linkage; + Nv2aVshExecutionState state = nv2a_vsh_emu_initialize_xss_execution_state( + &state_linkage, (float*)pg->vsh_constants); + memcpy(state_linkage.input_regs, pg->vertex_state_shader_v0, sizeof(pg->vertex_state_shader_v0)); + + nv2a_vsh_emu_execute_track_context_writes(&state, &program, pg->vsh_constants_dirty); + + nv2a_vsh_program_destroy(&program); +} + DEF_METHOD(NV097, SET_TRANSFORM_EXECUTION_MODE) { SET_MASK(pg->regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_MODE, diff --git a/hw/xbox/nv2a/pgraph_methods.h b/hw/xbox/nv2a/pgraph_methods.h index 16c5b2cca2..0d0bb1d7e9 100644 --- a/hw/xbox/nv2a/pgraph_methods.h +++ b/hw/xbox/nv2a/pgraph_methods.h @@ -182,6 +182,8 @@ DEF_METHOD(NV097, SET_SHADOW_DEPTH_FUNC) DEF_METHOD(NV097, SET_SHADER_STAGE_PROGRAM) DEF_METHOD(NV097, SET_DOT_RGBMAPPING) DEF_METHOD(NV097, SET_SHADER_OTHER_STAGE_INPUT) +DEF_METHOD_RANGE(NV097, SET_TRANSFORM_DATA, 4) +DEF_METHOD(NV097, LAUNCH_TRANSFORM_PROGRAM) DEF_METHOD(NV097, SET_TRANSFORM_EXECUTION_MODE) DEF_METHOD(NV097, SET_TRANSFORM_PROGRAM_CXT_WRITE_EN) DEF_METHOD(NV097, SET_TRANSFORM_PROGRAM_LOAD) diff --git a/hw/xbox/nv2a/thirdparty/nv2a_vsh_cpu b/hw/xbox/nv2a/thirdparty/nv2a_vsh_cpu index 89e6ec8526..ead0af5dee 160000 --- a/hw/xbox/nv2a/thirdparty/nv2a_vsh_cpu +++ b/hw/xbox/nv2a/thirdparty/nv2a_vsh_cpu @@ -1 +1 @@ -Subproject commit 89e6ec852601b77f3c097014af4d29720ab59721 +Subproject commit ead0af5dee49e408c005151393f8a7dbcd27026c