Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR: Add Metal support #98872

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions modules/openxr/extensions/SCsub
Original file line number Diff line number Diff line change
@@ -13,6 +13,8 @@ if env["platform"] == "android":
env_openxr.add_source_files(module_obj, "platform/openxr_android_extension.cpp")
if env["vulkan"]:
env_openxr.add_source_files(module_obj, "platform/openxr_vulkan_extension.cpp")
if env["metal"]:
env_openxr.add_source_files(module_obj, "platform/openxr_metal_extension.mm")
if env["opengl3"] and env["platform"] != "macos":
env_openxr.add_source_files(module_obj, "platform/openxr_opengl_extension.cpp")

72 changes: 72 additions & 0 deletions modules/openxr/extensions/platform/openxr_metal_extension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**************************************************************************/
/* openxr_metal_extension.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef OPENXR_METAL_EXTENSION_H
#define OPENXR_METAL_EXTENSION_H

#include "../../openxr_api.h"
#include "../../util.h"
#include "../openxr_extension_wrapper.h"

#include "core/templates/vector.h"

// Always include this as late as possible.
#include "../../openxr_platform_inc.h"

class OpenXRMetalExtension : public OpenXRGraphicsExtensionWrapper {
public:
virtual HashMap<String, bool *> get_requested_extensions() override;

virtual void on_instance_created(const XrInstance p_instance) override;
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

virtual void get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) override;
virtual void get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) override;
virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override;
virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override;
virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override;
virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override;
virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override;

private:
static XrGraphicsBindingMetalKHR graphics_binding_metal;

struct SwapchainGraphicsData {
bool is_multiview;
Vector<RID> texture_rids;
};

bool check_graphics_api_support();

EXT_PROTO_XRRESULT_FUNC3(xrGetMetalGraphicsRequirementsKHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsMetalKHR *), p_graphics_requirements)
EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainImages, (XrSwapchain), p_swapchain, (uint32_t), p_image_capacity_input, (uint32_t *), p_image_count_output, (XrSwapchainImageBaseHeader *), p_images)
};

#endif // OPENXR_METAL_EXTENSION_H
318 changes: 318 additions & 0 deletions modules/openxr/extensions/platform/openxr_metal_extension.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
/**************************************************************************/
/* openxr_metal_extension.mm */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "openxr_metal_extension.h"

#include "../../openxr_util.h"
#include "drivers/metal/rendering_device_driver_metal.h"
#include "servers/rendering/rendering_server_globals.h"

HashMap<String, bool *> OpenXRMetalExtension::get_requested_extensions() {
HashMap<String, bool *> request_extensions;

request_extensions[XR_KHR_METAL_ENABLE_EXTENSION_NAME] = nullptr;

return request_extensions;
}

void OpenXRMetalExtension::on_instance_created(const XrInstance p_instance) {
// Obtain pointers to functions we're accessing here.
ERR_FAIL_NULL(OpenXRAPI::get_singleton());

EXT_INIT_XR_FUNC(xrGetMetalGraphicsRequirementsKHR);
EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages);
}

bool OpenXRMetalExtension::check_graphics_api_support() {
ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), false);

// TODO We may need to do a callback like we do in Vulkan where we run this first
// and provide the obtained metalDevice to our Metal driver to use.
// But according to Stuart Macs only have 1 device so it should always be the
// same one and we should be able to get away with not doing this just yet.
// If we do go forward with this, this means that just like with Vulkan,
// we have to start with OpenXR before Metal can be setup, and we thus
// can't support applications that want to add XR as an optional/temporary
// feature that users enable when needed.

XrSystemId system_id = OpenXRAPI::get_singleton()->get_system_id();
XrInstance instance = OpenXRAPI::get_singleton()->get_instance();

XrGraphicsRequirementsMetalKHR metal_requirements;
metal_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_METAL_KHR;
metal_requirements.next = nullptr;
metal_requirements.metalDevice = nullptr;

XrResult result = xrGetMetalGraphicsRequirementsKHR(instance, system_id, &metal_requirements);
if (!OpenXRAPI::get_singleton()->xr_result(result, "Failed to get Metal graphics requirements!")) {
return false;
}

