[dxvk] Implement asynchronous presentation option in the backend

This commit is contained in:
Philip Rebohle 2019-08-04 16:28:32 +02:00
parent 77fde83479
commit a558f82b5f
5 changed files with 38 additions and 6 deletions

View File

@ -183,6 +183,19 @@
# dxvk.numCompilerThreads = 0
# Toggles asynchronous present.
#
# Off-loads presentation to the queue submission thread in
# order to reduce stalling on the main rendering thread and
# improve performance.
#
# Supported values:
# - Auto: Enable on certain drivers
# - True / False: Always enable / disable
# dxvk.asyncPresent = Auto
# Toggles raw SSBO usage.
#
# Uses storage buffers to implement raw and structured buffer

View File

@ -6,6 +6,7 @@ namespace dxvk {
enableStateCache = config.getOption<bool> ("dxvk.enableStateCache", true);
enableTransferQueue = config.getOption<bool> ("dxvk.enableTransferQueue", true);
numCompilerThreads = config.getOption<int32_t> ("dxvk.numCompilerThreads", 0);
asyncPresent = config.getOption<Tristate>("dxvk.asyncPresent", Tristate::Auto);
useRawSsbo = config.getOption<Tristate>("dxvk.useRawSsbo", Tristate::Auto);
useEarlyDiscard = config.getOption<Tristate>("dxvk.useEarlyDiscard", Tristate::Auto);
hud = config.getOption<std::string>("dxvk.hud", "");

View File

@ -18,6 +18,9 @@ namespace dxvk {
/// when using the state cache
int32_t numCompilerThreads;
/// Asynchronous presentation
Tristate asyncPresent;
/// Shader-related options
Tristate useRawSsbo;
Tristate useEarlyDiscard;

View File

@ -7,7 +7,12 @@ namespace dxvk {
: m_device(device),
m_submitThread([this] () { submitCmdLists(); }),
m_finishThread([this] () { finishCmdLists(); }) {
// Asynchronous presentation seems to increase the
// likelyhood of hangs on Nvidia for some reason.
m_asyncPresent = !m_device->adapter()->matchesDriver(
DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0);
applyTristate(m_asyncPresent, m_device->config().asyncPresent);
}
@ -43,12 +48,21 @@ namespace dxvk {
void DxvkSubmissionQueue::present(DxvkPresentInfo presentInfo, DxvkSubmitStatus* status) {
std::unique_lock<std::mutex> lock(m_mutex);
DxvkSubmitEntry entry = { };
entry.status = status;
entry.present = std::move(presentInfo);
if (m_asyncPresent) {
DxvkSubmitEntry entry = { };
entry.status = status;
entry.present = std::move(presentInfo);
m_submitQueue.push(std::move(entry));
m_appendCond.notify_all();
m_submitQueue.push(std::move(entry));
m_appendCond.notify_all();
} else {
m_submitCond.wait(lock, [this] {
return m_submitQueue.empty();
});
VkResult result = presentInfo.presenter->presentImage(presentInfo.waitSync);
status->result.store(result);
}
}

View File

@ -156,6 +156,7 @@ namespace dxvk {
private:
DxvkDevice* m_device;
bool m_asyncPresent;
std::atomic<bool> m_stopped = { false };
std::atomic<uint32_t> m_pending = { 0u };