Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/openxr/extensions/openxr_fb_foveation_extension.cpp
10278 views
1
/**************************************************************************/
2
/* openxr_fb_foveation_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_foveation_extension.h"
32
#include "core/config/project_settings.h"
33
34
#include "../openxr_platform_inc.h"
35
36
OpenXRFBFoveationExtension *OpenXRFBFoveationExtension::singleton = nullptr;
37
38
OpenXRFBFoveationExtension *OpenXRFBFoveationExtension::get_singleton() {
39
return singleton;
40
}
41
42
OpenXRFBFoveationExtension::OpenXRFBFoveationExtension(const String &p_rendering_driver) {
43
singleton = this;
44
rendering_driver = p_rendering_driver;
45
swapchain_update_state_ext = OpenXRFBUpdateSwapchainExtension::get_singleton();
46
int fov_level = GLOBAL_GET("xr/openxr/foveation_level");
47
if (fov_level >= 0 && fov_level < 4) {
48
foveation_level = XrFoveationLevelFB(fov_level);
49
}
50
bool fov_dyn = GLOBAL_GET("xr/openxr/foveation_dynamic");
51
foveation_dynamic = fov_dyn ? XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB : XR_FOVEATION_DYNAMIC_DISABLED_FB;
52
53
swapchain_create_info_foveation_fb.type = XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB;
54
swapchain_create_info_foveation_fb.next = nullptr;
55
swapchain_create_info_foveation_fb.flags = 0;
56
57
if (rendering_driver == "opengl3") {
58
swapchain_create_info_foveation_fb.flags = XR_SWAPCHAIN_CREATE_FOVEATION_SCALED_BIN_BIT_FB;
59
} else if (rendering_driver == "vulkan") {
60
swapchain_create_info_foveation_fb.flags = XR_SWAPCHAIN_CREATE_FOVEATION_FRAGMENT_DENSITY_MAP_BIT_FB;
61
}
62
}
63
64
OpenXRFBFoveationExtension::~OpenXRFBFoveationExtension() {
65
singleton = nullptr;
66
swapchain_update_state_ext = nullptr;
67
}
68
69
HashMap<String, bool *> OpenXRFBFoveationExtension::get_requested_extensions() {
70
HashMap<String, bool *> request_extensions;
71
72
request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext;
73
request_extensions[XR_FB_FOVEATION_CONFIGURATION_EXTENSION_NAME] = &fb_foveation_configuration_ext;
74
75
#ifdef XR_USE_GRAPHICS_API_VULKAN
76
if (rendering_driver == "vulkan") {
77
request_extensions[XR_FB_FOVEATION_VULKAN_EXTENSION_NAME] = &fb_foveation_vulkan_ext;
78
}
79
#endif // XR_USE_GRAPHICS_API_VULKAN
80
81
return request_extensions;
82
}
83
84
void OpenXRFBFoveationExtension::on_instance_created(const XrInstance p_instance) {
85
if (fb_foveation_ext) {
86
EXT_INIT_XR_FUNC(xrCreateFoveationProfileFB);
87
EXT_INIT_XR_FUNC(xrDestroyFoveationProfileFB);
88
}
89
90
if (fb_foveation_configuration_ext) {
91
// nothing to register here...
92
}
93
}
94
95
void OpenXRFBFoveationExtension::on_instance_destroyed() {
96
fb_foveation_ext = false;
97
fb_foveation_configuration_ext = false;
98
}
99
100
bool OpenXRFBFoveationExtension::is_enabled() const {
101
bool enabled = swapchain_update_state_ext != nullptr && swapchain_update_state_ext->is_enabled() && fb_foveation_ext && fb_foveation_configuration_ext;
102
#ifdef XR_USE_GRAPHICS_API_VULKAN
103
if (rendering_driver == "vulkan") {
104
enabled = enabled && fb_foveation_vulkan_ext;
105
}
106
#endif // XR_USE_GRAPHICS_API_VULKAN
107
return enabled;
108
}
109
110
void *OpenXRFBFoveationExtension::set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) {
111
if (is_enabled()) {
112
swapchain_create_info_foveation_fb.next = p_next_pointer;
113
return &swapchain_create_info_foveation_fb;
114
} else {
115
return p_next_pointer;
116
}
117
}
118
119
void OpenXRFBFoveationExtension::on_main_swapchains_created() {
120
update_profile();
121
}
122
123
XrFoveationLevelFB OpenXRFBFoveationExtension::get_foveation_level() const {
124
return foveation_level;
125
}
126
127
void OpenXRFBFoveationExtension::set_foveation_level(XrFoveationLevelFB p_foveation_level) {
128
foveation_level = p_foveation_level;
129
130
// Update profile will do nothing if we're not yet initialized.
131
update_profile();
132
}
133
134
XrFoveationDynamicFB OpenXRFBFoveationExtension::get_foveation_dynamic() const {
135
return foveation_dynamic;
136
}
137
138
void OpenXRFBFoveationExtension::set_foveation_dynamic(XrFoveationDynamicFB p_foveation_dynamic) {
139
foveation_dynamic = p_foveation_dynamic;
140
141
// Update profile will do nothing if we're not yet initialized.
142
update_profile();
143
}
144
145
void OpenXRFBFoveationExtension::_update_profile() {
146
// Must be called from rendering thread!
147
ERR_NOT_ON_RENDER_THREAD;
148
149
OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
150
ERR_FAIL_NULL(fov_ext);
151
152
if (!fov_ext->is_enabled()) {
153
return;
154
}
155
156
OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
157
ERR_FAIL_NULL(openxr_api);
158
159
XrSwapchain main_color_swapchain = openxr_api->get_color_swapchain();
160
if (main_color_swapchain == XR_NULL_HANDLE) {
161
// Our swapchain hasn't been created yet, we'll call this again once it has.
162
return;
163
}
164
165
XrFoveationLevelProfileCreateInfoFB level_profile_create_info;
166
level_profile_create_info.type = XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB;
167
level_profile_create_info.next = nullptr;
168
level_profile_create_info.level = fov_ext->foveation_level;
169
level_profile_create_info.verticalOffset = 0.0f;
170
level_profile_create_info.dynamic = fov_ext->foveation_dynamic;
171
172
XrFoveationProfileCreateInfoFB profile_create_info;
173
profile_create_info.type = XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB;
174
profile_create_info.next = &level_profile_create_info;
175
176
XrFoveationProfileFB foveation_profile;
177
XrResult result = fov_ext->xrCreateFoveationProfileFB(openxr_api->get_session(), &profile_create_info, &foveation_profile);
178
if (XR_FAILED(result)) {
179
print_line("OpenXR: Unable to create the foveation profile [", openxr_api->get_error_string(result), "]");
180
return;
181
}
182
183
XrSwapchainStateFoveationFB foveation_update_state;
184
foveation_update_state.type = XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB;
185
foveation_update_state.profile = foveation_profile;
186
187
result = fov_ext->swapchain_update_state_ext->xrUpdateSwapchainFB(main_color_swapchain, (XrSwapchainStateBaseHeaderFB *)&foveation_update_state);
188
if (XR_FAILED(result)) {
189
print_line("OpenXR: Unable to update the swapchain [", openxr_api->get_error_string(result), "]");
190
191
// We still want to destroy our profile so keep going...
192
}
193
194
result = fov_ext->xrDestroyFoveationProfileFB(foveation_profile);
195
if (XR_FAILED(result)) {
196
print_line("OpenXR: Unable to destroy the foveation profile [", openxr_api->get_error_string(result), "]");
197
}
198
}
199
200