mirror of
https://github.com/thejerf/baijiSteamVR.git
synced 2026-10-21 04:08:28 +02:00
116 lines
3.8 KiB
C++
116 lines
3.8 KiB
C++
// Copyright 2024 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#ifdef ENABLE_VR
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// VulkanLoader.h must come first — it defines VK_NO_PROTOTYPES before vulkan.h.
|
|
#include "VideoBackends/Vulkan/VulkanLoader.h"
|
|
|
|
#define XR_USE_GRAPHICS_API_VULKAN
|
|
#include <openxr/openxr.h>
|
|
#include <openxr/openxr_platform.h>
|
|
|
|
#include "VideoCommon/VR/OpenXRManager.h"
|
|
|
|
namespace Vulkan
|
|
{
|
|
class VKTexture;
|
|
class VKFramebuffer;
|
|
|
|
// Holds the swapchain images for one eye.
|
|
// The VkImage objects are owned by the OpenXR runtime; VKTexture wraps them
|
|
// (without allocation) and VKFramebuffer provides a render pass for rendering.
|
|
struct XRVkEyeSwapchain
|
|
{
|
|
XrSwapchain swapchain = XR_NULL_HANDLE;
|
|
uint32_t width = 0;
|
|
uint32_t height = 0;
|
|
|
|
// One entry per swapchain image.
|
|
std::vector<std::unique_ptr<VKTexture>> textures;
|
|
std::vector<std::unique_ptr<VKFramebuffer>> framebuffers;
|
|
};
|
|
|
|
// Vulkan-specific OpenXR backend. Implements VR::IOpenXRSwapchain so that
|
|
// Presenter::RenderXFBToScreen() can acquire/release eye images and submit
|
|
// frames using only VideoCommon-visible types (AbstractFramebuffer*).
|
|
// Vulkan extensions required by the OpenXR runtime, queried before VkInstance/VkDevice creation.
|
|
struct VulkanExtensionRequirements
|
|
{
|
|
std::vector<std::string> instance_extensions;
|
|
std::vector<std::string> device_extensions;
|
|
};
|
|
|
|
class VulkanOpenXR : public VR::IOpenXRSwapchain
|
|
{
|
|
public:
|
|
VulkanOpenXR();
|
|
~VulkanOpenXR() override;
|
|
|
|
VulkanOpenXR(const VulkanOpenXR&) = delete;
|
|
VulkanOpenXR& operator=(const VulkanOpenXR&) = delete;
|
|
|
|
// Must be called BEFORE VulkanContext::CreateVulkanInstance().
|
|
// Creates a temporary XrInstance, queries the Vulkan extensions required by the
|
|
// OpenXR runtime, and stores the OpenXRManager in VR::g_openxr for later reuse.
|
|
static bool PreQueryVulkanExtensions(VulkanExtensionRequirements& out_requirements);
|
|
|
|
// Full initialization: creates Vulkan-bound XrSession, reference space, and
|
|
// per-eye swapchains. If PreQueryVulkanExtensions() was called, reuses the
|
|
// existing VR::g_openxr; otherwise creates a new one.
|
|
bool Initialize();
|
|
|
|
// Tears down swapchains and resets g_openxr.
|
|
void Shutdown();
|
|
|
|
// ---- IOpenXRSwapchain ----
|
|
|
|
// Acquire the next swapchain image for the given eye.
|
|
// Returns AbstractFramebuffer* (actually VKFramebuffer*) to render into.
|
|
AbstractFramebuffer* AcquireEyeFramebuffer(uint32_t eye_index) override;
|
|
|
|
// Release the current swapchain image back to the runtime.
|
|
void ReleaseEyeTexture(uint32_t eye_index) override;
|
|
|
|
// Build the XrCompositionLayerProjection and call xrEndFrame.
|
|
bool SubmitFrame() override;
|
|
|
|
uint32_t GetEyeWidth() const override { return m_eye_swapchains[0].width; }
|
|
uint32_t GetEyeHeight() const override { return m_eye_swapchains[0].height; }
|
|
|
|
const XRVkEyeSwapchain& GetEyeSwapchain(uint32_t eye) const { return m_eye_swapchains[eye]; }
|
|
|
|
private:
|
|
// Creates XrSession with XrGraphicsBindingVulkanKHR.
|
|
bool CreateSessionVulkan();
|
|
|
|
// Allocates m_eye_swapchains and wraps images as VKTexture / VKFramebuffer.
|
|
bool CreateSwapchains();
|
|
|
|
void DestroySwapchains();
|
|
|
|
std::array<XRVkEyeSwapchain, 2> m_eye_swapchains{};
|
|
|
|
// Image index selected by xrAcquireSwapchainImage for the current frame.
|
|
std::array<uint32_t, 2> m_acquired_image_index{0, 0};
|
|
std::array<bool, 2> m_image_acquired{false, false};
|
|
|
|
// Reused per-frame composition data (avoids per-frame heap allocation).
|
|
std::array<XrCompositionLayerProjectionView, 2> m_projection_views{};
|
|
XrCompositionLayerProjection m_projection_layer{XR_TYPE_COMPOSITION_LAYER_PROJECTION};
|
|
};
|
|
|
|
// Global Vulkan OpenXR instance — valid between VideoBackend::Initialize() and Shutdown().
|
|
extern std::unique_ptr<VulkanOpenXR> g_openxr_vk;
|
|
|
|
} // namespace Vulkan
|
|
|
|
#endif // ENABLE_VR
|