Skip to content

Commit

Permalink
Added Latent Sync auto-bias tuning parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaldaien committed Oct 8, 2023
1 parent cee4fd9 commit c6bc0fd
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 19 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
23.10.8
23.10.8.1
=========
+ Added Auto-Bias tuning parameters to Latent Sync to control the maximum
input bias to apply, as well as the target input latency.

23.10.8
=======
+ Merge pull request #105 from Aemony/tlr-steamapi-fix
* Expect 85 KB minimum for steam_api.dll
Expand Down
4 changes: 2 additions & 2 deletions include/SpecialK/DLL_VERSION.H
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#define SK_YEAR 23
#define SK_MONTH 10
#define SK_DATE 8
#define SK_REV_N 0
#define SK_REV 0
#define SK_REV_N 1
#define SK_REV 1

#ifndef _A2
#define _A2(a) #a
Expand Down
2 changes: 2 additions & 0 deletions include/SpecialK/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,8 @@ struct sk_config_t
int scanline_error = 1;
float delay_bias = 0.0f;
bool auto_bias = false;
float max_auto_bias = 0.75f;
float auto_bias_target = 0.85f;
bool show_fcat_bars = false; // Not INI-persistent

bool flush_before_present = true;
Expand Down
16 changes: 15 additions & 1 deletion src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ struct {
sk::ParameterInt* error = nullptr;
sk::ParameterFloat* bias = nullptr;
sk::ParameterBool* auto_bias = nullptr;
sk::ParameterFloat* max_auto_bias = nullptr;
sk::ParameterFloat* auto_bias_target = nullptr;
} latent_sync;
} framerate;

Expand Down Expand Up @@ -1557,7 +1559,11 @@ auto DeclKeybind =
ConfigEntry (render.framerate.latent_sync.resync, L"Frequency (in frames) to Resync Timing", dll_ini, L"FrameRate.LatentSync", L"ResyncFrequency"),
ConfigEntry (render.framerate.latent_sync.error, L"Expected Error (in QPC ticks) of Refresh Rate Calculation", dll_ini, L"FrameRate.LatentSync", L"RoundingError"),
ConfigEntry (render.framerate.latent_sync.bias, L"Controls Distribution of Idle Time Per-Delayed Frame", dll_ini, L"FrameRate.LatentSync", L"DelayBias"),
ConfigEntry (render.framerate.latent_sync.auto_bias, L"Automatically Sets Delay Bias For Minimum Latency", dll_ini, L"FrameRate.latentSync", L"AutoBias"),
ConfigEntry (render.framerate.latent_sync.auto_bias, L"Automatically Sets Delay Bias For Minimum Latency", dll_ini, L"FrameRate.LatentSync", L"AutoBias"),
ConfigEntry (render.framerate.latent_sync.
auto_bias_target, L"Target input latency (in milliseconds) for auto-bias", dll_ini, L"FrameRate.LatentSync", L"AutoBiasTargetInMs"),
ConfigEntry (render.framerate.latent_sync.
max_auto_bias, L"Maximum percentage to bias towards low input latency", dll_ini, L"FrameRate.LatentSync", L"MaxAutoBias"),

