Skip to content

Commit

Permalink
Added Adaptive Tearing options and enabled Latent Sync 2x.. modes
Browse files Browse the repository at this point in the history
  • Loading branch information
Nustat0 committed Feb 8, 2025
1 parent 67fba4d commit 633c54e
Show file tree
Hide file tree
Showing 11 changed files with 2,436 additions and 269 deletions.
14 changes: 13 additions & 1 deletion include/SpecialK/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ enum SK_FrametimeMethod
SK_FrametimeMeasures_NewFrameBegin = 2
};

enum SK_TearingMode
{
AlwaysOn = 0,
AlwaysOff = 1,
AlwaysOff_LowLatency = 2,
AdaptiveOn = 3,
AdaptiveOff = 4, // Adaptive VSync
AppControlled = SK_NoPreference
};

struct sk_config_t
{
sk_config_t (void)
Expand Down Expand Up @@ -696,6 +706,7 @@ struct sk_config_t
int pre_render_limit = SK_NoPreference;
int present_interval = SK_NoPreference;
int sync_interval_clamp = SK_NoPreference;
int tearing_mode = SK_NoPreference;
int buffer_count = SK_NoPreference;
int max_delta_time = 0; // Bad old setting; needs to be phased
int swapchain_wait = 0;
Expand All @@ -708,6 +719,7 @@ struct sk_config_t
} rescan_;
int refresh_denom = 1;
int pin_render_thread = SK_NoPreference;
bool turn_vsync_off = false; // Turns VSync Off in Adaptive VSync mode
bool flip_discard = true; // Enabled by default (7/6/21)
bool flip_sequential = false;
bool disable_flip = false;
Expand Down Expand Up @@ -758,7 +770,7 @@ struct sk_config_t
}, L"ToggleFCATBars"
};
int scanline_offset = -1;
int scanline_resync = 750;
float scanline_resync = 30.0f;
int scanline_error = 1;
float delay_bias = 0.0f;
bool auto_bias = false;
Expand Down
1 change: 1 addition & 0 deletions include/SpecialK/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ bool SK_API_IsDXGIBased (SK_RenderAPI api);
bool SK_API_IsGDIBased (SK_RenderAPI api);
bool SK_API_IsDirect3D9 (SK_RenderAPI api);
bool SK_API_IsPlugInBased (SK_RenderAPI api);
bool SK_API_IsLayeredOnD3D10 (SK_RenderAPI api);
bool SK_API_IsLayeredOnD3D11 (SK_RenderAPI api);
bool SK_API_IsLayeredOnD3D12 (SK_RenderAPI api);

Expand Down
3 changes: 3 additions & 0 deletions include/SpecialK/framerate.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,8 @@ SK_DWM_GetCompositionTimingInfo (DWM_TIMING_INFO *pTimingInfo);
void SK_Framerate_WaitUntilQPC (LONGLONG llQPC, HANDLE& hTimer);
void SK_Framerate_EnergyControlPanel (void);

bool SK_LatentSync_AllowFrameSkip (void);

void SK_ImGui_DrawGraph_FramePacing (void);
void SK_ImGui_DrawFramePercentiles (void);
void SK_ImGui_DrawGraph_Latency (bool predraw);
Expand All @@ -817,6 +819,7 @@ extern int __SK_LatentSyncSkip;

extern float __target_fps;
extern float __target_fps_bg;
extern float __target_fps_temp;

extern LONGLONG __SK_LatentSyncPostDelay;

Expand Down
23 changes: 23 additions & 0 deletions src/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,29 @@ SK_ICommandProcessor::ProcessCommandLine (const char* szCommandLine)
(float)strtof (&cmd_args.c_str ()[2], nullptr);
}
/* Assign */
else if ( cmd_args.find ('/') != std::string::npos)
{
if ( cmd_word == "BackgroundFPS" ||
cmd_word == "TargetFPS" )
{
int numerator = 1, denominator = 1;

sscanf (cmd_args.c_str (), "%i/%i", &numerator, &denominator);

if (denominator != 0)
{
float_val = static_cast <float> (
( SK_GetCurrentRenderBackend ()
.windows
.device
.getDevCaps ()
.res
.refresh * numerator
) / denominator
);
}
}
}
else
float_val = (float)strtof (cmd_args.c_str (), nullptr);