// See what metal device we are using...
RenderingServer *rendering_server = RenderingServer::get_singleton();
ERR_FAIL_NULL_V(rendering_server, false);
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
ERR_FAIL_NULL_V(rendering_device, false);

void *our_metal_device = (void *)rendering_device->get_driver_resource(RD::DRIVER_RESOURCE_LOGICAL_DEVICE);

// Make sure we're using the same one.
ERR_FAIL_COND_V(metal_requirements.metalDevice != our_metal_device, false);

return true;
}

XrGraphicsBindingMetalKHR OpenXRMetalExtension::graphics_binding_metal;

void *OpenXRMetalExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
if (!check_graphics_api_support()) {
return p_next_pointer;
}

RenderingServer *rendering_server = RenderingServer::get_singleton();
ERR_FAIL_NULL_V(rendering_server, p_next_pointer);
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
ERR_FAIL_NULL_V(rendering_device, p_next_pointer);

graphics_binding_metal.type = XR_TYPE_GRAPHICS_BINDING_METAL_KHR;
graphics_binding_metal.next = p_next_pointer;
graphics_binding_metal.commandQueue = (void *)rendering_device->get_driver_resource(RD::DRIVER_RESOURCE_COMMAND_QUEUE);

return &graphics_binding_metal;
}

void OpenXRMetalExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {
p_usable_swap_chains.push_back(MTLPixelFormatRGBA8Unorm_sRGB);
p_usable_swap_chains.push_back(MTLPixelFormatBGRA8Unorm_sRGB);
p_usable_swap_chains.push_back(MTLPixelFormatRGBA8Uint);
}

void OpenXRMetalExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) {
p_usable_swap_chains.push_back(MTLPixelFormatDepth24Unorm_Stencil8);
p_usable_swap_chains.push_back(MTLPixelFormatDepth32Float_Stencil8);
p_usable_swap_chains.push_back(MTLPixelFormatDepth32Float);
}

#define ENUM_TO_STRING_CASE(m_e) \
case m_e: { \
return String(#m_e); \
} break;

String OpenXRMetalExtension::get_swapchain_format_name(int64_t p_swapchain_format) const {
// This really should be in vulkan_context...
MTLPixelFormat format = MTLPixelFormat(p_swapchain_format);
switch (format) {
ENUM_TO_STRING_CASE(MTLPixelFormatRGBA8Unorm)
ENUM_TO_STRING_CASE(MTLPixelFormatRGBA8Unorm_sRGB)
ENUM_TO_STRING_CASE(MTLPixelFormatBGRA8Unorm)
ENUM_TO_STRING_CASE(MTLPixelFormatBGRA8Unorm_sRGB)
ENUM_TO_STRING_CASE(MTLPixelFormatRGBA8Uint)
ENUM_TO_STRING_CASE(MTLPixelFormatDepth24Unorm_Stencil8)
ENUM_TO_STRING_CASE(MTLPixelFormatDepth32Float_Stencil8)
ENUM_TO_STRING_CASE(MTLPixelFormatDepth32Float)
default: {
return String("Swapchain format ") + String::num_int64(int64_t(p_swapchain_format));
} break;
}
}

bool OpenXRMetalExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
LocalVector<XrSwapchainImageMetalKHR, uint32_t, false, true> images;

RenderingServer *rendering_server = RenderingServer::get_singleton();
ERR_FAIL_NULL_V(rendering_server, false);
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
ERR_FAIL_NULL_V(rendering_device, false);

uint32_t swapchain_length;
XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr);
if (XR_FAILED(result)) {
print_line("OpenXR: Failed to get swapchaim image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
return false;
}

images.resize(swapchain_length);

for (XrSwapchainImageMetalKHR &image : images) {
image.type = XR_TYPE_SWAPCHAIN_IMAGE_METAL_KHR;
image.next = nullptr;
image.texture = nullptr;
}

result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr());
if (XR_FAILED(result)) {
print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
return false;
}

SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
if (data == nullptr) {
print_line("OpenXR: Failed to allocate memory for swapchain data");
return false;
}
*r_swapchain_graphics_data = data;
data->is_multiview = (p_array_size > 1);

RenderingDevice::DataFormat format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
RenderingDevice::TextureSamples samples = RenderingDevice::TEXTURE_SAMPLES_1;
uint64_t usage_flags = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT;

