Blender V4.3
GHOST_XrSwapchain.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cassert>
10
11#include "GHOST_C-api.h"
12
14#include "GHOST_XrException.hh"
15#include "GHOST_XrSession.hh"
16#include "GHOST_Xr_intern.hh"
17
18#include "GHOST_XrSwapchain.hh"
19
21 using ImageVec = std::vector<XrSwapchainImageBaseHeader *>;
22
23 XrSwapchain swapchain = XR_NULL_HANDLE;
25};
26
28 GHOST_IXrGraphicsBinding &gpu_binding)
29{
30 std::vector<XrSwapchainImageBaseHeader *> images;
31 uint32_t image_count;
32
33 CHECK_XR(xrEnumerateSwapchainImages(swapchain, 0, &image_count, nullptr),
34 "Failed to get count of swapchain images to create for the VR session.");
35 images = gpu_binding.createSwapchainImages(image_count);
36 CHECK_XR(xrEnumerateSwapchainImages(swapchain, images.size(), &image_count, images[0]),
37 "Failed to create swapchain images for the VR session.");
38
39 return images;
40}
41
43 const XrSession &session,
44 const XrViewConfigurationView &view_config)
45 : m_oxr(std::make_unique<OpenXRSwapchainData>())
46{
47 XrSwapchainCreateInfo create_info = {XR_TYPE_SWAPCHAIN_CREATE_INFO};
48 uint32_t format_count = 0;
49
50 CHECK_XR(xrEnumerateSwapchainFormats(session, 0, &format_count, nullptr),
51 "Failed to get count of swapchain image formats.");
52 std::vector<int64_t> swapchain_formats(format_count);
53 CHECK_XR(xrEnumerateSwapchainFormats(
54 session, swapchain_formats.size(), &format_count, swapchain_formats.data()),
55 "Failed to get swapchain image formats.");
56 assert(swapchain_formats.size() == format_count);
57
58 std::optional chosen_format = gpu_binding.chooseSwapchainFormat(
59 swapchain_formats, m_format, m_is_srgb_buffer);
60 if (!chosen_format) {
62 "Error: No format matching OpenXR runtime supported swapchain formats found.");
63 }
64
65 create_info.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT |
66 XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
67 create_info.format = *chosen_format;
68 create_info.sampleCount = view_config.recommendedSwapchainSampleCount;
69 create_info.width = view_config.recommendedImageRectWidth;
70 create_info.height = view_config.recommendedImageRectHeight;
71 create_info.faceCount = 1;
72 create_info.arraySize = 1;
73 create_info.mipCount = 1;
74
75 CHECK_XR(xrCreateSwapchain(session, &create_info, &m_oxr->swapchain),
76 "Failed to create OpenXR swapchain.");
77
78 m_image_width = create_info.width;
79 m_image_height = create_info.height;
80
81 m_oxr->swapchain_images = swapchain_images_create(m_oxr->swapchain, gpu_binding);
82}
83
85 : m_oxr(std::move(other.m_oxr)),
86 m_image_width(other.m_image_width),
87 m_image_height(other.m_image_height),
88 m_format(other.m_format),
89 m_is_srgb_buffer(other.m_is_srgb_buffer)
90{
91 /* Prevent xrDestroySwapchain call for the moved out item. */
92 other.m_oxr = nullptr;
93}
94
96{
97 /* m_oxr may be nullptr after move. */
98 if (m_oxr && m_oxr->swapchain != XR_NULL_HANDLE) {
99 CHECK_XR_ASSERT(xrDestroySwapchain(m_oxr->swapchain));
100 }
101}
102
104
105{
106 XrSwapchainImageAcquireInfo acquire_info = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO};
107 XrSwapchainImageWaitInfo wait_info = {XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO};
108 uint32_t image_idx;
109
110 CHECK_XR(xrAcquireSwapchainImage(m_oxr->swapchain, &acquire_info, &image_idx),
111 "Failed to acquire swapchain image for the VR session.");
112 wait_info.timeout = XR_INFINITE_DURATION;
113 CHECK_XR(xrWaitSwapchainImage(m_oxr->swapchain, &wait_info),
114 "Failed to acquire swapchain image for the VR session.");
115
116 return m_oxr->swapchain_images[image_idx];
117}
118
120{
121 r_sub_image.swapchain = m_oxr->swapchain;
122 r_sub_image.imageRect.offset = {0, 0};
123 r_sub_image.imageRect.extent = {m_image_width, m_image_height};
124}
125
126GHOST_TXrSwapchainFormat GHOST_XrSwapchain::getFormat() const
127{
128 return m_format;
129}
130
132{
133 return m_is_srgb_buffer;
134}
135
137{
138 XrSwapchainImageReleaseInfo release_info = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO};
139
140 CHECK_XR(xrReleaseSwapchainImage(m_oxr->swapchain, &release_info),
141 "Failed to release swapchain image used to submit VR session frame.");
142}
GHOST C-API function and type declarations.
static OpenXRSwapchainData::ImageVec swapchain_images_create(XrSwapchain swapchain, GHOST_IXrGraphicsBinding &gpu_binding)
#define CHECK_XR_ASSERT(call)
#define CHECK_XR(call, error_msg)
virtual std::vector< XrSwapchainImageBaseHeader * > createSwapchainImages(uint32_t image_count)=0
virtual std::optional< int64_t > chooseSwapchainFormat(const std::vector< int64_t > &runtime_formats, GHOST_TXrSwapchainFormat &r_format, bool &r_is_rgb_format) const =0
GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding, const XrSession &session, const XrViewConfigurationView &view_config)
GHOST_TXrSwapchainFormat getFormat() const
void updateCompositionLayerProjectViewSubImage(XrSwapchainSubImage &r_sub_image)
XrSwapchainImageBaseHeader * acquireDrawableSwapchainImage()
unsigned int uint32_t
Definition stdint.h:80
std::vector< XrSwapchainImageBaseHeader * > ImageVec