mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-02 04:29:14 +01:00
[dxvk] Handle device lost errors on command submission
This commit is contained in:
parent
92d1cf8ae0
commit
2e9a836adb
@ -173,6 +173,17 @@ namespace dxvk {
|
|||||||
return m_properties;
|
return m_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get device status
|
||||||
|
*
|
||||||
|
* This may report device loss in
|
||||||
|
* case a submission failed.
|
||||||
|
* \returns Device status
|
||||||
|
*/
|
||||||
|
VkResult getDeviceStatus() const {
|
||||||
|
return m_submissionQueue.getLastError();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries supported shader stages
|
* \brief Queries supported shader stages
|
||||||
* \returns Supported shader pipeline stages
|
* \returns Supported shader pipeline stages
|
||||||
|
@ -114,7 +114,8 @@ namespace dxvk {
|
|||||||
// Submit command buffer to device
|
// Submit command buffer to device
|
||||||
VkResult status = VK_NOT_READY;
|
VkResult status = VK_NOT_READY;
|
||||||
|
|
||||||
{ std::lock_guard<std::mutex> lock(m_mutexQueue);
|
if (m_lastError != VK_ERROR_DEVICE_LOST) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutexQueue);
|
||||||
|
|
||||||
if (entry.submit.cmdList != nullptr) {
|
if (entry.submit.cmdList != nullptr) {
|
||||||
status = entry.submit.cmdList->submit(
|
status = entry.submit.cmdList->submit(
|
||||||
@ -124,6 +125,10 @@ namespace dxvk {
|
|||||||
status = entry.present.presenter->presentImage(
|
status = entry.present.presenter->presentImage(
|
||||||
entry.present.waitSync);
|
entry.present.waitSync);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Don't submit anything after device loss
|
||||||
|
// so that drivers get a chance to recover
|
||||||
|
status = VK_ERROR_DEVICE_LOST;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.status)
|
if (entry.status)
|
||||||
@ -135,8 +140,10 @@ namespace dxvk {
|
|||||||
if (status == VK_SUCCESS) {
|
if (status == VK_SUCCESS) {
|
||||||
if (entry.submit.cmdList != nullptr)
|
if (entry.submit.cmdList != nullptr)
|
||||||
m_finishQueue.push(std::move(entry));
|
m_finishQueue.push(std::move(entry));
|
||||||
} else if (entry.submit.cmdList != nullptr) {
|
} else if (status == VK_ERROR_DEVICE_LOST || entry.submit.cmdList != nullptr) {
|
||||||
Logger::err(str::format("DxvkSubmissionQueue: Command submission failed: ", status));
|
Logger::err(str::format("DxvkSubmissionQueue: Command submission failed: ", status));
|
||||||
|
m_lastError = status;
|
||||||
|
m_device->waitForIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_submitQueue.pop();
|
m_submitQueue.pop();
|
||||||
@ -168,19 +175,22 @@ namespace dxvk {
|
|||||||
DxvkSubmitEntry entry = std::move(m_finishQueue.front());
|
DxvkSubmitEntry entry = std::move(m_finishQueue.front());
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
VkResult status = entry.submit.cmdList->synchronize();
|
VkResult status = m_lastError.load();
|
||||||
|
|
||||||
if (status == VK_SUCCESS) {
|
if (status != VK_ERROR_DEVICE_LOST)
|
||||||
entry.submit.cmdList->notifySignals();
|
status = entry.submit.cmdList->synchronize();
|
||||||
entry.submit.cmdList->reset();
|
|
||||||
|
if (status != VK_SUCCESS) {
|
||||||
m_device->recycleCommandList(entry.submit.cmdList);
|
Logger::err(str::format("DxvkSubmissionQueue: Failed to sync fence: ", status));
|
||||||
} else {
|
m_lastError = status;
|
||||||
Logger::err(str::format(
|
m_device->waitForIdle();
|
||||||
"DxvkSubmissionQueue: Failed to sync fence: ",
|
|
||||||
status));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry.submit.cmdList->notifySignals();
|
||||||
|
entry.submit.cmdList->reset();
|
||||||
|
|
||||||
|
m_device->recycleCommandList(entry.submit.cmdList);
|
||||||
|
|
||||||
lock = std::unique_lock<std::mutex>(m_mutex);
|
lock = std::unique_lock<std::mutex>(m_mutex);
|
||||||
m_pending -= 1;
|
m_pending -= 1;
|
||||||
|
|
||||||
|
@ -92,6 +92,17 @@ namespace dxvk {
|
|||||||
uint64_t gpuIdleTicks() const {
|
uint64_t gpuIdleTicks() const {
|
||||||
return m_gpuIdle.load();
|
return m_gpuIdle.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves last submission error
|
||||||
|
*
|
||||||
|
* In case an error occured during asynchronous command
|
||||||
|
* submission, it will be returned by this function.
|
||||||
|
* \returns Last error from command submission
|
||||||
|
*/
|
||||||
|
VkResult getLastError() const {
|
||||||
|
return m_lastError.load();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Submits a command list asynchronously
|
* \brief Submits a command list asynchronously
|
||||||
@ -157,6 +168,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDevice* m_device;
|
DxvkDevice* m_device;
|
||||||
bool m_asyncPresent;
|
bool m_asyncPresent;
|
||||||
|
|
||||||
|
std::atomic<VkResult> m_lastError = { VK_SUCCESS };
|
||||||
|
|
||||||
std::atomic<bool> m_stopped = { false };
|
std::atomic<bool> m_stopped = { false };
|
||||||
std::atomic<uint32_t> m_pending = { 0u };
|
std::atomic<uint32_t> m_pending = { 0u };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user