Merge pull request #1290 from vlj/rsx

Rsx: Fixes
This commit is contained in:
Ivan 2015-11-15 21:29:25 +03:00
commit 6e666b63fa
4 changed files with 40 additions and 17 deletions

View file

@ -200,6 +200,7 @@ std::string VertexProgramDecompiler::Format(const std::string& code)
{ "$1", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 1) }, { "$1", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 1) },
{ "$2", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 2) }, { "$2", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 2) },
{ "$s", 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) }, { "$am", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrMask), this) },
{ "$a", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrReg), this) }, { "$a", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrReg), this) },
@ -328,7 +329,12 @@ std::string VertexProgramDecompiler::AddAddrMask()
std::string VertexProgramDecompiler::AddAddrReg() std::string VertexProgramDecompiler::AddAddrReg()
{ {
static const char f[] = { 'x', 'y', 'z', 'w' }; 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() 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_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_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_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_FRC: SetDSTVec(getFunction(FUNCTION::FUNCTION_FRACT)); break;
case RSX_VEC_OPCODE_FLR: SetDSTVec("floor($0)"); 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; case RSX_VEC_OPCODE_SEQ: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SEQ, "$0", "$1") + ")"); break;

View file

@ -64,6 +64,7 @@ struct VertexProgramDecompiler
std::string GetCond(); std::string GetCond();
std::string AddAddrMask(); std::string AddAddrMask();
std::string AddAddrReg(); std::string AddAddrReg();
std::string AddAddrRegWithoutMask();
u32 GetAddr(); u32 GetAddr();
std::string Format(const std::string& code); std::string Format(const std::string& code);

View file

@ -200,12 +200,15 @@ namespace rsx
{ {
force_inline static void impl(thread* rsxthr, u32 arg) 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 count = 4;
static const size_t size = count * sizeof(f32); 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->gcm_current_buffer = arg;
rsx->flip(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->last_flip_time = get_system_time() - 1000000;
rsx->gcm_current_buffer = arg; rsx->gcm_current_buffer = arg;
@ -726,7 +732,7 @@ namespace rsx
bind_range<NV4097_SET_VERTEX_DATA4F_M + 3, 4, 16, nv4097::set_vertex_data4f_m>(); bind_range<NV4097_SET_VERTEX_DATA4F_M + 3, 4, 16, nv4097::set_vertex_data4f_m>();
bind_range<NV4097_SET_VERTEX_DATA2S_M, 1, 16, nv4097::set_vertex_data2s_m>(); bind_range<NV4097_SET_VERTEX_DATA2S_M, 1, 16, nv4097::set_vertex_data2s_m>();
bind_range<NV4097_SET_VERTEX_DATA4S_M + 1, 2, 16, nv4097::set_vertex_data4s_m>(); bind_range<NV4097_SET_VERTEX_DATA4S_M + 1, 2, 16, nv4097::set_vertex_data4s_m>();
bind_range<NV4097_SET_TRANSFORM_CONSTANT + 3, 4, 8, nv4097::set_transform_constant>(); bind_range<NV4097_SET_TRANSFORM_CONSTANT, 1, 32, nv4097::set_transform_constant>();
bind_range<NV4097_SET_TRANSFORM_PROGRAM + 3, 4, 128, nv4097::set_transform_program>(); bind_range<NV4097_SET_TRANSFORM_PROGRAM + 3, 4, 128, nv4097::set_transform_program>();
bind_cpu_only<NV4097_GET_REPORT, nv4097::get_report>(); bind_cpu_only<NV4097_GET_REPORT, nv4097::get_report>();
bind_cpu_only<NV4097_CLEAR_REPORT_VALUE, nv4097::clear_report_value>(); bind_cpu_only<NV4097_CLEAR_REPORT_VALUE, nv4097::clear_report_value>();

View file

@ -468,15 +468,20 @@ void SetupRsxRenderingStates(vm::ptr<CellGcmContextData>& cntxt)
{ {
//TODO: use cntxt //TODO: use cntxt
GSRender& r = Emu.GetGSManager().GetRender(); GSRender& r = Emu.GetGSManager().GetRender();
rsx::method_registers[NV4097_SET_COLOR_MASK] = -1;
rsx::method_registers[NV4097_SET_DEPTH_MASK] = 0; // FIXME: only RSX Thread can write rsx::method_registers
rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; // Others threads must fill the command buffer or use another
rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; // mechanism.
rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = false;
// 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; // 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; // 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_poly_offset_fill = false;
// r.m_set_stencil_test = false; // r.m_set_stencil_test = false;
// r.m_set_two_sided_stencil_test_enable = false; // r.m_set_two_sided_stencil_test_enable = false;
@ -486,8 +491,8 @@ void SetupRsxRenderingStates(vm::ptr<CellGcmContextData>& cntxt)
// r.m_set_shade_mode = true; r.m_shade_mode = CELL_GCM_SMOOTH; // r.m_set_shade_mode = true; r.m_shade_mode = CELL_GCM_SMOOTH;
// r.m_set_frequency_divider_operation = CELL_GCM_FREQUENCY_DIVIDE; // 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_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_VERTICAL] = s_rescInternalInstance->m_dstHeight << 16;
// r.m_set_scissor_horizontal = r.m_set_scissor_vertical = true; // r.m_set_scissor_horizontal = r.m_set_scissor_vertical = true;
// r.m_scissor_x = 0; // r.m_scissor_x = 0;
@ -499,7 +504,7 @@ void SetupRsxRenderingStates(vm::ptr<CellGcmContextData>& cntxt)
// r.m_height = s_rescInternalInstance->m_dstHeight; // r.m_height = s_rescInternalInstance->m_dstHeight;
// r.m_surface_depth_format = 2; // 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()) if (IsPalInterpolate())
{ {
@ -535,10 +540,14 @@ void SetupSurfaces(vm::ptr<CellGcmContextData>& cntxt)
GSRender& r = Emu.GetGSManager().GetRender(); 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_type = CELL_GCM_SURFACE_PITCH;
// r.m_surface_antialias = CELL_GCM_SURFACE_CENTER_1; // r.m_surface_antialias = CELL_GCM_SURFACE_CENTER_1;
// r.m_surface_color_format = (u8)s_rescInternalInstance->m_pRescDsts->format; // 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; //surface.colorLocation[0] = CELL_GCM_LOCATION_LOCAL;
rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET] = dstOffset0; rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET] = dstOffset0;
rsx::method_registers[NV4097_SET_SURFACE_PITCH_A] = s_rescInternalInstance->m_dstPitch; rsx::method_registers[NV4097_SET_SURFACE_PITCH_A] = s_rescInternalInstance->m_dstPitch;
@ -557,7 +566,7 @@ void SetupSurfaces(vm::ptr<CellGcmContextData>& cntxt)
rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z] = 64; rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z] = 64;
// r.m_surface_width = s_rescInternalInstance->m_dstWidth; // r.m_surface_width = s_rescInternalInstance->m_dstWidth;
// r.m_surface_height = s_rescInternalInstance->m_dstHeight; // 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; // r.m_surface_clip_y = 0;
} }