mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 09:00:28 +02:00
Implement retired swapchain management for OpenXR backends: add logic to handle swapchain lifecycle and ensure proper resource cleanup
This commit is contained in:
1 parent
e89988f92e
commit
5af0bdbee6
7 files changed
+188
-50
No files matched your search
@@ -876,6 +876,7 @@ private:
|
||||
// As the D3D12 backend's. Aurora's bridge wraps each swapchain VkImage for Dawn, and the
|
||||
// runtime may hand the old handles out again, so the wraps go with the swapchains.
|
||||
bool ResizeWritablePair() {
|
||||
ReapRetiredPairs(false);
|
||||
std::array<OpenXREyeSize, kOpenXREyeCount> current{};
|
||||
for (uint32_t eye = 0; eye < kOpenXREyeCount; ++eye) {
|
||||
if (eye_swapchains_[eye].acquired) {
|
||||
@@ -899,17 +900,8 @@ private:
|
||||
eye_size_ = current;
|
||||
return true;
|
||||
}
|
||||
std::vector<void*> retired;
|
||||
for (const EyeSwapchain& swapchain : eye_swapchains_) {
|
||||
for (const auto& image : swapchain.images) {
|
||||
retired.push_back(reinterpret_cast<void*>(image.image));
|
||||
}
|
||||
}
|
||||
if (!aurora_vulkan_win32_forget_targets(retired.data(), static_cast<uint32_t>(retired.size()))) {
|
||||
DestroySwapchainPair(replacement);
|
||||
return Fail("Aurora could not retire its copies into the old Vulkan eye swapchains");
|
||||
}
|
||||
DestroySwapchainPair(eye_swapchains_);
|
||||
// The compositor may still be reading the old pair (kOpenXRRetiredSwapchainCycles).
|
||||
retired_pairs_.push_back({std::move(eye_swapchains_), kOpenXRRetiredSwapchainCycles});
|
||||
eye_swapchains_ = std::move(replacement);
|
||||
std::ostringstream message;
|
||||
message << "OpenXR Vulkan eyes resized: " << eye_size_[0].width << 'x' << eye_size_[0].height << " / "
|
||||
@@ -918,6 +910,31 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
// As the D3D12 backend's: Aurora drains Dawn's queue and drops its wraps of the images (which
|
||||
// it does under Dawn's device guard, so before the guard is taken to destroy them).
|
||||
void ReapRetiredPairs(bool all) {
|
||||
for (auto it = retired_pairs_.begin(); it != retired_pairs_.end();) {
|
||||
if (!all && --it->cycles_left != 0) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
std::vector<void*> images;
|
||||
for (const EyeSwapchain& swapchain : it->swapchains) {
|
||||
for (const auto& image : swapchain.images) {
|
||||
images.push_back(reinterpret_cast<void*>(image.image));
|
||||
}
|
||||
}
|
||||
if (aurora_vulkan_win32_forget_targets(images.data(), static_cast<uint32_t>(images.size()))) {
|
||||
DestroySwapchainPair(it->swapchains);
|
||||
} else {
|
||||
Log(OpenXRLogLevel::Warning,
|
||||
"Aurora could not retire its copies into a replaced Vulkan eye swapchain pair; "
|
||||
"deferring its destruction to xrDestroySession");
|
||||
}
|
||||
it = retired_pairs_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool CreateSwapchain(EyeSwapchain& swapchain, uint32_t width, uint32_t height, const char* what) {
|
||||
swapchain.width = width;
|
||||
swapchain.height = height;
|
||||
@@ -936,7 +953,14 @@ private:
|
||||
create.faceCount = 1;
|
||||
create.arraySize = 1;
|
||||
create.mipCount = 1;
|
||||
XrResult result = xrCreateSwapchain(runtime_->Session(), &create, &swapchain.handle);
|
||||
XrResult result;
|
||||
{
|
||||
// The spec keeps the runtime off the VkQueue here, but mid-session (the panel's
|
||||
// swapchains, a new render resolution) Dawn's worker is submitting on it, and a
|
||||
// runtime that transitions its new images would race that; the guard costs nothing.
|
||||
const auto queue_guard = runtime_->LockGraphicsQueue();
|
||||
result = xrCreateSwapchain(runtime_->Session(), &create, &swapchain.handle);
|
||||
}
|
||||
ObserveResult(result);
|
||||
if (XR_FAILED(result)) {
|
||||
std::ostringstream message;
|
||||
@@ -1075,6 +1099,7 @@ private:
|
||||
void DestroyPanelSwapchains() {
|
||||
for (auto* swapchain : {&panel_swapchain_, &retained_panel_swapchain_}) {
|
||||
if (swapchain->handle != XR_NULL_HANDLE && !swapchain->acquired) {
|
||||
const auto queue_guard = runtime_ ? runtime_->LockGraphicsQueue() : OpenXRRuntime::GraphicsQueueGuard{nullptr, nullptr};
|
||||
xrDestroySwapchain(swapchain->handle);
|
||||
} else if (swapchain->acquired) {
|
||||
Log(OpenXRLogLevel::Warning,
|
||||
@@ -1088,6 +1113,7 @@ private:
|
||||
|
||||
void DestroySwapchains() {
|
||||
DestroyPanelSwapchains();
|
||||
ReapRetiredPairs(true);
|
||||
DestroySwapchainPair(eye_swapchains_);
|
||||
DestroySwapchainPair(retained_swapchains_);
|
||||
have_retained_frame_ = false;
|
||||
@@ -1098,6 +1124,7 @@ private:
|
||||
void DestroySwapchainPair(std::array<EyeSwapchain, kOpenXREyeCount>& pair) {
|
||||
for (auto& swapchain : pair) {
|
||||
if (swapchain.handle != XR_NULL_HANDLE && !swapchain.acquired) {
|
||||
const auto queue_guard = runtime_ ? runtime_->LockGraphicsQueue() : OpenXRRuntime::GraphicsQueueGuard{nullptr, nullptr};
|
||||
xrDestroySwapchain(swapchain.handle);
|
||||
} else if (swapchain.acquired) {
|
||||
Log(OpenXRLogLevel::Warning,
|
||||
@@ -1173,6 +1200,11 @@ private:
|
||||
// As the D3D12 backend's.
|
||||
std::array<OpenXREyeSize, kOpenXREyeCount> eye_size_{};
|
||||
std::array<OpenXREyeSize, kOpenXREyeCount> requested_eye_size_{};
|
||||
struct RetiredPair {
|
||||
std::array<EyeSwapchain, kOpenXREyeCount> swapchains;
|
||||
uint32_t cycles_left;
|
||||
};
|
||||
std::vector<RetiredPair> retired_pairs_;
|
||||
// The settings panel's layer: written like the eyes into panel_swapchain_,
|
||||
// shown from retained_panel_swapchain_ (see FinishFrame).
|
||||
EyeSwapchain panel_swapchain_{};
|
||||
|
||||
Reference in new issue
Block a user