Skip to content

Commit

Permalink
openxr extensions deferred init (#1258)
Browse files Browse the repository at this point in the history
Co-authored-by: Gary Hsu <[email protected]>
  • Loading branch information
CedricGuillemet and bghgary authored Jul 18, 2023
1 parent bd7a176 commit c89031e
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 67 deletions.
4 changes: 2 additions & 2 deletions Dependencies/xr/Source/OpenXR/SceneUnderstanding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct SceneUnderstanding::SceneUnderstanding::Impl

void Initialize(const InitOptions& options)
{
if (options.Extensions.SceneUnderstandingSupported)
if (options.Extensions.SceneUnderstandingSupported())
{
m_updateInterval = static_cast<XrTime>(NANOSECONDS_IN_SECOND * options.UpdateIntervalInSeconds);

Expand Down Expand Up @@ -215,7 +215,7 @@ struct SceneUnderstanding::SceneUnderstanding::Impl

void Enable(const InitOptions& options)
{
if (!options.Extensions.SceneUnderstandingSupported)
if (!options.Extensions.SceneUnderstandingSupported())
{
return;
}
Expand Down
33 changes: 21 additions & 12 deletions Dependencies/xr/Source/OpenXR/XR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,21 @@ namespace xr
XrSessionContext::Impl()
: Extensions(std::make_unique<XrSupportedExtensions>()) {}

void InitializeExtensions()
{
if (Instance.Get() == XR_NULL_HANDLE)
{
throw std::runtime_error{ "Attempted to initialize extensions when instance was null" };
}
Extensions->Initialize();
}

void PopulateExtensions()
{
if (Instance.Get() == XR_NULL_HANDLE)
{
throw std::runtime_error{ "Attempted to populate extensions when instance was null" };
}

Extensions->PopulateDispatchTable(Instance.Get());
}

Expand Down Expand Up @@ -210,12 +218,13 @@ namespace xr
// Phase one of initialization. Cannot fail without crashing.
void InitializeXrInstanceAndExtensions()
{
Context.ContextImpl->InitializeExtensions();
auto& extensions = Context.ContextImpl->Extensions;
auto& instanceHandle = Context.ContextImpl->Instance;

XrInstanceCreateInfo createInfo{ XR_TYPE_INSTANCE_CREATE_INFO };
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions->Names.size());
createInfo.enabledExtensionNames = extensions->Names.data();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions->Names().size());
createInfo.enabledExtensionNames = extensions->Names().data();
createInfo.applicationInfo = { "", 1, "BabylonNative", 1, XR_CURRENT_API_VERSION };
strcpy_s(createInfo.applicationInfo.applicationName, ApplicationName.c_str());
XrCheck(xrCreateInstance(&createInfo, instanceHandle.Put()));
Expand Down Expand Up @@ -344,7 +353,7 @@ namespace xr
XrCheck(xrCreateSession(instance, &createInfo, sessionHandle.Put()));

// Initialize scene space
if (extensions->UnboundedRefSpaceSupported)
if (extensions->UnboundedRefSpaceSupported())
{
sceneSpaceType = XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT;
}
Expand Down Expand Up @@ -441,7 +450,7 @@ namespace xr
const auto& apiExtensions = *HmdImpl.Context.Extensions();
const auto& sceneSpace = HmdImpl.Context.Space();

if (!apiExtensions.SpatialAnchorSupported)
if (!apiExtensions.SpatialAnchorSupported())
{
throw std::runtime_error("Spatial anchors are not supported for this device.");
}
Expand Down Expand Up @@ -578,7 +587,7 @@ namespace xr
{
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT
};
if (HmdImpl.Context.Extensions()->SecondaryViewConfigurationSupported &&
if (HmdImpl.Context.Extensions()->SecondaryViewConfigurationSupported() &&
viewConfigType == XR_VIEW_CONFIGURATION_TYPE_SECONDARY_MONO_FIRST_PERSON_OBSERVER_MSFT)
{
secondaryViewConfigCreateInfo.viewConfigurationType = viewConfigType;
Expand Down Expand Up @@ -654,8 +663,8 @@ namespace xr
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT
};
const auto& supportedSecondaryViewConfigTypes = HmdImpl.SupportedSecondaryViewConfigurationTypes;
if (HmdImpl.Context.Extensions()->SecondaryViewConfigurationSupported &&
HmdImpl.Context.Extensions()->FirstPersonObserverSupported &&
if (HmdImpl.Context.Extensions()->SecondaryViewConfigurationSupported() &&
HmdImpl.Context.Extensions()->FirstPersonObserverSupported() &&
supportedSecondaryViewConfigTypes.size() > 0)
{
secondaryViewConfigSessionBeginInfo.viewConfigurationCount = static_cast<uint32_t>(supportedSecondaryViewConfigTypes.size());
Expand Down Expand Up @@ -755,7 +764,7 @@ namespace xr
assert(viewCountOutput == renderResource.DepthSwapchain.ArraySize);

renderResource.ProjectionLayerViews.resize(viewCountOutput);
if (context.Extensions()->DepthExtensionSupported)
if (context.Extensions()->DepthExtensionSupported())
{
renderResource.DepthInfoViews.resize(viewCountOutput);
}
Expand Down Expand Up @@ -983,7 +992,7 @@ namespace xr
{
const auto& context = sessionImpl.HmdImpl.Context;
const auto& sceneSpace = context.Space();
const auto depthSupported = context.Extensions()->DepthExtensionSupported;
const auto depthSupported = context.Extensions()->DepthExtensionSupported();

uint32_t totalViewCount = 0;
uint32_t primaryViewCount;
Expand Down Expand Up @@ -1085,7 +1094,7 @@ namespace xr
const auto& supportedSecondaryViewConfigTypes = m_impl->sessionImpl.HmdImpl.SupportedSecondaryViewConfigurationTypes;
std::vector<XrSecondaryViewConfigurationLayerInfoMSFT> activeSecondaryViewConfigLayerInfos;
XrSecondaryViewConfigurationFrameEndInfoMSFT frameEndSecondaryViewConfigInfo{ XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT };
if (extensions->SecondaryViewConfigurationSupported && supportedSecondaryViewConfigTypes.size() > 0)
if (extensions->SecondaryViewConfigurationSupported() && supportedSecondaryViewConfigTypes.size() > 0)
{
activeSecondaryViewConfigLayerInfos.reserve(supportedSecondaryViewConfigTypes.size());
const auto& resourceMap = m_impl->sessionImpl.RenderResources.ResourceMap;
Expand Down Expand Up @@ -1151,7 +1160,7 @@ namespace xr
frameEndInfo.layerCount = 1;
frameEndInfo.layers = &layersPtr;

if (extensions->SecondaryViewConfigurationSupported &&
if (extensions->SecondaryViewConfigurationSupported() &&
activeSecondaryViewConfigLayerInfos.size() > 0)
{
for (size_t i = 0; i < activeSecondaryViewConfigLayerInfos.size(); i++)
Expand Down
12 changes: 6 additions & 6 deletions Dependencies/xr/Source/OpenXR/XrInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ namespace xr
SupportsEyeTracking = args.EyeGazeInteractionProps.supportsEyeGazeInteraction;

// Initialize the hand resources
HandData.SupportsArticulatedHandTracking = args.HandTrackingInteractionProps.supportsHandTracking && args.Extensions.HandTrackingSupported;
HandData.SupportsArticulatedHandTracking = args.HandTrackingInteractionProps.supportsHandTracking && args.Extensions.HandTrackingSupported();
InitializeHandResources(args.Session, args.Extensions);

m_destroyHandTrackers = [this, extensions = args.Extensions]() {
Expand Down Expand Up @@ -348,7 +348,7 @@ namespace xr
microsoftControllerBindings.push_back({ ActionResources.ControllerGetGripPoseAction });
XrCheck(xrStringToPath(instance, path.data(), &microsoftControllerBindings.back().binding));

if (extensions.HandInteractionSupported)
if (extensions.HandInteractionSupported())
{
microsoftHandBindings.push_back({ ActionResources.ControllerGetGripPoseAction });
XrCheck(xrStringToPath(instance, path.data(), &microsoftHandBindings.back().binding));
Expand Down Expand Up @@ -385,7 +385,7 @@ namespace xr
microsoftControllerBindings.push_back({ ActionResources.ControllerGetAimPoseAction });
XrCheck(xrStringToPath(instance, path.data(), &microsoftControllerBindings.back().binding));

if (extensions.HandInteractionSupported)
if (extensions.HandInteractionSupported())
{
microsoftHandBindings.push_back({ ActionResources.ControllerGetAimPoseAction });
XrCheck(xrStringToPath(instance, path.data(), &microsoftHandBindings.back().binding));
Expand Down Expand Up @@ -512,7 +512,7 @@ namespace xr
instance,
idx);

if (extensions.HandInteractionSupported)
if (extensions.HandInteractionSupported())
{
// Create action and suggested bindings specific to hands
CreateControllerActionAndBinding(
Expand Down Expand Up @@ -551,7 +551,7 @@ namespace xr
microsoftControllerSuggestedBindings.countSuggestedBindings = (uint32_t)microsoftControllerBindings.size();
XrCheck(xrSuggestInteractionProfileBindings(instance, &microsoftControllerSuggestedBindings));

if (extensions.HandInteractionSupported)
if (extensions.HandInteractionSupported())
{
// Provide Microsoft hand suggested binding to instance
XrInteractionProfileSuggestedBinding microsoftHandSuggestedBindings{ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING };
Expand Down Expand Up @@ -689,7 +689,7 @@ namespace xr
else if (interactionProfilePath == actionResources.MicrosoftHandInteractionPath)
{
// Get hand interaction data
if (args.Extensions.HandInteractionSupported)
if (args.Extensions.HandInteractionSupported())
{
const auto& controllerInfo = ControllerInfo;
auto& gamepadObject = inputSource.GamepadObject;
Expand Down
2 changes: 1 addition & 1 deletion Dependencies/xr/Source/OpenXR/XrRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace xr
bool OPENXR_CONTEXT_INTERFACE_API IsSessionRunning() const override;
XrResult OPENXR_CONTEXT_INTERFACE_API GetInstanceProcAddr(const char* name, PFN_xrVoidFunction* function) const override;

const std::unique_ptr<XrSupportedExtensions>& XrSessionContext::Extensions() const;
const std::unique_ptr<XrSupportedExtensions>& Extensions() const;
const SceneUnderstanding& SceneUnderstanding() const;

struct Impl;
Expand Down
165 changes: 119 additions & 46 deletions Dependencies/xr/Source/OpenXR/XrSupportedExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,13 @@ namespace xr
struct XrSupportedExtensions : ExtensionDispatchTable
{
XrSupportedExtensions()
: Names{}
: m_names{}
{
uint32_t extensionCount{};
XrResult result{ xrEnumerateInstanceExtensionProperties(nullptr, 0, &extensionCount, nullptr) };
if (result != XR_SUCCESS)
{
// Avoid failing if device doesn't support OpenXR
return;
}

m_extensionProperties.resize(extensionCount, { XR_TYPE_EXTENSION_PROPERTIES });
XrCheck(xrEnumerateInstanceExtensionProperties(nullptr, extensionCount, &extensionCount, m_extensionProperties.data()));

// D3D11 extension is required, so check if it's supported.
for (const char* extensionName : REQUIRED_EXTENSIONS)
{
if (!TryEnableExtension(extensionName))
{
throw std::runtime_error{ "Required extension not supported" };
}
}

// Additional optional extensions for enhanced functionality. Track whether enabled in m_optionalExtensions.
DepthExtensionSupported = TryEnableExtension(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME);
UnboundedRefSpaceSupported = TryEnableExtension(XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME);
SpatialAnchorSupported = TryEnableExtension(XR_MSFT_SPATIAL_ANCHOR_EXTENSION_NAME);
SpatialAnchorInteropSupported = TryEnableExtension(XR_MSFT_PERCEPTION_ANCHOR_INTEROP_EXTENSION_NAME);
SecondaryViewConfigurationSupported = TryEnableExtension(XR_MSFT_SECONDARY_VIEW_CONFIGURATION_EXTENSION_NAME);
FirstPersonObserverSupported = TryEnableExtension(XR_MSFT_FIRST_PERSON_OBSERVER_EXTENSION_NAME);
HandInteractionSupported = TryEnableExtension(XR_MSFT_HAND_INTERACTION_EXTENSION_NAME);
HandTrackingSupported = TryEnableExtension(XR_EXT_HAND_TRACKING_EXTENSION_NAME);
SceneUnderstandingSupported = TryEnableExtension(XR_MSFT_SCENE_UNDERSTANDING_EXTENSION_NAME);
SceneUnderstandingSerializationSupported = TryEnableExtension(XR_MSFT_SCENE_UNDERSTANDING_SERIALIZATION_EXTENSION_NAME);
EyeTrackingSupported = TryEnableExtension(XR_EXT_EYE_GAZE_INTERACTION_EXTENSION_NAME);
}

bool TryEnableExtension(const char* extensionName)
{
assert(m_initialized);
if (m_supportedExtensionNames.count(extensionName) > 0)
{
return true;
Expand All @@ -55,7 +24,7 @@ namespace xr
{
if (strcmp(extensionProperty.extensionName, extensionName) == 0)
{
Names.push_back(extensionName);
m_names.push_back(extensionName);
m_supportedExtensionNames.insert(extensionName);
return true;
}
Expand All @@ -65,25 +34,129 @@ namespace xr

bool IsExtensionSupported(const std::string& extensionName) const
{
assert(m_initialized);
return m_supportedExtensionNames.count(extensionName) > 0;
}

std::vector<const char*> Names{};
bool DepthExtensionSupported{ false };
bool UnboundedRefSpaceSupported{ false };
bool SpatialAnchorSupported{ false };
bool SpatialAnchorInteropSupported{ false };
bool SecondaryViewConfigurationSupported{ false };
bool FirstPersonObserverSupported{ false };
bool HandInteractionSupported{ false };
bool HandTrackingSupported{ false };
bool SceneUnderstandingSupported{ false };
bool SceneUnderstandingSerializationSupported{ false };
bool EyeTrackingSupported{ false };
bool DepthExtensionSupported() const
{
assert(m_initialized);
return m_depthExtensionSupported;
}
bool UnboundedRefSpaceSupported() const
{
assert(m_initialized);
return m_unboundedRefSpaceSupported;
}
bool SpatialAnchorSupported() const
{
assert(m_initialized);
return m_spatialAnchorSupported;
}
bool SpatialAnchorInteropSupported() const
{
assert(m_initialized);
return m_spatialAnchorInteropSupported;
}
bool SecondaryViewConfigurationSupported() const
{
assert(m_initialized);
return m_secondaryViewConfigurationSupported;
}
bool FirstPersonObserverSupported() const
{
assert(m_initialized);
return m_firstPersonObserverSupported;
}
bool HandInteractionSupported() const
{
assert(m_initialized);
return m_handInteractionSupported;
}
bool HandTrackingSupported() const
{
assert(m_initialized);
return m_handTrackingSupported;
}
bool SceneUnderstandingSupported() const
{
assert(m_initialized);
return m_sceneUnderstandingSupported;
}
bool SceneUnderstandingSerializationSupported() const
{
assert(m_initialized);
return m_sceneUnderstandingSerializationSupported;
}
bool EyeTrackingSupported() const
{
assert(m_initialized);
return m_eyeTrackingSupported;
}

void Initialize()
{
if (m_initialized)
{
return;
}
m_initialized = true;
uint32_t extensionCount{};
XrResult result{ xrEnumerateInstanceExtensionProperties(nullptr, 0, &extensionCount, nullptr) };
if (result != XR_SUCCESS)
{
// Avoid failing if device doesn't support OpenXR
return;
}

m_extensionProperties.resize(extensionCount, { XR_TYPE_EXTENSION_PROPERTIES });
XrCheck(xrEnumerateInstanceExtensionProperties(nullptr, extensionCount, &extensionCount, m_extensionProperties.data()));

// D3D11 extension is required, so check if it's supported.
for (const char* extensionName : REQUIRED_EXTENSIONS)
{
if (!TryEnableExtension(extensionName))
{
throw std::runtime_error{ "Required extension not supported" };
}
}

// Additional optional extensions for enhanced functionality. Track whether enabled in m_optionalExtensions.
m_depthExtensionSupported = TryEnableExtension(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME);
m_unboundedRefSpaceSupported = TryEnableExtension(XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME);
m_spatialAnchorSupported = TryEnableExtension(XR_MSFT_SPATIAL_ANCHOR_EXTENSION_NAME);
m_spatialAnchorInteropSupported = TryEnableExtension(XR_MSFT_PERCEPTION_ANCHOR_INTEROP_EXTENSION_NAME);
m_secondaryViewConfigurationSupported = TryEnableExtension(XR_MSFT_SECONDARY_VIEW_CONFIGURATION_EXTENSION_NAME);
m_firstPersonObserverSupported = TryEnableExtension(XR_MSFT_FIRST_PERSON_OBSERVER_EXTENSION_NAME);
m_handInteractionSupported = TryEnableExtension(XR_MSFT_HAND_INTERACTION_EXTENSION_NAME);
m_handTrackingSupported = TryEnableExtension(XR_EXT_HAND_TRACKING_EXTENSION_NAME);
m_sceneUnderstandingSupported = TryEnableExtension(XR_MSFT_SCENE_UNDERSTANDING_EXTENSION_NAME);
m_sceneUnderstandingSerializationSupported = TryEnableExtension(XR_MSFT_SCENE_UNDERSTANDING_SERIALIZATION_EXTENSION_NAME);
m_eyeTrackingSupported = TryEnableExtension(XR_EXT_EYE_GAZE_INTERACTION_EXTENSION_NAME);
}
const std::vector<const char*>& Names() const
{
assert(m_initialized);
return m_names;
}
private:
std::vector<const char*> m_names{};
std::vector<XrExtensionProperties> m_extensionProperties{};
std::unordered_set<std::string> m_supportedExtensionNames{};

bool m_depthExtensionSupported{ false };
bool m_unboundedRefSpaceSupported{ false };
bool m_spatialAnchorSupported{ false };
bool m_spatialAnchorInteropSupported{ false };
bool m_secondaryViewConfigurationSupported{ false };
bool m_firstPersonObserverSupported{ false };
bool m_handInteractionSupported{ false };
bool m_handTrackingSupported{ false };
bool m_sceneUnderstandingSupported{ false };
bool m_sceneUnderstandingSerializationSupported{ false };
bool m_eyeTrackingSupported{ false };

bool m_initialized{ false };
};
}
#endif

0 comments on commit c89031e

Please sign in to comment.