Blender  V2.93
GHOST_XrSwapchain.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include <cassert>
22 
23 #include "GHOST_C-api.h"
24 
26 #include "GHOST_XrException.h"
27 #include "GHOST_XrSession.h"
28 #include "GHOST_Xr_intern.h"
29 
30 #include "GHOST_XrSwapchain.h"
31 
33  using ImageVec = std::vector<XrSwapchainImageBaseHeader *>;
34 
35  XrSwapchain swapchain = XR_NULL_HANDLE;
37 };
38 
40  GHOST_IXrGraphicsBinding &gpu_binding)
41 {
42  std::vector<XrSwapchainImageBaseHeader *> images;
43  uint32_t image_count;
44 
45  CHECK_XR(xrEnumerateSwapchainImages(swapchain, 0, &image_count, nullptr),
46  "Failed to get count of swapchain images to create for the VR session.");
47  images = gpu_binding.createSwapchainImages(image_count);
48  CHECK_XR(xrEnumerateSwapchainImages(swapchain, images.size(), &image_count, images[0]),
49  "Failed to create swapchain images for the VR session.");
50 
51  return images;
52 }
53 
55  const XrSession &session,
56  const XrViewConfigurationView &view_config)
57  : m_oxr(std::make_unique<OpenXRSwapchainData>())
58 {
59  XrSwapchainCreateInfo create_info = {XR_TYPE_SWAPCHAIN_CREATE_INFO};
60  uint32_t format_count = 0;
61 
62  CHECK_XR(xrEnumerateSwapchainFormats(session, 0, &format_count, nullptr),
63  "Failed to get count of swapchain image formats.");
64  std::vector<int64_t> swapchain_formats(format_count);
65  CHECK_XR(xrEnumerateSwapchainFormats(
66  session, swapchain_formats.size(), &format_count, swapchain_formats.data()),
67  "Failed to get swapchain image formats.");
68  assert(swapchain_formats.size() == format_count);
69 
70  std::optional chosen_format = gpu_binding.chooseSwapchainFormat(swapchain_formats,
71  m_is_srgb_buffer);
72  if (!chosen_format) {
73  throw GHOST_XrException(
74  "Error: No format matching OpenXR runtime supported swapchain formats found.");
75  }
76 
77  create_info.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT |
78  XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
79  create_info.format = *chosen_format;
80  create_info.sampleCount = view_config.recommendedSwapchainSampleCount;
81  create_info.width = view_config.recommendedImageRectWidth;
82  create_info.height = view_config.recommendedImageRectHeight;
83  create_info.faceCount = 1;
84  create_info.arraySize = 1;
85  create_info.mipCount = 1;
86 
87  CHECK_XR(xrCreateSwapchain(session, &create_info, &m_oxr->swapchain),
88  "Failed to create OpenXR swapchain.");
89 
90  m_image_width = create_info.width;
91  m_image_height = create_info.height;
92 
93  m_oxr->swapchain_images = swapchain_images_create(m_oxr->swapchain, gpu_binding);
94 }
95 
97  : m_oxr(std::move(other.m_oxr)),
98  m_image_width(other.m_image_width),
99  m_image_height(other.m_image_height),
100  m_is_srgb_buffer(other.m_is_srgb_buffer)
101 {
102  /* Prevent xrDestroySwapchain call for the moved out item. */
103  other.m_oxr = nullptr;
104 }
105 
107 {
108  /* m_oxr may be NULL after move. */
109  if (m_oxr && m_oxr->swapchain != XR_NULL_HANDLE) {
110  CHECK_XR_ASSERT(xrDestroySwapchain(m_oxr->swapchain));
111  }
112 }
113 
115 
116 {
117  XrSwapchainImageAcquireInfo acquire_info = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO};
118  XrSwapchainImageWaitInfo wait_info = {XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO};
119  uint32_t image_idx;
120 
121  CHECK_XR(xrAcquireSwapchainImage(m_oxr->swapchain, &acquire_info, &image_idx),
122  "Failed to acquire swapchain image for the VR session.");
123  wait_info.timeout = XR_INFINITE_DURATION;
124  CHECK_XR(xrWaitSwapchainImage(m_oxr->swapchain, &wait_info),
125  "Failed to acquire swapchain image for the VR session.");
126 
127  return m_oxr->swapchain_images[image_idx];
128 }
129 
131 {
132  r_sub_image.swapchain = m_oxr->swapchain;
133  r_sub_image.imageRect.offset = {0, 0};
134  r_sub_image.imageRect.extent = {m_image_width, m_image_height};
135 }
136 
138 {
139  return m_is_srgb_buffer;
140 }
141 
143 {
144  XrSwapchainImageReleaseInfo release_info = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO};
145 
146  CHECK_XR(xrReleaseSwapchainImage(m_oxr->swapchain, &release_info),
147  "Failed to release swapchain image used to submit VR session frame.");
148 }
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, bool &r_is_rgb_format) const =0
GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding, const XrSession &session, const XrViewConfigurationView &view_config)
void updateCompositionLayerProjectViewSubImage(XrSwapchainSubImage &r_sub_image)
XrSwapchainImageBaseHeader * acquireDrawableSwapchainImage()
unsigned int uint32_t
Definition: stdint.h:83
std::vector< XrSwapchainImageBaseHeader * > ImageVec