PGXP: Make preserving pre-divide fractional coordinates an option

Fixes holes in geometry in Crash Team Racing with PGXP on.
This commit is contained in:
Connor McLaughlin 2020-10-10 00:07:07 +10:00
parent fa638ef9d2
commit 4f0007dd55
6 changed files with 43 additions and 9 deletions

View file

@ -624,16 +624,41 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
if (g_settings.gpu_pgxp_enable)
{
// this can potentially use increased precision on Z
const float precise_z = std::max<float>((float)REGS.H / 2.f, (float)z / 4096.0f);
const float precise_h_div_sz = (float)REGS.H / precise_z;
const float fofx = ((float)REGS.OFX / (float)(1 << 16));
const float fofy = ((float)REGS.OFY / (float)(1 << 16));
float precise_x = fofx + ((float)REGS.IR1 * precise_h_div_sz) * ((g_settings.gpu_widescreen_hack) ? 0.75f : 1.00f);
float precise_y = fofy + ((float)REGS.IR2 * precise_h_div_sz);
float precise_sz3, precise_ir1, precise_ir2;
precise_x = std::clamp<float>(precise_x, -0x400, 0x3ff);
precise_y = std::clamp<float>(precise_y, -0x400, 0x3ff);
if (g_settings.gpu_pgxp_preserve_proj_fp)
{
precise_sz3 = float(z) / 4096.0f;
precise_ir1 = float(x) / (static_cast<float>(1 << shift));
precise_ir2 = float(y) / (static_cast<float>(1 << shift));
if (lm)
{
precise_ir1 = std::clamp(precise_ir1, float(IR123_MIN_VALUE), float(IR123_MAX_VALUE));
precise_ir2 = std::clamp(precise_ir2, float(IR123_MIN_VALUE), float(IR123_MAX_VALUE));
}
else
{
precise_ir1 = std::min(precise_ir1, float(IR123_MAX_VALUE));
precise_ir2 = std::min(precise_ir2, float(IR123_MAX_VALUE));
}
}
else
{
precise_sz3 = float(REGS.SZ3);
precise_ir1 = float(REGS.IR1);
precise_ir2 = float(REGS.IR2);
}
// this can potentially use increased precision on Z
const float precise_z = std::max<float>(float(REGS.H) / 2.0f, precise_sz3);
const float precise_h_div_sz = float(REGS.H) / precise_z;
const float fofx = float(REGS.OFX) / float(1 << 16);
const float fofy = float(REGS.OFY) / float(1 << 16);
float precise_x = fofx + (precise_ir1 * precise_h_div_sz) * ((g_settings.gpu_widescreen_hack) ? 0.75f : 1.00f);
float precise_y = fofy + (precise_ir2 * precise_h_div_sz);
precise_x = std::clamp<float>(precise_x, -1024.0f, 1023.0f);
precise_y = std::clamp<float>(precise_y, -1024.0f, 1023.0f);
PGXP::GTE_PushSXYZ2f(precise_x, precise_y, precise_z, REGS.dr32[14]);
}

View file

@ -434,6 +434,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
si.SetBoolValue("GPU", "PGXPTextureCorrection", true);
si.SetBoolValue("GPU", "PGXPVertexCache", false);
si.SetBoolValue("GPU", "PGXPCPU", false);
si.SetBoolValue("GPU", "PGXPPreserveProjFP", false);
si.SetStringValue("Display", "CropMode", Settings::GetDisplayCropModeName(Settings::DEFAULT_DISPLAY_CROP_MODE));
si.SetIntValue("Display", "ActiveStartOffset", 0);

View file

@ -149,6 +149,7 @@ void Settings::Load(SettingsInterface& si)
gpu_pgxp_texture_correction = si.GetBoolValue("GPU", "PGXPTextureCorrection", true);
gpu_pgxp_vertex_cache = si.GetBoolValue("GPU", "PGXPVertexCache", false);
gpu_pgxp_cpu = si.GetBoolValue("GPU", "PGXPCPU", false);
gpu_pgxp_preserve_proj_fp = si.GetBoolValue("GPU", "PGXPPreserveProjFP", false);
display_crop_mode =
ParseDisplayCropMode(
@ -273,6 +274,7 @@ void Settings::Save(SettingsInterface& si) const
si.SetBoolValue("GPU", "PGXPTextureCorrection", gpu_pgxp_texture_correction);
si.SetBoolValue("GPU", "PGXPVertexCache", gpu_pgxp_vertex_cache);
si.SetBoolValue("GPU", "PGXPCPU", gpu_pgxp_cpu);
si.SetBoolValue("GPU", "PGXPPreserveProjFP", gpu_pgxp_preserve_proj_fp);
si.SetStringValue("Display", "CropMode", GetDisplayCropModeName(display_crop_mode));
si.SetIntValue("Display", "ActiveStartOffset", display_active_start_offset);

View file

@ -104,6 +104,7 @@ struct Settings
bool gpu_pgxp_texture_correction = true;
bool gpu_pgxp_vertex_cache = false;
bool gpu_pgxp_cpu = false;
bool gpu_pgxp_preserve_proj_fp = false;
DisplayCropMode display_crop_mode = DisplayCropMode::None;
s16 display_active_start_offset = 0;
s16 display_active_end_offset = 0;

View file

@ -85,6 +85,8 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(QtHostInterface* host_interface,
addBooleanTweakOption(m_host_interface, m_ui.tweakOptionTable, tr("PGXP Vertex Cache"), "GPU", "PGXPVertexCache",
false);
addBooleanTweakOption(m_host_interface, m_ui.tweakOptionTable, tr("PGXP CPU Mode"), "GPU", "PGXPCPU", false);
addBooleanTweakOption(m_host_interface, m_ui.tweakOptionTable, tr("PGXP Preserve Projection Precision"), "GPU",
"PGXPPreserveProjFP", false);
addBooleanTweakOption(m_host_interface, m_ui.tweakOptionTable, tr("Enable Recompiler Memory Exceptions"), "CPU",
"RecompilerMemoryExceptions", false);

View file

@ -959,6 +959,9 @@ void SDLHostInterface::DrawQuickSettingsMenu()
m_settings_copy.gpu_pgxp_enable);
settings_changed |=
ImGui::MenuItem("PGXP CPU Instructions", nullptr, &m_settings_copy.gpu_pgxp_cpu, m_settings_copy.gpu_pgxp_enable);
settings_changed |=
ImGui::MenuItem("PGXP Preserve Projection Precision", nullptr, &m_settings_copy.gpu_pgxp_preserve_proj_fp,
m_settings_copy.gpu_pgxp_enable);
ImGui::EndMenu();
}