mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-24 04:54:14 +01:00
[dxvk] Add latency tracker to queue submissions
This commit is contained in:
parent
9a0057fc45
commit
26ff3d9817
@ -425,7 +425,7 @@ namespace dxvk {
|
|||||||
ctx->synchronizeWsi(cSync);
|
ctx->synchronizeWsi(cSync);
|
||||||
ctx->flushCommandList(nullptr);
|
ctx->flushCommandList(nullptr);
|
||||||
|
|
||||||
cDevice->presentImage(cPresenter, cFrameId, nullptr);
|
cDevice->presentImage(cPresenter, nullptr, cFrameId, nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (m_backBuffers.size() > 1u)
|
if (m_backBuffers.size() > 1u)
|
||||||
|
@ -876,7 +876,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
uint64_t frameId = cRepeat ? 0 : cFrameId;
|
uint64_t frameId = cRepeat ? 0 : cFrameId;
|
||||||
|
|
||||||
cDevice->presentImage(cPresenter, frameId, nullptr);
|
cDevice->presentImage(cPresenter, nullptr, frameId, nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
m_parent->FlushCsChunk();
|
m_parent->FlushCsChunk();
|
||||||
|
@ -111,8 +111,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::flushCommandList(DxvkSubmitStatus* status) {
|
void DxvkContext::flushCommandList(DxvkSubmitStatus* status) {
|
||||||
m_device->submitCommandList(
|
m_device->submitCommandList(this->endRecording(),
|
||||||
this->endRecording(), status);
|
nullptr, 0, status);
|
||||||
|
|
||||||
this->beginRecording(
|
this->beginRecording(
|
||||||
m_device->createCommandList());
|
m_device->createCommandList());
|
||||||
|
@ -318,12 +318,18 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkDevice::presentImage(
|
void DxvkDevice::presentImage(
|
||||||
const Rc<Presenter>& presenter,
|
const Rc<Presenter>& presenter,
|
||||||
|
const Rc<DxvkLatencyTracker>& tracker,
|
||||||
uint64_t frameId,
|
uint64_t frameId,
|
||||||
DxvkSubmitStatus* status) {
|
DxvkSubmitStatus* status) {
|
||||||
DxvkPresentInfo presentInfo = { };
|
DxvkPresentInfo presentInfo = { };
|
||||||
presentInfo.presenter = presenter;
|
presentInfo.presenter = presenter;
|
||||||
presentInfo.frameId = frameId;
|
presentInfo.frameId = frameId;
|
||||||
m_submissionQueue.present(presentInfo, status);
|
|
||||||
|
DxvkLatencyInfo latencyInfo;
|
||||||
|
latencyInfo.tracker = tracker;
|
||||||
|
latencyInfo.frameId = frameId;
|
||||||
|
|
||||||
|
m_submissionQueue.present(presentInfo, latencyInfo, status);
|
||||||
|
|
||||||
std::lock_guard<sync::Spinlock> statLock(m_statLock);
|
std::lock_guard<sync::Spinlock> statLock(m_statLock);
|
||||||
m_statCounters.addCtr(DxvkStatCounter::QueuePresentCount, 1);
|
m_statCounters.addCtr(DxvkStatCounter::QueuePresentCount, 1);
|
||||||
@ -332,10 +338,17 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkDevice::submitCommandList(
|
void DxvkDevice::submitCommandList(
|
||||||
const Rc<DxvkCommandList>& commandList,
|
const Rc<DxvkCommandList>& commandList,
|
||||||
|
const Rc<DxvkLatencyTracker>& tracker,
|
||||||
|
uint64_t frameId,
|
||||||
DxvkSubmitStatus* status) {
|
DxvkSubmitStatus* status) {
|
||||||
DxvkSubmitInfo submitInfo = { };
|
DxvkSubmitInfo submitInfo = { };
|
||||||
submitInfo.cmdList = commandList;
|
submitInfo.cmdList = commandList;
|
||||||
m_submissionQueue.submit(submitInfo, status);
|
|
||||||
|
DxvkLatencyInfo latencyInfo;
|
||||||
|
latencyInfo.tracker = tracker;
|
||||||
|
latencyInfo.frameId = frameId;
|
||||||
|
|
||||||
|
m_submissionQueue.submit(submitInfo, latencyInfo, status);
|
||||||
|
|
||||||
std::lock_guard<sync::Spinlock> statLock(m_statLock);
|
std::lock_guard<sync::Spinlock> statLock(m_statLock);
|
||||||
m_statCounters.merge(commandList->statCounters());
|
m_statCounters.merge(commandList->statCounters());
|
||||||
|
@ -496,11 +496,13 @@ namespace dxvk {
|
|||||||
* the submission thread. The status of this operation
|
* the submission thread. The status of this operation
|
||||||
* can be retrieved with \ref waitForSubmission.
|
* can be retrieved with \ref waitForSubmission.
|
||||||
* \param [in] presenter The presenter
|
* \param [in] presenter The presenter
|
||||||
* \param [in] frameId Optional frame ID
|
* \param [in] tracker Latency tracker
|
||||||
|
* \param [in] frameId Frame ID
|
||||||
* \param [out] status Present status
|
* \param [out] status Present status
|
||||||
*/
|
*/
|
||||||
void presentImage(
|
void presentImage(
|
||||||
const Rc<Presenter>& presenter,
|
const Rc<Presenter>& presenter,
|
||||||
|
const Rc<DxvkLatencyTracker>& tracker,
|
||||||
uint64_t frameId,
|
uint64_t frameId,
|
||||||
DxvkSubmitStatus* status);
|
DxvkSubmitStatus* status);
|
||||||
|
|
||||||
@ -510,10 +512,14 @@ namespace dxvk {
|
|||||||
* Submits the given command list to the device using
|
* Submits the given command list to the device using
|
||||||
* the given set of optional synchronization primitives.
|
* the given set of optional synchronization primitives.
|
||||||
* \param [in] commandList The command list to submit
|
* \param [in] commandList The command list to submit
|
||||||
|
* \param [in] tracker Latency tracker
|
||||||
|
* \param [in] frameId Frame ID
|
||||||
* \param [out] status Submission feedback
|
* \param [out] status Submission feedback
|
||||||
*/
|
*/
|
||||||
void submitCommandList(
|
void submitCommandList(
|
||||||
const Rc<DxvkCommandList>& commandList,
|
const Rc<DxvkCommandList>& commandList,
|
||||||
|
const Rc<DxvkLatencyTracker>& tracker,
|
||||||
|
uint64_t frameId,
|
||||||
DxvkSubmitStatus* status);
|
DxvkSubmitStatus* status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +42,10 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkSubmissionQueue::submit(DxvkSubmitInfo submitInfo, DxvkSubmitStatus* status) {
|
void DxvkSubmissionQueue::submit(
|
||||||
|
DxvkSubmitInfo submitInfo,
|
||||||
|
DxvkLatencyInfo latencyInfo,
|
||||||
|
DxvkSubmitStatus* status) {
|
||||||
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
m_finishCond.wait(lock, [this] {
|
m_finishCond.wait(lock, [this] {
|
||||||
@ -52,18 +55,23 @@ namespace dxvk {
|
|||||||
DxvkSubmitEntry entry = { };
|
DxvkSubmitEntry entry = { };
|
||||||
entry.status = status;
|
entry.status = status;
|
||||||
entry.submit = std::move(submitInfo);
|
entry.submit = std::move(submitInfo);
|
||||||
|
entry.latency = std::move(latencyInfo);
|
||||||
|
|
||||||
m_submitQueue.push(std::move(entry));
|
m_submitQueue.push(std::move(entry));
|
||||||
m_appendCond.notify_all();
|
m_appendCond.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkSubmissionQueue::present(DxvkPresentInfo presentInfo, DxvkSubmitStatus* status) {
|
void DxvkSubmissionQueue::present(
|
||||||
|
DxvkPresentInfo presentInfo,
|
||||||
|
DxvkLatencyInfo latencyInfo,
|
||||||
|
DxvkSubmitStatus* status) {
|
||||||
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
DxvkSubmitEntry entry = { };
|
DxvkSubmitEntry entry = { };
|
||||||
entry.status = status;
|
entry.status = status;
|
||||||
entry.present = std::move(presentInfo);
|
entry.present = std::move(presentInfo);
|
||||||
|
entry.latency = std::move(latencyInfo);
|
||||||
|
|
||||||
m_submitQueue.push(std::move(entry));
|
m_submitQueue.push(std::move(entry));
|
||||||
m_appendCond.notify_all();
|
m_appendCond.notify_all();
|
||||||
@ -142,10 +150,21 @@ namespace dxvk {
|
|||||||
m_callback(true);
|
m_callback(true);
|
||||||
|
|
||||||
if (entry.submit.cmdList != nullptr) {
|
if (entry.submit.cmdList != nullptr) {
|
||||||
|
if (entry.latency.tracker)
|
||||||
|
entry.latency.tracker->notifyQueueSubmit(entry.latency.frameId);
|
||||||
|
|
||||||
entry.result = entry.submit.cmdList->submit(m_semaphores, m_timelines);
|
entry.result = entry.submit.cmdList->submit(m_semaphores, m_timelines);
|
||||||
entry.timelines = m_timelines;
|
entry.timelines = m_timelines;
|
||||||
} else if (entry.present.presenter != nullptr) {
|
} else if (entry.present.presenter != nullptr) {
|
||||||
|
if (entry.latency.tracker)
|
||||||
|
entry.latency.tracker->notifyQueuePresentBegin(entry.latency.frameId);
|
||||||
|
|
||||||
entry.result = entry.present.presenter->presentImage(entry.present.frameId);
|
entry.result = entry.present.presenter->presentImage(entry.present.frameId);
|
||||||
|
|
||||||
|
if (entry.latency.tracker) {
|
||||||
|
entry.latency.tracker->notifyQueuePresentEnd(
|
||||||
|
entry.latency.frameId, entry.result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_callback)
|
if (m_callback)
|
||||||
@ -217,12 +236,18 @@ namespace dxvk {
|
|||||||
std::array<VkSemaphore, 2> semaphores = { m_semaphores.graphics, m_semaphores.transfer };
|
std::array<VkSemaphore, 2> semaphores = { m_semaphores.graphics, m_semaphores.transfer };
|
||||||
std::array<uint64_t, 2> timelines = { entry.timelines.graphics, entry.timelines.transfer };
|
std::array<uint64_t, 2> timelines = { entry.timelines.graphics, entry.timelines.transfer };
|
||||||
|
|
||||||
|
if (entry.latency.tracker)
|
||||||
|
entry.latency.tracker->notifyGpuExecutionBegin(entry.latency.frameId);
|
||||||
|
|
||||||
VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO };
|
VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO };
|
||||||
waitInfo.semaphoreCount = semaphores.size();
|
waitInfo.semaphoreCount = semaphores.size();
|
||||||
waitInfo.pSemaphores = semaphores.data();
|
waitInfo.pSemaphores = semaphores.data();
|
||||||
waitInfo.pValues = timelines.data();
|
waitInfo.pValues = timelines.data();
|
||||||
|
|
||||||
status = vk->vkWaitSemaphores(vk->device(), &waitInfo, ~0ull);
|
status = vk->vkWaitSemaphores(vk->device(), &waitInfo, ~0ull);
|
||||||
|
|
||||||
|
if (entry.latency.tracker && status == VK_SUCCESS)
|
||||||
|
entry.latency.tracker->notifyGpuExecutionEnd(entry.latency.frameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != VK_SUCCESS) {
|
if (status != VK_SUCCESS) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "../util/thread.h"
|
#include "../util/thread.h"
|
||||||
|
|
||||||
#include "dxvk_cmdlist.h"
|
#include "dxvk_cmdlist.h"
|
||||||
|
#include "dxvk_latency.h"
|
||||||
#include "dxvk_presenter.h"
|
#include "dxvk_presenter.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -47,6 +48,18 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Latency info
|
||||||
|
*
|
||||||
|
* Optionally stores a latency tracker
|
||||||
|
* and the associated frame ID.
|
||||||
|
*/
|
||||||
|
struct DxvkLatencyInfo {
|
||||||
|
Rc<DxvkLatencyTracker> tracker;
|
||||||
|
uint64_t frameId = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Submission queue entry
|
* \brief Submission queue entry
|
||||||
*/
|
*/
|
||||||
@ -55,6 +68,7 @@ namespace dxvk {
|
|||||||
DxvkSubmitStatus* status;
|
DxvkSubmitStatus* status;
|
||||||
DxvkSubmitInfo submit;
|
DxvkSubmitInfo submit;
|
||||||
DxvkPresentInfo present;
|
DxvkPresentInfo present;
|
||||||
|
DxvkLatencyInfo latency;
|
||||||
DxvkTimelineSemaphoreValues timelines;
|
DxvkTimelineSemaphoreValues timelines;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,10 +116,12 @@ namespace dxvk {
|
|||||||
* dedicated submission thread. Use this to take
|
* dedicated submission thread. Use this to take
|
||||||
* the submission overhead off the calling thread.
|
* the submission overhead off the calling thread.
|
||||||
* \param [in] submitInfo Submission parameters
|
* \param [in] submitInfo Submission parameters
|
||||||
|
* \param [in] latencyInfo Latency tracker info
|
||||||
* \param [out] status Submission feedback
|
* \param [out] status Submission feedback
|
||||||
*/
|
*/
|
||||||
void submit(
|
void submit(
|
||||||
DxvkSubmitInfo submitInfo,
|
DxvkSubmitInfo submitInfo,
|
||||||
|
DxvkLatencyInfo latencyInfo,
|
||||||
DxvkSubmitStatus* status);
|
DxvkSubmitStatus* status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,10 +131,12 @@ namespace dxvk {
|
|||||||
* and then presents the current swap chain image
|
* and then presents the current swap chain image
|
||||||
* of the presenter. May stall the calling thread.
|
* of the presenter. May stall the calling thread.
|
||||||
* \param [in] present Present parameters
|
* \param [in] present Present parameters
|
||||||
|
* \param [in] latencyInfo Latency tracker info
|
||||||
* \param [out] status Submission feedback
|
* \param [out] status Submission feedback
|
||||||
*/
|
*/
|
||||||
void present(
|
void present(
|
||||||
DxvkPresentInfo presentInfo,
|
DxvkPresentInfo presentInfo,
|
||||||
|
DxvkLatencyInfo latencyInfo,
|
||||||
DxvkSubmitStatus* status);
|
DxvkSubmitStatus* status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user