mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 07:00:30 +02:00
The panel was drawn into the eye images, so below a 1.00x OpenXR resolution its 1440x1080 canvas was minified into a small eye region and the text became hard to read. It is now submitted as a quad layer of its own over the scene's projection or menu quad, which the compositor samples directly at any render scale. Each backend (D3D12, Windows Vulkan, Quest) makes the panel's swapchain pair (plus two shared buffers on the Quest) the first time the panel opens. While it is open, the frame hands Aurora one more stereo target after the eyes, which the bridge fills with the panel texture or a transparent image. The panel image follows the eyes' displayed/retained pairing, so a cancelled frame never shows an unwritten panel. The quad hangs where the pointer's hits are tested. Aurora leaves the panel out of the eyes in layer mode, and a backend that cannot make the layer falls back to drawing it into the eyes. On the Quest, debug.wiicompiled.panel_layer 0 selects the old path at run time. Measured there at a race start (render_scale 0.8), the layer costs nothing while the panel is closed; while it is open, app GPU time is 10.5 ms against 9.7 ms drawn into the eyes, with unchanged frame rates. The replay tests cover lazy creation, cancelled frames, closed and unplaced panels, and render-first pacing on D3D12 and Windows Vulkan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
68 lines
3.6 KiB
C++
68 lines
3.6 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
#pragma once
|
|
#include "vr/openxr_d3d12.h"
|
|
#include "vr/openxr_vulkan_win32.h"
|
|
#include <variant>
|
|
namespace mkw::vr {
|
|
// Runtime API selection; both backends expose the same pacing/ownership contract.
|
|
class OpenXRWindowsBackend {
|
|
std::variant<std::unique_ptr<OpenXRD3D12Backend>, std::unique_ptr<OpenXRWindowsVulkanBackend>> backend_;
|
|
public:
|
|
OpenXRWindowsBackend(OpenXRLogCallback logger, bool vulkan) {
|
|
if (vulkan) backend_ = std::make_unique<OpenXRWindowsVulkanBackend>(logger);
|
|
else backend_ = std::make_unique<OpenXRD3D12Backend>(logger);
|
|
}
|
|
const OpenXRD3D12GraphicsRequirements& GraphicsRequirements() {
|
|
return std::get<0>(backend_)->GraphicsRequirements();
|
|
}
|
|
bool QueryGraphicsRequirements(OpenXRRuntime& runtime) {
|
|
return std::visit([&](auto& backend) -> bool { return backend->QueryGraphicsRequirements(runtime); }, backend_);
|
|
}
|
|
bool BindAurora(OpenXRRuntime& runtime) {
|
|
return std::visit([&](auto& backend) -> bool { return backend->BindAurora(runtime); }, backend_);
|
|
}
|
|
OpenXRBeginStatus BeginFrame(const OpenXRPresentation& presentation, OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> OpenXRBeginStatus { return backend->BeginFrame(presentation, frame); }, backend_);
|
|
}
|
|
OpenXRSubmissionStatus WaitForSubmission(const OpenXRBackendFrame& frame, uint32_t timeout) {
|
|
return std::visit([&](auto& backend) -> OpenXRSubmissionStatus { return backend->WaitForSubmission(frame, timeout); }, backend_);
|
|
}
|
|
bool TryCancelPendingFrame(OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> bool { return backend->TryCancelPendingFrame(frame); }, backend_);
|
|
}
|
|
bool RepeatFrame(const OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> bool { return backend->RepeatFrame(frame); }, backend_);
|
|
}
|
|
bool FinishFrame(OpenXRBackendFrame& frame, bool submit) {
|
|
return std::visit([&](auto& backend) -> bool { return backend->FinishFrame(frame, submit); }, backend_);
|
|
}
|
|
OpenXRBeginStatus PreparePacket(const OpenXRPresentation& presentation, OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> OpenXRBeginStatus { return backend->PreparePacket(presentation, frame); }, backend_);
|
|
}
|
|
bool TryCancelPendingPacket(OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> bool { return backend->TryCancelPendingPacket(frame); }, backend_);
|
|
}
|
|
OpenXRBeginStatus BeginFrameForPacket(const OpenXRBackendFrame& packet, OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> OpenXRBeginStatus { return backend->BeginFrameForPacket(packet, frame); }, backend_);
|
|
}
|
|
OpenXRSubmissionStatus CopyRenderedEyes(const OpenXRBackendFrame& frame) {
|
|
return std::visit([&](auto& backend) -> OpenXRSubmissionStatus { return backend->CopyRenderedEyes(frame); }, backend_);
|
|
}
|
|
OpenXRBeginStatus KeepAliveCycle() {
|
|
return std::visit([&](auto& backend) -> OpenXRBeginStatus { return backend->KeepAliveCycle(); }, backend_);
|
|
}
|
|
bool Shutdown() {
|
|
return std::visit([&](auto& backend) -> bool { return backend->Shutdown(); }, backend_);
|
|
}
|
|
bool PanelLayerAvailable() {
|
|
return std::visit([&](auto& backend) -> bool { return backend->PanelLayerAvailable(); }, backend_);
|
|
}
|
|
int64_t SwapchainFormat() {
|
|
return std::visit([&](auto& backend) -> int64_t { return backend->SwapchainFormat(); }, backend_);
|
|
}
|
|
const std::string& LastError() {
|
|
return std::visit([&](auto& backend) -> const std::string& { return backend->LastError(); }, backend_);
|
|
}
|
|
};
|
|
}
|