Expand Down
44 changes: 28 additions & 16 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ struct {
sk::ParameterInt* prerender_limit = nullptr;
sk::ParameterInt* present_interval = nullptr;
sk::ParameterInt* sync_interval_clamp = nullptr;
sk::ParameterInt* tearing_mode = nullptr;
sk::ParameterInt* buffer_count = nullptr;
sk::ParameterInt* max_delta_time = nullptr;
sk::ParameterBool* flip_discard = nullptr;
Expand Down Expand Up @@ -893,7 +894,7 @@ struct {
struct
{
sk::ParameterInt* offset = nullptr;
sk::ParameterInt* resync = nullptr;
sk::ParameterFloat* resync = nullptr;
sk::ParameterInt* error = nullptr;
sk::ParameterFloat* bias = nullptr;
sk::ParameterBool* auto_bias = nullptr;
Expand Down Expand Up @@ -1949,6 +1950,7 @@ auto DeclKeybind =
ConfigEntry (render.framerate.buffer_count, L"Number of Backbuffers in the Swapchain", dll_ini, L"Render.FrameRate", L"BackBufferCount"),
ConfigEntry (render.framerate.present_interval, L"Presentation Interval (VSYNC)", dll_ini, L"Render.FrameRate", L"PresentationInterval"),
ConfigEntry (render.framerate.sync_interval_clamp, L"Maximum Sync Interval (Clamp VSYNC)", dll_ini, L"Render.FrameRate", L"SyncIntervalClamp"),
ConfigEntry (render.framerate.tearing_mode, L"Tearing Mode (Always On/Off or Adaptive)", dll_ini, L"Render.FrameRate", L"TearingMode"),
ConfigEntry (render.framerate.prerender_limit, L"Maximum Frames to Render-Ahead", dll_ini, L"Render.FrameRate", L"PreRenderLimit"),
ConfigEntry (render.framerate.sleepless_render, L"Sleep Free Render Thread", dll_ini, L"Render.FrameRate", L"SleeplessRenderThread"),
ConfigEntry (render.framerate.sleepless_window, L"Sleep Free Window Thread", dll_ini, L"Render.FrameRate", L"SleeplessWindowThread"),
Expand All @@ -1963,7 +1965,7 @@ auto DeclKeybind =
ConfigEntry (render.framerate.control.render_ahead, L"Maximum number of CPU-side frames to work ahead of GPU.", dll_ini, L"FrameRate.Control", L"MaxRenderAheadFrames"),
ConfigEntry (render.framerate.override_cpu_count, L"Number of CPU cores to tell the game about", dll_ini, L"FrameRate.Control", L"OverrideCPUCoreCount"),
ConfigEntry (render.framerate.latent_sync.offset, L"Offset in Scanlines from Top of Screen to Steer Tearing", dll_ini, L"FrameRate.LatentSync", L"TearlineOffset"),
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.resync, L"Frequency (in -frames or seconds) 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"),
Expand Down Expand Up @@ -4327,16 +4329,20 @@ auto DeclKeybind =
{
if (target_fps.find (L'/') != std::wstring::npos)
{
UINT numerator = 1, denominator = 1;
int numerator = 1, denominator = 1;

swscanf (target_fps.c_str (), L"%i/%i", (INT*)&numerator, (INT*)&denominator);
swscanf (target_fps.c_str (), L"%i/%i", &numerator, &denominator);

if (denominator != 0)
{
config.render.framerate.target_fps =
static_cast <float> (
(rb.windows.device.getDevCaps ().res.refresh * numerator) / denominator
);
config.render.framerate.target_fps = static_cast <float> (
( rb.windows
.device
.getDevCaps ()
.res
.refresh * numerator
) / denominator
);
}
}

Expand All @@ -4352,16 +4358,20 @@ auto DeclKeybind =
{
if (target_fps_bg.find (L'/') != std::wstring::npos)
{
UINT numerator = 1, denominator = 1;
int numerator = 1, denominator = 1;

swscanf (target_fps_bg.c_str (), L"%i/%i", (INT*)&numerator, (INT*)&denominator);
swscanf (target_fps_bg.c_str (), L"%i/%i", &numerator, &denominator);

if (denominator != 0)
{
config.render.framerate.target_fps_bg =
static_cast <float> (
(rb.windows.device.getDevCaps ().res.refresh * numerator) / denominator
);
config.render.framerate.target_fps_bg = static_cast <float> (
( rb.windows
.device
.getDevCaps ()
.res
.refresh * numerator
) / denominator
);
}
}

Expand Down Expand Up @@ -4468,6 +4478,7 @@ auto DeclKeybind =
render.framerate.prerender_limit->load (config.render.framerate.pre_render_limit);
render.framerate.present_interval->load (config.render.framerate.present_interval);
render.framerate.sync_interval_clamp->load (config.render.framerate.sync_interval_clamp);
render.framerate.tearing_mode->load (config.render.framerate.tearing_mode);

if (render.framerate.refresh_rate)
{
Expand Down Expand Up @@ -6654,6 +6665,7 @@ SK_SaveConfig ( std::wstring name,

render.framerate.present_interval->store (config.render.framerate.present_interval);
render.framerate.sync_interval_clamp->store (config.render.framerate.sync_interval_clamp);
render.framerate.tearing_mode->store (config.render.framerate.tearing_mode);
render.framerate.enforcement_policy->store (config.render.framerate.enforcement_policy);
render.framerate.enable_etw_tracing->store (config.render.framerate.enable_etw_tracing);

Expand All @@ -6675,15 +6687,15 @@ SK_SaveConfig ( std::wstring name,

else
{
wchar_t wszPercent [16] = { };
wchar_t wszPercent [16] = { };
swprintf (wszPercent, L"%08.6f", 100.0f * config.render.framerate.latent_sync.auto_bias_target.percent);

SK_RemoveTrailingDecimalZeros (wszPercent);
lstrcatW (wszPercent, L"%");
render.framerate.latent_sync.auto_bias_target->store (wszPercent);
}

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

// SLI only works in Direct3D
// + Keep these out of the INI on non-SLI systems for simplicity
Expand Down
Loading

0 comments on commit 633c54e

Please sign in to comment.