ConfigEntry (render.framerate.allow_dwm_tearing, L"Enable DWM Tearing (Windows 10+)", dll_ini, L"Render.DXGI", L"AllowTearingInDWM"),
ConfigEntry (render.framerate.drop_late_frames, L"Enable Flip Model to Render (and drop) frames at rates >"
Expand Down Expand Up @@ -3366,6 +3372,10 @@ auto DeclKeybind =
render.framerate.latent_sync.error->load (config.render.framerate.latent_sync.scanline_error);
render.framerate.latent_sync.bias->load (config.render.framerate.latent_sync.delay_bias);
render.framerate.latent_sync.auto_bias->load(config.render.framerate.latent_sync.auto_bias);
render.framerate.latent_sync.max_auto_bias
->load (config.render.framerate.latent_sync.max_auto_bias);
render.framerate.latent_sync.auto_bias_target
->load (config.render.framerate.latent_sync.auto_bias_target);



Expand Down Expand Up @@ -5178,6 +5188,10 @@ SK_SaveConfig ( std::wstring name,
render.framerate.latent_sync.error->store (config.render.framerate.latent_sync.scanline_error);
render.framerate.latent_sync.bias->store (config.render.framerate.latent_sync.delay_bias);
render.framerate.latent_sync.auto_bias->store (config.render.framerate.latent_sync.auto_bias);
render.framerate.latent_sync.max_auto_bias
->store (config.render.framerate.latent_sync.max_auto_bias);
render.framerate.latent_sync.auto_bias_target
->store (config.render.framerate.latent_sync.auto_bias_target);

texture.d3d9.clamp_lod_bias->store (config.textures.clamp_lod_bias);

Expand Down
53 changes: 38 additions & 15 deletions src/framerate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,34 @@ SK_ImGui_LatentSyncConfig (void)
ImGui::SameLine ();
ImGui::Spacing ();
ImGui::SameLine ();

ImGui::Checkbox ("Auto Bias", &config.render.framerate.latent_sync.auto_bias);

if (ImGui::IsItemHovered ())
{
ImGui::SetTooltip ("Experimental, may lead to visible tearing during extreme CPU/GPU load changes.");
}

if (config.render.framerate.latent_sync.auto_bias)
{
float fBiasPercent = config.render.framerate.latent_sync.max_auto_bias * 100.0f;

if (ImGui::SliderFloat ("Maximum Bias", &fBiasPercent, 0.0f, 90.0f, "%4.1f%%"))
config.render.framerate.latent_sync.max_auto_bias = fBiasPercent > 0.0f ? fBiasPercent / 100.0f
: 0.0f;

if (ImGui::InputFloat ("Target Input Latency (ms)", &config.render.framerate.latent_sync.auto_bias_target))
{
config.render.framerate.latent_sync.auto_bias_target =
std::clamp (config.render.framerate.latent_sync.auto_bias_target, 0.0f, 25.0f);
}

if (ImGui::IsItemHovered ())
ImGui::SetTooltip ("Setting this too low is likely to cause visible tearing and possible framerate instability.");
}

ImGui::Separator ();

ImGui::Checkbox ("Allow Tearing", &config.render.dxgi.allow_tearing);

if (ImGui::IsItemHovered ())
Expand All @@ -484,17 +512,12 @@ SK_ImGui_LatentSyncConfig (void)
ImGui::EndTooltip ();
}

ImGui::Checkbox ("Auto Delay Bias", &config.render.framerate.latent_sync.auto_bias);

if (ImGui::IsItemHovered ())
{
ImGui::SetTooltip ("Experimental, may lead to visible tearing during extreme CPU/GPU load changes.");
}

ImGui::Separator ();

if (config.render.dxgi.allow_tearing)
{
ImGui::SameLine ();
ImGui::SeparatorEx (ImGuiSeparatorFlags_Vertical);
ImGui::SameLine ();

ImGui::Checkbox ("Visualize Tearlines", &config.render.framerate.latent_sync.show_fcat_bars);

if (ImGui::IsItemHovered ())
Expand Down Expand Up @@ -1852,7 +1875,7 @@ SK::Framerate::Limiter::wait (void)

else if (config.render.framerate.latent_sync.auto_bias)
{
static constexpr int _MAX_FRAMES = 8;
static constexpr int _MAX_FRAMES = 6;

struct {
double input [_MAX_FRAMES] = { };
Expand Down Expand Up @@ -1895,16 +1918,16 @@ SK::Framerate::Limiter::wait (void)
latency_avg.display [latency_avg.frames++ % _MAX_FRAMES] =
effective_frametime ();

if (latency_avg.getInput () > 0.333)
if (latency_avg.getInput () > (config.render.framerate.latent_sync.auto_bias_target * 1.05f))
{
config.render.framerate.latent_sync.delay_bias += 0.003f;
config.render.framerate.latent_sync.delay_bias += static_cast <float> (effective_frametime () * 0.00025);
}

else
config.render.framerate.latent_sync.delay_bias -= 0.01f;
else if (latency_avg.getInput () < (config.render.framerate.latent_sync.auto_bias_target * .95f))
config.render.framerate.latent_sync.delay_bias -= static_cast <float> (effective_frametime () * 0.001);

config.render.framerate.latent_sync.delay_bias =
std::clamp (config.render.framerate.latent_sync.delay_bias, 0.0f, 1.0f);
std::clamp (config.render.framerate.latent_sync.delay_bias, 0.0f, config.render.framerate.latent_sync.max_auto_bias);

__SK_LatentSyncPostDelay =
(config.render.framerate.latent_sync.delay_bias == 0.0f) ? 0
Expand Down

0 comments on commit c6bc0fd

Please sign in to comment.