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