Revert "[dxvk] Remove dxvk.lowLatencyAllowCpuFramesOverlap config variable"

This reverts commit c802bdf42e and makes small adjustments.
Until we have a proper synchronization in place between emitting Cs triggered by the app thread, and fetching them from the queue, to measure the CsThread-caused delay, this config option is still useful for running some rare CsThread-limited games.
This commit is contained in:
netborg 2025-02-28 11:23:02 +01:00
parent fd68a08572
commit 775b3dfe71
6 changed files with 36 additions and 2 deletions

View file

@ -20,6 +20,8 @@ namespace dxvk {
allowFse = config.getOption<bool> ("dxvk.allowFse", false);
framePace = config.getOption<std::string>("dxvk.framePace", "");
lowLatencyOffset = config.getOption<int32_t> ("dxvk.lowLatencyOffset", 0);
lowLatencyAllowCpuFramesOverlap
= config.getOption<bool> ("dxvk.lowLatencyAllowCpuFramesOverlap", true);
deviceFilter = config.getOption<std::string>("dxvk.deviceFilter", "");
tilerMode = config.getOption<Tristate>("dxvk.tilerMode", Tristate::Auto);
}

View file

@ -71,6 +71,7 @@ namespace dxvk {
m_mode->signalGpuStart ( firstFrameId-1 );
m_mode->signalRenderFinished ( firstFrameId-1 );
m_mode->signalCsFinished ( firstFrameId );
}

View file

@ -53,6 +53,7 @@ namespace dxvk {
auto now = high_resolution_clock::now();
LatencyMarkers* m = m_latencyMarkersStorage.getMarkers(frameId);
m->csFinished = std::chrono::duration_cast<microseconds>(now - m->start).count();
m_mode->signalCsFinished( frameId );
}
void notifySubmit( uint64_t frameId ) override {

View file

@ -44,6 +44,9 @@ namespace dxvk {
void signalGpuStart( uint64_t frameId ) {
if (m_mode) m_fenceGpuStart.signal(frameId); }
void signalCsFinished( uint64_t frameId ) {
if (m_mode) m_fenceCsFinished.signal(frameId); }
void setTargetFrameRate( double frameRate ) {
if (!m_fpsLimitEnvOverride && frameRate > 1.0)
m_fpsLimitFrametime.store( 1'000'000/frameRate );
@ -65,6 +68,7 @@ namespace dxvk {
sync::Fence m_fenceGpuStart = { sync::Fence(DXGI_MAX_SWAP_CHAIN_BUFFERS) };
sync::Fence m_fenceGpuFinished = { sync::Fence(DXGI_MAX_SWAP_CHAIN_BUFFERS) };
sync::Fence m_fenceCsFinished = { sync::Fence(DXGI_MAX_SWAP_CHAIN_BUFFERS) };
};

View file

@ -10,6 +10,15 @@ namespace dxvk {
}
bool getLowLatencyAllowCpuFramesOverlapFromEnv( bool& allowOverlap ) {
int32_t o;
if (!FramePacerMode::getIntFromEnv("DXVK_LOW_LATENCY_ALLOW_CPU_FRAMES_OVERLAP", &o))
return false;
allowOverlap = (bool) o;
return true;
}
int32_t LowLatencyMode::getLowLatencyOffset( const DxvkOptions& options ) {
int32_t offset = options.lowLatencyOffset;
int32_t o;
@ -21,4 +30,14 @@ namespace dxvk {
return offset;
}
bool LowLatencyMode::getLowLatencyAllowCpuFramesOverlap( const DxvkOptions& options ) {
bool allowOverlap = options.lowLatencyAllowCpuFramesOverlap;
bool o;
if (getLowLatencyAllowCpuFramesOverlapFromEnv(o))
allowOverlap = o;
return allowOverlap;
}
}

View file

@ -44,17 +44,21 @@ namespace dxvk {
LowLatencyMode(Mode mode, LatencyMarkersStorage* storage, const DxvkOptions& options)
: FramePacerMode(mode, storage),
m_lowLatencyOffset(getLowLatencyOffset(options)) {
m_lowLatencyOffset(getLowLatencyOffset(options)),
m_allowCpuFramesOverlap(getLowLatencyAllowCpuFramesOverlap(options)) {
Logger::info( str::format("Using lowLatencyOffset: ", m_lowLatencyOffset) );
Logger::info( str::format("Using lowLatencyAllowCpuFramesOverlap: ", m_allowCpuFramesOverlap) );
}
~LowLatencyMode() {}
void startFrame( uint64_t frameId ) override {
using std::chrono::duration_cast;
if (!m_allowCpuFramesOverlap)
m_fenceCsFinished.wait( frameId-1 );
m_fenceGpuStart.wait( frameId-1 );
time_point now = high_resolution_clock::now();
@ -227,7 +231,10 @@ namespace dxvk {
int32_t getLowLatencyOffset( const DxvkOptions& options );
bool getLowLatencyAllowCpuFramesOverlap( const DxvkOptions& options );
const int32_t m_lowLatencyOffset;
const bool m_allowCpuFramesOverlap;
Sleep::TimePoint m_lastStart = { high_resolution_clock::now() };
std::array<SyncProps, 16> m_props;