Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/openxr/extensions/openxr_fb_update_swapchain_extension.cpp
10278 views
1
/**************************************************************************/
2
/* openxr_fb_update_swapchain_extension.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "openxr_fb_update_swapchain_extension.h"
32
33
// Always include this as late as possible.
34
#include "../openxr_platform_inc.h"
35
36
#ifndef GL_CUBIC_IMG
37
#define GL_CUBIC_IMG 0x9139
38
#endif
39
#ifndef GL_CUBIC_MIPMAP_LINEAR_IMG
40
#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B
41
#endif
42
#ifndef GL_CUBIC_MIPMAP_NEAREST_IMG
43
#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A
44
#endif
45
#ifndef GL_CLAMP_TO_BORDER
46
#define GL_CLAMP_TO_BORDER 0x812D
47
#endif
48
49
OpenXRFBUpdateSwapchainExtension *OpenXRFBUpdateSwapchainExtension::singleton = nullptr;
50
51
OpenXRFBUpdateSwapchainExtension *OpenXRFBUpdateSwapchainExtension::get_singleton() {
52
return singleton;
53
}
54
55
OpenXRFBUpdateSwapchainExtension::OpenXRFBUpdateSwapchainExtension(const String &p_rendering_driver) {
56
singleton = this;
57
rendering_driver = p_rendering_driver;
58
}
59
60
OpenXRFBUpdateSwapchainExtension::~OpenXRFBUpdateSwapchainExtension() {
61
singleton = nullptr;
62
}
63
64
HashMap<String, bool *> OpenXRFBUpdateSwapchainExtension::get_requested_extensions() {
65
HashMap<String, bool *> request_extensions;
66
67
request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME] = &fb_swapchain_update_state_ext;
68
69
if (rendering_driver == "vulkan") {
70
#ifdef XR_USE_GRAPHICS_API_VULKAN
71
request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_VULKAN_EXTENSION_NAME] = &fb_swapchain_update_state_vulkan_ext;
72
#endif
73
} else if (rendering_driver == "opengl3") {
74
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
75
request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME] = &fb_swapchain_update_state_opengles_ext;
76
#endif
77
}
78
79
#ifdef ANDROID_ENABLED
80
request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_ANDROID_SURFACE_EXTENSION_NAME] = &fb_swapchain_update_state_android_ext;
81
#endif
82
83
return request_extensions;
84
}
85
86
void OpenXRFBUpdateSwapchainExtension::on_instance_created(const XrInstance p_instance) {
87
if (fb_swapchain_update_state_ext) {
88
EXT_INIT_XR_FUNC(xrUpdateSwapchainFB);
89
EXT_INIT_XR_FUNC(xrGetSwapchainStateFB);
90
}
91
92
if (fb_swapchain_update_state_vulkan_ext) {
93
// nothing to register here...
94
}
95
96
if (fb_swapchain_update_state_opengles_ext) {
97
// nothing to register here...
98
}
99
}
100
101
void OpenXRFBUpdateSwapchainExtension::on_instance_destroyed() {
102
fb_swapchain_update_state_ext = false;
103
fb_swapchain_update_state_vulkan_ext = false;
104
fb_swapchain_update_state_opengles_ext = false;
105
}
106
107
bool OpenXRFBUpdateSwapchainExtension::is_enabled() const {
108
if (rendering_driver == "vulkan") {
109
return fb_swapchain_update_state_ext && fb_swapchain_update_state_vulkan_ext;
110
} else if (rendering_driver == "opengl3") {
111
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
112
return fb_swapchain_update_state_ext && fb_swapchain_update_state_opengles_ext;
113
#else
114
return fb_swapchain_update_state_ext;
115
#endif
116
}
117
118
return false;
119
}
120
121
bool OpenXRFBUpdateSwapchainExtension::is_android_ext_enabled() const {
122
return fb_swapchain_update_state_android_ext;
123
}
124
125
void OpenXRFBUpdateSwapchainExtension::update_swapchain_state(XrSwapchain p_swapchain, const OpenXRViewportCompositionLayerProvider::SwapchainState *p_swapchain_state) {
126
if (!p_swapchain_state) {
127
return;
128
}
129
130
if (rendering_driver == "vulkan") {
131
#ifdef XR_USE_GRAPHICS_API_VULKAN
132
if (!fb_swapchain_update_state_ext || !fb_swapchain_update_state_vulkan_ext) {
133
return;
134
}
135
136
Color border_color = p_swapchain_state->border_color;
137
XrSwapchainStateSamplerVulkanFB swapchain_state = {
138
XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB, // type
139
nullptr, // next
140
(VkFilter)filter_to_vk(p_swapchain_state->min_filter), // minFilter
141
(VkFilter)filter_to_vk(p_swapchain_state->mag_filter), // magFilter
142
(VkSamplerMipmapMode)mipmap_mode_to_vk(p_swapchain_state->mipmap_mode), // mipmapMode
143
(VkSamplerAddressMode)wrap_to_vk(p_swapchain_state->horizontal_wrap), // wrapModeS;
144
(VkSamplerAddressMode)wrap_to_vk(p_swapchain_state->vertical_wrap), // wrapModeT
145
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->red_swizzle), // swizzleRed
146
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->green_swizzle), // swizzleGreen
147
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->blue_swizzle), // swizzleBlue
148
(VkComponentSwizzle)swizzle_to_vk(p_swapchain_state->alpha_swizzle), // swizzleAlpha
149
p_swapchain_state->max_anisotropy, // maxAnisotropy
150
{ border_color.r, border_color.g, border_color.b, border_color.a } // borderColor
151
};
152
153
XrResult result = xrUpdateSwapchainFB(p_swapchain, (XrSwapchainStateBaseHeaderFB *)&swapchain_state);
154
if (XR_FAILED(result)) {
155
print_error(vformat("OpenXR: Failed to update swapchain [%s]", OpenXRAPI::get_singleton()->get_error_string(result)));
156
return;
157
}
158
#endif
159
} else if (rendering_driver == "opengl3") {
160
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
161
if (!fb_swapchain_update_state_ext || !fb_swapchain_update_state_opengles_ext) {
162
return;
163
}
164
165
Color border_color = p_swapchain_state->border_color;
166
XrSwapchainStateSamplerOpenGLESFB swapchain_state = {
167
XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB, // type
168
nullptr, // next
169
filter_to_gl(p_swapchain_state->min_filter, p_swapchain_state->mipmap_mode), // minFilter
170
filter_to_gl(p_swapchain_state->mag_filter), // magFilter
171
wrap_to_gl(p_swapchain_state->horizontal_wrap), // wrapModeS;
172
wrap_to_gl(p_swapchain_state->vertical_wrap), // wrapModeT
173
swizzle_to_gl(p_swapchain_state->red_swizzle), // swizzleRed
174
swizzle_to_gl(p_swapchain_state->green_swizzle), // swizzleGreen
175
swizzle_to_gl(p_swapchain_state->blue_swizzle), // swizzleBlue
176
swizzle_to_gl(p_swapchain_state->alpha_swizzle), // swizzleAlpha
177
p_swapchain_state->max_anisotropy, // maxAnisotropy
178
{ border_color.r, border_color.g, border_color.b, border_color.a } // borderColor
179
};
180
181
XrResult result = xrUpdateSwapchainFB(p_swapchain, (XrSwapchainStateBaseHeaderFB *)&swapchain_state);
182
if (XR_FAILED(result)) {
183
print_error(vformat("OpenXR: Failed to update swapchain [%s]", OpenXRAPI::get_singleton()->get_error_string(result)));
184
return;
185
}
186
#endif
187
}
188
}
189
190
void OpenXRFBUpdateSwapchainExtension::update_swapchain_surface_size(XrSwapchain p_swapchain, const Size2i &p_size) {
191
#ifdef ANDROID_ENABLED
192
if (!fb_swapchain_update_state_ext || !fb_swapchain_update_state_android_ext) {
193
return;
194
}
195
196
XrSwapchainStateAndroidSurfaceDimensionsFB swapchain_state = {
197
XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB, // type
198
nullptr, // next
199
(uint32_t)p_size.width, // width
200
(uint32_t)p_size.height // height
201
};
202
203
XrResult result = xrUpdateSwapchainFB(p_swapchain, (XrSwapchainStateBaseHeaderFB *)&swapchain_state);
204
if (XR_FAILED(result)) {
205
print_error(vformat("OpenXR: Failed to update swapchain surface size [%s]", OpenXRAPI::get_singleton()->get_error_string(result)));
206
}
207
#endif
208
}
209
210
uint32_t OpenXRFBUpdateSwapchainExtension::filter_to_gl(OpenXRViewportCompositionLayerProvider::Filter p_filter, OpenXRViewportCompositionLayerProvider::MipmapMode p_mipmap_mode) {
211
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
212
switch (p_mipmap_mode) {
213
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_DISABLED:
214
switch (p_filter) {
215
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
216
return GL_NEAREST;
217
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
218
return GL_LINEAR;
219
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
220
return GL_CUBIC_IMG;
221
}
222
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_NEAREST:
223
switch (p_filter) {
224
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
225
return GL_NEAREST_MIPMAP_NEAREST;
226
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
227
return GL_LINEAR_MIPMAP_NEAREST;
228
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
229
return GL_CUBIC_MIPMAP_NEAREST_IMG;
230
}
231
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_LINEAR:
232
switch (p_filter) {
233
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
234
return GL_NEAREST_MIPMAP_LINEAR;
235
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
236
return GL_LINEAR_MIPMAP_LINEAR;
237
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
238
return GL_CUBIC_MIPMAP_LINEAR_IMG;
239
}
240
}
241
#endif
242
return 0;
243
}
244
245
uint32_t OpenXRFBUpdateSwapchainExtension::wrap_to_gl(OpenXRViewportCompositionLayerProvider::Wrap p_wrap) {
246
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
247
switch (p_wrap) {
248
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_BORDER:
249
return GL_CLAMP_TO_BORDER;
250
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_EDGE:
251
return GL_CLAMP_TO_EDGE;
252
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_REPEAT:
253
return GL_REPEAT;
254
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRRORED_REPEAT:
255
return GL_MIRRORED_REPEAT;
256
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRROR_CLAMP_TO_EDGE:
257
return GL_CLAMP_TO_EDGE;
258
}
259
#endif
260
return 0;
261
}
262
263
uint32_t OpenXRFBUpdateSwapchainExtension::swizzle_to_gl(OpenXRViewportCompositionLayerProvider::Swizzle p_swizzle) {
264
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
265
switch (p_swizzle) {
266
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_RED:
267
return GL_RED;
268
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_GREEN:
269
return GL_GREEN;
270
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_BLUE:
271
return GL_BLUE;
272
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ALPHA:
273
return GL_ALPHA;
274
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ZERO:
275
return GL_ZERO;
276
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ONE:
277
return GL_ONE;
278
}
279
#endif
280
return 0;
281
}
282
283
uint32_t OpenXRFBUpdateSwapchainExtension::filter_to_vk(OpenXRViewportCompositionLayerProvider::Filter p_filter) {
284
#ifdef XR_USE_GRAPHICS_API_VULKAN
285
switch (p_filter) {
286
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_NEAREST:
287
return VK_FILTER_NEAREST;
288
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_LINEAR:
289
return VK_FILTER_LINEAR;
290
case OpenXRViewportCompositionLayerProvider::Filter::FILTER_CUBIC:
291
return VK_FILTER_CUBIC_EXT;
292
}
293
#endif
294
return 0;
295
}
296
297
uint32_t OpenXRFBUpdateSwapchainExtension::mipmap_mode_to_vk(OpenXRViewportCompositionLayerProvider::MipmapMode p_mipmap_mode) {
298
#ifdef XR_USE_GRAPHICS_API_VULKAN
299
switch (p_mipmap_mode) {
300
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_DISABLED:
301
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
302
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_NEAREST:
303
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
304
case OpenXRViewportCompositionLayerProvider::MipmapMode::MIPMAP_MODE_LINEAR:
305
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
306
}
307
#endif
308
return 0;
309
}
310
311
uint32_t OpenXRFBUpdateSwapchainExtension::wrap_to_vk(OpenXRViewportCompositionLayerProvider::Wrap p_wrap) {
312
#ifdef XR_USE_GRAPHICS_API_VULKAN
313
switch (p_wrap) {
314
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_BORDER:
315
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
316
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_CLAMP_TO_EDGE:
317
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
318
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_REPEAT:
319
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
320
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRRORED_REPEAT:
321
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
322
case OpenXRViewportCompositionLayerProvider::Wrap::WRAP_MIRROR_CLAMP_TO_EDGE:
323
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
324
}
325
#endif
326
return 0;
327
}
328
329
uint32_t OpenXRFBUpdateSwapchainExtension::swizzle_to_vk(OpenXRViewportCompositionLayerProvider::Swizzle p_swizzle) {
330
#ifdef XR_USE_GRAPHICS_API_VULKAN
331
switch (p_swizzle) {
332
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_RED:
333
return VK_COMPONENT_SWIZZLE_R;
334
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_GREEN:
335
return VK_COMPONENT_SWIZZLE_G;
336
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_BLUE:
337
return VK_COMPONENT_SWIZZLE_B;
338
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ALPHA:
339
return VK_COMPONENT_SWIZZLE_A;
340
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ZERO:
341
return VK_COMPONENT_SWIZZLE_ZERO;
342
case OpenXRViewportCompositionLayerProvider::Swizzle::SWIZZLE_ONE:
343
return VK_COMPONENT_SWIZZLE_ONE;
344
}
345
#endif
346
return 0;
347
}
348
349