diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index 585931c544..10511e6b98 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -200,6 +200,7 @@ std::string VertexProgramDecompiler::Format(const std::string& code) { "$1", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 1) }, { "$2", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 2) }, { "$s", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 2) }, + { "$awm", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrRegWithoutMask), this) }, { "$am", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrMask), this) }, { "$a", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrReg), this) }, @@ -328,7 +329,12 @@ std::string VertexProgramDecompiler::AddAddrMask() std::string VertexProgramDecompiler::AddAddrReg() { static const char f[] = { 'x', 'y', 'z', 'w' }; - return m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), "a" + std::to_string(d0.addr_reg_sel_1), getFloatTypeName(4) + "(0, 0, 0, 0)") + AddAddrMask(); + return m_parr.AddParam(PF_PARAM_NONE, getIntTypeName(4), "a" + std::to_string(d0.addr_reg_sel_1), getFloatTypeName(4) + "(0, 0, 0, 0)") + AddAddrMask(); +} + +std::string VertexProgramDecompiler::AddAddrRegWithoutMask() +{ + return m_parr.AddParam(PF_PARAM_NONE, getIntTypeName(4), "a" + std::to_string(d0.addr_reg_sel_1), getFloatTypeName(4) + "(0, 0, 0, 0)"); } u32 VertexProgramDecompiler::GetAddr() @@ -657,7 +663,8 @@ std::string VertexProgramDecompiler::Decompile() case RSX_VEC_OPCODE_MAX: SetDSTVec("max($0, $1)"); break; case RSX_VEC_OPCODE_SLT: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SLT, "$0", "$1") + ")"); break; case RSX_VEC_OPCODE_SGE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SGE, "$0", "$1") + ")"); break; - case RSX_VEC_OPCODE_ARL: AddCode("$ifcond $a = " + getIntTypeName(4) + "($0)$am;"); break; + // Note: It looks like ARL opcode ignore input/output swizzle mask (SH3) + case RSX_VEC_OPCODE_ARL: AddCode("$ifcond $awm = " + getIntTypeName(4) + "($0);"); break; case RSX_VEC_OPCODE_FRC: SetDSTVec(getFunction(FUNCTION::FUNCTION_FRACT)); break; case RSX_VEC_OPCODE_FLR: SetDSTVec("floor($0)"); break; case RSX_VEC_OPCODE_SEQ: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SEQ, "$0", "$1") + ")"); break; diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h index 6fbe1807e0..24daff2979 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h @@ -64,6 +64,7 @@ struct VertexProgramDecompiler std::string GetCond(); std::string AddAddrMask(); std::string AddAddrReg(); + std::string AddAddrRegWithoutMask(); u32 GetAddr(); std::string Format(const std::string& code); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 4335bf19ff..f0a4cd6ef1 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -200,12 +200,15 @@ namespace rsx { force_inline static void impl(thread* rsxthr, u32 arg) { - u32& load = method_registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; + u32 load = method_registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; static const size_t count = 4; static const size_t size = count * sizeof(f32); - memcpy(rsxthr->transform_constants[load++].rgba, method_registers + NV4097_SET_TRANSFORM_CONSTANT + index * count, size); + size_t reg = index / 4; + size_t subreg = index % 4; + + memcpy(rsxthr->transform_constants[load + reg].rgba + subreg, method_registers + NV4097_SET_TRANSFORM_CONSTANT + reg * count + subreg, sizeof(f32)); } }; @@ -567,6 +570,9 @@ namespace rsx rsx->gcm_current_buffer = arg; rsx->flip(arg); + // After each flip PS3 system is executing a routine that changes registers value to some default. + // Some game use this default state (SH3). + rsx->reset(); rsx->last_flip_time = get_system_time() - 1000000; rsx->gcm_current_buffer = arg; @@ -726,7 +732,7 @@ namespace rsx bind_range(); bind_range(); bind_range(); - bind_range(); + bind_range(); bind_range(); bind_cpu_only(); bind_cpu_only(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 03812a55cf..02f1de3183 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -468,15 +468,20 @@ void SetupRsxRenderingStates(vm::ptr& cntxt) { //TODO: use cntxt GSRender& r = Emu.GetGSManager().GetRender(); - rsx::method_registers[NV4097_SET_COLOR_MASK] = -1; - rsx::method_registers[NV4097_SET_DEPTH_MASK] = 0; - rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; - rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; - rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = false; + + // FIXME: only RSX Thread can write rsx::method_registers + // Others threads must fill the command buffer or use another + // mechanism. + +// rsx::method_registers[NV4097_SET_COLOR_MASK] = -1; +// rsx::method_registers[NV4097_SET_DEPTH_MASK] = 0; +// rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; +// rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; +// rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = false; // r.m_set_logic_op = false; - rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false; +// rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false; // r.m_set_depth_bounds_test = false; - rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; +// rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; // r.m_set_poly_offset_fill = false; // r.m_set_stencil_test = false; // r.m_set_two_sided_stencil_test_enable = false; @@ -486,8 +491,8 @@ void SetupRsxRenderingStates(vm::ptr& cntxt) // r.m_set_shade_mode = true; r.m_shade_mode = CELL_GCM_SMOOTH; // r.m_set_frequency_divider_operation = CELL_GCM_FREQUENCY_DIVIDE; - rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] = s_rescInternalInstance->m_dstWidth << 16; - rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] = s_rescInternalInstance->m_dstHeight << 16; +// rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] = s_rescInternalInstance->m_dstWidth << 16; +// rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] = s_rescInternalInstance->m_dstHeight << 16; // r.m_set_scissor_horizontal = r.m_set_scissor_vertical = true; // r.m_scissor_x = 0; @@ -499,7 +504,7 @@ void SetupRsxRenderingStates(vm::ptr& cntxt) // r.m_height = s_rescInternalInstance->m_dstHeight; // r.m_surface_depth_format = 2; - rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET] = 1; +// rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET] = 1; if (IsPalInterpolate()) { @@ -535,10 +540,14 @@ void SetupSurfaces(vm::ptr& cntxt) GSRender& r = Emu.GetGSManager().GetRender(); + // FIXME: only RSX Thread can write rsx::method_registers + // Others threads must fill the command buffer or use another + // mechanism. + // r.m_surface_type = CELL_GCM_SURFACE_PITCH; // r.m_surface_antialias = CELL_GCM_SURFACE_CENTER_1; // r.m_surface_color_format = (u8)s_rescInternalInstance->m_pRescDsts->format; - rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET] = (!isMrt) ? CELL_GCM_SURFACE_TARGET_0 : CELL_GCM_SURFACE_TARGET_MRT1; +/* rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET] = (!isMrt) ? CELL_GCM_SURFACE_TARGET_0 : CELL_GCM_SURFACE_TARGET_MRT1; //surface.colorLocation[0] = CELL_GCM_LOCATION_LOCAL; rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET] = dstOffset0; rsx::method_registers[NV4097_SET_SURFACE_PITCH_A] = s_rescInternalInstance->m_dstPitch; @@ -557,7 +566,7 @@ void SetupSurfaces(vm::ptr& cntxt) rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z] = 64; // r.m_surface_width = s_rescInternalInstance->m_dstWidth; // r.m_surface_height = s_rescInternalInstance->m_dstHeight; -// r.m_surface_clip_x = 0; +// r.m_surface_clip_x = 0;*/ // r.m_surface_clip_y = 0; }