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