switch (p_swapchain_format) {
case MTLPixelFormatRGBA8Unorm_sRGB:
// Even though this is an sRGB framebuffer format we're using UNORM here.
// The reason here is because Godot does a linear to sRGB conversion while
// with the sRGB format, this conversion would be doubled by the hardware.
// This also means we're reading the values as is for our preview on screen.
// The OpenXR runtime however is still treating this as an sRGB format and
// will thus do an sRGB -> Linear conversion as expected.
//format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM;
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case MTLPixelFormatBGRA8Unorm_sRGB:
format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UNORM;
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case MTLPixelFormatRGBA8Uint:
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UINT;
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case MTLPixelFormatDepth32Float:
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT;
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
break;
case MTLPixelFormatDepth24Unorm_Stencil8:
format = RenderingDevice::DATA_FORMAT_D24_UNORM_S8_UINT;
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
break;
case MTLPixelFormatDepth32Float_Stencil8:
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT_S8_UINT;
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
break;
default:
// Continue with our default value.
print_line("OpenXR: Unsupported swapchain format", p_swapchain_format);
break;
}

switch (p_sample_count) {
case 1:
samples = RenderingDevice::TEXTURE_SAMPLES_1;
break;
case 2:
samples = RenderingDevice::TEXTURE_SAMPLES_2;
break;
case 4:
samples = RenderingDevice::TEXTURE_SAMPLES_4;
break;
case 8:
samples = RenderingDevice::TEXTURE_SAMPLES_8;
break;
case 16:
samples = RenderingDevice::TEXTURE_SAMPLES_16;
break;
case 32:
samples = RenderingDevice::TEXTURE_SAMPLES_32;
break;
case 64:
samples = RenderingDevice::TEXTURE_SAMPLES_64;
break;
default:
// Continue with our default value.
print_line("OpenXR: Unsupported sample count", p_sample_count);
break;
}

Vector<RID> texture_rids;

// Create Godot texture objects for each entry in our swapchain.
for (uint64_t i = 0; i < swapchain_length; i++) {
// Note, the formats we sent to render_device are ignored on metal.
RID image_rid = rendering_device->texture_create_from_extension(
p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY,
format,
samples,
usage_flags,
(uint64_t)images[i].texture,
p_width,
p_height,
1,
p_array_size);

texture_rids.push_back(image_rid);
}

data->texture_rids = texture_rids;

return true;
}

void OpenXRMetalExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) {
if (*p_swapchain_graphics_data == nullptr) {
return;
}

SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data;

RenderingServer *rendering_server = RenderingServer::get_singleton();
ERR_FAIL_NULL(rendering_server);
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
ERR_FAIL_NULL(rendering_device);

for (const RID &texture_rid : data->texture_rids) {
rendering_device->free(texture_rid);
}
data->texture_rids.clear();

memdelete(data);
*p_swapchain_graphics_data = nullptr;
}

bool OpenXRMetalExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
// Even though this is a Metal renderer we're using OpenGL coordinate systems.
OpenXRUtil::XrMatrix4x4f matrix;
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);

for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
r_camera_matrix.columns[j][i] = matrix.m[j * 4 + i];
}
}

return true;
}

RID OpenXRMetalExtension::get_texture(void *p_swapchain_graphics_data, int p_image_index) {
SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
ERR_FAIL_NULL_V(data, RID());

ERR_FAIL_INDEX_V(p_image_index, data->texture_rids.size(), RID());
return data->texture_rids[p_image_index];
}
Original file line number Diff line number Diff line change
@@ -315,8 +315,8 @@ void OpenXROpenGLExtension::cleanup_swapchain_graphics_data(void **p_swapchain_g

SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data;

for (int i = 0; i < data->texture_rids.size(); i++) {
texture_storage->texture_free(data->texture_rids[i]);
for (const RID &texture_rid : data->texture_rids) {
texture_storage->texture_free(texture_rid);
}
data->texture_rids.clear();

16 changes: 8 additions & 8 deletions modules/openxr/extensions/platform/openxr_vulkan_extension.cpp
Original file line number Diff line number Diff line change
@@ -291,12 +291,12 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
// This also means we're reading the values as is for our preview on screen.
// The OpenXR runtime however is still treating this as an sRGB format and
// will thus do an sRGB -> Linear conversion as expected.
// format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
//format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM;
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
case VK_FORMAT_B8G8R8A8_SRGB:
// format = RenderingDevice::DATA_FORMAT_B8G8R8A8_SRGB;
//format = RenderingDevice::DATA_FORMAT_B8G8R8A8_SRGB;
format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UNORM;
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
break;
@@ -322,7 +322,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
break;
default:
// continue with our default value
print_line("Unsupported swapchain format ", p_swapchain_format);
print_line("OpenXR: Unsupported swapchain format", p_swapchain_format);
break;
}

@@ -350,7 +350,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
break;
default:
// continue with our default value
print_line("Unsupported sample count ", p_sample_count);
print_line("OpenXR: Unsupported sample count", p_sample_count);
break;
}

