mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-24 04:54:14 +01:00
[d3d11] Implement latency tracking
This commit is contained in:
parent
bf39c3a4bd
commit
93269aa330
@ -861,11 +861,15 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D11ImmediateContext::EndFrame() {
|
||||
void D3D11ImmediateContext::EndFrame(
|
||||
Rc<DxvkLatencyTracker> LatencyTracker) {
|
||||
D3D10DeviceLock lock = LockContext();
|
||||
|
||||
EmitCs<false>([] (DxvkContext* ctx) {
|
||||
EmitCs<false>([
|
||||
cTracker = std::move(LatencyTracker)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->endFrame();
|
||||
ctx->endLatencyTracking(cTracker);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,8 @@ namespace dxvk {
|
||||
|
||||
void SynchronizeDevice();
|
||||
|
||||
void EndFrame();
|
||||
void EndFrame(
|
||||
Rc<DxvkLatencyTracker> LatencyTracker);
|
||||
|
||||
bool WaitForResource(
|
||||
const DxvkPagedResource& Resource,
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_swapchain.h"
|
||||
|
||||
#include "../dxvk/dxvk_latency_builtin.h"
|
||||
|
||||
#include "../util/util_win32_compat.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -80,6 +82,7 @@ namespace dxvk {
|
||||
m_presenter->destroyResources();
|
||||
|
||||
DestroyFrameLatencyEvent();
|
||||
DestroyLatencyTracker();
|
||||
}
|
||||
|
||||
|
||||
@ -279,6 +282,18 @@ namespace dxvk {
|
||||
// applications using the semaphore may deadlock. This works because
|
||||
// we do not increment the frame ID in those situations.
|
||||
SyncFrameLatency();
|
||||
|
||||
// Ignore latency stuff if presentation failed
|
||||
DxvkLatencyStats latencyStats = { };
|
||||
|
||||
if (hr == S_OK && m_latency) {
|
||||
latencyStats = m_latency->getStatistics(m_frameId);
|
||||
m_latency->sleepAndBeginFrame(m_frameId + 1, std::abs(m_targetFrameRate));
|
||||
}
|
||||
|
||||
if (m_latencyHud)
|
||||
m_latencyHud->accumulateStats(latencyStats);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
@ -364,17 +379,23 @@ namespace dxvk {
|
||||
auto immediateContext = m_parent->GetContext();
|
||||
auto immediateContextLock = immediateContext->LockContext();
|
||||
|
||||
immediateContext->EndFrame();
|
||||
immediateContext->EndFrame(m_latency);
|
||||
immediateContext->Flush();
|
||||
|
||||
m_presenter->setSyncInterval(SyncInterval);
|
||||
|
||||
// Presentation semaphores and WSI swap chain image
|
||||
if (m_latency)
|
||||
m_latency->notifyCpuPresentBegin(m_frameId + 1u);
|
||||
|
||||
PresenterSync sync;
|
||||
Rc<DxvkImage> backBuffer;
|
||||
|
||||
VkResult status = m_presenter->acquireNextImage(sync, backBuffer);
|
||||
|
||||
if (status != VK_SUCCESS && m_latency)
|
||||
m_latency->discardTimings();
|
||||
|
||||
if (status < 0)
|
||||
return E_FAIL;
|
||||
|
||||
@ -402,6 +423,7 @@ namespace dxvk {
|
||||
cSwapImage = GetBackBufferView(),
|
||||
cSync = sync,
|
||||
cPresenter = m_presenter,
|
||||
cLatency = m_latency,
|
||||
cColorSpace = m_colorSpace,
|
||||
cFrameId = m_frameId
|
||||
] (DxvkContext* ctx) {
|
||||
@ -425,13 +447,27 @@ namespace dxvk {
|
||||
ctx->synchronizeWsi(cSync);
|
||||
ctx->flushCommandList(nullptr);
|
||||
|
||||
cDevice->presentImage(cPresenter, cFrameId, nullptr, 0, nullptr);
|
||||
cDevice->presentImage(cPresenter, cFrameId, cLatency, cFrameId, nullptr);
|
||||
});
|
||||
|
||||
if (m_backBuffers.size() > 1u)
|
||||
RotateBackBuffers(immediateContext);
|
||||
|
||||
immediateContext->FlushCsChunk();
|
||||
|
||||
if (m_latency) {
|
||||
m_latency->notifyCpuPresentEnd(m_frameId);
|
||||
|
||||
immediateContext->SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
||||
|
||||
immediateContext->EmitCs([
|
||||
cLatency = m_latency,
|
||||
cFrameId = m_frameId
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->beginLatencyTracking(cLatency, cFrameId + 1u);
|
||||
});
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -479,6 +515,8 @@ namespace dxvk {
|
||||
m_presenter->setSurfaceFormat(GetSurfaceFormat(m_desc.Format));
|
||||
m_presenter->setSurfaceExtent({ m_desc.Width, m_desc.Height });
|
||||
m_presenter->setFrameRateLimit(m_targetFrameRate, GetActualFrameLatency());
|
||||
|
||||
m_latency = m_device->createLatencyTracker(m_presenter);
|
||||
}
|
||||
|
||||
|
||||
@ -555,9 +593,13 @@ namespace dxvk {
|
||||
void D3D11SwapChain::CreateBlitter() {
|
||||
Rc<hud::Hud> hud = hud::Hud::createHud(m_device);
|
||||
|
||||
if (hud)
|
||||
if (hud) {
|
||||
hud->addItem<hud::HudClientApiItem>("api", 1, GetApiName());
|
||||
|
||||
if (m_latency)
|
||||
m_latencyHud = hud->addItem<hud::HudLatencyItem>("latency", 4);
|
||||
}
|
||||
|
||||
m_blitter = new DxvkSwapchainBlitter(m_device, std::move(hud));
|
||||
}
|
||||
|
||||
@ -567,6 +609,17 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D11SwapChain::DestroyLatencyTracker() {
|
||||
// Need to make sure the context stops using
|
||||
// the tracker for submissions
|
||||
m_parent->GetContext()->InjectCs([
|
||||
cLatency = m_latency
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->endLatencyTracking(cLatency);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void D3D11SwapChain::SyncFrameLatency() {
|
||||
// Wait for the sync event so that we respect the maximum frame latency
|
||||
m_frameLatencySignal->wait(m_frameId - GetActualFrameLatency());
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "../dxvk/hud/dxvk_hud.h"
|
||||
|
||||
#include "../dxvk/dxvk_latency.h"
|
||||
#include "../dxvk/dxvk_swapchain_blitter.h"
|
||||
|
||||
#include "../util/sync/sync_signal.h"
|
||||
@ -107,6 +108,7 @@ namespace dxvk {
|
||||
Rc<Presenter> m_presenter;
|
||||
|
||||
Rc<DxvkSwapchainBlitter> m_blitter;
|
||||
Rc<DxvkLatencyTracker> m_latency;
|
||||
|
||||
small_vector<Com<D3D11Texture2D, false>, 4> m_backBuffers;
|
||||
|
||||
@ -123,6 +125,8 @@ namespace dxvk {
|
||||
dxvk::mutex m_frameStatisticsLock;
|
||||
DXGI_VK_FRAME_STATISTICS m_frameStatistics = { };
|
||||
|
||||
Rc<hud::HudLatencyItem> m_latencyHud;
|
||||
|
||||
Rc<DxvkImageView> GetBackBufferView();
|
||||
|
||||
HRESULT PresentImage(UINT SyncInterval);
|
||||
@ -139,6 +143,8 @@ namespace dxvk {
|
||||
|
||||
void DestroyFrameLatencyEvent();
|
||||
|
||||
void DestroyLatencyTracker();
|
||||
|
||||
void SyncFrameLatency();
|
||||
|
||||
uint32_t GetActualFrameLatency();
|
||||
|
Loading…
x
Reference in New Issue
Block a user