rsx: Do not overflow the program buffer!

- Some games overflow the program buffer e.g Resistance games
  The observed overflow is one instruction longer, likely an engine bug
with counting instructions
This commit is contained in:
kd-11 2018-08-17 21:59:56 +03:00 committed by kd-11
parent dd21e43ed5
commit 7915dcb23c
2 changed files with 16 additions and 2 deletions

View file

@ -348,7 +348,7 @@ namespace rsx
if (address >= 468) if (address >= 468)
{ {
// Ignore addresses outside the usable [0, 467] range // Ignore addresses outside the usable [0, 467] range
LOG_ERROR(RSX, "Invalid transform register index (load=%d, index=%d)", load, index); LOG_WARNING(RSX, "Invalid transform register index (load=%d, index=%d)", load, index);
return; return;
} }
@ -367,6 +367,15 @@ namespace rsx
{ {
static void impl(thread* rsx, u32 _reg, u32 arg) static void impl(thread* rsx, u32 _reg, u32 arg)
{ {
if (rsx::method_registers.transform_program_load() >= 512)
{
// PS3 seems to allow exceeding the program buffer by upto 32 instructions before crashing
// Discard the "excess" instructions to not overflow our transform program buffer
// TODO: Check if the instructions in the overflow area are executed by PS3
LOG_WARNING(RSX, "Program buffer overflow!");
return;
}
method_registers.commit_4_transform_program_instructions(index); method_registers.commit_4_transform_program_instructions(index);
rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty; rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty;
} }

View file

@ -1181,6 +1181,11 @@ namespace rsx
return u16(registers[NV308A_SIZE_OUT] & 0xFFFF); return u16(registers[NV308A_SIZE_OUT] & 0xFFFF);
} }
u32 transform_program_load()
{
return registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD];
}
void commit_4_transform_program_instructions(u32 index) void commit_4_transform_program_instructions(u32 index)
{ {
u32& load = registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD]; u32& load = registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD];
@ -1194,7 +1199,7 @@ namespace rsx
u32 transform_constant_load() u32 transform_constant_load()
{ {
return decode<NV4097_SET_TRANSFORM_CONSTANT_LOAD>().transform_constant_load(); return registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD];
} }
u32 transform_branch_bits() u32 transform_branch_bits()