@@ -380,7 +380,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
}

bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
// Even though this is a Vulkan renderer we're using OpenGL coordinate systems
// Even though this is a Vulkan renderer we're using OpenGL coordinate systems.
OpenXRUtil::XrMatrix4x4f matrix;
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);

@@ -413,9 +413,9 @@ void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_g
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
ERR_FAIL_NULL(rendering_device);

for (int i = 0; i < data->texture_rids.size(); i++) {
// This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain
rendering_device->free(data->texture_rids[i]);
for (const RID &texture_rid : data->texture_rids) {
// This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain.
rendering_device->free(texture_rid);
}
data->texture_rids.clear();

29 changes: 18 additions & 11 deletions modules/openxr/openxr_api.cpp
Original file line number Diff line number Diff line change
@@ -49,6 +49,10 @@
#include "extensions/platform/openxr_vulkan_extension.h"
#endif

#ifdef METAL_ENABLED
#include "extensions/platform/openxr_metal_extension.h"
#endif

#if defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
#include "extensions/platform/openxr_opengl_extension.h"
#endif
@@ -1174,12 +1178,9 @@ bool OpenXRAPI::obtain_swapchain_formats() {
}
}

if (color_swapchain_format == 0) {
color_swapchain_format = usable_swapchain_formats[0]; // just use the first one and hope for the best...
print_line("Couldn't find usable color swap chain format, using", get_swapchain_format_name(color_swapchain_format), "instead.");
} else {
print_verbose(String("Using color swap chain format:") + get_swapchain_format_name(color_swapchain_format));
}
ERR_FAIL_COND_V_MSG(color_swapchain_format == 0, false, "OpenXR: No usable color swap chain format available!");

print_verbose(String("Using color swap chain format:") + get_swapchain_format_name(color_swapchain_format));
}

{
@@ -1196,11 +1197,9 @@ bool OpenXRAPI::obtain_swapchain_formats() {
}
}

if (depth_swapchain_format == 0) {
WARN_PRINT_ONCE("Couldn't find usable depth swap chain format, depth buffer will not be submitted if requested.");
} else {
print_verbose(String("Using depth swap chain format:") + get_swapchain_format_name(depth_swapchain_format));
}
ERR_FAIL_COND_V_MSG(depth_swapchain_format == 0, false, "OpenXR: No usable depth swap chain format available!");

print_verbose(String("Using depth swap chain format:") + get_swapchain_format_name(depth_swapchain_format));
}

return true;
@@ -1657,6 +1656,14 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
#else
// shouldn't be possible...
ERR_FAIL_V(false);
#endif
} else if (p_rendering_driver == "metal") {
#ifdef METAL_ENABLED
graphics_extension = memnew(OpenXRMetalExtension);
register_extension_wrapper(graphics_extension);
#else
// shouldn't be possible...
ERR_FAIL_V(false);
#endif
} else if (p_rendering_driver == "opengl3") {
#if defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
5 changes: 5 additions & 0 deletions modules/openxr/openxr_platform_inc.h
Original file line number Diff line number Diff line change
@@ -39,6 +39,11 @@
#include "drivers/vulkan/rendering_context_driver_vulkan.h"
#endif // VULKAN_ENABLED

#ifdef METAL_ENABLED
#define XR_USE_GRAPHICS_API_METAL
#include "drivers/metal/rendering_context_driver_metal.h"
#endif // METAL_ENABLED

#if defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
#ifdef ANDROID_ENABLED
#define XR_USE_GRAPHICS_API_OPENGL_ES