Skip to content

Commit 551e077

Browse files
committed
Add back callspot switching + prevent use after free in LFX
Thanks to @koffiato for all the testing in: https://github.com/cdozdil/OptiScaler/issues/523
1 parent 23be402 commit 551e077

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

src/low_latency_tech/ll_antilag2.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ inline HRESULT AntiLag2::al2_sleep() {
3030

3131
// log_event("al2_sleep", "{}", get_timestamp() - pre_sleep);
3232

33+
spdlog::trace("AntiLag 2 Call Spot: {}", current_call_spot == CallSpot::SimulationStart ? "SimulationStart" : "SleepCall");
34+
3335
return result;
3436
}
3537

@@ -101,13 +103,22 @@ void AntiLag2::set_sleep_mode(SleepMode* sleep_mode) {
101103
}
102104

103105
void AntiLag2::sleep() {
106+
last_sleep_framecount = simulation_framecount;
107+
104108
if (current_call_spot == CallSpot::SleepCall)
105109
al2_sleep();
106110
}
107111

108112
void AntiLag2::set_marker(IUnknown* pDevice, MarkerParams* marker_params) {
109113
switch(marker_params->marker_type) {
110114
case MarkerType::SIMULATION_START:
115+
simulation_framecount++;
116+
117+
if (last_sleep_framecount + call_spot_switch_threshold < simulation_framecount)
118+
current_call_spot = CallSpot::SimulationStart;
119+
else
120+
current_call_spot = CallSpot::SleepCall;
121+
111122
if (current_call_spot == CallSpot::SimulationStart)
112123
al2_sleep();
113124
break;

src/low_latency_tech/ll_antilag2.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ class AntiLag2 : public virtual LowLatencyTech {
1111
AMD::AntiLag2DX11::Context dx11_ctx = {};
1212

1313
uint32_t minimum_interval_us = 0;
14+
15+
uint64_t last_sleep_framecount = 0;
16+
uint64_t simulation_framecount = 0;
17+
const uint64_t call_spot_switch_threshold = 20;
1418

1519
HRESULT al2_sleep();
1620

src/low_latency_tech/ll_latencyflex.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ void LatencyFlex::lfx_sleep(uint64_t reflex_frame_id) {
1919
eepy(200000000ULL);
2020
frame_id = 1;
2121
needs_reset = false;
22-
ctx->Reset();
22+
23+
if (ctx)
24+
ctx->Reset();
2325
}
2426

2527
uint64_t current_timestamp = get_timestamp();
@@ -33,7 +35,8 @@ void LatencyFlex::lfx_sleep(uint64_t reflex_frame_id) {
3335
mutex.lock();
3436
auto local_frame_id = lfx_mode == LFXMode::ReflexIDs ? reflex_frame_id : this->frame_id + 1;
3537
// log_event("lfx_get_wait_target", "{}", frame_id);
36-
target = ctx->GetWaitTarget(local_frame_id);
38+
if (ctx)
39+
target = ctx->GetWaitTarget(local_frame_id);
3740
mutex.unlock();
3841

3942
if (target > current_timestamp) {
@@ -55,10 +58,13 @@ void LatencyFlex::lfx_sleep(uint64_t reflex_frame_id) {
5558
timestamp = current_timestamp;
5659
}
5760

61+
spdlog::trace("LatencyFlex Call Spot: {}", current_call_spot == CallSpot::SimulationStart ? "SimulationStart" : "SleepCall");
62+
5863
mutex.lock();
5964
this->frame_id++;
6065
// log_event("lfx_beginframe", "{}", frame_id);
61-
ctx->BeginFrame(local_frame_id, target, timestamp);
66+
if (ctx)
67+
ctx->BeginFrame(local_frame_id, target, timestamp);
6268
mutex.unlock();
6369
}
6470

@@ -67,7 +73,8 @@ void LatencyFlex::lfx_end_frame(uint64_t reflex_frame_id) {
6773
mutex.lock();
6874
auto frame_id = Config::get().get_latencyflex_mode() == LFXMode::ReflexIDs ? reflex_frame_id : this->frame_id;
6975
// log_event("lfx_endframe", "{}", frame_id);
70-
ctx->EndFrame(frame_id, current_timestamp, &latency, &frame_time);
76+
if (ctx)
77+
ctx->EndFrame(frame_id, current_timestamp, &latency, &frame_time);
7178
mutex.unlock();
7279
spdlog::trace("LFX latency: {}, frame_time: {}, current_timestamp: {}", latency, frame_time, current_timestamp);
7380
}
@@ -112,13 +119,24 @@ void LatencyFlex::set_sleep_mode(SleepMode* sleep_mode) {
112119
};
113120

114121
void LatencyFlex::sleep() {
115-
if (current_call_spot == CallSpot::SleepCall && Config::get().get_latencyflex_mode() != LFXMode::ReflexIDs)
116-
lfx_sleep(INVALID_ID);
122+
if (Config::get().get_latencyflex_mode() != LFXMode::ReflexIDs) {
123+
last_sleep_framecount = simulation_framecount;
124+
125+
if (current_call_spot == CallSpot::SleepCall)
126+
lfx_sleep(INVALID_ID);
127+
}
117128
};
118129

119130
void LatencyFlex::set_marker(IUnknown* pDevice, MarkerParams* marker_params) {
120131
switch(marker_params->marker_type) {
121132
case MarkerType::SIMULATION_START:
133+
simulation_framecount++;
134+
135+
if (last_sleep_framecount + call_spot_switch_threshold < simulation_framecount)
136+
current_call_spot = CallSpot::SimulationStart;
137+
else
138+
current_call_spot = CallSpot::SleepCall;
139+
122140
if (current_call_spot == CallSpot::SimulationStart)
123141
lfx_sleep(marker_params->frame_id);
124142
break;

src/low_latency_tech/ll_latencyflex.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ class LatencyFlex : public virtual LowLatencyTech {
1212

1313
uint32_t minimum_interval_us = 0;
1414

15+
uint64_t last_sleep_framecount = 0;
16+
uint64_t simulation_framecount = 0;
17+
const uint64_t call_spot_switch_threshold = 20;
18+
1519
uint64_t latency = 0;
1620
uint64_t frame_time = 1;
1721
uint64_t target = 0;

0 commit comments

Comments
 (0)