add package files

This commit is contained in:
VR164000
2023-06-15 09:52:08 +08:00
parent 06d41412be
commit a0b3b91879
382 changed files with 44971 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
// Unity Native Plugin API copyright © 2015 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
// Unity native plugin API
// Compatible with C99
#if defined(__CYGWIN32__)
#define UNITY_INTERFACE_API __stdcall
#define UNITY_INTERFACE_EXPORT __declspec(dllexport)
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WINAPI_FAMILY)
#define UNITY_INTERFACE_API __stdcall
#define UNITY_INTERFACE_EXPORT __declspec(dllexport)
#elif defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || defined(LUMIN)
#define UNITY_INTERFACE_API
#define UNITY_INTERFACE_EXPORT __attribute__ ((visibility ("default")))
#else
#define UNITY_INTERFACE_API
#define UNITY_INTERFACE_EXPORT
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IUnityInterface is a registry of interfaces we choose to expose to plugins.
//
// USAGE:
// ---------
// To retrieve an interface a user can do the following from a plugin, assuming they have the header file for the interface:
//
// IMyInterface * ptr = registry->Get<IMyInterface>();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Unity Interface GUID
// Ensures global uniqueness.
//
// Template specialization is used to produce a means of looking up a GUID from its interface type at compile time.
// The net result should compile down to passing around the GUID.
//
// UNITY_REGISTER_INTERFACE_GUID should be placed in the header file of any interface definition outside of all namespaces.
// The interface structure and the registration GUID are all that is required to expose the interface to other systems.
struct UnityInterfaceGUID
{
#ifdef __cplusplus
UnityInterfaceGUID(unsigned long long high, unsigned long long low)
: m_GUIDHigh(high)
, m_GUIDLow(low)
{
}
UnityInterfaceGUID(const UnityInterfaceGUID& other)
{
m_GUIDHigh = other.m_GUIDHigh;
m_GUIDLow = other.m_GUIDLow;
}
UnityInterfaceGUID& operator=(const UnityInterfaceGUID& other)
{
m_GUIDHigh = other.m_GUIDHigh;
m_GUIDLow = other.m_GUIDLow;
return *this;
}
bool Equals(const UnityInterfaceGUID& other) const { return m_GUIDHigh == other.m_GUIDHigh && m_GUIDLow == other.m_GUIDLow; }
bool LessThan(const UnityInterfaceGUID& other) const { return m_GUIDHigh < other.m_GUIDHigh || (m_GUIDHigh == other.m_GUIDHigh && m_GUIDLow < other.m_GUIDLow); }
#endif
unsigned long long m_GUIDHigh;
unsigned long long m_GUIDLow;
};
#ifdef __cplusplus
inline bool operator==(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return left.Equals(right); }
inline bool operator!=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !left.Equals(right); }
inline bool operator<(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return left.LessThan(right); }
inline bool operator>(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return right.LessThan(left); }
inline bool operator>=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !operator<(left, right); }
inline bool operator<=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !operator>(left, right); }
#else
typedef struct UnityInterfaceGUID UnityInterfaceGUID;
#endif
#ifdef __cplusplus
#define UNITY_DECLARE_INTERFACE(NAME) \
struct NAME : IUnityInterface
// Generic version of GetUnityInterfaceGUID to allow us to specialize it
// per interface below. The generic version has no actual implementation
// on purpose.
//
// If you get errors about return values related to this method then
// you have forgotten to include UNITY_REGISTER_INTERFACE_GUID with
// your interface, or it is not visible at some point when you are
// trying to retrieve or add an interface.
template<typename TYPE>
inline const UnityInterfaceGUID GetUnityInterfaceGUID();
// This is the macro you provide in your public interface header
// outside of a namespace to allow us to map between type and GUID
// without the user having to worry about it when attempting to
// add or retrieve and interface from the registry.
#define UNITY_REGISTER_INTERFACE_GUID(HASHH, HASHL, TYPE) \
template<> \
inline const UnityInterfaceGUID GetUnityInterfaceGUID<TYPE>() \
{ \
return UnityInterfaceGUID(HASHH,HASHL); \
}
// Same as UNITY_REGISTER_INTERFACE_GUID but allows the interface to live in
// a particular namespace. As long as the namespace is visible at the time you call
// GetUnityInterfaceGUID< INTERFACETYPE >() or you explicitly qualify it in the template
// calls this will work fine, only the macro here needs to have the additional parameter
#define UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(HASHH, HASHL, TYPE, NAMESPACE) \
const UnityInterfaceGUID TYPE##_GUID(HASHH, HASHL); \
template<> \
inline const UnityInterfaceGUID GetUnityInterfaceGUID< NAMESPACE :: TYPE >() \
{ \
return UnityInterfaceGUID(HASHH,HASHL); \
}
// These macros allow for C compatibility in user code.
#define UNITY_GET_INTERFACE_GUID(TYPE) GetUnityInterfaceGUID< TYPE >()
#else
#define UNITY_DECLARE_INTERFACE(NAME) \
typedef struct NAME NAME; \
struct NAME
// NOTE: This has the downside that one some compilers it will not get stripped from all compilation units that
// can see a header containing this constant. However, it's only for C compatibility and thus should have
// minimal impact.
#define UNITY_REGISTER_INTERFACE_GUID(HASHH, HASHL, TYPE) \
const UnityInterfaceGUID TYPE##_GUID = {HASHH, HASHL};
// In general namespaces are going to be a problem for C code any interfaces we expose in a namespace are
// not going to be usable from C.
#define UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(HASHH, HASHL, TYPE, NAMESPACE)
// These macros allow for C compatibility in user code.
#define UNITY_GET_INTERFACE_GUID(TYPE) TYPE##_GUID
#endif
// Using this in user code rather than INTERFACES->Get<TYPE>() will be C compatible for those places in plugins where
// this may be needed. Unity code itself does not need this.
#define UNITY_GET_INTERFACE(INTERFACES, TYPE) (TYPE*)INTERFACES->GetInterfaceSplit (UNITY_GET_INTERFACE_GUID(TYPE).m_GUIDHigh, UNITY_GET_INTERFACE_GUID(TYPE).m_GUIDLow);
#ifdef __cplusplus
struct IUnityInterface
{
};
#else
typedef void IUnityInterface;
#endif
typedef struct IUnityInterfaces
{
// Returns an interface matching the guid.
// Returns nullptr if the given interface is unavailable in the active Unity runtime.
IUnityInterface* (UNITY_INTERFACE_API * GetInterface)(UnityInterfaceGUID guid);
// Registers a new interface.
void(UNITY_INTERFACE_API * RegisterInterface)(UnityInterfaceGUID guid, IUnityInterface * ptr);
// Split APIs for C
IUnityInterface* (UNITY_INTERFACE_API * GetInterfaceSplit)(unsigned long long guidHigh, unsigned long long guidLow);
void(UNITY_INTERFACE_API * RegisterInterfaceSplit)(unsigned long long guidHigh, unsigned long long guidLow, IUnityInterface * ptr);
#ifdef __cplusplus
// Helper for GetInterface.
template<typename INTERFACE>
INTERFACE* Get()
{
return static_cast<INTERFACE*>(GetInterface(GetUnityInterfaceGUID<INTERFACE>()));
}
// Helper for RegisterInterface.
template<typename INTERFACE>
void Register(IUnityInterface* ptr)
{
RegisterInterface(GetUnityInterfaceGUID<INTERFACE>(), ptr);
}
#endif
} IUnityInterfaces;
#ifdef __cplusplus
extern "C" {
#endif
// If exported by a plugin, this function will be called when the plugin is loaded.
void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces);
// If exported by a plugin, this function will be called when the plugin is about to be unloaded.
void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload();
#ifdef __cplusplus
}
#endif
struct RenderSurfaceBase;
typedef struct RenderSurfaceBase* UnityRenderBuffer;
typedef unsigned int UnityTextureID;

View File

@@ -0,0 +1,382 @@
// Unity Native Plugin API copyright © 2019 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
#if UNITY
# include "Modules/XR/ProviderInterface/UnityXRTypes.h"
# include "Modules/XR/ProviderInterface/UnityXRSubsystemTypes.h"
#else
# include "UnityXRTypes.h"
# include "UnityXRSubsystemTypes.h"
#endif
#include <stddef.h>
#include <stdint.h>
/// @file IUnityXRMeshing.h
/// @brief XR interface for mesh generation and allocation of related data structures.
/// @see IUnityXRMeshInterface
/// The format used for an index buffer
typedef enum UnityXRIndexFormat
{
kUnityXRIndexFormat16Bit, ///< 16 bit indices, e.g., uint16_t
kUnityXRIndexFormat32Bit ///< 32 bit indices, e.g., uint32_t
} UnityXRIndexFormat;
/// The type of mesh data, e.g., points, triangles, quads, etc.
/// This affects how the vertex and index data are interpreted.
typedef enum UnityXRMeshTopology
{
/// The mesh data represents triangles, with 3 indices per triangle.
kUnityXRMeshTopologyTriangles,
/// The mesh data represents a triangle strip. There are 3 indices
/// for the first triangle, then every point after that is another triangle.
kUnityXRMeshTopologyTriangleStrip,
/// The mesh data represents quads, with 4 indices per quad.
kUnityXRMeshTopologyQuads,
/// The mesh data represents lines, with 2 indices per line.
kUnityXRMeshTopologyLines,
/// The mesh data represents a line strip. The are 2 indices
/// for the first line, then every index after that is another line.
kUnityXRMeshTopologyLineStrip,
/// The mesh data represents individual points, with 1 index per point.
kUnityXRMeshTopologyPoints
} UnityXRMeshTopology;
/// Flags representing vertex attributes
typedef enum UnityXRMeshVertexAttributeFlags
{
/// The vertex contains normal data
kUnityXRMeshVertexAttributeFlagsNormals = 1 << 0,
/// The vertex contains tangent data
kUnityXRMeshVertexAttributeFlagsTangents = 1 << 1,
/// The vertex contains uv data
kUnityXRMeshVertexAttributeFlagsUvs = 1 << 2,
/// The vertex contains color data
kUnityXRMeshVertexAttributeFlagsColors = 1 << 3
} UnityXRMeshVertexAttributeFlags;
/// Describes a single mesh, with buffers pointing to each vertex attribute.
/// Note: Unity uses a left-handed coordinate system with clockwise triangle winding.
/// +X is right
/// +Y is up
/// +Z is forward
typedef struct UnityXRMeshDescriptor
{
/// Pointer to positions buffer. May not be null.
UnityXRVector3* positions;
/// Pointer to normals buffer. May be null.
UnityXRVector3* normals;
/// Pointer to tangents buffer. May be null.
UnityXRVector4* tangents;
/// Pointer to uvs buffer. May be null.
UnityXRVector2* uvs;
/// Pointer to colors buffer. May be null.
UnityXRColorRGBA32* colors;
/// Index buffers
union
{
uint16_t* indices16; ///< Used if @a indexFormat is @a kUnityXRIndexFormat16Bit
uint32_t* indices32; ///< Used if @a indexFormat is @a kUnityXRIndexFormat32Bit
};
/// The number of vertices. Each non-null buffer above must
/// contain this number of elements.
size_t vertexCount;
/// The number of indices in the mesh.
size_t indexCount;
/// Which index format should be used, 16 or 32 bit.
UnityXRIndexFormat indexFormat;
/// The primitive type of the mesh data (e.g., points, lines, triangles, quads)
UnityXRMeshTopology topology;
} UnityXRMeshDescriptor;
/// Interface for allocating or setting mesh-related data
typedef struct UnityXRMeshDataAllocator UnityXRMeshDataAllocator;
/// A unique id assignable to a 'trackable', e.g. a plane or
/// point cloud point. Although this id is 128 bits, it may
/// not necessarily be globally unique; it just needs to be
/// unique to a particular XREnvironment session.
typedef struct UnityXRMeshId
{
/// 128-bit id data
uint64_t idPart[2];
} UnityXRMeshId;
#ifdef __cplusplus
inline bool operator==(const UnityXRMeshId& a, const UnityXRMeshId& b)
{
return
(a.idPart[0] == b.idPart[0]) &&
(a.idPart[1] == b.idPart[1]);
}
inline bool operator!=(const UnityXRMeshId& a, const UnityXRMeshId& b)
{
return
(a.idPart[0] != b.idPart[0]) ||
(a.idPart[1] != b.idPart[1]);
}
/// A comparator for UnityXRMeshId suitable for algorithms or containers that
/// require ordered UnityXRMeshIds, e.g. std::map
struct MeshIdLessThanComparator
{
bool operator()(const UnityXRMeshId& lhs, const UnityXRMeshId& rhs) const
{
if (lhs.idPart[0] == rhs.idPart[0])
{
return lhs.idPart[1] < rhs.idPart[1];
}
return lhs.idPart[0] < rhs.idPart[0];
}
};
#endif // __cplusplus
/// Information related to a mesh
typedef struct UnityXRMeshInfo
{
/// A session-unique identifier for the mesh.
UnityXRMeshId meshId;
/// True if the mesh has been updated (e.g., since the last query).
bool updated;
/// A hint for the system that determines when it should update
/// the corresponding Unity mesh.
int priorityHint;
} UnityXRMeshInfo;
/// An allocator for the @a UnityXRMeshInfo type.
typedef struct UnityXRMeshInfoAllocator UnityXRMeshInfoAllocator;
/// Enum describing the type of the bounding volume that will be passed
/// into @a SetBoundingVolume.
typedef enum UnityXRBoundingVolumeType
{
/// Axis Aligned Bounding Box bounding volume
kUnityXRBoundingVolumeAABB,
} UnityXRBoundingVolumeType;
/// Definition for an Axis Aligned Bounding Box (AABB).
/// This type of volume is aligned with the axis of the
/// current coordinate space. The definition of the
/// dimensions (m, cm, ft, etc.) is left up to the provider.
typedef struct UnityXRAABBBoundingVolume
{
/// The origin or center point for the AABB
/// In the current coordinate space.
UnityXRVector3 origin;
/// The extents of the AABB in each major axis
/// in the current coordinate space.
UnityXRVector3 extents;
} UnityXRAABBBoundingVolume;
/// Generic definition for a bounding volume passed to the
/// @a SetBoundingVolume api.
typedef struct UnityXRBoundingVolume
{
/// The type of the bounding volume described by
/// an instance of this struct.
/// See @a UnityXRBoundingVolumeType
UnityXRBoundingVolumeType type;
/// The actual bounding volume definition for
/// an instance of this struct. The specific field
/// to be used will be determined by what is set in the
/// @a type field.
union
{
/// See @a UnityXRAABBBoundingVolume
UnityXRAABBBoundingVolume aabb;
};
} UnityXRBoundingVolume;
/// Implement this interface for your mesh provider. A mesh provider will typically
/// provide multiple meshes, addressable by @a UnityXRMeshId.
typedef struct SUBSYSTEM_PROVIDER UnityXRMeshProvider
{
/// Plugin-specific data pointer. Every function in this structure will
/// be passed this data by the Unity runtime. The plugin should allocate
/// an appropriate data container for any information that is needed when
/// a callback function is called.
void* userData;
/// Invoked by Unity to retrieve information about every tracked mesh.
///
/// @param handle Handle obtained from UnityLifecycleProvider callbacks.
/// @param userData Value of userData field when provider was registered.
/// @param allocator Use this allocator to get a buffer of @a UnityXRMeshInfo.
/// This method should populate the buffer.
/// @return A @a UnitySubsystemErrorCode indicating success or failure.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * GetMeshInfos)(
UnitySubsystemHandle handle, void* userData, UnityXRMeshInfoAllocator * allocator);
/// Invoked from any thread by Unity to acquire a particular mesh by id.
/// This method should fill out a @a UnityXRMeshDescriptor using the provided
/// @a allocator. If the plugin owns the mesh memory, it should not mutate
/// the data until @a ReleaseMesh is called (see below).
///
/// @param handle Handle obtained from UnityLifecycleProvider callbacks.
/// @param userData Value of userData field when provider was registered.
/// @param meshId The session-unique identifier associated with this mesh.
/// @param allocator Used to either allocate a @a UnityXRMeshDescriptor from Unity
/// or provide one owned by the plugin.
/// @return A @a UnitySubsystemErrorCode indicating success or failure.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * AcquireMesh)(
UnitySubsystemHandle handle,
void* userData,
const UnityXRMeshId * meshId,
UnityXRMeshDataAllocator * allocator);
/// Invoked by Unity on the main thread to release a mesh by id.
/// This method should perform any required cleanup for the mesh.
///
/// @param handle Handle obtained from UnityLifecycleProvider callbacks.
/// @param userData Value of userData field when provider was registered.
/// @param meshId The session-unique identifier associated with this mesh.
/// @param mesh If the plugin owns the memory, then this is the same mesh
/// descriptor provided by the plugin in @a AcquireMesh. Otherwise, if Unity
/// owns the memory, then @a mesh will be null.
/// @param pluginData A pointer provided by the provider during @a AcquireMesh.
/// @return A @a UnitySubsystemErrorCode indicating success or failure.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * ReleaseMesh)(
UnitySubsystemHandle handle,
void* userData,
const UnityXRMeshId * meshId,
const UnityXRMeshDescriptor * mesh,
void* pluginData);
/// Invoked by Unity on the main thread to request a change in the density
/// of the generated meshes. Density level will be given as a value in the
/// range [0.0-1.0] and the provider will determine how best to map that
/// value to their implementation.
///
/// Setting this value does not guarantee an immediate change in the density
/// of any currently created mesh and may only change the density for new or
/// updated meshes.
///
/// @param handle Handle obtained from UnityLifecycleProvider callbacks.
/// @param userData Value of userData field when provider was registered.
/// @param density The requested density of generated meshes. Defined as a
/// float in the range [0.0-1.0]
/// @return A @a UnitySubsystemErrorCode indicating success or failure.
/// @a kUnitySubsystemErrorCodeSuccess Returned if everything is ok.
/// @a kUnitySubsystemErrorCodeInvalidArguments Returned if the density level
/// falls outside the expected range.
/// @a kUnitySubsystemErrorCodeNotSupported Returned if the provider does not
/// support this API in their implementation.
/// @a kUnitySubsystemErrorCodeFailure Returned for ny other error or issue
/// not defined above.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * SetMeshDensity)(
UnitySubsystemHandle handle,
void* userData,
float density);
/// Set the bounding volume to be used to restrict the space in which meshes will
/// be generated and tracked.
///
/// @param handle Handle obtained from UnityLifecycleProvider callbacks.
/// @param userData Value of userData field when provider was registered.
/// @param boundingVolume The bounding volume definition to use.
/// @return A @a UnitySubsystemErrorCode indicating success or failure.
/// @a kUnitySubsystemErrorCodeSuccess Returned if everything is ok.
/// @a kUnitySubsystemErrorCodeInvalidArguments Returned it the bounding
/// volume is null or the definition is incorrect.
/// @a kUnitySubsystemErrorCodeNotSupported Returned if the provider does not
/// support this API.
/// @a kUnitySubsystemErrorCodeNotSupported Returned if the provider does not
/// support the type of bounding volume being requested.
/// @a kUnitySubsystemErrorCodeFailure Returned for ny other error or issue
/// not defined above.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * SetBoundingVolume)(
UnitySubsystemHandle handle,
void* userData,
const UnityXRBoundingVolume* boundingVolume);
} UnityXRMeshProvider;
/// @brief XR interface for mesh generation and allocation of related data structures.
UNITY_DECLARE_INTERFACE(SUBSYSTEM_INTERFACE IUnityXRMeshInterface)
{
/// Allocates @a count @a UnityXRMeshInfo. Unity will periodically invoke your
/// plugin's @a GetMeshInfos function. Your plugin should then call
/// this function to allocate an array of @a UnityXRMeshInfo and populate them.
///
/// @param count The number of meshes currently tracked.
/// @return An array of @a UnityXRMeshInfo which the caller should populate with mesh info.
UnityXRMeshInfo* (UNITY_INTERFACE_API * MeshInfoAllocator_Allocate)(
UnityXRMeshInfoAllocator * allocator, size_t count);
/// Allocates mesh data according to the attributes specified in @a attributes.
/// Use this method if you want Unity to manage the mesh memory.
///
/// @param vertexCount The number of vertices to allocate.
/// @param triangleCount The number of triangles to allocate.
/// @param indexFormat The @a UnityXRIndexFormat indicating 16 or 32 bit indices
/// @param attributes The vertex attributes for which to allocate buffers.
UnityXRMeshDescriptor* (UNITY_INTERFACE_API * MeshDataAllocator_AllocateMesh)(
UnityXRMeshDataAllocator * allocator,
size_t vertexCount,
size_t indexCount,
UnityXRIndexFormat indexFormat,
UnityXRMeshVertexAttributeFlags attributes,
UnityXRMeshTopology topology);
/// Sets the mesh descriptor to use. Use this method if the plugin manages the memory.
/// The buffers pointed to by @a mesh must exist until Unity invokes @a ReleaseMesh.
///
/// @param meshDescriptor The mesh descriptor for a mesh. Unused vertex attributes should
/// be null. @a positions must be non null.
void(UNITY_INTERFACE_API * MeshDataAllocator_SetMesh)(
UnityXRMeshDataAllocator * allocator, const UnityXRMeshDescriptor * meshDescriptor);
/// (Optional) Set user data associated with this mesh. The userData pointer
/// will be passed back to the provider's @a ReleaseMesh method.
/// Use this to store additional data required to release the mesh.
///
/// @param userData A pointer which will be passed to ReleaseMesh
void(UNITY_INTERFACE_API * MeshDataAllocator_SetUserData)(
UnityXRMeshDataAllocator * allocator, void* userData);
/// Registers a mesh provider for your plugin to communicate mesh data back to Unity.
/// @param meshProvider The @a UnityXRMeshProvider which will be invoked by Unity to
/// retrieve mesh data.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * SUBSYSTEM_REGISTER_PROVIDER(UnityXRMeshProvider) RegisterMeshProvider)(
UnitySubsystemHandle handle, const UnityXRMeshProvider * meshProvider);
/// Entry-point for getting callbacks when the mesh subsystem is initialized / started / stopped / shutdown.
///
/// @param[in] pluginName Name of the plugin which was registered in your xr.json
/// @param[in] id Id of the subsystem that was registered in your xr.json
/// @param[in] provider Callbacks to register.
/// @return Status of function execution.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * RegisterLifecycleProvider)(
const char* pluginName, const char* id, const UnityLifecycleProvider * provider);
};
UNITY_REGISTER_INTERFACE_GUID(0x3007fd5885a346efULL, 0x9eeb2c84aa0a9dd9ULL, IUnityXRMeshInterface)

View File

@@ -0,0 +1,89 @@
// Unity Native Plugin API copyright © 2019 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
#if UNITY
#include "Runtime/PluginInterface/Headers/IUnityInterface.h"
#else
#include "IUnityInterface.h"
#endif
#include "stddef.h"
/// Error codes for Subsystem operations
typedef enum UnitySubsystemErrorCode
{
/// Indicates a successful operation
kUnitySubsystemErrorCodeSuccess,
/// Indicates the operation failed
kUnitySubsystemErrorCodeFailure,
/// Indicates invalid arguments were passed to the method
kUnitySubsystemErrorCodeInvalidArguments,
/// Indicates this feature is not supported
kUnitySubsystemErrorCodeNotSupported,
// A request to allocate memory by a subsystem has failed or can not be completed.
kUnitySubsystemErrorCodeOutOfMemory
} UnitySubsystemErrorCode;
/// An UnitySubsystemHandle is an opaque type that's passed between the plugin and Unity. (C-API)
typedef void* UnitySubsystemHandle;
/// Event handler implemented by the plugin for subsystem specific lifecycle events (C-API).
typedef struct UnityLifecycleProvider
{
/// Plugin-specific data pointer. Every function in this structure will
/// be passed this data by the Unity runtime. The plugin should allocate
/// an appropriate data container for any information that is needed when
/// a callback function is called.
void* userData;
/// Initialize the subsystem.
///
/// @param handle Handle for the current subsystem which can be passed to methods related to that subsystem.
/// @param data Value of userData field when provider was registered.
/// @return Status of function execution.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * Initialize)(UnitySubsystemHandle handle, void* data);
/// Start the subsystem.
///
/// @param handle Handle for the current subsystem which can be passed to methods related to that subsystem.
/// @param data Value of userData field when provider was registered.
/// @return Status of function execution.
UnitySubsystemErrorCode(UNITY_INTERFACE_API * Start)(UnitySubsystemHandle handle, void* data);
/// Stop the subsystem.
///
/// @param handle Handle for the current subsystem which can be passed to methods related to that subsystem.
/// @param data Value of userData field when provider was registered.
void(UNITY_INTERFACE_API * Stop)(UnitySubsystemHandle handle, void* data);
/// Shutdown the subsystem.
///
/// @param handle Handle for the current subsystem which can be passed to methods related to that subsystem.
/// @param data Value of userData field when provider was registered.
void(UNITY_INTERFACE_API * Shutdown)(UnitySubsystemHandle handle, void* data);
} UnityLifecycleProvider;
// Macros and defines for back-compatibility code-gen (#defined to no-op when code-gen not running)
#if SUBSYSTEM_CODE_GEN
#define SUBSYSTEM_PROVIDER __attribute__((annotate("provider")))
#define SUBSYSTEM_INTERFACE __attribute__((annotate("interface")))
#define SUBSYSTEM_ADAPT_FROM(FUNC_NAME) __attribute__((annotate("adapt_from_" #FUNC_NAME)))
#define SUBSYSTEM_REGISTER_PROVIDER(PROVIDER) __attribute__((annotate("register_provider_" #PROVIDER)))
#define SUBSYSTEM_ADAPT_IN_PROVIDER_REGISTRATION __attribute__((annotate("in_provider_registration")))
#define UNITY_DECLARE_INTERFACE(NAME) struct NAME
#define UNITY_INTERFACE_API
#else
#define SUBSYSTEM_PROVIDER
#define SUBSYSTEM_INTERFACE
#define SUBSYSTEM_ADAPT_FROM(FUNC_NAME)
#define SUBSYSTEM_REGISTER_PROVIDER(PROVIDER)
#define SUBSYSTEM_ADAPT_IN_PROVIDER_REGISTRATION
#endif

View File

@@ -0,0 +1,17 @@
// Unity Native Plugin API copyright © 2019 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
#include <stdint.h>
/// @cond undoc
#ifndef __cplusplus
#include <stdbool.h>
#endif
/// @endcond
/// The maximum length of a string, used in some structs with the subsystem headers
enum { kUnitySubsystemsStringSize = 128 };

View File

@@ -0,0 +1,15 @@
// Unity Native Plugin API copyright © 2019 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
#if UNITY
#include "Modules/Subsystems/ProviderInterface/UnitySubsystemTypes.h"
#include "Runtime/PluginInterface/Headers/IUnityInterface.h"
#else
#include "UnitySubsystemTypes.h"
#include "IUnityInterface.h"
#endif
#include "stddef.h"

View File

@@ -0,0 +1,146 @@
// Unity Native Plugin API copyright © 2019 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
#if UNITY
#include "Modules/Subsystems/ProviderInterface/UnityTypes.h"
#else
#include "UnityTypes.h"
#endif
/// The maximum length of a string, used in some structs with the XR headers
enum { kUnityXRStringSize = kUnitySubsystemsStringSize };
/// Simple 2-Element Float Vector
typedef struct UnityXRVector2
{
/// X component of the vector.
float x;
/// Y component of the vector.
float y;
} UnityXRVector2;
/// Simple 3-Element float vector
typedef struct UnityXRVector3
{
/// X component of the vector.
float x;
/// Y component of the vector.
float y;
/// Z component of the vector.
float z;
} UnityXRVector3;
/// Simple 4 Element Quaternion with indices ordered x, y, z, and w in order
typedef struct UnityXRVector4
{
/// X component of the vector.
float x;
/// Y component of the vector.
float y;
/// Z component of the vector.
float z;
/// W component of the vector.
float w;
} UnityXRVector4;
/// A simple struct representing a point in space with position and orientation
typedef struct UnityXRPose
{
/// Position of the pose.
UnityXRVector3 position;
/// Rotation of the pose, stored as a quaternion.
UnityXRVector4 rotation;
} UnityXRPose;
/// A 4x4 column-major matrix
typedef struct UnityXRMatrix4x4
{
///. The columns of the matrix
UnityXRVector4 columns[4];
} UnityXRMatrix4x4;
/// Multiple ways of representing a projection.
typedef enum UnityXRProjectionType
{
/// Projection represented as tangents of half angles from center.
kUnityXRProjectionTypeHalfAngles,
/// Projection represented as a 4x4 matrix.
kUnityXRProjectionTypeMatrix
} UnityXRProjectionType;
/// Projection as tangent of half angles on near plane.
typedef struct UnityXRProjectionHalfAngles
{
/// Tangent of the half angle from center to left clipping plane. (should be negative)
float left;
/// Tangent of the half angle from center to right clipping plane. (should be positive)
float right;
/// Tangent of the half angle from center to top clipping plane. (should be positive)
float top;
/// Tangent of the half angle from center to bottom clipping plane. (should be negative)
float bottom;
} UnityXRProjectionHalfAngles;
/// Container for the different methods of representing a projection matrix.
typedef struct UnityXRProjection
{
/// Choose the way this projection is represented.
UnityXRProjectionType type;
union
{
/// Valid if type is kUnityXRProjectionTypeHalfAngles.
UnityXRProjectionHalfAngles halfAngles;
/// Valid if type is kUnityXRProjectionTypeMatrix.
UnityXRMatrix4x4 matrix;
} data; ///< Contains all supported ways of representing a projection matrix.
} UnityXRProjection;
/// A 2D rectangle defined by X and Y position, width and height.
typedef struct UnityXRRectf
{
/// X position of the rectangle.
float x;
/// Y position of the rectangle.
float y;
/// Width of the rectangle.
float width;
/// Height of the rectangle.
float height;
} UnityXRRectf;
/// An RGBA color
typedef struct UnityXRColorRGBA32
{
/// The red channel
uint8_t red;
/// The green channel
uint8_t green;
/// The blue channel
uint8_t blue;
/// The alpha channel
uint8_t alpha;
} UnityXRColorRGBA32;
/// Represents milliseconds of UTC time since Unix epoch 1970-01-01T00:00:00Z.
typedef int64_t UnityXRTimeStamp;

View File

@@ -0,0 +1,594 @@
#include <openxr/openxr.h>
#include "IUnityInterface.h"
#include "XR/IUnityXRMeshing.h"
#include <map>
#include <memory>
#include <string>
#include <thread>
#include <fstream>
#include <vector>
static IUnityXRMeshInterface* s_Meshing = nullptr;
static XrInstance s_XrInstance = nullptr;
static XrSession s_XrSession = nullptr;
// XrSpace related function pointers
static PFN_xrEnumerateReferenceSpaces s_xrEnumerateReferenceSpaces = nullptr;
static PFN_xrCreateReferenceSpace s_xrCreateReferenceSpace = nullptr;
static PFN_xrDestroySpace s_xrDestroySpace = nullptr;
// XR_MSFT_scene_understanding function pointers
static PFN_xrEnumerateSceneComputeFeaturesMSFT s_xrEnumerateSceneComputeFeaturesMSFT = nullptr;
static PFN_xrCreateSceneObserverMSFT s_xrCreateSceneObserverMSFT = nullptr;
static PFN_xrDestroySceneObserverMSFT s_xrDestroySceneObserverMSFT = nullptr;
static PFN_xrCreateSceneMSFT s_xrCreateSceneMSFT = nullptr;
static PFN_xrDestroySceneMSFT s_xrDestroySceneMSFT = nullptr;
static PFN_xrComputeNewSceneMSFT s_xrComputeNewSceneMSFT = nullptr;
static PFN_xrGetSceneComputeStateMSFT s_xrGetSceneComputeStateMSFT = nullptr;
static PFN_xrGetSceneComponentsMSFT s_xrGetSceneComponentsMSFT = nullptr;
static PFN_xrLocateSceneComponentsMSFT s_xrLocateSceneComponentsMSFT = nullptr;
static PFN_xrGetSceneMeshBuffersMSFT s_xrGetSceneMeshBuffersMSFT = nullptr;
static XrReferenceSpaceType s_ReferenceSpaceType = XrReferenceSpaceType::XR_REFERENCE_SPACE_TYPE_STAGE;
static XrSpace s_XrSpace = nullptr;
static XrSceneObserverMSFT s_SceneObserver = nullptr;
static bool s_OpenXRReady = false;
static XrSceneComputeConsistencyMSFT s_SceneComputeConsistency = XrSceneComputeConsistencyMSFT::XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_INCOMPLETE_FAST_MSFT;
// User specified scene computation boundaries.
static std::vector<XrSceneSphereBoundMSFT> s_SceneSphereBounds;
static std::vector<XrSceneOrientedBoxBoundMSFT> s_SceneOrientedBoxBounds;
static std::vector<XrSceneFrustumBoundMSFT> s_SceneFrustumBounds;
static XrMeshComputeLodMSFT s_MeshComputeLod = XrMeshComputeLodMSFT::XR_MESH_COMPUTE_LOD_COARSE_MSFT;
void Log(const std::string& line)
{
std::ofstream file("meshing_plugin.log", std::ios::app);
if (!file.is_open()) return;
file << line << "\n";
}
void CheckResult(XrResult result, const std::string& funcName)
{
if (result != XrResult::XR_SUCCESS)
{
Log(funcName + " failure: " + std::to_string(result));
}
}
/**
* Make an XRSceneMSFT can be managed by shared pointers.
* The containing XRSceneMSFT is destroyed in the destructor
* by an OpenXR function, xrDestroySceneMSFT.
*/
class SharedOpenXRScene
{
public:
/**
* @param[in] scene A valid scene, which is created by xrCreateSceneMSFT.
*/
SharedOpenXRScene(XrSceneMSFT scene) : m_Scene(scene) {}
~SharedOpenXRScene()
{
if (s_xrDestroySceneMSFT != nullptr && s_SceneObserver != nullptr)
{
CheckResult(s_xrDestroySceneMSFT(m_Scene), "xrDestroySceneMSFT");
}
}
XrSceneMSFT GetScene() const { return m_Scene; };
private:
XrSceneMSFT m_Scene;
};
/**
* Store mesh data belonging to a UnityXRMeshId.
*/
class MeshData
{
public:
MeshData() : m_UpdateTime(0) {}
UnityXRMeshInfo m_UnityXRMeshInfo;
/**
* Point to a shared OpenXR scene.
* When there is no mesh data pointing to a scene,
* the scene will be destroyed by an OpenXR function (xrDestroySceneMSFT).
*/
std::shared_ptr<SharedOpenXRScene> m_SharedOpenXRScene;
XrSceneMeshMSFT m_OpenXRSceneMesh;
long long m_UpdateTime;
};
static std::map<UnityXRMeshId, MeshData, MeshIdLessThanComparator> s_MeshDataByMeshId;
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* interfaces)
{
s_Meshing = interfaces->Get<IUnityXRMeshInterface>();
if (s_Meshing == nullptr)
return;
UnityLifecycleProvider meshingLifecycleHandler{};
meshingLifecycleHandler.Initialize = [](UnitySubsystemHandle handle, void* userData) -> UnitySubsystemErrorCode {
// Reset scene computation bounds.
// Use an axis-aligned bounding box by default.
s_SceneSphereBounds.clear();
s_SceneOrientedBoxBounds.clear();
s_SceneFrustumBounds.clear();
s_MeshDataByMeshId.clear();
UnityXRMeshProvider meshProvider{};
meshProvider.GetMeshInfos = [](UnitySubsystemHandle handle, void* userData, UnityXRMeshInfoAllocator* allocator) -> UnitySubsystemErrorCode {
if (s_SceneObserver == nullptr) return kUnitySubsystemErrorCodeFailure;
// Set existing mesh infos as not updated.
for (auto&& pair : s_MeshDataByMeshId)
{
pair.second.m_UnityXRMeshInfo.updated = false;
}
bool canComputeNewScene = false;
// Check the scene compute state.
XrSceneComputeStateMSFT computeState;
CheckResult(s_xrGetSceneComputeStateMSFT(s_SceneObserver, &computeState), "xrGetSceneComputeStateMSFT");
switch (computeState)
{
case XrSceneComputeStateMSFT::XR_SCENE_COMPUTE_STATE_NONE_MSFT:
{
// Compute a new scene at the end of the function.
canComputeNewScene = true;
break;
}
case XrSceneComputeStateMSFT::XR_SCENE_COMPUTE_STATE_UPDATING_MSFT:
// Wait for scene computation.
canComputeNewScene = false;
break;
case XrSceneComputeStateMSFT::XR_SCENE_COMPUTE_STATE_COMPLETED_MSFT:
{
// Compute a new scene at the end of the function.
canComputeNewScene = true;
// Create a scene of the computation result.
XrSceneCreateInfoMSFT sceneCreateInfo;
sceneCreateInfo.type = XrStructureType::XR_TYPE_SCENE_CREATE_INFO_MSFT;
sceneCreateInfo.next = NULL;
XrSceneMSFT scene;
CheckResult(s_xrCreateSceneMSFT(s_SceneObserver, &sceneCreateInfo, &scene), "xrCreateSceneMSFT");
// Create a shared scene to be stored in mesh data.
auto sharedScene = std::make_shared<SharedOpenXRScene>(scene);
// Stage 1: Get scene visual mesh components.
XrSceneComponentsGetInfoMSFT sceneComponentsGetInfo;
sceneComponentsGetInfo.type = XrStructureType::XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT;
sceneComponentsGetInfo.next = NULL;
sceneComponentsGetInfo.componentType = XrSceneComponentTypeMSFT::XR_SCENE_COMPONENT_TYPE_VISUAL_MESH_MSFT;
// First get the buffer capacity.
XrSceneComponentsMSFT sceneComponents;
sceneComponents.type = XrStructureType::XR_TYPE_SCENE_COMPONENTS_MSFT;
sceneComponents.next = NULL;
sceneComponents.componentCapacityInput = 0;
sceneComponents.components = NULL;
CheckResult(s_xrGetSceneComponentsMSFT(scene, &sceneComponentsGetInfo, &sceneComponents), "xrGetSceneComponentsMSFT");
// Create scene components by the provided capacity.
std::vector<XrSceneComponentMSFT> sceneComponentsVector(sceneComponents.componentCountOutput);
sceneComponents.componentCapacityInput = sceneComponents.componentCountOutput;
sceneComponents.components = sceneComponentsVector.data();
// Also add an instance in the structure chain for getting scene visual mesh components.
std::vector<XrSceneMeshMSFT> sceneMeshesVector(sceneComponents.componentCountOutput);
XrSceneMeshesMSFT sceneMeshes;
sceneMeshes.type = XrStructureType::XR_TYPE_SCENE_MESHES_MSFT;
sceneMeshes.next = NULL;
sceneMeshes.sceneMeshCount = sceneComponents.componentCountOutput;
sceneMeshes.sceneMeshes = sceneMeshesVector.data();
sceneComponents.next = &sceneMeshes;
// Call xrGetSceneComponentsMSFT() again to fill out the scene components and scene visual mesh components.
CheckResult(s_xrGetSceneComponentsMSFT(scene, &sceneComponentsGetInfo, &sceneComponents), "xrGetSceneComponentsMSFT");
// Fill out mesh info from the scene visual mesh components.
for (size_t componentIndex = 0; componentIndex < sceneComponents.componentCountOutput; ++componentIndex)
{
auto& sceneComponent = sceneComponentsVector[componentIndex];
auto& sceneMesh = sceneMeshesVector[componentIndex];
// Create a Unity mesh id by the OpenXR component id.
// If OpenXR scene components of different time have the same component id,
// they represent the same physical object. Thus use component id
// as Unity mesh id.
UnityXRMeshId meshId;
memcpy(&meshId, &sceneComponent.id, sizeof(UnityXRMeshId));
// Prepare to store mesh data of the mesh id.
// The mesh data can be an existing one from the previous scene,
// or a new one of the current scene.
auto& meshData = s_MeshDataByMeshId[meshId];
// Set the mesh info of the mesh id.
// If the current update time is larger than the stored value,
// set the mesh as updated.
auto& meshInfo = meshData.m_UnityXRMeshInfo;
meshInfo.meshId = meshId;
meshInfo.updated = sceneComponent.updateTime > meshData.m_UpdateTime;
meshInfo.priorityHint = 0;
// Store the shared scene in order to manage the destruction of scene.
meshData.m_SharedOpenXRScene = sharedScene;
// Store the OpenXR scene mesh.
meshData.m_OpenXRSceneMesh = sceneMesh;
// Store the update time.
meshData.m_UpdateTime = sceneComponent.updateTime;
}
// After setting data of the current scene, remove mesh data
// not belonging to the current scene.
for (auto iterator = s_MeshDataByMeshId.cbegin(); iterator != s_MeshDataByMeshId.cend();)
{
if (iterator->second.m_SharedOpenXRScene != sharedScene)
{
// The mesh data does not exist in the current scene.
// Erase it from the container, and get the iterator
// after the erased position.
iterator = s_MeshDataByMeshId.erase(iterator);
}
else
{
// The mesh data exist in the current scene.
// Do nothing and increment the iterator.
++iterator;
}
}
}
break;
case XrSceneComputeStateMSFT::XR_SCENE_COMPUTE_STATE_COMPLETED_WITH_ERROR_MSFT:
Log("Scene computation failed");
// Compute a new scene at the end of the function.
canComputeNewScene = true;
break;
default:
Log("Invalid scene compute state: " + std::to_string(computeState));
// Compute a new scene at the end of the function.
canComputeNewScene = true;
break;
}
if (canComputeNewScene)
{
// Compute a new scene.
XrVisualMeshComputeLodInfoMSFT visualMeshComputeLodInfo;
visualMeshComputeLodInfo.type = XrStructureType::XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT;
visualMeshComputeLodInfo.next = NULL;
visualMeshComputeLodInfo.lod = s_MeshComputeLod;
std::vector<XrSceneComputeFeatureMSFT> sceneComputeFeatures = {XrSceneComputeFeatureMSFT::XR_SCENE_COMPUTE_FEATURE_VISUAL_MESH_MSFT};
XrNewSceneComputeInfoMSFT newSceneComputeInfo;
newSceneComputeInfo.type = XrStructureType::XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT;
newSceneComputeInfo.next = &visualMeshComputeLodInfo;
newSceneComputeInfo.requestedFeatureCount = (uint32_t) sceneComputeFeatures.size();
newSceneComputeInfo.requestedFeatures = sceneComputeFeatures.data();
newSceneComputeInfo.consistency = s_SceneComputeConsistency;
newSceneComputeInfo.bounds.sphereCount = (uint32_t) s_SceneSphereBounds.size();
newSceneComputeInfo.bounds.spheres = s_SceneSphereBounds.data();
newSceneComputeInfo.bounds.boxCount = (uint32_t) s_SceneOrientedBoxBounds.size();
newSceneComputeInfo.bounds.boxes = s_SceneOrientedBoxBounds.data();
newSceneComputeInfo.bounds.frustumCount = (uint32_t) s_SceneFrustumBounds.size();
newSceneComputeInfo.bounds.frustums = s_SceneFrustumBounds.data();
CheckResult(s_xrComputeNewSceneMSFT(s_SceneObserver, &newSceneComputeInfo), "xrComputeNewSceneMSFT");
}
// Allocate an output array and copy mesh infos to it.
auto pMeshInfos = s_Meshing->MeshInfoAllocator_Allocate(allocator, s_MeshDataByMeshId.size());
size_t meshInfoIndex = 0;
for (auto&& pair : s_MeshDataByMeshId)
{
pMeshInfos[meshInfoIndex] = pair.second.m_UnityXRMeshInfo;
++meshInfoIndex;
}
return kUnitySubsystemErrorCodeSuccess;
};
meshProvider.AcquireMesh = [](UnitySubsystemHandle handle, void* userData, const UnityXRMeshId* meshId, UnityXRMeshDataAllocator* allocator) -> UnitySubsystemErrorCode {
// Get mesh data from the input mesh id.
MeshData* pMeshData = nullptr;
try
{
pMeshData = &s_MeshDataByMeshId.at(*meshId);
}
catch(const std::exception& e)
{
Log("Mesh id not found: " + std::string(e.what()));
return UnitySubsystemErrorCode::kUnitySubsystemErrorCodeFailure;
}
// Check if the shared OpenXR scene is not null.
if (pMeshData->m_SharedOpenXRScene == nullptr)
{
// Mesh data with null shared scene implies that a mesh
// of the mesh data has been acquired before.
return UnitySubsystemErrorCode::kUnitySubsystemErrorCodeFailure;
}
// Stage 2: Get mesh buffers of the first scene visual mesh component.
XrSceneMeshBuffersGetInfoMSFT sceneMeshBuffersGetInfo;
sceneMeshBuffersGetInfo.type = XrStructureType::XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT;
sceneMeshBuffersGetInfo.next = NULL;
sceneMeshBuffersGetInfo.meshBufferId = pMeshData->m_OpenXRSceneMesh.meshBufferId;
// Create buffers on the structure chain of XrSceneMeshBuffersMSFT.
// Set input capacity to zero to get buffer capacity.
XrSceneMeshBuffersMSFT sceneMeshBuffers;
sceneMeshBuffers.type = XrStructureType::XR_TYPE_SCENE_MESH_BUFFERS_MSFT;
XrSceneMeshVertexBufferMSFT sceneMeshVerticesBuffer;
sceneMeshVerticesBuffer.type = XrStructureType::XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT;
sceneMeshVerticesBuffer.vertexCapacityInput = 0;
sceneMeshVerticesBuffer.vertices = NULL;
XrSceneMeshIndicesUint32MSFT sceneMeshIndicesUint32Buffer;
sceneMeshIndicesUint32Buffer.type = XrStructureType::XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT;
sceneMeshIndicesUint32Buffer.indexCapacityInput = 0;
sceneMeshIndicesUint32Buffer.indices = NULL;
// Chain the structure instances.
sceneMeshBuffers.next = &sceneMeshVerticesBuffer;
sceneMeshVerticesBuffer.next = &sceneMeshIndicesUint32Buffer;
sceneMeshIndicesUint32Buffer.next = NULL;
// Call xrGetSceneMeshBuffersMSFT() to get buffer capacity.
CheckResult(s_xrGetSceneMeshBuffersMSFT(pMeshData->m_SharedOpenXRScene->GetScene(),
&sceneMeshBuffersGetInfo, &sceneMeshBuffers), "xrGetSceneMeshBuffersMSFT");
// Create buffers by the capacity.
std::vector<XrVector3f> vertices(sceneMeshVerticesBuffer.vertexCountOutput);
std::vector<uint32_t> indices(sceneMeshIndicesUint32Buffer.indexCountOutput);
sceneMeshVerticesBuffer.vertexCapacityInput = sceneMeshVerticesBuffer.vertexCountOutput;
sceneMeshVerticesBuffer.vertices = vertices.data();
sceneMeshIndicesUint32Buffer.indexCapacityInput = sceneMeshIndicesUint32Buffer.indexCountOutput;
sceneMeshIndicesUint32Buffer.indices = indices.data();
// Call xrGetSceneMeshBuffersMSFT() again to fill out buffers.
CheckResult(s_xrGetSceneMeshBuffersMSFT(pMeshData->m_SharedOpenXRScene->GetScene(),
&sceneMeshBuffersGetInfo, &sceneMeshBuffers), "xrGetSceneMeshBuffersMSFT");
// After getting OpenXR mesh buffers, reset the shared pointer to the scene
// to release the scene. The scene will be destroyed when no shared pointers
// pointing to it.
pMeshData->m_SharedOpenXRScene = nullptr;
// Test
// sceneMeshVerticesBuffer.vertices[0] = {0, 0, 0};
// sceneMeshVerticesBuffer.vertices[1] = {0, 0, 1};
// sceneMeshVerticesBuffer.vertices[2] = {1, 0, 0};
// sceneMeshIndicesUint32Buffer.indices[0] = 0;
// sceneMeshIndicesUint32Buffer.indices[1] = 1;
// sceneMeshIndicesUint32Buffer.indices[2] = 2;
// Now the buffers are filled with mesh data.
// Copy data to the Unity XR mesh descriptor.
auto& verticesCount = sceneMeshVerticesBuffer.vertexCountOutput;
auto& indicesCount = sceneMeshIndicesUint32Buffer.indexCountOutput;
auto* meshDesc = s_Meshing->MeshDataAllocator_AllocateMesh(allocator,
verticesCount, indicesCount, kUnityXRIndexFormat32Bit,
(UnityXRMeshVertexAttributeFlags) 0,kUnityXRMeshTopologyTriangles);
memcpy(meshDesc->positions, sceneMeshVerticesBuffer.vertices, verticesCount * sizeof(float) * 3);
memcpy(meshDesc->indices32, sceneMeshIndicesUint32Buffer.indices, indicesCount * sizeof(uint32_t));
// Convert meshes from right-handed to left-handed.
for (size_t i = 0; i < verticesCount; ++i)
{
// Multiply the z value by -1.
meshDesc->positions[i].z *= -1.0f;
}
for (size_t i = 0; i < indicesCount; i += 3)
{
// Swap the second and the third index in a triangle.
std::swap(meshDesc->indices32[i + 1], meshDesc->indices32[i + 2]);
}
// int numVerts = sizeof(positionsTeapot) / sizeof(float) / 3;
// int numIndices = sizeof(indicesTeapot) / sizeof(uint16_t);
// auto* meshDesc = s_Meshing->MeshDataAllocator_AllocateMesh(allocator, numVerts, numIndices, kUnityXRIndexFormat16Bit, (UnityXRMeshVertexAttributeFlags)(kUnityXRMeshVertexAttributeFlagsNormals | kUnityXRMeshVertexAttributeFlagsUvs), kUnityXRMeshTopologyTriangles);
// memcpy(meshDesc->positions, positionsTeapot, numVerts * sizeof(float) * 3);
// memcpy(meshDesc->normals, normalsTeapot, numVerts * sizeof(float) * 3);
// memcpy(meshDesc->uvs, uvsTeapot, (numVerts * 2) * sizeof(float));
// memcpy(meshDesc->indices16, indicesTeapot, numIndices * sizeof(uint16_t));
return kUnitySubsystemErrorCodeSuccess;
};
meshProvider.ReleaseMesh = [](UnitySubsystemHandle handle, void* userData, const UnityXRMeshId* meshId, const UnityXRMeshDescriptor* mesh, void* pluginData) -> UnitySubsystemErrorCode {
return kUnitySubsystemErrorCodeSuccess;
};
meshProvider.SetMeshDensity = [](UnitySubsystemHandle handle, void* userData, float density) -> UnitySubsystemErrorCode {
return kUnitySubsystemErrorCodeSuccess;
};
meshProvider.SetBoundingVolume = [](UnitySubsystemHandle handle, void* userData, const UnityXRBoundingVolume* boundingVolume) -> UnitySubsystemErrorCode {
return kUnitySubsystemErrorCodeSuccess;
};
s_Meshing->RegisterMeshProvider(handle, &meshProvider);
return kUnitySubsystemErrorCodeSuccess;
};
meshingLifecycleHandler.Start = [](UnitySubsystemHandle handle, void* userData) -> UnitySubsystemErrorCode {
// Create a scene observer.
XrSceneObserverCreateInfoMSFT sceneObserverCreateInfo;
sceneObserverCreateInfo.type = XrStructureType::XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT;
sceneObserverCreateInfo.next = NULL;
CheckResult(s_xrCreateSceneObserverMSFT(s_XrSession, &sceneObserverCreateInfo, &s_SceneObserver), "xrCreateSceneObserverMSFT");
return kUnitySubsystemErrorCodeSuccess;
};
meshingLifecycleHandler.Stop = [](UnitySubsystemHandle handle, void* userData) -> void {
// Clear mesh data.
// All pointed shared OpenXR scenes are also destroyed.
s_MeshDataByMeshId.clear();
// Destroy the scene observer.
CheckResult(s_xrDestroySceneObserverMSFT(s_SceneObserver), "xrDestroySceneObserverMSFT");
};
meshingLifecycleHandler.Shutdown = [](UnitySubsystemHandle handle, void* userData) -> void {
s_OpenXRReady = false;
// Destroy the reference space.
CheckResult(s_xrDestroySpace(s_XrSpace), "xrDestroySpace");
};
s_Meshing->RegisterLifecycleProvider("OpenXR Extension Sample", "Sample Meshing", &meshingLifecycleHandler);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginUnload()
{
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
SetOpenXRVariables(unsigned long long instance, unsigned long long session,
void* xrEnumerateReferenceSpaces,
void* xrCreateReferenceSpace,
void* xrDestroySpace,
void* xrEnumerateSceneComputeFeaturesMSFTptr,
void* xrCreateSceneObserverMSFTptr,
void* xrDestroySceneObserverMSFTptr,
void* xrCreateSceneMSFTptr,
void* xrDestroySceneMSFTptr,
void* xrComputeNewSceneMSFTptr,
void* xrGetSceneComputeStateMSFTptr,
void* xrGetSceneComponentsMSFTptr,
void* xrLocateSceneComponentsMSFTptr,
void* xrGetSceneMeshBuffersMSFTptr)
{
s_XrInstance = (XrInstance)instance;
s_XrSession = (XrSession)session;
s_xrEnumerateReferenceSpaces = (PFN_xrEnumerateReferenceSpaces)xrEnumerateReferenceSpaces;
s_xrCreateReferenceSpace = (PFN_xrCreateReferenceSpace)xrCreateReferenceSpace;
s_xrDestroySpace = (PFN_xrDestroySpace)xrDestroySpace;
s_xrEnumerateSceneComputeFeaturesMSFT = (PFN_xrEnumerateSceneComputeFeaturesMSFT)xrEnumerateSceneComputeFeaturesMSFTptr;
s_xrCreateSceneObserverMSFT = (PFN_xrCreateSceneObserverMSFT)xrCreateSceneObserverMSFTptr;
s_xrDestroySceneObserverMSFT = (PFN_xrDestroySceneObserverMSFT)xrDestroySceneObserverMSFTptr;
s_xrCreateSceneMSFT = (PFN_xrCreateSceneMSFT)xrCreateSceneMSFTptr;
s_xrDestroySceneMSFT = (PFN_xrDestroySceneMSFT)xrDestroySceneMSFTptr;
s_xrComputeNewSceneMSFT = (PFN_xrComputeNewSceneMSFT)xrComputeNewSceneMSFTptr;
s_xrGetSceneComputeStateMSFT = (PFN_xrGetSceneComputeStateMSFT)xrGetSceneComputeStateMSFTptr;
s_xrGetSceneComponentsMSFT = (PFN_xrGetSceneComponentsMSFT)xrGetSceneComponentsMSFTptr;
s_xrLocateSceneComponentsMSFT = (PFN_xrLocateSceneComponentsMSFT)xrLocateSceneComponentsMSFTptr;
s_xrGetSceneMeshBuffersMSFT = (PFN_xrGetSceneMeshBuffersMSFT)xrGetSceneMeshBuffersMSFTptr;
s_XrInstance = (XrInstance) instance;
s_XrSession = (XrSession) session;
// Enumerate supported reference space types.
std::vector<XrReferenceSpaceType> supportedReferenceSpaceTypes;
uint32_t supportedReferenceSpaceTypeCount = 0;
CheckResult(s_xrEnumerateReferenceSpaces(s_XrSession, 0, &supportedReferenceSpaceTypeCount,
supportedReferenceSpaceTypes.data()), "xrEnumerateReferenceSpaces");
supportedReferenceSpaceTypes.resize(supportedReferenceSpaceTypeCount);
CheckResult(s_xrEnumerateReferenceSpaces(s_XrSession, (uint32_t) supportedReferenceSpaceTypes.size(), &supportedReferenceSpaceTypeCount,
supportedReferenceSpaceTypes.data()), "xrEnumerateReferenceSpaces");
// Get a supported reference space type. Prefer the stage space type.
for (auto&& type : supportedReferenceSpaceTypes)
{
s_ReferenceSpaceType = type;
if (type == XrReferenceSpaceType::XR_REFERENCE_SPACE_TYPE_STAGE)
{
break;
}
}
// Create a reference space.
XrReferenceSpaceCreateInfo referenceSpaceCreateInfo;
referenceSpaceCreateInfo.type = XrStructureType::XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
referenceSpaceCreateInfo.next = NULL;
referenceSpaceCreateInfo.referenceSpaceType = s_ReferenceSpaceType;
referenceSpaceCreateInfo.poseInReferenceSpace.orientation = {0, 0, 0, 1};
referenceSpaceCreateInfo.poseInReferenceSpace.position = {0, 0, 0};
CheckResult(s_xrCreateReferenceSpace(s_XrSession, &referenceSpaceCreateInfo, &s_XrSpace), "xrCreateReferenceSpace");
s_OpenXRReady = true;
}
/**
* Set a scene compute sphere bound in a right-handed world space.
* Existing sphere bound will be replaced.
*/
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
SetSceneComputeSphereBound(XrVector3f center, float radius)
{
s_SceneSphereBounds.resize(1);
auto& bound = s_SceneSphereBounds[0];
bound.center = center;
bound.radius = radius;
}
/**
* Set a scene compute oriented box bound in a right-handed world space.
* Existing oriented box bound will be replaced.
*/
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
SetSceneComputeOrientedBoxBound(XrQuaternionf orientation, XrVector3f position, XrVector3f extents)
{
s_SceneOrientedBoxBounds.resize(1);
auto& bound = s_SceneOrientedBoxBounds[0];
bound.pose.orientation = orientation;
bound.pose.position = position;
bound.extents = extents;
}
/**
* Set a scene compute oriented box bound in a right-handed world space.
* Existing frustum bound will be replaced.
*/
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
SetSceneComputeFrustumBound(XrQuaternionf orientation, XrVector3f position,
float angleUp, float angleDown, float angleRight, float angleLeft, float farDistance)
{
s_SceneFrustumBounds.resize(1);
auto& bound = s_SceneFrustumBounds[0];
bound.pose.orientation = orientation;
bound.pose.position = position;
bound.fov.angleUp = angleUp;
bound.fov.angleDown = angleDown;
bound.fov.angleRight = angleRight;
bound.fov.angleLeft = angleLeft;
bound.farDistance = farDistance;
}
enum XrSceneBoundType
{
XR_SCENE_BOUND_SPHERE_TYPE = 1,
XR_SCENE_BOUND_ORIENTED_BOX_TYPE = 2,
XR_SCENE_BOUND_FRUSTUM_TYPE = 3,
XR_SCENE_BOUND_MAX = 4
};
/**
* Clear scene compute bounds of a specified type.
*/
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
ClearSceneComputeBounds(XrSceneBoundType type)
{
switch (type)
{
case XrSceneBoundType::XR_SCENE_BOUND_SPHERE_TYPE:
s_SceneSphereBounds.clear();
break;
case XrSceneBoundType::XR_SCENE_BOUND_ORIENTED_BOX_TYPE:
s_SceneOrientedBoxBounds.clear();
break;
case XrSceneBoundType::XR_SCENE_BOUND_FRUSTUM_TYPE:
s_SceneFrustumBounds.clear();
break;
default:
break;
}
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
SetSceneComputeConsistency(XrSceneComputeConsistencyMSFT consistency)
{
s_SceneComputeConsistency = consistency;
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
SetMeshComputeLod(XrMeshComputeLodMSFT lod)
{
s_MeshComputeLod = lod;
}

View File

@@ -0,0 +1,47 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
// Copyright (c) 2019 Collabora, Ltd.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Author: Ryan Pavlik <ryan.pavlik@collabora.com>
//
/*!
* @file
*
* Additional functions along the lines of the standard library algorithms.
*/
#pragma once
#include <algorithm>
#include <vector>
/// Like std::remove_if, except it works on associative containers and it actually removes this.
///
/// The iterator stuff in here is subtle - .erase() invalidates only that iterator, but it returns a non-invalidated iterator to the
/// next valid element which we can use instead of incrementing.
template <typename T, typename Pred>
static inline void map_erase_if(T &container, Pred &&predicate) {
for (auto it = container.begin(); it != container.end();) {
if (predicate(*it)) {
it = container.erase(it);
} else {
++it;
}
}
}
/*!
* Moves all elements matching the predicate to the end of the vector then erases them.
*
* Combines the two parts of the erase-remove idiom to simplify things and avoid accidentally using the wrong erase overload.
*/
template <typename T, typename Alloc, typename Pred>
static inline void vector_remove_if_and_erase(std::vector<T, Alloc> &vec, Pred &&predicate) {
auto b = vec.begin();
auto e = vec.end();
vec.erase(std::remove_if(b, e, std::forward<Pred>(predicate)), e);
}

View File

@@ -0,0 +1,355 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Authors: Mark Young <marky@lunarg.com>
// Nat Brown <natb@valvesoftware.com>
//
#include "filesystem_utils.hpp"
#include "platform_utils.hpp"
#include <cstring>
#include <string>
#if defined DISABLE_STD_FILESYSTEM
#define USE_EXPERIMENTAL_FS 0
#define USE_FINAL_FS 0
#else
// If the C++ macro is set to the version containing C++17, it must support
// the final C++17 package
#if __cplusplus >= 201703L
#define USE_EXPERIMENTAL_FS 0
#define USE_FINAL_FS 1
#elif defined(_MSC_VER) && _MSC_VER >= 1900
#if defined(_HAS_CXX17) && _HAS_CXX17
// When MSC supports c++17 use <filesystem> package.
#define USE_EXPERIMENTAL_FS 0
#define USE_FINAL_FS 1
#endif // !_HAS_CXX17
// Right now, GCC still only supports the experimental filesystem items starting in GCC 6
#elif (__GNUC__ >= 6)
#define USE_EXPERIMENTAL_FS 1
#define USE_FINAL_FS 0
// If Clang, check for feature support
#elif defined(__clang__) && (__cpp_lib_filesystem || __cpp_lib_experimental_filesystem)
#if __cpp_lib_filesystem
#define USE_EXPERIMENTAL_FS 0
#define USE_FINAL_FS 1
#else
#define USE_EXPERIMENTAL_FS 1
#define USE_FINAL_FS 0
#endif
// If all above fails, fall back to standard C++ and OS-specific items
#else
#define USE_EXPERIMENTAL_FS 0
#define USE_FINAL_FS 0
#endif
#endif
#if USE_FINAL_FS == 1
#include <filesystem>
#define FS_PREFIX std::filesystem
#elif USE_EXPERIMENTAL_FS == 1
#include <experimental/filesystem>
#define FS_PREFIX std::experimental::filesystem
#elif defined(XR_USE_PLATFORM_WIN32)
// Windows fallback includes
#include <stdint.h>
#include <direct.h>
#else
// Linux/Apple fallback includes
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <dirent.h>
#endif
#if defined(XR_USE_PLATFORM_WIN32)
#define PATH_SEPARATOR ';'
#define DIRECTORY_SYMBOL '\\'
#define ALTERNATE_DIRECTORY_SYMBOL '/'
#else
#define PATH_SEPARATOR ':'
#define DIRECTORY_SYMBOL '/'
#endif
#if (USE_FINAL_FS == 1) || (USE_EXPERIMENTAL_FS == 1)
// We can use one of the C++ filesystem packages
bool FileSysUtilsIsRegularFile(const std::string& path) { return FS_PREFIX::is_regular_file(path); }
bool FileSysUtilsIsDirectory(const std::string& path) { return FS_PREFIX::is_directory(path); }
bool FileSysUtilsPathExists(const std::string& path) { return FS_PREFIX::exists(path); }
bool FileSysUtilsIsAbsolutePath(const std::string& path) {
FS_PREFIX::path file_path(path);
return file_path.is_absolute();
}
bool FileSysUtilsGetCurrentPath(std::string& path) {
FS_PREFIX::path cur_path = FS_PREFIX::current_path();
path = cur_path.string();
return true;
}
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
FS_PREFIX::path path_var(file_path);
parent_path = path_var.parent_path().string();
return true;
}
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
absolute = FS_PREFIX::absolute(path).string();
return true;
}
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical) {
#if defined(XR_USE_PLATFORM_WIN32)
// std::filesystem::canonical fails on UWP and must be avoided. Further, PathCchCanonicalize is not available on Windows 7 and
// PathCanonicalizeW is not available on UWP. However, symbolic links are not important on Windows since the loader uses the
// registry for indirection instead, and so this function can be a no-op on Windows.
canonical = path;
#else
canonical = FS_PREFIX::canonical(path).string();
#endif
return true;
}
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
FS_PREFIX::path parent_path(parent);
FS_PREFIX::path child_path(child);
FS_PREFIX::path full_path = parent_path / child_path;
combined = full_path.string();
return true;
}
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths) {
std::string::size_type start = 0;
std::string::size_type location = path_list.find(PATH_SEPARATOR);
while (location != std::string::npos) {
paths.push_back(path_list.substr(start, location));
start = location + 1;
location = path_list.find(PATH_SEPARATOR, start);
}
paths.push_back(path_list.substr(start, location));
return true;
}
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files) {
for (auto& dir_iter : FS_PREFIX::directory_iterator(path)) {
files.push_back(dir_iter.path().filename().string());
}
return true;
}
#elif defined(XR_OS_WINDOWS)
// For pre C++17 compiler that doesn't support experimental filesystem
bool FileSysUtilsIsRegularFile(const std::string& path) {
const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str());
return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY);
}
bool FileSysUtilsIsDirectory(const std::string& path) {
const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str());
return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
}
bool FileSysUtilsPathExists(const std::string& path) {
return (GetFileAttributesW(utf8_to_wide(path).c_str()) != INVALID_FILE_ATTRIBUTES);
}
bool FileSysUtilsIsAbsolutePath(const std::string& path) {
bool pathStartsWithDir = (path.size() >= 1) && ((path[0] == DIRECTORY_SYMBOL) || (path[0] == ALTERNATE_DIRECTORY_SYMBOL));
bool pathStartsWithDrive =
(path.size() >= 3) && (path[1] == ':' && (path[2] == DIRECTORY_SYMBOL || path[2] == ALTERNATE_DIRECTORY_SYMBOL));
return pathStartsWithDir || pathStartsWithDrive;
}
bool FileSysUtilsGetCurrentPath(std::string& path) {
wchar_t tmp_path[MAX_PATH];
if (nullptr != _wgetcwd(tmp_path, MAX_PATH - 1)) {
path = wide_to_utf8(tmp_path);
return true;
}
return false;
}
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
std::string full_path;
if (FileSysUtilsGetAbsolutePath(file_path, full_path)) {
std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL);
parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator);
return true;
}
return false;
}
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
wchar_t tmp_path[MAX_PATH];
if (0 != GetFullPathNameW(utf8_to_wide(path).c_str(), MAX_PATH, tmp_path, NULL)) {
absolute = wide_to_utf8(tmp_path);
return true;
}
return false;
}
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& absolute) {
// PathCchCanonicalize is not available on Windows 7 and PathCanonicalizeW is not available on UWP. However, symbolic links are
// not important on Windows since the loader uses the registry for indirection instead, and so this function can be a no-op on
// Windows.
absolute = path;
return true;
}
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
std::string::size_type parent_len = parent.length();
if (0 == parent_len || "." == parent || ".\\" == parent || "./" == parent) {
combined = child;
return true;
}
char last_char = parent[parent_len - 1];
if ((last_char == DIRECTORY_SYMBOL) || (last_char == ALTERNATE_DIRECTORY_SYMBOL)) {
parent_len--;
}
combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child;
return true;
}
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths) {
std::string::size_type start = 0;
std::string::size_type location = path_list.find(PATH_SEPARATOR);
while (location != std::string::npos) {
paths.push_back(path_list.substr(start, location));
start = location + 1;
location = path_list.find(PATH_SEPARATOR, start);
}
paths.push_back(path_list.substr(start, location));
return true;
}
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files) {
std::string searchPath;
FileSysUtilsCombinePaths(path, "*", searchPath);
WIN32_FIND_DATAW file_data;
HANDLE file_handle = FindFirstFileW(utf8_to_wide(searchPath).c_str(), &file_data);
if (file_handle != INVALID_HANDLE_VALUE) {
do {
if (!(file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
files.push_back(wide_to_utf8(file_data.cFileName));
}
} while (FindNextFileW(file_handle, &file_data));
return true;
}
return false;
}
#else // XR_OS_LINUX/XR_OS_APPLE fallback
// simple POSIX-compatible implementation of the <filesystem> pieces used by OpenXR
bool FileSysUtilsIsRegularFile(const std::string& path) {
struct stat path_stat;
stat(path.c_str(), &path_stat);
return S_ISREG(path_stat.st_mode);
}
bool FileSysUtilsIsDirectory(const std::string& path) {
struct stat path_stat;
stat(path.c_str(), &path_stat);
return S_ISDIR(path_stat.st_mode);
}
bool FileSysUtilsPathExists(const std::string& path) { return (access(path.c_str(), F_OK) != -1); }
bool FileSysUtilsIsAbsolutePath(const std::string& path) { return (path[0] == DIRECTORY_SYMBOL); }
bool FileSysUtilsGetCurrentPath(std::string& path) {
char tmp_path[PATH_MAX];
if (nullptr != getcwd(tmp_path, PATH_MAX - 1)) {
path = tmp_path;
return true;
}
return false;
}
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
std::string full_path;
if (FileSysUtilsGetAbsolutePath(file_path, full_path)) {
std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL);
parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator);
return true;
}
return false;
}
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
// canonical path is absolute
return FileSysUtilsGetCanonicalPath(path, absolute);
}
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical) {
char buf[PATH_MAX];
if (nullptr != realpath(path.c_str(), buf)) {
canonical = buf;
return true;
}
return false;
}
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
std::string::size_type parent_len = parent.length();
if (0 == parent_len || "." == parent || "./" == parent) {
combined = child;
return true;
}
char last_char = parent[parent_len - 1];
if (last_char == DIRECTORY_SYMBOL) {
parent_len--;
}
combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child;
return true;
}
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths) {
std::string::size_type start = 0;
std::string::size_type location = path_list.find(PATH_SEPARATOR);
while (location != std::string::npos) {
paths.push_back(path_list.substr(start, location));
start = location + 1;
location = path_list.find(PATH_SEPARATOR, start);
}
paths.push_back(path_list.substr(start, location));
return true;
}
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files) {
DIR* dir = opendir(path.c_str());
if (dir == nullptr) {
return false;
}
struct dirent* entry;
while ((entry = readdir(dir)) != nullptr) {
files.emplace_back(entry->d_name);
}
closedir(dir);
return true;
}
#endif

View File

@@ -0,0 +1,46 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Author: Mark Young <marky@lunarg.com>
//
#pragma once
#include <string>
#include <vector>
// Determine if the path indicates a regular file (not a directory or symbolic link)
bool FileSysUtilsIsRegularFile(const std::string& path);
// Determine if the path indicates a directory
bool FileSysUtilsIsDirectory(const std::string& path);
// Determine if the provided path exists on the filesystem
bool FileSysUtilsPathExists(const std::string& path);
// Get the current directory
bool FileSysUtilsGetCurrentPath(std::string& path);
// Get the parent path of a file
bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path);
// Determine if the provided path is an absolute path
bool FileSysUtilsIsAbsolutePath(const std::string& path);
// Get the absolute path for a provided file
bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute);
// Get the absolute path for a provided file
bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical);
// Combine a parent and child directory
bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined);
// Parse out individual paths in a path list
bool FileSysUtilsParsePathList(std::string& path_list, std::vector<std::string>& paths);
// Record all the filenames for files found in the provided path.
bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector<std::string>& files);

View File

@@ -0,0 +1,108 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
// Copyright (c) 2019 Collabora, Ltd.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Author: Ryan Pavlik <ryan.pavlik@collabora.com>
//
/*!
* @file
*
* Some utilities, primarily for working with OpenXR handles in a generic way.
*/
#pragma once
#include <openxr/openxr.h>
#include <string>
#include <stdint.h>
inline std::string to_hex(const uint8_t* const data, size_t bytes) {
std::string out(2 + bytes * 2, '?');
out[0] = '0';
out[1] = 'x';
static const char* hex = "0123456789abcdef";
auto ch = out.end();
for (size_t i = 0; i < bytes; ++i) {
auto b = data[i];
*--ch = hex[(b >> 0) & 0xf];
*--ch = hex[(b >> 4) & 0xf];
}
return out;
}
template <typename T>
inline std::string to_hex(const T& data) {
return to_hex(reinterpret_cast<const uint8_t* const>(&data), sizeof(data));
}
#if XR_PTR_SIZE == 8
/// Convert a handle into a same-sized integer.
template <typename T>
static inline uint64_t MakeHandleGeneric(T handle) {
return reinterpret_cast<uint64_t>(handle);
}
/// Treat an integer as a handle
template <typename T>
static inline T& TreatIntegerAsHandle(uint64_t& handle) {
return reinterpret_cast<T&>(handle);
}
/// @overload
template <typename T>
static inline T const& TreatIntegerAsHandle(uint64_t const& handle) {
return reinterpret_cast<T const&>(handle);
}
/// Does a correctly-sized integer represent a null handle?
static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == reinterpret_cast<void*>(handle); }
#else
/// Convert a handle into a same-sized integer: no-op on 32-bit systems
static inline uint64_t MakeHandleGeneric(uint64_t handle) { return handle; }
/// Treat an integer as a handle: no-op on 32-bit systems
template <typename T>
static inline T& TreatIntegerAsHandle(uint64_t& handle) {
return handle;
}
/// @overload
template <typename T>
static inline T const& TreatIntegerAsHandle(uint64_t const& handle) {
return handle;
}
/// Does a correctly-sized integer represent a null handle?
static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == handle; }
#endif
/// Turns a uint64_t into a string formatted as hex.
///
/// The core of the HandleToHexString implementation is in here.
inline std::string Uint64ToHexString(uint64_t val) { return to_hex(val); }
/// Turns a uint32_t into a string formatted as hex.
inline std::string Uint32ToHexString(uint32_t val) { return to_hex(val); }
/// Turns an OpenXR handle into a string formatted as hex.
template <typename T>
inline std::string HandleToHexString(T handle) {
return to_hex(handle);
}
/// Turns a pointer-sized integer into a string formatted as hex.
inline std::string UintptrToHexString(uintptr_t val) { return to_hex(val); }
/// Convert a pointer to a string formatted as hex.
template <typename T>
inline std::string PointerToHexString(T const* ptr) {
return to_hex(ptr);
}

View File

@@ -0,0 +1,114 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Author: Mark Young <marky@lunarg.com>
//
#pragma once
#include <openxr/openxr.h>
#ifdef __cplusplus
extern "C" {
#endif
// Forward declare.
typedef struct XrApiLayerCreateInfo XrApiLayerCreateInfo;
// Function pointer prototype for the xrCreateApiLayerInstance function used in place of xrCreateInstance.
// This function allows us to pass special API layer information to each layer during the process of creating an Instance.
typedef XrResult(XRAPI_PTR *PFN_xrCreateApiLayerInstance)(const XrInstanceCreateInfo *info,
const XrApiLayerCreateInfo *apiLayerInfo, XrInstance *instance);
// Loader/API Layer Interface versions
// 1 - First version, introduces negotiation structure and functions
#define XR_CURRENT_LOADER_API_LAYER_VERSION 1
// Loader/Runtime Interface versions
// 1 - First version, introduces negotiation structure and functions
#define XR_CURRENT_LOADER_RUNTIME_VERSION 1
// Version negotiation values
typedef enum XrLoaderInterfaceStructs {
XR_LOADER_INTERFACE_STRUCT_UNINTIALIZED = 0,
XR_LOADER_INTERFACE_STRUCT_LOADER_INFO,
XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST,
XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST,
XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO,
XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO,
} XrLoaderInterfaceStructs;
#define XR_LOADER_INFO_STRUCT_VERSION 1
typedef struct XrNegotiateLoaderInfo {
XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_LOADER_INFO
uint32_t structVersion; // XR_LOADER_INFO_STRUCT_VERSION
size_t structSize; // sizeof(XrNegotiateLoaderInfo)
uint32_t minInterfaceVersion;
uint32_t maxInterfaceVersion;
XrVersion minApiVersion;
XrVersion maxApiVersion;
} XrNegotiateLoaderInfo;
#define XR_API_LAYER_INFO_STRUCT_VERSION 1
typedef struct XrNegotiateApiLayerRequest {
XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST
uint32_t structVersion; // XR_API_LAYER_INFO_STRUCT_VERSION
size_t structSize; // sizeof(XrNegotiateApiLayerRequest)
uint32_t layerInterfaceVersion; // CURRENT_LOADER_API_LAYER_VERSION
XrVersion layerApiVersion;
PFN_xrGetInstanceProcAddr getInstanceProcAddr;
PFN_xrCreateApiLayerInstance createApiLayerInstance;
} XrNegotiateApiLayerRequest;
#define XR_RUNTIME_INFO_STRUCT_VERSION 1
typedef struct XrNegotiateRuntimeRequest {
XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST
uint32_t structVersion; // XR_RUNTIME_INFO_STRUCT_VERSION
size_t structSize; // sizeof(XrNegotiateRuntimeRequest)
uint32_t runtimeInterfaceVersion; // CURRENT_LOADER_RUNTIME_VERSION
XrVersion runtimeApiVersion;
PFN_xrGetInstanceProcAddr getInstanceProcAddr;
} XrNegotiateRuntimeRequest;
// Function used to negotiate an interface betewen the loader and an API layer. Each library exposing one or
// more API layers needs to expose at least this function.
typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderApiLayerInterface)(const XrNegotiateLoaderInfo *loaderInfo,
const char *apiLayerName,
XrNegotiateApiLayerRequest *apiLayerRequest);
// Function used to negotiate an interface betewen the loader and a runtime. Each runtime should expose
// at least this function.
typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderRuntimeInterface)(const XrNegotiateLoaderInfo *loaderInfo,
XrNegotiateRuntimeRequest *runtimeRequest);
// Forward declare.
typedef struct XrApiLayerNextInfo XrApiLayerNextInfo;
#define XR_API_LAYER_NEXT_INFO_STRUCT_VERSION 1
struct XrApiLayerNextInfo {
XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO
uint32_t structVersion; // XR_API_LAYER_NEXT_INFO_STRUCT_VERSION
size_t structSize; // sizeof(XrApiLayerNextInfo)
char layerName[XR_MAX_API_LAYER_NAME_SIZE]; // Name of API layer which should receive this info
PFN_xrGetInstanceProcAddr nextGetInstanceProcAddr; // Pointer to next API layer's xrGetInstanceProcAddr
PFN_xrCreateApiLayerInstance nextCreateApiLayerInstance; // Pointer to next API layer's xrCreateApiLayerInstance
XrApiLayerNextInfo *next; // Pointer to the next API layer info in the sequence
};
#define XR_API_LAYER_MAX_SETTINGS_PATH_SIZE 512
#define XR_API_LAYER_CREATE_INFO_STRUCT_VERSION 1
typedef struct XrApiLayerCreateInfo {
XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO
uint32_t structVersion; // XR_API_LAYER_CREATE_INFO_STRUCT_VERSION
size_t structSize; // sizeof(XrApiLayerCreateInfo)
void *loaderInstance; // Pointer to the LoaderInstance class
char settings_file_location[XR_API_LAYER_MAX_SETTINGS_PATH_SIZE]; // Location to the found settings file (or empty '\0')
XrApiLayerNextInfo *nextInfo; // Pointer to the next API layer's Info
} XrApiLayerCreateInfo;
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,276 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
// Copyright (c) 2019 Collabora, Ltd.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Authors: Mark Young <marky@lunarg.com>
// Ryan Pavlik <ryan.pavlik@collabora.com>
// Dave Houlton <daveh@lunarg.com>
//
#include "object_info.h"
#include "extra_algorithms.h"
#include "hex_and_handles.h"
#include <openxr/openxr.h>
#include <algorithm>
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include "memory.h"
std::string XrSdkLogObjectInfo::ToString() const {
std::ostringstream oss;
oss << Uint64ToHexString(handle);
if (!name.empty()) {
oss << " (" << name << ")";
}
return oss.str();
}
void ObjectInfoCollection::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {
// If name is empty, we should erase it
if (object_name.empty()) {
RemoveObject(object_handle, object_type);
return;
}
// Otherwise, add it or update the name
XrSdkLogObjectInfo new_obj = {object_handle, object_type};
// If it already exists, update the name
auto lookup_info = LookUpStoredObjectInfo(new_obj);
if (lookup_info != nullptr) {
lookup_info->name = object_name;
return;
}
// It doesn't exist, so add a new info block
new_obj.name = object_name;
object_info_.push_back(new_obj);
}
void ObjectInfoCollection::RemoveObject(uint64_t object_handle, XrObjectType object_type) {
vector_remove_if_and_erase(
object_info_, [=](XrSdkLogObjectInfo const& info) { return info.handle == object_handle && info.type == object_type; });
}
XrSdkLogObjectInfo const* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const {
auto e = object_info_.end();
auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); });
if (it != e) {
return &(*it);
}
return nullptr;
}
XrSdkLogObjectInfo* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) {
auto e = object_info_.end();
auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); });
if (it != e) {
return &(*it);
}
return nullptr;
}
bool ObjectInfoCollection::LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const {
auto info_lookup = LookUpStoredObjectInfo(info.objectHandle, info.objectType);
if (info_lookup != nullptr) {
info.objectName = info_lookup->name.c_str();
return true;
}
return false;
}
bool ObjectInfoCollection::LookUpObjectName(XrSdkLogObjectInfo& info) const {
auto info_lookup = LookUpStoredObjectInfo(info);
if (info_lookup != nullptr) {
info.name = info_lookup->name;
return true;
}
return false;
}
static std::vector<XrDebugUtilsObjectNameInfoEXT> PopulateObjectNameInfo(std::vector<XrSdkLogObjectInfo> const& obj) {
std::vector<XrDebugUtilsObjectNameInfoEXT> ret;
ret.reserve(obj.size());
std::transform(obj.begin(), obj.end(), std::back_inserter(ret), [](XrSdkLogObjectInfo const& info) {
return XrDebugUtilsObjectNameInfoEXT{XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, info.type, info.handle,
info.name.c_str()};
});
return ret;
}
NamesAndLabels::NamesAndLabels(std::vector<XrSdkLogObjectInfo> obj, std::vector<XrDebugUtilsLabelEXT> lab)
: sdk_objects(std::move(obj)), objects(PopulateObjectNameInfo(sdk_objects)), labels(std::move(lab)) {}
void NamesAndLabels::PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& callback_data) const {
callback_data.objects = objects.empty() ? nullptr : const_cast<XrDebugUtilsObjectNameInfoEXT*>(objects.data());
callback_data.objectCount = static_cast<uint32_t>(objects.size());
callback_data.sessionLabels = labels.empty() ? nullptr : const_cast<XrDebugUtilsLabelEXT*>(labels.data());
callback_data.sessionLabelCount = static_cast<uint32_t>(labels.size());
}
void DebugUtilsData::LookUpSessionLabels(XrSession session, std::vector<XrDebugUtilsLabelEXT>& labels) const {
auto session_label_iterator = session_labels_.find(session);
if (session_label_iterator != session_labels_.end()) {
auto& XrSdkSessionLabels = *session_label_iterator->second;
// Copy the debug utils labels in reverse order in the the labels vector.
std::transform(XrSdkSessionLabels.rbegin(), XrSdkSessionLabels.rend(), std::back_inserter(labels),
[](XrSdkSessionLabelPtr const& label) { return label->debug_utils_label; });
}
}
XrSdkSessionLabel::XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual)
: label_name(label_info.labelName), debug_utils_label(label_info), is_individual_label(individual) {
// Update the c string pointer to the one we hold.
debug_utils_label.labelName = label_name.c_str();
}
XrSdkSessionLabelPtr XrSdkSessionLabel::make(const XrDebugUtilsLabelEXT& label_info, bool individual) {
XrSdkSessionLabelPtr ret(new XrSdkSessionLabel(label_info, individual));
return ret;
}
void DebugUtilsData::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {
object_info_.AddObjectName(object_handle, object_type, object_name);
}
// We always want to remove the old individual label before we do anything else.
// So, do that in it's own method
void DebugUtilsData::RemoveIndividualLabel(XrSdkSessionLabelList& label_vec) {
if (!label_vec.empty() && label_vec.back()->is_individual_label) {
label_vec.pop_back();
}
}
XrSdkSessionLabelList* DebugUtilsData::GetSessionLabelList(XrSession session) {
auto session_label_iterator = session_labels_.find(session);
if (session_label_iterator == session_labels_.end()) {
return nullptr;
}
return session_label_iterator->second.get();
}
XrSdkSessionLabelList& DebugUtilsData::GetOrCreateSessionLabelList(XrSession session) {
XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
if (vec_ptr == nullptr) {
std::unique_ptr<XrSdkSessionLabelList> vec(new XrSdkSessionLabelList);
vec_ptr = vec.get();
session_labels_[session] = std::move(vec);
}
return *vec_ptr;
}
void DebugUtilsData::BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info) {
auto& vec = GetOrCreateSessionLabelList(session);
// Individual labels do not stay around in the transition into a new label region
RemoveIndividualLabel(vec);
// Start the new label region
vec.emplace_back(XrSdkSessionLabel::make(label_info, false));
}
void DebugUtilsData::EndLabelRegion(XrSession session) {
XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
if (vec_ptr == nullptr) {
return;
}
// Individual labels do not stay around in the transition out of label region
RemoveIndividualLabel(*vec_ptr);
// Remove the last label region
if (!vec_ptr->empty()) {
vec_ptr->pop_back();
}
}
void DebugUtilsData::InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info) {
auto& vec = GetOrCreateSessionLabelList(session);
// Remove any individual layer that might already be there
RemoveIndividualLabel(vec);
// Insert a new individual label
vec.emplace_back(XrSdkSessionLabel::make(label_info, true));
}
void DebugUtilsData::DeleteObject(uint64_t object_handle, XrObjectType object_type) {
object_info_.RemoveObject(object_handle, object_type);
if (object_type == XR_OBJECT_TYPE_SESSION) {
auto session = TreatIntegerAsHandle<XrSession>(object_handle);
XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
if (vec_ptr != nullptr) {
session_labels_.erase(session);
}
}
}
void DebugUtilsData::DeleteSessionLabels(XrSession session) { session_labels_.erase(session); }
NamesAndLabels DebugUtilsData::PopulateNamesAndLabels(std::vector<XrSdkLogObjectInfo> objects) const {
std::vector<XrDebugUtilsLabelEXT> labels;
for (auto& obj : objects) {
// Check for any names that have been associated with the objects and set them up here
object_info_.LookUpObjectName(obj);
// If this is a session, see if there are any labels associated with it for us to add
// to the callback content.
if (XR_OBJECT_TYPE_SESSION == obj.type) {
LookUpSessionLabels(obj.GetTypedHandle<XrSession>(), labels);
}
}
return {objects, labels};
}
void DebugUtilsData::WrapCallbackData(AugmentedCallbackData* aug_data,
const XrDebugUtilsMessengerCallbackDataEXT* callback_data) const {
// If there's nothing to add, just return the original data as the augmented copy
aug_data->exported_data = callback_data;
if (object_info_.Empty() || callback_data->objectCount == 0) {
return;
}
// Inspect each of the callback objects
bool name_found = false;
for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
auto& current_obj = callback_data->objects[obj];
name_found |= (nullptr != object_info_.LookUpStoredObjectInfo(current_obj.objectHandle, current_obj.objectType));
// If this is a session, record any labels associated with it
if (XR_OBJECT_TYPE_SESSION == current_obj.objectType) {
XrSession session = TreatIntegerAsHandle<XrSession>(current_obj.objectHandle);
LookUpSessionLabels(session, aug_data->labels);
}
}
// If we found nothing to add, return the original data
if (!name_found && aug_data->labels.empty()) {
return;
}
// Found additional data - modify an internal copy and return that as the exported data
memcpy(&aug_data->modified_data, callback_data, sizeof(XrDebugUtilsMessengerCallbackDataEXT));
aug_data->new_objects.assign(callback_data->objects, callback_data->objects + callback_data->objectCount);
// Record (overwrite) the names of all incoming objects provided in our internal list
for (auto& obj : aug_data->new_objects) {
object_info_.LookUpObjectName(obj);
}
// Update local copy & point export to it
aug_data->modified_data.objects = aug_data->new_objects.data();
aug_data->modified_data.sessionLabelCount = static_cast<uint32_t>(aug_data->labels.size());
aug_data->modified_data.sessionLabels = aug_data->labels.empty() ? nullptr : aug_data->labels.data();
aug_data->exported_data = &aug_data->modified_data;
return;
}

View File

@@ -0,0 +1,229 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
// Copyright (c) 2019 Collabora, Ltd.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Authors: Mark Young <marky@lunarg.com>, Ryan Pavlik <ryan.pavlik@collabora.com
//
/*!
* @file
*
* The core of an XR_EXT_debug_utils implementation, used/shared by the loader and several SDK layers.
*/
#pragma once
#include "hex_and_handles.h"
#include <openxr/openxr.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
struct XrSdkGenericObject {
//! Type-erased handle value
uint64_t handle;
//! Kind of object this handle refers to
XrObjectType type;
/// Un-erase the type of the handle and get it properly typed again.
///
/// Note: Does not check the type before doing it!
template <typename HandleType>
HandleType& GetTypedHandle() {
return TreatIntegerAsHandle<HandleType&>(handle);
}
//! @overload
template <typename HandleType>
HandleType const& GetTypedHandle() const {
return TreatIntegerAsHandle<HandleType&>(handle);
}
//! Create from a typed handle and object type
template <typename T>
XrSdkGenericObject(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {}
//! Create from an untyped handle value (integer) and object type
XrSdkGenericObject(uint64_t h, XrObjectType t) : handle(h), type(t) {}
};
struct XrSdkLogObjectInfo {
//! Type-erased handle value
uint64_t handle;
//! Kind of object this handle refers to
XrObjectType type;
//! To be assigned by the application - not part of this object's identity
std::string name;
/// Un-erase the type of the handle and get it properly typed again.
///
/// Note: Does not check the type before doing it!
template <typename HandleType>
HandleType& GetTypedHandle() {
return TreatIntegerAsHandle<HandleType&>(handle);
}
//! @overload
template <typename HandleType>
HandleType const& GetTypedHandle() const {
return TreatIntegerAsHandle<HandleType&>(handle);
}
XrSdkLogObjectInfo() = default;
//! Create from a typed handle and object type
template <typename T>
XrSdkLogObjectInfo(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {}
//! Create from an untyped handle value (integer) and object type
XrSdkLogObjectInfo(uint64_t h, XrObjectType t) : handle(h), type(t) {}
//! Create from an untyped handle value (integer), object type, and name
XrSdkLogObjectInfo(uint64_t h, XrObjectType t, const char* n) : handle(h), type(t), name(n == nullptr ? "" : n) {}
std::string ToString() const;
};
//! True if the two object infos have the same handle value and handle type
static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrSdkLogObjectInfo const& b) {
return a.handle == b.handle && a.type == b.type;
}
//! @overload
static inline bool Equivalent(XrDebugUtilsObjectNameInfoEXT const& a, XrSdkLogObjectInfo const& b) {
return a.objectHandle == b.handle && a.objectType == b.type;
}
//! @overload
static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrDebugUtilsObjectNameInfoEXT const& b) { return Equivalent(b, a); }
/// Object info registered with calls to xrSetDebugUtilsObjectNameEXT
class ObjectInfoCollection {
public:
void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name);
void RemoveObject(uint64_t object_handle, XrObjectType object_type);
//! Find the stored object info, if any, matching handle and type.
//! Return nullptr if not found.
XrSdkLogObjectInfo const* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const;
//! Find the stored object info, if any, matching handle and type.
//! Return nullptr if not found.
XrSdkLogObjectInfo* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info);
//! Find the stored object info, if any.
//! Return nullptr if not found.
XrSdkLogObjectInfo const* LookUpStoredObjectInfo(uint64_t handle, XrObjectType type) const {
return LookUpStoredObjectInfo({handle, type});
}
//! Find the object name, if any, and update debug utils info accordingly.
//! Return true if found and updated.
bool LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const;
//! Find the object name, if any, and update logging info accordingly.
//! Return true if found and updated.
bool LookUpObjectName(XrSdkLogObjectInfo& info) const;
//! Is the collection empty?
bool Empty() const { return object_info_.empty(); }
private:
// Object names that have been set for given objects
std::vector<XrSdkLogObjectInfo> object_info_;
};
struct XrSdkSessionLabel;
using XrSdkSessionLabelPtr = std::unique_ptr<XrSdkSessionLabel>;
using XrSdkSessionLabelList = std::vector<XrSdkSessionLabelPtr>;
struct XrSdkSessionLabel {
static XrSdkSessionLabelPtr make(const XrDebugUtilsLabelEXT& label_info, bool individual);
std::string label_name;
XrDebugUtilsLabelEXT debug_utils_label;
bool is_individual_label;
private:
XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual);
};
/// The metadata for a collection of objects. Must persist unmodified during the entire debug messenger call!
struct NamesAndLabels {
NamesAndLabels() = default;
NamesAndLabels(std::vector<XrSdkLogObjectInfo> obj, std::vector<XrDebugUtilsLabelEXT> lab);
/// C++ structure owning the data (strings) backing the objects vector.
std::vector<XrSdkLogObjectInfo> sdk_objects;
std::vector<XrDebugUtilsObjectNameInfoEXT> objects;
std::vector<XrDebugUtilsLabelEXT> labels;
/// Populate the debug utils callback data structure.
void PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& data) const;
// XrDebugUtilsMessengerCallbackDataEXT MakeCallbackData() const;
};
struct AugmentedCallbackData {
std::vector<XrDebugUtilsLabelEXT> labels;
std::vector<XrDebugUtilsObjectNameInfoEXT> new_objects;
XrDebugUtilsMessengerCallbackDataEXT modified_data;
const XrDebugUtilsMessengerCallbackDataEXT* exported_data;
};
/// Tracks all the data (handle names and session labels) required to fully augment XR_EXT_debug_utils-related calls.
class DebugUtilsData {
public:
DebugUtilsData() = default;
DebugUtilsData(const DebugUtilsData&) = delete;
DebugUtilsData& operator=(const DebugUtilsData&) = delete;
bool Empty() const { return object_info_.Empty() && session_labels_.empty(); }
//! Core of implementation for xrSetDebugUtilsObjectNameEXT
void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name);
/// Core of implementation for xrSessionBeginDebugUtilsLabelRegionEXT
void BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info);
/// Core of implementation for xrSessionEndDebugUtilsLabelRegionEXT
void EndLabelRegion(XrSession session);
/// Core of implementation for xrSessionInsertDebugUtilsLabelEXT
void InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info);
/// Removes all labels associated with a session - call in xrDestroySession and xrDestroyInstance (for all child sessions)
void DeleteSessionLabels(XrSession session);
/// Retrieve labels for the given session, if any, and push them in reverse order on the vector.
void LookUpSessionLabels(XrSession session, std::vector<XrDebugUtilsLabelEXT>& labels) const;
/// Removes all data related to this object - including session labels if it's a session.
///
/// Does not take care of handling child objects - you must do this yourself.
void DeleteObject(uint64_t object_handle, XrObjectType object_type);
/// Given the collection of objects, populate their names and list of labels
NamesAndLabels PopulateNamesAndLabels(std::vector<XrSdkLogObjectInfo> objects) const;
void WrapCallbackData(AugmentedCallbackData* aug_data,
const XrDebugUtilsMessengerCallbackDataEXT* provided_callback_data) const;
private:
void RemoveIndividualLabel(XrSdkSessionLabelList& label_vec);
XrSdkSessionLabelList* GetSessionLabelList(XrSession session);
XrSdkSessionLabelList& GetOrCreateSessionLabelList(XrSession session);
// Session labels: one vector of them per session.
std::unordered_map<XrSession, std::unique_ptr<XrSdkSessionLabelList>> session_labels_;
// Names for objects.
ObjectInfoCollection object_info_;
};

View File

@@ -0,0 +1,345 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Authors: Mark Young <marky@lunarg.com>, Dave Houlton <daveh@lunarg.com>
//
#pragma once
#include "xr_dependencies.h"
#include <string>
#include <stdlib.h>
// OpenXR paths and registry key locations
#define OPENXR_RELATIVE_PATH "openxr/"
#define OPENXR_IMPLICIT_API_LAYER_RELATIVE_PATH "/api_layers/implicit.d"
#define OPENXR_EXPLICIT_API_LAYER_RELATIVE_PATH "/api_layers/explicit.d"
#ifdef XR_OS_WINDOWS
#define OPENXR_REGISTRY_LOCATION "SOFTWARE\\Khronos\\OpenXR\\"
#define OPENXR_IMPLICIT_API_LAYER_REGISTRY_LOCATION "\\ApiLayers\\Implicit"
#define OPENXR_EXPLICIT_API_LAYER_REGISTRY_LOCATION "\\ApiLayers\\Explicit"
#endif
// OpenXR Loader environment variables of interest
#define OPENXR_RUNTIME_JSON_ENV_VAR "XR_RUNTIME_JSON"
#define OPENXR_API_LAYER_PATH_ENV_VAR "XR_API_LAYER_PATH"
// This is a CMake generated file with #defines for any functions/includes
// that it found present and build-time configuration.
// If you don't have this file, on non-Windows you'll need to define
// one of HAVE_SECURE_GETENV or HAVE___SECURE_GETENV depending on which
// of secure_getenv or __secure_getenv are present
#ifdef OPENXR_HAVE_COMMON_CONFIG
#include "common_config.h"
#endif // OPENXR_HAVE_COMMON_CONFIG
// Environment variables
#if defined(XR_OS_LINUX) || defined(XR_OS_APPLE)
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
namespace detail {
static inline char* ImplGetEnv(const char* name) { return getenv(name); }
static inline int ImplSetEnv(const char* name, const char* value, int overwrite) { return setenv(name, value, overwrite); }
static inline char* ImplGetSecureEnv(const char* name) {
#ifdef HAVE_SECURE_GETENV
return secure_getenv(name);
#elif defined(HAVE___SECURE_GETENV)
return __secure_getenv(name);
#else
#pragma message( \
"Warning: Falling back to non-secure getenv for environmental" \
"lookups! Consider updating to a different libc.")
return ImplGetEnv(name);
#endif
}
} // namespace detail
#endif // defined(XR_OS_LINUX) || defined(XR_OS_APPLE)
#if defined(XR_OS_LINUX)
static inline std::string PlatformUtilsGetEnv(const char* name) {
auto str = detail::ImplGetEnv(name);
if (str == nullptr) {
return {};
}
return str;
}
static inline std::string PlatformUtilsGetSecureEnv(const char* name) {
auto str = detail::ImplGetSecureEnv(name);
if (str == nullptr) {
return {};
}
return str;
}
static inline bool PlatformUtilsGetEnvSet(const char* name) { return detail::ImplGetEnv(name) != nullptr; }
static inline bool PlatformUtilsSetEnv(const char* name, const char* value) {
const int shouldOverwrite = 1;
int result = detail::ImplSetEnv(name, value, shouldOverwrite);
return (result == 0);
}
#elif defined(XR_OS_APPLE)
static inline std::string PlatformUtilsGetEnv(const char* name) {
auto str = detail::ImplGetEnv(name);
if (str == nullptr) {
return {};
}
return str;
}
static inline std::string PlatformUtilsGetSecureEnv(const char* name) {
auto str = detail::ImplGetSecureEnv(name);
if (str == nullptr) {
return {};
}
return str;
}
static inline bool PlatformUtilsGetEnvSet(const char* name) { return detail::ImplGetEnv(name) != nullptr; }
static inline bool PlatformUtilsSetEnv(const char* name, const char* value) {
const int shouldOverwrite = 1;
int result = detail::ImplSetEnv(name, value, shouldOverwrite);
return (result == 0);
}
// Prefix for the Apple global runtime JSON file name
static const std::string rt_dir_prefix = "/usr/local/share/openxr/";
static const std::string rt_filename = "/active_runtime.json";
static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std::string& file_name) {
file_name = rt_dir_prefix;
file_name += std::to_string(major_version);
file_name += rt_filename;
return true;
}
#elif defined(XR_OS_WINDOWS)
#if !defined(NDEBUG)
inline void LogError(const std::string& error) { OutputDebugStringA(error.c_str()); }
#else
#define LogError(x)
#endif
inline std::wstring utf8_to_wide(const std::string& utf8Text) {
if (utf8Text.empty()) {
return {};
}
std::wstring wideText;
const int wideLength = ::MultiByteToWideChar(CP_UTF8, 0, utf8Text.data(), (int)utf8Text.size(), nullptr, 0);
if (wideLength == 0) {
LogError("utf8_to_wide get size error: " + std::to_string(::GetLastError()));
return {};
}
// MultiByteToWideChar returns number of chars of the input buffer, regardless of null terminitor
wideText.resize(wideLength, 0);
wchar_t* wideString = const_cast<wchar_t*>(wideText.data()); // mutable data() only exists in c++17
const int length = ::MultiByteToWideChar(CP_UTF8, 0, utf8Text.data(), (int)utf8Text.size(), wideString, wideLength);
if (length != wideLength) {
LogError("utf8_to_wide convert string error: " + std::to_string(::GetLastError()));
return {};
}
return wideText;
}
inline std::string wide_to_utf8(const std::wstring& wideText) {
if (wideText.empty()) {
return {};
}
std::string narrowText;
int narrowLength = ::WideCharToMultiByte(CP_UTF8, 0, wideText.data(), (int)wideText.size(), nullptr, 0, nullptr, nullptr);
if (narrowLength == 0) {
LogError("wide_to_utf8 get size error: " + std::to_string(::GetLastError()));
return {};
}
// WideCharToMultiByte returns number of chars of the input buffer, regardless of null terminitor
narrowText.resize(narrowLength, 0);
char* narrowString = const_cast<char*>(narrowText.data()); // mutable data() only exists in c++17
const int length =
::WideCharToMultiByte(CP_UTF8, 0, wideText.data(), (int)wideText.size(), narrowString, narrowLength, nullptr, nullptr);
if (length != narrowLength) {
LogError("wide_to_utf8 convert string error: " + std::to_string(::GetLastError()));
return {};
}
return narrowText;
}
// Returns true if the current process has an integrity level > SECURITY_MANDATORY_MEDIUM_RID.
static inline bool IsHighIntegrityLevel() {
// Execute this check once and save the value as a static bool.
static bool isHighIntegrityLevel = ([] {
HANDLE processToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &processToken)) {
// Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
uint8_t mandatoryLabelBuffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)]{};
DWORD bufferSize;
if (GetTokenInformation(processToken, TokenIntegrityLevel, mandatoryLabelBuffer, sizeof(mandatoryLabelBuffer),
&bufferSize) != 0) {
const auto mandatoryLabel = reinterpret_cast<const TOKEN_MANDATORY_LABEL*>(mandatoryLabelBuffer);
if (mandatoryLabel->Label.Sid != 0) {
const DWORD subAuthorityCount = *GetSidSubAuthorityCount(mandatoryLabel->Label.Sid);
const DWORD integrityLevel = *GetSidSubAuthority(mandatoryLabel->Label.Sid, subAuthorityCount - 1);
CloseHandle(processToken);
return integrityLevel > SECURITY_MANDATORY_MEDIUM_RID;
}
}
CloseHandle(processToken);
}
return false;
})();
return isHighIntegrityLevel;
}
// Returns true if the given environment variable exists.
// The name is a case-sensitive UTF8 string.
static inline bool PlatformUtilsGetEnvSet(const char* name) {
const std::wstring wname = utf8_to_wide(name);
const DWORD valSize = ::GetEnvironmentVariableW(wname.c_str(), nullptr, 0);
// GetEnvironmentVariable returns 0 when environment variable does not exist or there is an error.
return 0 != valSize;
}
// Returns the environment variable value for the given name.
// Returns an empty string if the environment variable doesn't exist or if it exists but is empty.
// Use PlatformUtilsGetEnvSet to tell if it exists.
// The name is a case-sensitive UTF8 string.
static inline std::string PlatformUtilsGetEnv(const char* name) {
const std::wstring wname = utf8_to_wide(name);
const DWORD valSize = ::GetEnvironmentVariableW(wname.c_str(), nullptr, 0);
// GetEnvironmentVariable returns 0 when environment variable does not exist or there is an error.
// The size includes the null-terminator, so a size of 1 is means the variable was explicitly set to empty.
if (valSize == 0 || valSize == 1) {
return {};
}
// GetEnvironmentVariable returns size including null terminator for "query size" call.
std::wstring wValue(valSize, 0);
wchar_t* wValueData = &wValue[0];
// GetEnvironmentVariable returns string length, excluding null terminator for "get value"
// call if there was enough capacity. Else it returns the required capacity (including null terminator).
const DWORD length = ::GetEnvironmentVariableW(wname.c_str(), wValueData, (DWORD)wValue.size());
if ((length == 0) || (length >= wValue.size())) { // If error or the variable increased length between calls...
LogError("GetEnvironmentVariable get value error: " + std::to_string(::GetLastError()));
return {};
}
wValue.resize(length); // Strip the null terminator.
return wide_to_utf8(wValue);
}
// Acts the same as PlatformUtilsGetEnv except returns an empty string if IsHighIntegrityLevel.
static inline std::string PlatformUtilsGetSecureEnv(const char* name) {
// Do not allow high integrity processes to act on data that can be controlled by medium integrity processes.
if (IsHighIntegrityLevel()) {
return {};
}
// No secure version for Windows so the above integrity check is needed.
return PlatformUtilsGetEnv(name);
}
// Sets an environment variable via UTF8 strings.
// The name is case-sensitive.
// Overwrites the variable if it already exists.
// Returns true if it could be set.
static inline bool PlatformUtilsSetEnv(const char* name, const char* value) {
const std::wstring wname = utf8_to_wide(name);
const std::wstring wvalue = utf8_to_wide(value);
BOOL result = ::SetEnvironmentVariableW(wname.c_str(), wvalue.c_str());
return (result != 0);
}
#elif defined(XR_OS_ANDROID)
static inline bool PlatformUtilsGetEnvSet(const char* /* name */) {
// Stub func
return false;
}
static inline std::string PlatformUtilsGetEnv(const char* /* name */) {
// Stub func
return {};
}
static inline std::string PlatformUtilsGetSecureEnv(const char* /* name */) {
// Stub func
return {};
}
static inline bool PlatformUtilsSetEnv(const char* /* name */, const char* /* value */) {
// Stub func
return false;
}
#include <sys/stat.h>
// Intended to be only used as a fallback on Android, with a more open, "native" technique used in most cases
static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std::string& file_name) {
// Prefix for the runtime JSON file name
static const char* rt_dir_prefixes[] = {"/oem", "/vendor"};
static const std::string rt_filename = "/active_runtime.json";
static const std::string subdir = "/etc/openxr/";
for (const auto prefix : rt_dir_prefixes) {
auto path = prefix + subdir + std::to_string(major_version) + rt_filename;
struct stat buf;
if (0 == stat(path.c_str(), &buf)) {
file_name = path;
return true;
}
}
return false;
}
#else // Not Linux, Apple, nor Windows
static inline bool PlatformUtilsGetEnvSet(const char* /* name */) {
// Stub func
return false;
}
static inline std::string PlatformUtilsGetEnv(const char* /* name */) {
// Stub func
return {};
}
static inline std::string PlatformUtilsGetSecureEnv(const char* /* name */) {
// Stub func
return {};
}
static inline bool PlatformUtilsSetEnv(const char* /* name */, const char* /* value */) {
// Stub func
return false;
}
static inline bool PlatformGetGlobalRuntimeFileName(uint16_t /* major_version */, std::string const& /* file_name */) {
// Stub func
return false;
}
#endif

View File

@@ -0,0 +1,89 @@
// Copyright (c) 2018-2021, The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// This file includes headers with types which openxr.h depends on in order
// to compile when platforms, graphics apis, and the like are enabled.
#pragma once
#ifdef XR_USE_PLATFORM_ANDROID
#include <android/native_window.h>
#include <android/window.h>
#include <android/native_window_jni.h>
#endif // XR_USE_PLATFORM_ANDROID
#ifdef XR_USE_PLATFORM_WIN32
#include <winapifamily.h>
#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM))
// Enable desktop partition APIs, such as RegOpenKeyEx, LoadLibraryEx, PathFileExists etc.
#undef WINAPI_PARTITION_DESKTOP
#define WINAPI_PARTITION_DESKTOP 1
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif // !NOMINMAX
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // !WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <unknwn.h>
#endif // XR_USE_PLATFORM_WIN32
#ifdef XR_USE_GRAPHICS_API_D3D11
#include <d3d11.h>
#endif // XR_USE_GRAPHICS_API_D3D11
#ifdef XR_USE_GRAPHICS_API_D3D12
#include <d3d12.h>
#endif // XR_USE_GRAPHICS_API_D3D12
#ifdef XR_USE_PLATFORM_XLIB
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef Success
#undef Success
#endif // Success
#ifdef Always
#undef Always
#endif // Always
#ifdef None
#undef None
#endif // None
#endif // XR_USE_PLATFORM_XLIB
#ifdef XR_USE_PLATFORM_XCB
#include <xcb/xcb.h>
#endif // XR_USE_PLATFORM_XCB
#ifdef XR_USE_GRAPHICS_API_OPENGL
#if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB)
#include <GL/glx.h>
#endif // (XR_USE_PLATFORM_XLIB || XR_USE_PLATFORM_XCB)
#ifdef XR_USE_PLATFORM_XCB
#include <xcb/glx.h>
#endif // XR_USE_PLATFORM_XCB
#ifdef XR_USE_PLATFORM_MACOS
#include <CL/cl_gl_ext.h>
#endif // XR_USE_PLATFORM_MACOS
#endif // XR_USE_GRAPHICS_API_OPENGL
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
#include <EGL/egl.h>
#endif // XR_USE_GRAPHICS_API_OPENGL_ES
#ifdef XR_USE_GRAPHICS_API_VULKAN
#include <vulkan/vulkan.h>
#endif // XR_USE_GRAPHICS_API_VULKAN
#ifdef XR_USE_PLATFORM_WAYLAND
#include "wayland-client.h"
#endif // XR_USE_PLATFORM_WAYLAND

View File

@@ -0,0 +1,787 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2016 Oculus VR, LLC.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: J.M.P. van Waveren
//
#ifndef XR_LINEAR_H_
#define XR_LINEAR_H_
#if defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) || defined(OS_LINUX_WAYLAND)
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wunused-function"
#endif
#include <openxr/openxr.h>
/*
================================================================================================
Description : Vector, matrix and quaternion math.
Author : J.M.P. van Waveren
Date : 12/10/2016
Language : C99
Format : Indent 4 spaces - no tabs.
Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved.
DESCRIPTION
===========
All matrices are column-major.
INTERFACE
=========
XrVector2f
XrVector3f
XrVector4f
XrQuaternionf
XrMatrix4x4f
inline static void XrVector3f_Set(XrVector3f* v, const float value);
inline static void XrVector3f_Add(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Sub(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Min(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Max(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Decay(XrVector3f* result, const XrVector3f* a, const float value);
inline static void XrVector3f_Lerp(XrVector3f* result, const XrVector3f* a, const XrVector3f* b, const float fraction);
inline static void XrVector3f_Scale(XrVector3f* result, const XrVector3f* a, const float scaleFactor);
inline static void XrVector3f_Normalize(XrVector3f* v);
inline static float XrVector3f_Length(const XrVector3f* v);
inline static void XrQuaternionf_Lerp(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b, const float fraction);
inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b;
inline static void XrMatrix4x4f_CreateIdentity(XrMatrix4x4f* result);
inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const float x, const float y, const float z);
inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY,
const float degreesZ);
inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z);
inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* result, const XrVector3f* translation,
const XrQuaternionf* rotation, const XrVector3f* scale);
inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, const float tanAngleLeft, const float tanAngleRight,
const float tanAngleUp, float const tanAngleDown, const float nearZ,
const float farZ);
inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, const float fovDegreesLeft, const float fovDegreesRight,
const float fovDegreeUp, const float fovDegreesDown, const float nearZ,
const float farZ);
inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* src);
inline static void XrMatrix4x4f_CreateOffsetScaleForBounds(XrMatrix4x4f* result, const XrMatrix4x4f* matrix, const XrVector3f* mins,
const XrVector3f* maxs);
inline static bool XrMatrix4x4f_IsAffine(const XrMatrix4x4f* matrix, const float epsilon);
inline static bool XrMatrix4x4f_IsOrthogonal(const XrMatrix4x4f* matrix, const float epsilon);
inline static bool XrMatrix4x4f_IsOrthonormal(const XrMatrix4x4f* matrix, const float epsilon);
inline static bool XrMatrix4x4f_IsRigidBody(const XrMatrix4x4f* matrix, const float epsilon);
inline static void XrMatrix4x4f_GetTranslation(XrVector3f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_GetRotation(XrQuaternionf* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_GetScale(XrVector3f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_Multiply(XrMatrix4x4f* result, const XrMatrix4x4f* a, const XrMatrix4x4f* b);
inline static void XrMatrix4x4f_Transpose(XrMatrix4x4f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_Invert(XrMatrix4x4f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_InvertRigidBody(XrMatrix4x4f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_TransformVector3f(XrVector3f* result, const XrMatrix4x4f* m, const XrVector3f* v);
inline static void XrMatrix4x4f_TransformVector4f(XrVector4f* result, const XrMatrix4x4f* m, const XrVector4f* v);
inline static void XrMatrix4x4f_TransformBounds(XrVector3f* resultMins, XrVector3f* resultMaxs, const XrMatrix4x4f* matrix,
const XrVector3f* mins, const XrVector3f* maxs);
inline static bool XrMatrix4x4f_CullBounds(const XrMatrix4x4f* mvp, const XrVector3f* mins, const XrVector3f* maxs);
================================================================================================
*/
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#define MATH_PI 3.14159265358979323846f
#define DEFAULT_NEAR_Z 0.015625f // exact floating point representation
#define INFINITE_FAR_Z 0.0f
static const XrColor4f XrColorRed = {1.0f, 0.0f, 0.0f, 1.0f};
static const XrColor4f XrColorGreen = {0.0f, 1.0f, 0.0f, 1.0f};
static const XrColor4f XrColorBlue = {0.0f, 0.0f, 1.0f, 1.0f};
static const XrColor4f XrColorYellow = {1.0f, 1.0f, 0.0f, 1.0f};
static const XrColor4f XrColorPurple = {1.0f, 0.0f, 1.0f, 1.0f};
static const XrColor4f XrColorCyan = {0.0f, 1.0f, 1.0f, 1.0f};
static const XrColor4f XrColorLightGrey = {0.7f, 0.7f, 0.7f, 1.0f};
static const XrColor4f XrColorDarkGrey = {0.3f, 0.3f, 0.3f, 1.0f};
enum GraphicsAPI { GRAPHICS_VULKAN, GRAPHICS_OPENGL, GRAPHICS_OPENGL_ES, GRAPHICS_D3D };
// Column-major, pre-multiplied. This type does not exist in the OpenXR API and is provided for convenience.
struct XrMatrix4x4f {
float m[16];
};
inline static float XrRcpSqrt(const float x) {
const float SMALLEST_NON_DENORMAL = 1.1754943508222875e-038f; // ( 1U << 23 )
const float rcp = (x >= SMALLEST_NON_DENORMAL) ? 1.0f / sqrtf(x) : 1.0f;
return rcp;
}
inline static void XrVector3f_Set(XrVector3f* v, const float value) {
v->x = value;
v->y = value;
v->z = value;
}
inline static void XrVector3f_Add(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = a->x + b->x;
result->y = a->y + b->y;
result->z = a->z + b->z;
}
inline static void XrVector3f_Sub(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = a->x - b->x;
result->y = a->y - b->y;
result->z = a->z - b->z;
}
inline static void XrVector3f_Min(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = (a->x < b->x) ? a->x : b->x;
result->y = (a->y < b->y) ? a->y : b->y;
result->z = (a->z < b->z) ? a->z : b->z;
}
inline static void XrVector3f_Max(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = (a->x > b->x) ? a->x : b->x;
result->y = (a->y > b->y) ? a->y : b->y;
result->z = (a->z > b->z) ? a->z : b->z;
}
inline static void XrVector3f_Decay(XrVector3f* result, const XrVector3f* a, const float value) {
result->x = (fabsf(a->x) > value) ? ((a->x > 0.0f) ? (a->x - value) : (a->x + value)) : 0.0f;
result->y = (fabsf(a->y) > value) ? ((a->y > 0.0f) ? (a->y - value) : (a->y + value)) : 0.0f;
result->z = (fabsf(a->z) > value) ? ((a->z > 0.0f) ? (a->z - value) : (a->z + value)) : 0.0f;
}
inline static void XrVector3f_Lerp(XrVector3f* result, const XrVector3f* a, const XrVector3f* b, const float fraction) {
result->x = a->x + fraction * (b->x - a->x);
result->y = a->y + fraction * (b->y - a->y);
result->z = a->z + fraction * (b->z - a->z);
}
inline static void XrVector3f_Scale(XrVector3f* result, const XrVector3f* a, const float scaleFactor) {
result->x = a->x * scaleFactor;
result->y = a->y * scaleFactor;
result->z = a->z * scaleFactor;
}
inline static float XrVector3f_Dot(const XrVector3f* a, const XrVector3f* b) { return a->x * b->x + a->y * b->y + a->z * b->z; }
// Compute cross product, which generates a normal vector.
// Direction vector can be determined by right-hand rule: Pointing index finder in
// direction a and middle finger in direction b, thumb will point in Cross(a, b).
inline static void XrVector3f_Cross(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = a->y * b->z - a->z * b->y;
result->y = a->z * b->x - a->x * b->z;
result->x = a->x * b->y - a->y * b->x;
}
inline static void XrVector3f_Normalize(XrVector3f* v) {
const float lengthRcp = XrRcpSqrt(v->x * v->x + v->y * v->y + v->z * v->z);
v->x *= lengthRcp;
v->y *= lengthRcp;
v->z *= lengthRcp;
}
inline static float XrVector3f_Length(const XrVector3f* v) { return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); }
inline static void XrQuaternionf_CreateFromAxisAngle(XrQuaternionf* result, const XrVector3f* axis, const float angleInRadians) {
float s = sinf(angleInRadians / 2.0f);
float lengthRcp = XrRcpSqrt(axis->x * axis->x + axis->y * axis->y + axis->z * axis->z);
result->x = s * axis->x * lengthRcp;
result->y = s * axis->y * lengthRcp;
result->z = s * axis->z * lengthRcp;
result->w = cosf(angleInRadians / 2.0f);
}
inline static void XrQuaternionf_Lerp(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b, const float fraction) {
const float s = a->x * b->x + a->y * b->y + a->z * b->z + a->w * b->w;
const float fa = 1.0f - fraction;
const float fb = (s < 0.0f) ? -fraction : fraction;
const float x = a->x * fa + b->x * fb;
const float y = a->y * fa + b->y * fb;
const float z = a->z * fa + b->z * fb;
const float w = a->w * fa + b->w * fb;
const float lengthRcp = XrRcpSqrt(x * x + y * y + z * z + w * w);
result->x = x * lengthRcp;
result->y = y * lengthRcp;
result->z = z * lengthRcp;
result->w = w * lengthRcp;
}
inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b) {
result->x = (b->w * a->x) + (b->x * a->w) + (b->y * a->z) - (b->z * a->y);
result->y = (b->w * a->y) - (b->x * a->z) + (b->y * a->w) + (b->z * a->x);
result->z = (b->w * a->z) + (b->x * a->y) - (b->y * a->x) + (b->z * a->w);
result->w = (b->w * a->w) - (b->x * a->x) - (b->y * a->y) - (b->z * a->z);
}
// Use left-multiplication to accumulate transformations.
inline static void XrMatrix4x4f_Multiply(XrMatrix4x4f* result, const XrMatrix4x4f* a, const XrMatrix4x4f* b) {
result->m[0] = a->m[0] * b->m[0] + a->m[4] * b->m[1] + a->m[8] * b->m[2] + a->m[12] * b->m[3];
result->m[1] = a->m[1] * b->m[0] + a->m[5] * b->m[1] + a->m[9] * b->m[2] + a->m[13] * b->m[3];
result->m[2] = a->m[2] * b->m[0] + a->m[6] * b->m[1] + a->m[10] * b->m[2] + a->m[14] * b->m[3];
result->m[3] = a->m[3] * b->m[0] + a->m[7] * b->m[1] + a->m[11] * b->m[2] + a->m[15] * b->m[3];
result->m[4] = a->m[0] * b->m[4] + a->m[4] * b->m[5] + a->m[8] * b->m[6] + a->m[12] * b->m[7];
result->m[5] = a->m[1] * b->m[4] + a->m[5] * b->m[5] + a->m[9] * b->m[6] + a->m[13] * b->m[7];
result->m[6] = a->m[2] * b->m[4] + a->m[6] * b->m[5] + a->m[10] * b->m[6] + a->m[14] * b->m[7];
result->m[7] = a->m[3] * b->m[4] + a->m[7] * b->m[5] + a->m[11] * b->m[6] + a->m[15] * b->m[7];
result->m[8] = a->m[0] * b->m[8] + a->m[4] * b->m[9] + a->m[8] * b->m[10] + a->m[12] * b->m[11];
result->m[9] = a->m[1] * b->m[8] + a->m[5] * b->m[9] + a->m[9] * b->m[10] + a->m[13] * b->m[11];
result->m[10] = a->m[2] * b->m[8] + a->m[6] * b->m[9] + a->m[10] * b->m[10] + a->m[14] * b->m[11];
result->m[11] = a->m[3] * b->m[8] + a->m[7] * b->m[9] + a->m[11] * b->m[10] + a->m[15] * b->m[11];
result->m[12] = a->m[0] * b->m[12] + a->m[4] * b->m[13] + a->m[8] * b->m[14] + a->m[12] * b->m[15];
result->m[13] = a->m[1] * b->m[12] + a->m[5] * b->m[13] + a->m[9] * b->m[14] + a->m[13] * b->m[15];
result->m[14] = a->m[2] * b->m[12] + a->m[6] * b->m[13] + a->m[10] * b->m[14] + a->m[14] * b->m[15];
result->m[15] = a->m[3] * b->m[12] + a->m[7] * b->m[13] + a->m[11] * b->m[14] + a->m[15] * b->m[15];
}
// Creates the transpose of the given matrix.
inline static void XrMatrix4x4f_Transpose(XrMatrix4x4f* result, const XrMatrix4x4f* src) {
result->m[0] = src->m[0];
result->m[1] = src->m[4];
result->m[2] = src->m[8];
result->m[3] = src->m[12];
result->m[4] = src->m[1];
result->m[5] = src->m[5];
result->m[6] = src->m[9];
result->m[7] = src->m[13];
result->m[8] = src->m[2];
result->m[9] = src->m[6];
result->m[10] = src->m[10];
result->m[11] = src->m[14];
result->m[12] = src->m[3];
result->m[13] = src->m[7];
result->m[14] = src->m[11];
result->m[15] = src->m[15];
}
// Returns a 3x3 minor of a 4x4 matrix.
inline static float XrMatrix4x4f_Minor(const XrMatrix4x4f* matrix, int r0, int r1, int r2, int c0, int c1, int c2) {
return matrix->m[4 * r0 + c0] *
(matrix->m[4 * r1 + c1] * matrix->m[4 * r2 + c2] - matrix->m[4 * r2 + c1] * matrix->m[4 * r1 + c2]) -
matrix->m[4 * r0 + c1] *
(matrix->m[4 * r1 + c0] * matrix->m[4 * r2 + c2] - matrix->m[4 * r2 + c0] * matrix->m[4 * r1 + c2]) +
matrix->m[4 * r0 + c2] *
(matrix->m[4 * r1 + c0] * matrix->m[4 * r2 + c1] - matrix->m[4 * r2 + c0] * matrix->m[4 * r1 + c1]);
}
// Calculates the inverse of a 4x4 matrix.
inline static void XrMatrix4x4f_Invert(XrMatrix4x4f* result, const XrMatrix4x4f* src) {
const float rcpDet =
1.0f / (src->m[0] * XrMatrix4x4f_Minor(src, 1, 2, 3, 1, 2, 3) - src->m[1] * XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 2, 3) +
src->m[2] * XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 3) - src->m[3] * XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 2));
result->m[0] = XrMatrix4x4f_Minor(src, 1, 2, 3, 1, 2, 3) * rcpDet;
result->m[1] = -XrMatrix4x4f_Minor(src, 0, 2, 3, 1, 2, 3) * rcpDet;
result->m[2] = XrMatrix4x4f_Minor(src, 0, 1, 3, 1, 2, 3) * rcpDet;
result->m[3] = -XrMatrix4x4f_Minor(src, 0, 1, 2, 1, 2, 3) * rcpDet;
result->m[4] = -XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 2, 3) * rcpDet;
result->m[5] = XrMatrix4x4f_Minor(src, 0, 2, 3, 0, 2, 3) * rcpDet;
result->m[6] = -XrMatrix4x4f_Minor(src, 0, 1, 3, 0, 2, 3) * rcpDet;
result->m[7] = XrMatrix4x4f_Minor(src, 0, 1, 2, 0, 2, 3) * rcpDet;
result->m[8] = XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 3) * rcpDet;
result->m[9] = -XrMatrix4x4f_Minor(src, 0, 2, 3, 0, 1, 3) * rcpDet;
result->m[10] = XrMatrix4x4f_Minor(src, 0, 1, 3, 0, 1, 3) * rcpDet;
result->m[11] = -XrMatrix4x4f_Minor(src, 0, 1, 2, 0, 1, 3) * rcpDet;
result->m[12] = -XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 2) * rcpDet;
result->m[13] = XrMatrix4x4f_Minor(src, 0, 2, 3, 0, 1, 2) * rcpDet;
result->m[14] = -XrMatrix4x4f_Minor(src, 0, 1, 3, 0, 1, 2) * rcpDet;
result->m[15] = XrMatrix4x4f_Minor(src, 0, 1, 2, 0, 1, 2) * rcpDet;
}
// Calculates the inverse of a rigid body transform.
inline static void XrMatrix4x4f_InvertRigidBody(XrMatrix4x4f* result, const XrMatrix4x4f* src) {
result->m[0] = src->m[0];
result->m[1] = src->m[4];
result->m[2] = src->m[8];
result->m[3] = 0.0f;
result->m[4] = src->m[1];
result->m[5] = src->m[5];
result->m[6] = src->m[9];
result->m[7] = 0.0f;
result->m[8] = src->m[2];
result->m[9] = src->m[6];
result->m[10] = src->m[10];
result->m[11] = 0.0f;
result->m[12] = -(src->m[0] * src->m[12] + src->m[1] * src->m[13] + src->m[2] * src->m[14]);
result->m[13] = -(src->m[4] * src->m[12] + src->m[5] * src->m[13] + src->m[6] * src->m[14]);
result->m[14] = -(src->m[8] * src->m[12] + src->m[9] * src->m[13] + src->m[10] * src->m[14]);
result->m[15] = 1.0f;
}
// Creates an identity matrix.
inline static void XrMatrix4x4f_CreateIdentity(XrMatrix4x4f* result) {
result->m[0] = 1.0f;
result->m[1] = 0.0f;
result->m[2] = 0.0f;
result->m[3] = 0.0f;
result->m[4] = 0.0f;
result->m[5] = 1.0f;
result->m[6] = 0.0f;
result->m[7] = 0.0f;
result->m[8] = 0.0f;
result->m[9] = 0.0f;
result->m[10] = 1.0f;
result->m[11] = 0.0f;
result->m[12] = 0.0f;
result->m[13] = 0.0f;
result->m[14] = 0.0f;
result->m[15] = 1.0f;
}
// Creates a translation matrix.
inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const float x, const float y, const float z) {
result->m[0] = 1.0f;
result->m[1] = 0.0f;
result->m[2] = 0.0f;
result->m[3] = 0.0f;
result->m[4] = 0.0f;
result->m[5] = 1.0f;
result->m[6] = 0.0f;
result->m[7] = 0.0f;
result->m[8] = 0.0f;
result->m[9] = 0.0f;
result->m[10] = 1.0f;
result->m[11] = 0.0f;
result->m[12] = x;
result->m[13] = y;
result->m[14] = z;
result->m[15] = 1.0f;
}
// Creates a rotation matrix.
// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll.
inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY,
const float degreesZ) {
const float sinX = sinf(degreesX * (MATH_PI / 180.0f));
const float cosX = cosf(degreesX * (MATH_PI / 180.0f));
const XrMatrix4x4f rotationX = {{1, 0, 0, 0, 0, cosX, sinX, 0, 0, -sinX, cosX, 0, 0, 0, 0, 1}};
const float sinY = sinf(degreesY * (MATH_PI / 180.0f));
const float cosY = cosf(degreesY * (MATH_PI / 180.0f));
const XrMatrix4x4f rotationY = {{cosY, 0, -sinY, 0, 0, 1, 0, 0, sinY, 0, cosY, 0, 0, 0, 0, 1}};
const float sinZ = sinf(degreesZ * (MATH_PI / 180.0f));
const float cosZ = cosf(degreesZ * (MATH_PI / 180.0f));
const XrMatrix4x4f rotationZ = {{cosZ, sinZ, 0, 0, -sinZ, cosZ, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}};
XrMatrix4x4f rotationXY;
XrMatrix4x4f_Multiply(&rotationXY, &rotationY, &rotationX);
XrMatrix4x4f_Multiply(result, &rotationZ, &rotationXY);
}
// Creates a scale matrix.
inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z) {
result->m[0] = x;
result->m[1] = 0.0f;
result->m[2] = 0.0f;
result->m[3] = 0.0f;
result->m[4] = 0.0f;
result->m[5] = y;
result->m[6] = 0.0f;
result->m[7] = 0.0f;
result->m[8] = 0.0f;
result->m[9] = 0.0f;
result->m[10] = z;
result->m[11] = 0.0f;
result->m[12] = 0.0f;
result->m[13] = 0.0f;
result->m[14] = 0.0f;
result->m[15] = 1.0f;
}
// Creates a matrix from a quaternion.
inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* quat) {
const float x2 = quat->x + quat->x;
const float y2 = quat->y + quat->y;
const float z2 = quat->z + quat->z;
const float xx2 = quat->x * x2;
const float yy2 = quat->y * y2;
const float zz2 = quat->z * z2;
const float yz2 = quat->y * z2;
const float wx2 = quat->w * x2;
const float xy2 = quat->x * y2;
const float wz2 = quat->w * z2;
const float xz2 = quat->x * z2;
const float wy2 = quat->w * y2;
result->m[0] = 1.0f - yy2 - zz2;
result->m[1] = xy2 + wz2;
result->m[2] = xz2 - wy2;
result->m[3] = 0.0f;
result->m[4] = xy2 - wz2;
result->m[5] = 1.0f - xx2 - zz2;
result->m[6] = yz2 + wx2;
result->m[7] = 0.0f;
result->m[8] = xz2 + wy2;
result->m[9] = yz2 - wx2;
result->m[10] = 1.0f - xx2 - yy2;
result->m[11] = 0.0f;
result->m[12] = 0.0f;
result->m[13] = 0.0f;
result->m[14] = 0.0f;
result->m[15] = 1.0f;
}
// Creates a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* result, const XrVector3f* translation,
const XrQuaternionf* rotation, const XrVector3f* scale) {
XrMatrix4x4f scaleMatrix;
XrMatrix4x4f_CreateScale(&scaleMatrix, scale->x, scale->y, scale->z);
XrMatrix4x4f rotationMatrix;
XrMatrix4x4f_CreateFromQuaternion(&rotationMatrix, rotation);
XrMatrix4x4f translationMatrix;
XrMatrix4x4f_CreateTranslation(&translationMatrix, translation->x, translation->y, translation->z);
XrMatrix4x4f combinedMatrix;
XrMatrix4x4f_Multiply(&combinedMatrix, &rotationMatrix, &scaleMatrix);
XrMatrix4x4f_Multiply(result, &translationMatrix, &combinedMatrix);
}
// Creates a projection matrix based on the specified dimensions.
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API.
// The far plane is placed at infinity if farZ <= nearZ.
// An infinite projection matrix is preferred for rasterization because, except for
// things *right* up against the near plane, it always provides better precision:
// "Tightening the Precision of Perspective Rendering"
// Paul Upchurch, Mathieu Desbrun
// Journal of Graphics Tools, Volume 16, Issue 1, 2012
inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const float tanAngleLeft,
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
const float nearZ, const float farZ) {
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan).
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal).
const float tanAngleHeight = graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown);
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
const float offsetZ = (graphicsApi == GRAPHICS_OPENGL || graphicsApi == GRAPHICS_OPENGL_ES) ? nearZ : 0;
if (farZ <= nearZ) {
// place the far plane at infinity
result->m[0] = 2.0f / tanAngleWidth;
result->m[4] = 0.0f;
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
result->m[12] = 0.0f;
result->m[1] = 0.0f;
result->m[5] = 2.0f / tanAngleHeight;
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
result->m[13] = 0.0f;
result->m[2] = 0.0f;
result->m[6] = 0.0f;
result->m[10] = -1.0f;
result->m[14] = -(nearZ + offsetZ);
result->m[3] = 0.0f;
result->m[7] = 0.0f;
result->m[11] = -1.0f;
result->m[15] = 0.0f;
} else {
// normal projection
result->m[0] = 2.0f / tanAngleWidth;
result->m[4] = 0.0f;
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
result->m[12] = 0.0f;
result->m[1] = 0.0f;
result->m[5] = 2.0f / tanAngleHeight;
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
result->m[13] = 0.0f;
result->m[2] = 0.0f;
result->m[6] = 0.0f;
result->m[10] = -(farZ + offsetZ) / (farZ - nearZ);
result->m[14] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
result->m[3] = 0.0f;
result->m[7] = 0.0f;
result->m[11] = -1.0f;
result->m[15] = 0.0f;
}
}
// Creates a projection matrix based on the specified FOV.
inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const XrFovf fov,
const float nearZ, const float farZ) {
const float tanLeft = tanf(fov.angleLeft);
const float tanRight = tanf(fov.angleRight);
const float tanDown = tanf(fov.angleDown);
const float tanUp = tanf(fov.angleUp);
XrMatrix4x4f_CreateProjection(result, graphicsApi, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
}
// Creates a matrix that transforms the -1 to 1 cube to cover the given 'mins' and 'maxs' transformed with the given 'matrix'.
inline static void XrMatrix4x4f_CreateOffsetScaleForBounds(XrMatrix4x4f* result, const XrMatrix4x4f* matrix, const XrVector3f* mins,
const XrVector3f* maxs) {
const XrVector3f offset = {(maxs->x + mins->x) * 0.5f, (maxs->y + mins->y) * 0.5f, (maxs->z + mins->z) * 0.5f};
const XrVector3f scale = {(maxs->x - mins->x) * 0.5f, (maxs->y - mins->y) * 0.5f, (maxs->z - mins->z) * 0.5f};
result->m[0] = matrix->m[0] * scale.x;
result->m[1] = matrix->m[1] * scale.x;
result->m[2] = matrix->m[2] * scale.x;
result->m[3] = matrix->m[3] * scale.x;
result->m[4] = matrix->m[4] * scale.y;
result->m[5] = matrix->m[5] * scale.y;
result->m[6] = matrix->m[6] * scale.y;
result->m[7] = matrix->m[7] * scale.y;
result->m[8] = matrix->m[8] * scale.z;
result->m[9] = matrix->m[9] * scale.z;
result->m[10] = matrix->m[10] * scale.z;
result->m[11] = matrix->m[11] * scale.z;
result->m[12] = matrix->m[12] + matrix->m[0] * offset.x + matrix->m[4] * offset.y + matrix->m[8] * offset.z;
result->m[13] = matrix->m[13] + matrix->m[1] * offset.x + matrix->m[5] * offset.y + matrix->m[9] * offset.z;
result->m[14] = matrix->m[14] + matrix->m[2] * offset.x + matrix->m[6] * offset.y + matrix->m[10] * offset.z;
result->m[15] = matrix->m[15] + matrix->m[3] * offset.x + matrix->m[7] * offset.y + matrix->m[11] * offset.z;
}
// Returns true if the given matrix is affine.
inline static bool XrMatrix4x4f_IsAffine(const XrMatrix4x4f* matrix, const float epsilon) {
return fabsf(matrix->m[3]) <= epsilon && fabsf(matrix->m[7]) <= epsilon && fabsf(matrix->m[11]) <= epsilon &&
fabsf(matrix->m[15] - 1.0f) <= epsilon;
}
// Returns true if the given matrix is orthogonal.
inline static bool XrMatrix4x4f_IsOrthogonal(const XrMatrix4x4f* matrix, const float epsilon) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i != j) {
if (fabsf(matrix->m[4 * i + 0] * matrix->m[4 * j + 0] + matrix->m[4 * i + 1] * matrix->m[4 * j + 1] +
matrix->m[4 * i + 2] * matrix->m[4 * j + 2]) > epsilon) {
return false;
}
if (fabsf(matrix->m[4 * 0 + i] * matrix->m[4 * 0 + j] + matrix->m[4 * 1 + i] * matrix->m[4 * 1 + j] +
matrix->m[4 * 2 + i] * matrix->m[4 * 2 + j]) > epsilon) {
return false;
}
}
}
}
return true;
}
// Returns true if the given matrix is orthonormal.
inline static bool XrMatrix4x4f_IsOrthonormal(const XrMatrix4x4f* matrix, const float epsilon) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
const float kd = (i == j) ? 1.0f : 0.0f; // Kronecker delta
if (fabsf(kd - (matrix->m[4 * i + 0] * matrix->m[4 * j + 0] + matrix->m[4 * i + 1] * matrix->m[4 * j + 1] +
matrix->m[4 * i + 2] * matrix->m[4 * j + 2])) > epsilon) {
return false;
}
if (fabsf(kd - (matrix->m[4 * 0 + i] * matrix->m[4 * 0 + j] + matrix->m[4 * 1 + i] * matrix->m[4 * 1 + j] +
matrix->m[4 * 2 + i] * matrix->m[4 * 2 + j])) > epsilon) {
return false;
}
}
}
return true;
}
// Returns true if the given matrix is a rigid body transform.
inline static bool XrMatrix4x4f_IsRigidBody(const XrMatrix4x4f* matrix, const float epsilon) {
return XrMatrix4x4f_IsAffine(matrix, epsilon) && XrMatrix4x4f_IsOrthonormal(matrix, epsilon);
}
// Get the translation from a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_GetTranslation(XrVector3f* result, const XrMatrix4x4f* src) {
assert(XrMatrix4x4f_IsAffine(src, 1e-4f));
assert(XrMatrix4x4f_IsOrthogonal(src, 1e-4f));
result->x = src->m[12];
result->y = src->m[13];
result->z = src->m[14];
}
// Get the rotation from a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_GetRotation(XrQuaternionf* result, const XrMatrix4x4f* src) {
assert(XrMatrix4x4f_IsAffine(src, 1e-4f));
assert(XrMatrix4x4f_IsOrthogonal(src, 1e-4f));
const float rcpScaleX = XrRcpSqrt(src->m[0] * src->m[0] + src->m[1] * src->m[1] + src->m[2] * src->m[2]);
const float rcpScaleY = XrRcpSqrt(src->m[4] * src->m[4] + src->m[5] * src->m[5] + src->m[6] * src->m[6]);
const float rcpScaleZ = XrRcpSqrt(src->m[8] * src->m[8] + src->m[9] * src->m[9] + src->m[10] * src->m[10]);
const float m[9] = {src->m[0] * rcpScaleX, src->m[1] * rcpScaleX, src->m[2] * rcpScaleX,
src->m[4] * rcpScaleY, src->m[5] * rcpScaleY, src->m[6] * rcpScaleY,
src->m[8] * rcpScaleZ, src->m[9] * rcpScaleZ, src->m[10] * rcpScaleZ};
if (m[0 * 3 + 0] + m[1 * 3 + 1] + m[2 * 3 + 2] > 0.0f) {
float t = +m[0 * 3 + 0] + m[1 * 3 + 1] + m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->w = s * t;
result->z = (m[0 * 3 + 1] - m[1 * 3 + 0]) * s;
result->y = (m[2 * 3 + 0] - m[0 * 3 + 2]) * s;
result->x = (m[1 * 3 + 2] - m[2 * 3 + 1]) * s;
} else if (m[0 * 3 + 0] > m[1 * 3 + 1] && m[0 * 3 + 0] > m[2 * 3 + 2]) {
float t = +m[0 * 3 + 0] - m[1 * 3 + 1] - m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->x = s * t;
result->y = (m[0 * 3 + 1] + m[1 * 3 + 0]) * s;
result->z = (m[2 * 3 + 0] + m[0 * 3 + 2]) * s;
result->w = (m[1 * 3 + 2] - m[2 * 3 + 1]) * s;
} else if (m[1 * 3 + 1] > m[2 * 3 + 2]) {
float t = -m[0 * 3 + 0] + m[1 * 3 + 1] - m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->y = s * t;
result->x = (m[0 * 3 + 1] + m[1 * 3 + 0]) * s;
result->w = (m[2 * 3 + 0] - m[0 * 3 + 2]) * s;
result->z = (m[1 * 3 + 2] + m[2 * 3 + 1]) * s;
} else {
float t = -m[0 * 3 + 0] - m[1 * 3 + 1] + m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->z = s * t;
result->w = (m[0 * 3 + 1] - m[1 * 3 + 0]) * s;
result->x = (m[2 * 3 + 0] + m[0 * 3 + 2]) * s;
result->y = (m[1 * 3 + 2] + m[2 * 3 + 1]) * s;
}
}
// Get the scale from a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_GetScale(XrVector3f* result, const XrMatrix4x4f* src) {
assert(XrMatrix4x4f_IsAffine(src, 1e-4f));
assert(XrMatrix4x4f_IsOrthogonal(src, 1e-4f));
result->x = sqrtf(src->m[0] * src->m[0] + src->m[1] * src->m[1] + src->m[2] * src->m[2]);
result->y = sqrtf(src->m[4] * src->m[4] + src->m[5] * src->m[5] + src->m[6] * src->m[6]);
result->z = sqrtf(src->m[8] * src->m[8] + src->m[9] * src->m[9] + src->m[10] * src->m[10]);
}
// Transforms a 3D vector.
inline static void XrMatrix4x4f_TransformVector3f(XrVector3f* result, const XrMatrix4x4f* m, const XrVector3f* v) {
const float w = m->m[3] * v->x + m->m[7] * v->y + m->m[11] * v->z + m->m[15];
const float rcpW = 1.0f / w;
result->x = (m->m[0] * v->x + m->m[4] * v->y + m->m[8] * v->z + m->m[12]) * rcpW;
result->y = (m->m[1] * v->x + m->m[5] * v->y + m->m[9] * v->z + m->m[13]) * rcpW;
result->z = (m->m[2] * v->x + m->m[6] * v->y + m->m[10] * v->z + m->m[14]) * rcpW;
}
// Transforms a 4D vector.
inline static void XrMatrix4x4f_TransformVector4f(XrVector4f* result, const XrMatrix4x4f* m, const XrVector4f* v) {
result->x = m->m[0] * v->x + m->m[4] * v->y + m->m[8] * v->z + m->m[12] * v->w;
result->y = m->m[1] * v->x + m->m[5] * v->y + m->m[9] * v->z + m->m[13] * v->w;
result->z = m->m[2] * v->x + m->m[6] * v->y + m->m[10] * v->z + m->m[14] * v->w;
result->w = m->m[3] * v->x + m->m[7] * v->y + m->m[11] * v->z + m->m[15] * v->w;
}
// Transforms the 'mins' and 'maxs' bounds with the given 'matrix'.
inline static void XrMatrix4x4f_TransformBounds(XrVector3f* resultMins, XrVector3f* resultMaxs, const XrMatrix4x4f* matrix,
const XrVector3f* mins, const XrVector3f* maxs) {
assert(XrMatrix4x4f_IsAffine(matrix, 1e-4f));
const XrVector3f center = {(mins->x + maxs->x) * 0.5f, (mins->y + maxs->y) * 0.5f, (mins->z + maxs->z) * 0.5f};
const XrVector3f extents = {maxs->x - center.x, maxs->y - center.y, maxs->z - center.z};
const XrVector3f newCenter = {matrix->m[0] * center.x + matrix->m[4] * center.y + matrix->m[8] * center.z + matrix->m[12],
matrix->m[1] * center.x + matrix->m[5] * center.y + matrix->m[9] * center.z + matrix->m[13],
matrix->m[2] * center.x + matrix->m[6] * center.y + matrix->m[10] * center.z + matrix->m[14]};
const XrVector3f newExtents = {
fabsf(extents.x * matrix->m[0]) + fabsf(extents.y * matrix->m[4]) + fabsf(extents.z * matrix->m[8]),
fabsf(extents.x * matrix->m[1]) + fabsf(extents.y * matrix->m[5]) + fabsf(extents.z * matrix->m[9]),
fabsf(extents.x * matrix->m[2]) + fabsf(extents.y * matrix->m[6]) + fabsf(extents.z * matrix->m[10])};
XrVector3f_Sub(resultMins, &newCenter, &newExtents);
XrVector3f_Add(resultMaxs, &newCenter, &newExtents);
}
// Returns true if the 'mins' and 'maxs' bounds is completely off to one side of the projection matrix.
inline static bool XrMatrix4x4f_CullBounds(const XrMatrix4x4f* mvp, const XrVector3f* mins, const XrVector3f* maxs) {
if (maxs->x <= mins->x && maxs->y <= mins->y && maxs->z <= mins->z) {
return false;
}
XrVector4f c[8];
for (int i = 0; i < 8; i++) {
const XrVector4f corner = {(i & 1) != 0 ? maxs->x : mins->x, (i & 2) != 0 ? maxs->y : mins->y,
(i & 4) != 0 ? maxs->z : mins->z, 1.0f};
XrMatrix4x4f_TransformVector4f(&c[i], mvp, &corner);
}
int i;
for (i = 0; i < 8; i++) {
if (c[i].x > -c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].x < c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].y > -c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].y < c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].z > -c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].z < c[i].w) {
break;
}
}
return i == 8;
}
#endif // XR_LINEAR_H_

View File

@@ -0,0 +1,675 @@
#ifndef OPENXR_PLATFORM_H_
#define OPENXR_PLATFORM_H_ 1
/*
** Copyright (c) 2017-2021, The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0 OR MIT
*/
/*
** This header is generated from the Khronos OpenXR XML API Registry.
**
*/
#include "openxr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_android_thread_settings 1
#define XR_KHR_android_thread_settings_SPEC_VERSION 5
#define XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME "XR_KHR_android_thread_settings"
typedef enum XrAndroidThreadTypeKHR {
XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR = 1,
XR_ANDROID_THREAD_TYPE_APPLICATION_WORKER_KHR = 2,
XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR = 3,
XR_ANDROID_THREAD_TYPE_RENDERER_WORKER_KHR = 4,
XR_ANDROID_THREAD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
} XrAndroidThreadTypeKHR;
typedef XrResult (XRAPI_PTR *PFN_xrSetAndroidApplicationThreadKHR)(XrSession session, XrAndroidThreadTypeKHR threadType, uint32_t threadId);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrSetAndroidApplicationThreadKHR(
XrSession session,
XrAndroidThreadTypeKHR threadType,
uint32_t threadId);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_android_surface_swapchain 1
#define XR_KHR_android_surface_swapchain_SPEC_VERSION 4
#define XR_KHR_ANDROID_SURFACE_SWAPCHAIN_EXTENSION_NAME "XR_KHR_android_surface_swapchain"
typedef XrResult (XRAPI_PTR *PFN_xrCreateSwapchainAndroidSurfaceKHR)(XrSession session, const XrSwapchainCreateInfo* info, XrSwapchain* swapchain, jobject* surface);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateSwapchainAndroidSurfaceKHR(
XrSession session,
const XrSwapchainCreateInfo* info,
XrSwapchain* swapchain,
jobject* surface);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_android_create_instance 1
#define XR_KHR_android_create_instance_SPEC_VERSION 3
#define XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME "XR_KHR_android_create_instance"
// XrInstanceCreateInfoAndroidKHR extends XrInstanceCreateInfo
typedef struct XrInstanceCreateInfoAndroidKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
void* XR_MAY_ALIAS applicationVM;
void* XR_MAY_ALIAS applicationActivity;
} XrInstanceCreateInfoAndroidKHR;
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_KHR_vulkan_swapchain_format_list 1
#define XR_KHR_vulkan_swapchain_format_list_SPEC_VERSION 4
#define XR_KHR_VULKAN_SWAPCHAIN_FORMAT_LIST_EXTENSION_NAME "XR_KHR_vulkan_swapchain_format_list"
typedef struct XrVulkanSwapchainFormatListCreateInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
uint32_t viewFormatCount;
const VkFormat* viewFormats;
} XrVulkanSwapchainFormatListCreateInfoKHR;
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_GRAPHICS_API_OPENGL
#define XR_KHR_opengl_enable 1
#define XR_KHR_opengl_enable_SPEC_VERSION 9
#define XR_KHR_OPENGL_ENABLE_EXTENSION_NAME "XR_KHR_opengl_enable"
#ifdef XR_USE_PLATFORM_WIN32
// XrGraphicsBindingOpenGLWin32KHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLWin32KHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
HDC hDC;
HGLRC hGLRC;
} XrGraphicsBindingOpenGLWin32KHR;
#endif // XR_USE_PLATFORM_WIN32
#ifdef XR_USE_PLATFORM_XLIB
// XrGraphicsBindingOpenGLXlibKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLXlibKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
Display* xDisplay;
uint32_t visualid;
GLXFBConfig glxFBConfig;
GLXDrawable glxDrawable;
GLXContext glxContext;
} XrGraphicsBindingOpenGLXlibKHR;
#endif // XR_USE_PLATFORM_XLIB
#ifdef XR_USE_PLATFORM_XCB
// XrGraphicsBindingOpenGLXcbKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLXcbKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
xcb_connection_t* connection;
uint32_t screenNumber;
xcb_glx_fbconfig_t fbconfigid;
xcb_visualid_t visualid;
xcb_glx_drawable_t glxDrawable;
xcb_glx_context_t glxContext;
} XrGraphicsBindingOpenGLXcbKHR;
#endif // XR_USE_PLATFORM_XCB
#ifdef XR_USE_PLATFORM_WAYLAND
// XrGraphicsBindingOpenGLWaylandKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLWaylandKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
struct wl_display* display;
} XrGraphicsBindingOpenGLWaylandKHR;
#endif // XR_USE_PLATFORM_WAYLAND
typedef struct XrSwapchainImageOpenGLKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
uint32_t image;
} XrSwapchainImageOpenGLKHR;
typedef struct XrGraphicsRequirementsOpenGLKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrVersion minApiVersionSupported;
XrVersion maxApiVersionSupported;
} XrGraphicsRequirementsOpenGLKHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLGraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsOpenGLKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_OPENGL */
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
#define XR_KHR_opengl_es_enable 1
#define XR_KHR_opengl_es_enable_SPEC_VERSION 7
#define XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME "XR_KHR_opengl_es_enable"
#ifdef XR_USE_PLATFORM_ANDROID
// XrGraphicsBindingOpenGLESAndroidKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLESAndroidKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
EGLDisplay display;
EGLConfig config;
EGLContext context;
} XrGraphicsBindingOpenGLESAndroidKHR;
#endif // XR_USE_PLATFORM_ANDROID
typedef struct XrSwapchainImageOpenGLESKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
uint32_t image;
} XrSwapchainImageOpenGLESKHR;
typedef struct XrGraphicsRequirementsOpenGLESKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrVersion minApiVersionSupported;
XrVersion maxApiVersionSupported;
} XrGraphicsRequirementsOpenGLESKHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLESGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLESGraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_KHR_vulkan_enable 1
#define XR_KHR_vulkan_enable_SPEC_VERSION 8
#define XR_KHR_VULKAN_ENABLE_EXTENSION_NAME "XR_KHR_vulkan_enable"
// XrGraphicsBindingVulkanKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingVulkanKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
VkInstance instance;
VkPhysicalDevice physicalDevice;
VkDevice device;
uint32_t queueFamilyIndex;
uint32_t queueIndex;
} XrGraphicsBindingVulkanKHR;
typedef struct XrSwapchainImageVulkanKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
VkImage image;
} XrSwapchainImageVulkanKHR;
typedef struct XrGraphicsRequirementsVulkanKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrVersion minApiVersionSupported;
XrVersion maxApiVersionSupported;
} XrGraphicsRequirementsVulkanKHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanInstanceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanDeviceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDeviceKHR)(XrInstance instance, XrSystemId systemId, VkInstance vkInstance, VkPhysicalDevice* vkPhysicalDevice);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanInstanceExtensionsKHR(
XrInstance instance,
XrSystemId systemId,
uint32_t bufferCapacityInput,
uint32_t* bufferCountOutput,
char* buffer);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanDeviceExtensionsKHR(
XrInstance instance,
XrSystemId systemId,
uint32_t bufferCapacityInput,
uint32_t* bufferCountOutput,
char* buffer);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDeviceKHR(
XrInstance instance,
XrSystemId systemId,
VkInstance vkInstance,
VkPhysicalDevice* vkPhysicalDevice);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_GRAPHICS_API_D3D11
#define XR_KHR_D3D11_enable 1
#define XR_KHR_D3D11_enable_SPEC_VERSION 5
#define XR_KHR_D3D11_ENABLE_EXTENSION_NAME "XR_KHR_D3D11_enable"
// XrGraphicsBindingD3D11KHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingD3D11KHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
ID3D11Device* device;
} XrGraphicsBindingD3D11KHR;
typedef struct XrSwapchainImageD3D11KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
ID3D11Texture2D* texture;
} XrSwapchainImageD3D11KHR;
typedef struct XrGraphicsRequirementsD3D11KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
LUID adapterLuid;
D3D_FEATURE_LEVEL minFeatureLevel;
} XrGraphicsRequirementsD3D11KHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetD3D11GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D11KHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D11GraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsD3D11KHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_D3D11 */
#ifdef XR_USE_GRAPHICS_API_D3D12
#define XR_KHR_D3D12_enable 1
#define XR_KHR_D3D12_enable_SPEC_VERSION 7
#define XR_KHR_D3D12_ENABLE_EXTENSION_NAME "XR_KHR_D3D12_enable"
// XrGraphicsBindingD3D12KHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingD3D12KHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
ID3D12Device* device;
ID3D12CommandQueue* queue;
} XrGraphicsBindingD3D12KHR;
typedef struct XrSwapchainImageD3D12KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
ID3D12Resource* texture;
} XrSwapchainImageD3D12KHR;
typedef struct XrGraphicsRequirementsD3D12KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
LUID adapterLuid;
D3D_FEATURE_LEVEL minFeatureLevel;
} XrGraphicsRequirementsD3D12KHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetD3D12GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D12KHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsD3D12KHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_D3D12 */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_KHR_win32_convert_performance_counter_time 1
#define XR_KHR_win32_convert_performance_counter_time_SPEC_VERSION 1
#define XR_KHR_WIN32_CONVERT_PERFORMANCE_COUNTER_TIME_EXTENSION_NAME "XR_KHR_win32_convert_performance_counter_time"
typedef XrResult (XRAPI_PTR *PFN_xrConvertWin32PerformanceCounterToTimeKHR)(XrInstance instance, const LARGE_INTEGER* performanceCounter, XrTime* time);
typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToWin32PerformanceCounterKHR)(XrInstance instance, XrTime time, LARGE_INTEGER* performanceCounter);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrConvertWin32PerformanceCounterToTimeKHR(
XrInstance instance,
const LARGE_INTEGER* performanceCounter,
XrTime* time);
XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToWin32PerformanceCounterKHR(
XrInstance instance,
XrTime time,
LARGE_INTEGER* performanceCounter);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_TIMESPEC
#define XR_KHR_convert_timespec_time 1
#define XR_KHR_convert_timespec_time_SPEC_VERSION 1
#define XR_KHR_CONVERT_TIMESPEC_TIME_EXTENSION_NAME "XR_KHR_convert_timespec_time"
typedef XrResult (XRAPI_PTR *PFN_xrConvertTimespecTimeToTimeKHR)(XrInstance instance, const struct timespec* timespecTime, XrTime* time);
typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToTimespecTimeKHR)(XrInstance instance, XrTime time, struct timespec* timespecTime);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimespecTimeToTimeKHR(
XrInstance instance,
const struct timespec* timespecTime,
XrTime* time);
XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToTimespecTimeKHR(
XrInstance instance,
XrTime time,
struct timespec* timespecTime);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_TIMESPEC */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_loader_init_android 1
#define XR_KHR_loader_init_android_SPEC_VERSION 1
#define XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME "XR_KHR_loader_init_android"
typedef struct XrLoaderInitInfoAndroidKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
void* XR_MAY_ALIAS applicationVM;
void* XR_MAY_ALIAS applicationContext;
} XrLoaderInitInfoAndroidKHR;
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_KHR_vulkan_enable2 1
#define XR_KHR_vulkan_enable2_SPEC_VERSION 2
#define XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME "XR_KHR_vulkan_enable2"
typedef XrFlags64 XrVulkanInstanceCreateFlagsKHR;
// Flag bits for XrVulkanInstanceCreateFlagsKHR
typedef XrFlags64 XrVulkanDeviceCreateFlagsKHR;
// Flag bits for XrVulkanDeviceCreateFlagsKHR
typedef struct XrVulkanInstanceCreateInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrSystemId systemId;
XrVulkanInstanceCreateFlagsKHR createFlags;
PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
const VkInstanceCreateInfo* vulkanCreateInfo;
const VkAllocationCallbacks* vulkanAllocator;
} XrVulkanInstanceCreateInfoKHR;
typedef struct XrVulkanDeviceCreateInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrSystemId systemId;
XrVulkanDeviceCreateFlagsKHR createFlags;
PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
VkPhysicalDevice vulkanPhysicalDevice;
const VkDeviceCreateInfo* vulkanCreateInfo;
const VkAllocationCallbacks* vulkanAllocator;
} XrVulkanDeviceCreateInfoKHR;
typedef XrGraphicsBindingVulkanKHR XrGraphicsBindingVulkan2KHR;
typedef struct XrVulkanGraphicsDeviceGetInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrSystemId systemId;
VkInstance vulkanInstance;
} XrVulkanGraphicsDeviceGetInfoKHR;
typedef XrSwapchainImageVulkanKHR XrSwapchainImageVulkan2KHR;
typedef XrGraphicsRequirementsVulkanKHR XrGraphicsRequirementsVulkan2KHR;
typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanInstanceKHR)(XrInstance instance, const XrVulkanInstanceCreateInfoKHR*createInfo, VkInstance* vulkanInstance, VkResult* vulkanResult);
typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanDeviceKHR)(XrInstance instance, const XrVulkanDeviceCreateInfoKHR* createInfo, VkDevice* vulkanDevice, VkResult* vulkanResult);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDevice2KHR)(XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR* getInfo, VkPhysicalDevice* vulkanPhysicalDevice);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirements2KHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateVulkanInstanceKHR(
XrInstance instance,
const XrVulkanInstanceCreateInfoKHR* createInfo,
VkInstance* vulkanInstance,
VkResult* vulkanResult);
XRAPI_ATTR XrResult XRAPI_CALL xrCreateVulkanDeviceKHR(
XrInstance instance,
const XrVulkanDeviceCreateInfoKHR* createInfo,
VkDevice* vulkanDevice,
VkResult* vulkanResult);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDevice2KHR(
XrInstance instance,
const XrVulkanGraphicsDeviceGetInfoKHR* getInfo,
VkPhysicalDevice* vulkanPhysicalDevice);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirements2KHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_PLATFORM_EGL
#define XR_MNDX_egl_enable 1
#define XR_MNDX_egl_enable_SPEC_VERSION 1
#define XR_MNDX_EGL_ENABLE_EXTENSION_NAME "XR_MNDX_egl_enable"
// XrGraphicsBindingEGLMNDX extends XrSessionCreateInfo
typedef struct XrGraphicsBindingEGLMNDX {
XrStructureType type;
const void* XR_MAY_ALIAS next;
PFNEGLGETPROCADDRESSPROC getProcAddress;
EGLDisplay display;
EGLConfig config;
EGLContext context;
} XrGraphicsBindingEGLMNDX;
#endif /* XR_USE_PLATFORM_EGL */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_MSFT_perception_anchor_interop 1
#define XR_MSFT_perception_anchor_interop_SPEC_VERSION 1
#define XR_MSFT_PERCEPTION_ANCHOR_INTEROP_EXTENSION_NAME "XR_MSFT_perception_anchor_interop"
typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorFromPerceptionAnchorMSFT)(XrSession session, IUnknown* perceptionAnchor, XrSpatialAnchorMSFT* anchor);
typedef XrResult (XRAPI_PTR *PFN_xrTryGetPerceptionAnchorFromSpatialAnchorMSFT)(XrSession session, XrSpatialAnchorMSFT anchor, IUnknown** perceptionAnchor);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorFromPerceptionAnchorMSFT(
XrSession session,
IUnknown* perceptionAnchor,
XrSpatialAnchorMSFT* anchor);
XRAPI_ATTR XrResult XRAPI_CALL xrTryGetPerceptionAnchorFromSpatialAnchorMSFT(
XrSession session,
XrSpatialAnchorMSFT anchor,
IUnknown** perceptionAnchor);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_MSFT_holographic_window_attachment 1
#define XR_MSFT_holographic_window_attachment_SPEC_VERSION 1
#define XR_MSFT_HOLOGRAPHIC_WINDOW_ATTACHMENT_EXTENSION_NAME "XR_MSFT_holographic_window_attachment"
#ifdef XR_USE_PLATFORM_WIN32
// XrHolographicWindowAttachmentMSFT extends XrSessionCreateInfo
typedef struct XrHolographicWindowAttachmentMSFT {
XrStructureType type;
const void* XR_MAY_ALIAS next;
IUnknown* holographicSpace;
IUnknown* coreWindow;
} XrHolographicWindowAttachmentMSFT;
#endif // XR_USE_PLATFORM_WIN32
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_FB_android_surface_swapchain_create 1
#define XR_FB_android_surface_swapchain_create_SPEC_VERSION 1
#define XR_FB_ANDROID_SURFACE_SWAPCHAIN_CREATE_EXTENSION_NAME "XR_FB_android_surface_swapchain_create"
typedef XrFlags64 XrAndroidSurfaceSwapchainFlagsFB;
// Flag bits for XrAndroidSurfaceSwapchainFlagsFB
static const XrAndroidSurfaceSwapchainFlagsFB XR_ANDROID_SURFACE_SWAPCHAIN_SYNCHRONOUS_BIT_FB = 0x00000001;
static const XrAndroidSurfaceSwapchainFlagsFB XR_ANDROID_SURFACE_SWAPCHAIN_USE_TIMESTAMPS_BIT_FB = 0x00000002;
#ifdef XR_USE_PLATFORM_ANDROID
// XrAndroidSurfaceSwapchainCreateInfoFB extends XrSwapchainCreateInfo
typedef struct XrAndroidSurfaceSwapchainCreateInfoFB {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrAndroidSurfaceSwapchainFlagsFB createFlags;
} XrAndroidSurfaceSwapchainCreateInfoFB;
#endif // XR_USE_PLATFORM_ANDROID
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_OCULUS_audio_device_guid 1
#define XR_OCULUS_audio_device_guid_SPEC_VERSION 1
#define XR_OCULUS_AUDIO_DEVICE_GUID_EXTENSION_NAME "XR_OCULUS_audio_device_guid"
#define XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS 128
typedef XrResult (XRAPI_PTR *PFN_xrGetAudioOutputDeviceGuidOculus)(XrInstance instance, wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
typedef XrResult (XRAPI_PTR *PFN_xrGetAudioInputDeviceGuidOculus)(XrInstance instance, wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetAudioOutputDeviceGuidOculus(
XrInstance instance,
wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
XRAPI_ATTR XrResult XRAPI_CALL xrGetAudioInputDeviceGuidOculus(
XrInstance instance,
wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_FB_foveation_vulkan 1
#define XR_FB_foveation_vulkan_SPEC_VERSION 1
#define XR_FB_FOVEATION_VULKAN_EXTENSION_NAME "XR_FB_foveation_vulkan"
// XrSwapchainImageFoveationVulkanFB extends XrSwapchainImageVulkanKHR
typedef struct XrSwapchainImageFoveationVulkanFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
VkImage image;
uint32_t width;
uint32_t height;
} XrSwapchainImageFoveationVulkanFB;
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_FB_swapchain_update_state_android_surface 1
#define XR_FB_swapchain_update_state_android_surface_SPEC_VERSION 1
#define XR_FB_SWAPCHAIN_UPDATE_STATE_ANDROID_SURFACE_EXTENSION_NAME "XR_FB_swapchain_update_state_android_surface"
#ifdef XR_USE_PLATFORM_ANDROID
typedef struct XrSwapchainStateAndroidSurfaceDimensionsFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
uint32_t width;
uint32_t height;
} XrSwapchainStateAndroidSurfaceDimensionsFB;
#endif // XR_USE_PLATFORM_ANDROID
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
#define XR_FB_swapchain_update_state_opengl_es 1
#define XR_FB_swapchain_update_state_opengl_es_SPEC_VERSION 1
#define XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME "XR_FB_swapchain_update_state_opengl_es"
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
typedef struct XrSwapchainStateSamplerOpenGLESFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
EGLenum minFilter;
EGLenum magFilter;
EGLenum wrapModeS;
EGLenum wrapModeT;
EGLenum swizzleRed;
EGLenum swizzleGreen;
EGLenum swizzleBlue;
EGLenum swizzleAlpha;
float maxAnisotropy;
XrColor4f borderColor;
} XrSwapchainStateSamplerOpenGLESFB;
#endif // XR_USE_GRAPHICS_API_OPENGL_ES
#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_FB_swapchain_update_state_vulkan 1
#define XR_FB_swapchain_update_state_vulkan_SPEC_VERSION 1
#define XR_FB_SWAPCHAIN_UPDATE_STATE_VULKAN_EXTENSION_NAME "XR_FB_swapchain_update_state_vulkan"
#ifdef XR_USE_GRAPHICS_API_VULKAN
typedef struct XrSwapchainStateSamplerVulkanFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
VkFilter minFilter;
VkFilter magFilter;
VkSamplerMipmapMode mipmapMode;
VkSamplerAddressMode wrapModeS;
VkSamplerAddressMode wrapModeT;
VkComponentSwizzle swizzleRed;
VkComponentSwizzle swizzleGreen;
VkComponentSwizzle swizzleBlue;
VkComponentSwizzle swizzleAlpha;
float maxAnisotropy;
XrColor4f borderColor;
} XrSwapchainStateSamplerVulkanFB;
#endif // XR_USE_GRAPHICS_API_VULKAN
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,110 @@
/*
** Copyright (c) 2017-2021, The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0 OR MIT
*/
#ifndef OPENXR_PLATFORM_DEFINES_H_
#define OPENXR_PLATFORM_DEFINES_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Platform-specific calling convention macros.
*
* Platforms should define these so that OpenXR clients call OpenXR functions
* with the same calling conventions that the OpenXR implementation expects.
*
* XRAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* XRAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* XRAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void);
* Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void);
*/
#if defined(_WIN32)
#define XRAPI_ATTR
// On Windows, functions use the stdcall convention
#define XRAPI_CALL __stdcall
#define XRAPI_PTR XRAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "API not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define XRAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define XRAPI_CALL
#define XRAPI_PTR XRAPI_ATTR
#else
// On other platforms, use the default calling convention
#define XRAPI_ATTR
#define XRAPI_CALL
#define XRAPI_PTR
#endif
#include <stddef.h>
#if !defined(XR_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined( XR_NO_STDINT_H )
// XR_PTR_SIZE (in bytes)
#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__))
#define XR_PTR_SIZE 8
#else
#define XR_PTR_SIZE 4
#endif
// Needed so we can use clang __has_feature portably.
#if !defined(XR_COMPILER_HAS_FEATURE)
#if defined(__clang__)
#define XR_COMPILER_HAS_FEATURE(x) __has_feature(x)
#else
#define XR_COMPILER_HAS_FEATURE(x) 0
#endif
#endif
// Identifies if the current compiler has C++11 support enabled.
// Does not by itself identify if any given C++11 feature is present.
#if !defined(XR_CPP11_ENABLED) && defined(__cplusplus)
#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#define XR_CPP11_ENABLED 1
#elif defined(_MSC_VER) && (_MSC_VER >= 1600)
#define XR_CPP11_ENABLED 1
#elif (__cplusplus >= 201103L) // 201103 is the first C++11 version.
#define XR_CPP11_ENABLED 1
#endif
#endif
// Identifies if the current compiler supports C++11 nullptr.
#if !defined(XR_CPP_NULLPTR_SUPPORTED)
#if defined(XR_CPP11_ENABLED) && \
((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \
(defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1600)) || \
(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403)))
#define XR_CPP_NULLPTR_SUPPORTED 1
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,277 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// *********** THIS FILE IS GENERATED - DO NOT EDIT ***********
// See utility_source_generator.py for modifications
// ************************************************************
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Mark Young <marky@lunarg.com>
//
#include "xr_generated_dispatch_table.h"
#include "common/xr_dependencies.h"
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
// Helper function to populate an instance dispatch table
void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table,
XrInstance instance,
PFN_xrGetInstanceProcAddr get_inst_proc_addr) {
// ---- Core 1.0 commands
table->GetInstanceProcAddr = get_inst_proc_addr;
(get_inst_proc_addr(instance, "xrCreateInstance", (PFN_xrVoidFunction*)&table->CreateInstance));
(get_inst_proc_addr(instance, "xrDestroyInstance", (PFN_xrVoidFunction*)&table->DestroyInstance));
(get_inst_proc_addr(instance, "xrGetInstanceProperties", (PFN_xrVoidFunction*)&table->GetInstanceProperties));
(get_inst_proc_addr(instance, "xrPollEvent", (PFN_xrVoidFunction*)&table->PollEvent));
(get_inst_proc_addr(instance, "xrResultToString", (PFN_xrVoidFunction*)&table->ResultToString));
(get_inst_proc_addr(instance, "xrStructureTypeToString", (PFN_xrVoidFunction*)&table->StructureTypeToString));
(get_inst_proc_addr(instance, "xrGetSystem", (PFN_xrVoidFunction*)&table->GetSystem));
(get_inst_proc_addr(instance, "xrGetSystemProperties", (PFN_xrVoidFunction*)&table->GetSystemProperties));
(get_inst_proc_addr(instance, "xrEnumerateEnvironmentBlendModes", (PFN_xrVoidFunction*)&table->EnumerateEnvironmentBlendModes));
(get_inst_proc_addr(instance, "xrCreateSession", (PFN_xrVoidFunction*)&table->CreateSession));
(get_inst_proc_addr(instance, "xrDestroySession", (PFN_xrVoidFunction*)&table->DestroySession));
(get_inst_proc_addr(instance, "xrEnumerateReferenceSpaces", (PFN_xrVoidFunction*)&table->EnumerateReferenceSpaces));
(get_inst_proc_addr(instance, "xrCreateReferenceSpace", (PFN_xrVoidFunction*)&table->CreateReferenceSpace));
(get_inst_proc_addr(instance, "xrGetReferenceSpaceBoundsRect", (PFN_xrVoidFunction*)&table->GetReferenceSpaceBoundsRect));
(get_inst_proc_addr(instance, "xrCreateActionSpace", (PFN_xrVoidFunction*)&table->CreateActionSpace));
(get_inst_proc_addr(instance, "xrLocateSpace", (PFN_xrVoidFunction*)&table->LocateSpace));
(get_inst_proc_addr(instance, "xrDestroySpace", (PFN_xrVoidFunction*)&table->DestroySpace));
(get_inst_proc_addr(instance, "xrEnumerateViewConfigurations", (PFN_xrVoidFunction*)&table->EnumerateViewConfigurations));
(get_inst_proc_addr(instance, "xrGetViewConfigurationProperties", (PFN_xrVoidFunction*)&table->GetViewConfigurationProperties));
(get_inst_proc_addr(instance, "xrEnumerateViewConfigurationViews", (PFN_xrVoidFunction*)&table->EnumerateViewConfigurationViews));
(get_inst_proc_addr(instance, "xrEnumerateSwapchainFormats", (PFN_xrVoidFunction*)&table->EnumerateSwapchainFormats));
(get_inst_proc_addr(instance, "xrCreateSwapchain", (PFN_xrVoidFunction*)&table->CreateSwapchain));
(get_inst_proc_addr(instance, "xrDestroySwapchain", (PFN_xrVoidFunction*)&table->DestroySwapchain));
(get_inst_proc_addr(instance, "xrEnumerateSwapchainImages", (PFN_xrVoidFunction*)&table->EnumerateSwapchainImages));
(get_inst_proc_addr(instance, "xrAcquireSwapchainImage", (PFN_xrVoidFunction*)&table->AcquireSwapchainImage));
(get_inst_proc_addr(instance, "xrWaitSwapchainImage", (PFN_xrVoidFunction*)&table->WaitSwapchainImage));
(get_inst_proc_addr(instance, "xrReleaseSwapchainImage", (PFN_xrVoidFunction*)&table->ReleaseSwapchainImage));
(get_inst_proc_addr(instance, "xrBeginSession", (PFN_xrVoidFunction*)&table->BeginSession));
(get_inst_proc_addr(instance, "xrEndSession", (PFN_xrVoidFunction*)&table->EndSession));
(get_inst_proc_addr(instance, "xrRequestExitSession", (PFN_xrVoidFunction*)&table->RequestExitSession));
(get_inst_proc_addr(instance, "xrWaitFrame", (PFN_xrVoidFunction*)&table->WaitFrame));
(get_inst_proc_addr(instance, "xrBeginFrame", (PFN_xrVoidFunction*)&table->BeginFrame));
(get_inst_proc_addr(instance, "xrEndFrame", (PFN_xrVoidFunction*)&table->EndFrame));
(get_inst_proc_addr(instance, "xrLocateViews", (PFN_xrVoidFunction*)&table->LocateViews));
(get_inst_proc_addr(instance, "xrStringToPath", (PFN_xrVoidFunction*)&table->StringToPath));
(get_inst_proc_addr(instance, "xrPathToString", (PFN_xrVoidFunction*)&table->PathToString));
(get_inst_proc_addr(instance, "xrCreateActionSet", (PFN_xrVoidFunction*)&table->CreateActionSet));
(get_inst_proc_addr(instance, "xrDestroyActionSet", (PFN_xrVoidFunction*)&table->DestroyActionSet));
(get_inst_proc_addr(instance, "xrCreateAction", (PFN_xrVoidFunction*)&table->CreateAction));
(get_inst_proc_addr(instance, "xrDestroyAction", (PFN_xrVoidFunction*)&table->DestroyAction));
(get_inst_proc_addr(instance, "xrSuggestInteractionProfileBindings", (PFN_xrVoidFunction*)&table->SuggestInteractionProfileBindings));
(get_inst_proc_addr(instance, "xrAttachSessionActionSets", (PFN_xrVoidFunction*)&table->AttachSessionActionSets));
(get_inst_proc_addr(instance, "xrGetCurrentInteractionProfile", (PFN_xrVoidFunction*)&table->GetCurrentInteractionProfile));
(get_inst_proc_addr(instance, "xrGetActionStateBoolean", (PFN_xrVoidFunction*)&table->GetActionStateBoolean));
(get_inst_proc_addr(instance, "xrGetActionStateFloat", (PFN_xrVoidFunction*)&table->GetActionStateFloat));
(get_inst_proc_addr(instance, "xrGetActionStateVector2f", (PFN_xrVoidFunction*)&table->GetActionStateVector2f));
(get_inst_proc_addr(instance, "xrGetActionStatePose", (PFN_xrVoidFunction*)&table->GetActionStatePose));
(get_inst_proc_addr(instance, "xrSyncActions", (PFN_xrVoidFunction*)&table->SyncActions));
(get_inst_proc_addr(instance, "xrEnumerateBoundSourcesForAction", (PFN_xrVoidFunction*)&table->EnumerateBoundSourcesForAction));
(get_inst_proc_addr(instance, "xrGetInputSourceLocalizedName", (PFN_xrVoidFunction*)&table->GetInputSourceLocalizedName));
(get_inst_proc_addr(instance, "xrApplyHapticFeedback", (PFN_xrVoidFunction*)&table->ApplyHapticFeedback));
(get_inst_proc_addr(instance, "xrStopHapticFeedback", (PFN_xrVoidFunction*)&table->StopHapticFeedback));
// ---- XR_KHR_android_thread_settings extension commands
#if defined(XR_USE_PLATFORM_ANDROID)
(get_inst_proc_addr(instance, "xrSetAndroidApplicationThreadKHR", (PFN_xrVoidFunction*)&table->SetAndroidApplicationThreadKHR));
#endif // defined(XR_USE_PLATFORM_ANDROID)
// ---- XR_KHR_android_surface_swapchain extension commands
#if defined(XR_USE_PLATFORM_ANDROID)
(get_inst_proc_addr(instance, "xrCreateSwapchainAndroidSurfaceKHR", (PFN_xrVoidFunction*)&table->CreateSwapchainAndroidSurfaceKHR));
#endif // defined(XR_USE_PLATFORM_ANDROID)
// ---- XR_KHR_opengl_enable extension commands
#if defined(XR_USE_GRAPHICS_API_OPENGL)
(get_inst_proc_addr(instance, "xrGetOpenGLGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&table->GetOpenGLGraphicsRequirementsKHR));
#endif // defined(XR_USE_GRAPHICS_API_OPENGL)
// ---- XR_KHR_opengl_es_enable extension commands
#if defined(XR_USE_GRAPHICS_API_OPENGL_ES)
(get_inst_proc_addr(instance, "xrGetOpenGLESGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&table->GetOpenGLESGraphicsRequirementsKHR));
#endif // defined(XR_USE_GRAPHICS_API_OPENGL_ES)
// ---- XR_KHR_vulkan_enable extension commands
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrGetVulkanInstanceExtensionsKHR", (PFN_xrVoidFunction*)&table->GetVulkanInstanceExtensionsKHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrGetVulkanDeviceExtensionsKHR", (PFN_xrVoidFunction*)&table->GetVulkanDeviceExtensionsKHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrGetVulkanGraphicsDeviceKHR", (PFN_xrVoidFunction*)&table->GetVulkanGraphicsDeviceKHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrGetVulkanGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&table->GetVulkanGraphicsRequirementsKHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
// ---- XR_KHR_D3D11_enable extension commands
#if defined(XR_USE_GRAPHICS_API_D3D11)
(get_inst_proc_addr(instance, "xrGetD3D11GraphicsRequirementsKHR", (PFN_xrVoidFunction*)&table->GetD3D11GraphicsRequirementsKHR));
#endif // defined(XR_USE_GRAPHICS_API_D3D11)
// ---- XR_KHR_D3D12_enable extension commands
#if defined(XR_USE_GRAPHICS_API_D3D12)
(get_inst_proc_addr(instance, "xrGetD3D12GraphicsRequirementsKHR", (PFN_xrVoidFunction*)&table->GetD3D12GraphicsRequirementsKHR));
#endif // defined(XR_USE_GRAPHICS_API_D3D12)
// ---- XR_KHR_visibility_mask extension commands
(get_inst_proc_addr(instance, "xrGetVisibilityMaskKHR", (PFN_xrVoidFunction*)&table->GetVisibilityMaskKHR));
// ---- XR_KHR_win32_convert_performance_counter_time extension commands
#if defined(XR_USE_PLATFORM_WIN32)
(get_inst_proc_addr(instance, "xrConvertWin32PerformanceCounterToTimeKHR", (PFN_xrVoidFunction*)&table->ConvertWin32PerformanceCounterToTimeKHR));
#endif // defined(XR_USE_PLATFORM_WIN32)
#if defined(XR_USE_PLATFORM_WIN32)
(get_inst_proc_addr(instance, "xrConvertTimeToWin32PerformanceCounterKHR", (PFN_xrVoidFunction*)&table->ConvertTimeToWin32PerformanceCounterKHR));
#endif // defined(XR_USE_PLATFORM_WIN32)
// ---- XR_KHR_convert_timespec_time extension commands
#if defined(XR_USE_TIMESPEC)
(get_inst_proc_addr(instance, "xrConvertTimespecTimeToTimeKHR", (PFN_xrVoidFunction*)&table->ConvertTimespecTimeToTimeKHR));
#endif // defined(XR_USE_TIMESPEC)
#if defined(XR_USE_TIMESPEC)
(get_inst_proc_addr(instance, "xrConvertTimeToTimespecTimeKHR", (PFN_xrVoidFunction*)&table->ConvertTimeToTimespecTimeKHR));
#endif // defined(XR_USE_TIMESPEC)
// ---- XR_KHR_vulkan_enable2 extension commands
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrCreateVulkanInstanceKHR", (PFN_xrVoidFunction*)&table->CreateVulkanInstanceKHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrCreateVulkanDeviceKHR", (PFN_xrVoidFunction*)&table->CreateVulkanDeviceKHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrGetVulkanGraphicsDevice2KHR", (PFN_xrVoidFunction*)&table->GetVulkanGraphicsDevice2KHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
(get_inst_proc_addr(instance, "xrGetVulkanGraphicsRequirements2KHR", (PFN_xrVoidFunction*)&table->GetVulkanGraphicsRequirements2KHR));
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
// ---- XR_EXT_performance_settings extension commands
(get_inst_proc_addr(instance, "xrPerfSettingsSetPerformanceLevelEXT", (PFN_xrVoidFunction*)&table->PerfSettingsSetPerformanceLevelEXT));
// ---- XR_EXT_thermal_query extension commands
(get_inst_proc_addr(instance, "xrThermalGetTemperatureTrendEXT", (PFN_xrVoidFunction*)&table->ThermalGetTemperatureTrendEXT));
// ---- XR_EXT_debug_utils extension commands
(get_inst_proc_addr(instance, "xrSetDebugUtilsObjectNameEXT", (PFN_xrVoidFunction*)&table->SetDebugUtilsObjectNameEXT));
(get_inst_proc_addr(instance, "xrCreateDebugUtilsMessengerEXT", (PFN_xrVoidFunction*)&table->CreateDebugUtilsMessengerEXT));
(get_inst_proc_addr(instance, "xrDestroyDebugUtilsMessengerEXT", (PFN_xrVoidFunction*)&table->DestroyDebugUtilsMessengerEXT));
(get_inst_proc_addr(instance, "xrSubmitDebugUtilsMessageEXT", (PFN_xrVoidFunction*)&table->SubmitDebugUtilsMessageEXT));
(get_inst_proc_addr(instance, "xrSessionBeginDebugUtilsLabelRegionEXT", (PFN_xrVoidFunction*)&table->SessionBeginDebugUtilsLabelRegionEXT));
(get_inst_proc_addr(instance, "xrSessionEndDebugUtilsLabelRegionEXT", (PFN_xrVoidFunction*)&table->SessionEndDebugUtilsLabelRegionEXT));
(get_inst_proc_addr(instance, "xrSessionInsertDebugUtilsLabelEXT", (PFN_xrVoidFunction*)&table->SessionInsertDebugUtilsLabelEXT));
// ---- XR_MSFT_spatial_anchor extension commands
(get_inst_proc_addr(instance, "xrCreateSpatialAnchorMSFT", (PFN_xrVoidFunction*)&table->CreateSpatialAnchorMSFT));
(get_inst_proc_addr(instance, "xrCreateSpatialAnchorSpaceMSFT", (PFN_xrVoidFunction*)&table->CreateSpatialAnchorSpaceMSFT));
(get_inst_proc_addr(instance, "xrDestroySpatialAnchorMSFT", (PFN_xrVoidFunction*)&table->DestroySpatialAnchorMSFT));
// ---- XR_EXT_conformance_automation extension commands
(get_inst_proc_addr(instance, "xrSetInputDeviceActiveEXT", (PFN_xrVoidFunction*)&table->SetInputDeviceActiveEXT));
(get_inst_proc_addr(instance, "xrSetInputDeviceStateBoolEXT", (PFN_xrVoidFunction*)&table->SetInputDeviceStateBoolEXT));
(get_inst_proc_addr(instance, "xrSetInputDeviceStateFloatEXT", (PFN_xrVoidFunction*)&table->SetInputDeviceStateFloatEXT));
(get_inst_proc_addr(instance, "xrSetInputDeviceStateVector2fEXT", (PFN_xrVoidFunction*)&table->SetInputDeviceStateVector2fEXT));
(get_inst_proc_addr(instance, "xrSetInputDeviceLocationEXT", (PFN_xrVoidFunction*)&table->SetInputDeviceLocationEXT));
// ---- XR_MSFT_spatial_graph_bridge extension commands
(get_inst_proc_addr(instance, "xrCreateSpatialGraphNodeSpaceMSFT", (PFN_xrVoidFunction*)&table->CreateSpatialGraphNodeSpaceMSFT));
// ---- XR_EXT_hand_tracking extension commands
(get_inst_proc_addr(instance, "xrCreateHandTrackerEXT", (PFN_xrVoidFunction*)&table->CreateHandTrackerEXT));
(get_inst_proc_addr(instance, "xrDestroyHandTrackerEXT", (PFN_xrVoidFunction*)&table->DestroyHandTrackerEXT));
(get_inst_proc_addr(instance, "xrLocateHandJointsEXT", (PFN_xrVoidFunction*)&table->LocateHandJointsEXT));
// ---- XR_MSFT_hand_tracking_mesh extension commands
(get_inst_proc_addr(instance, "xrCreateHandMeshSpaceMSFT", (PFN_xrVoidFunction*)&table->CreateHandMeshSpaceMSFT));
(get_inst_proc_addr(instance, "xrUpdateHandMeshMSFT", (PFN_xrVoidFunction*)&table->UpdateHandMeshMSFT));
// ---- XR_MSFT_controller_model extension commands
(get_inst_proc_addr(instance, "xrGetControllerModelKeyMSFT", (PFN_xrVoidFunction*)&table->GetControllerModelKeyMSFT));
(get_inst_proc_addr(instance, "xrLoadControllerModelMSFT", (PFN_xrVoidFunction*)&table->LoadControllerModelMSFT));
(get_inst_proc_addr(instance, "xrGetControllerModelPropertiesMSFT", (PFN_xrVoidFunction*)&table->GetControllerModelPropertiesMSFT));
(get_inst_proc_addr(instance, "xrGetControllerModelStateMSFT", (PFN_xrVoidFunction*)&table->GetControllerModelStateMSFT));
// ---- XR_MSFT_perception_anchor_interop extension commands
#if defined(XR_USE_PLATFORM_WIN32)
(get_inst_proc_addr(instance, "xrCreateSpatialAnchorFromPerceptionAnchorMSFT", (PFN_xrVoidFunction*)&table->CreateSpatialAnchorFromPerceptionAnchorMSFT));
#endif // defined(XR_USE_PLATFORM_WIN32)
#if defined(XR_USE_PLATFORM_WIN32)
(get_inst_proc_addr(instance, "xrTryGetPerceptionAnchorFromSpatialAnchorMSFT", (PFN_xrVoidFunction*)&table->TryGetPerceptionAnchorFromSpatialAnchorMSFT));
#endif // defined(XR_USE_PLATFORM_WIN32)
// ---- XR_MSFT_composition_layer_reprojection extension commands
(get_inst_proc_addr(instance, "xrEnumerateReprojectionModesMSFT", (PFN_xrVoidFunction*)&table->EnumerateReprojectionModesMSFT));
// ---- XR_FB_swapchain_update_state extension commands
(get_inst_proc_addr(instance, "xrUpdateSwapchainFB", (PFN_xrVoidFunction*)&table->UpdateSwapchainFB));
(get_inst_proc_addr(instance, "xrGetSwapchainStateFB", (PFN_xrVoidFunction*)&table->GetSwapchainStateFB));
// ---- XR_MSFT_scene_understanding extension commands
(get_inst_proc_addr(instance, "xrEnumerateSceneComputeFeaturesMSFT", (PFN_xrVoidFunction*)&table->EnumerateSceneComputeFeaturesMSFT));
(get_inst_proc_addr(instance, "xrCreateSceneObserverMSFT", (PFN_xrVoidFunction*)&table->CreateSceneObserverMSFT));
(get_inst_proc_addr(instance, "xrDestroySceneObserverMSFT", (PFN_xrVoidFunction*)&table->DestroySceneObserverMSFT));
(get_inst_proc_addr(instance, "xrCreateSceneMSFT", (PFN_xrVoidFunction*)&table->CreateSceneMSFT));
(get_inst_proc_addr(instance, "xrDestroySceneMSFT", (PFN_xrVoidFunction*)&table->DestroySceneMSFT));
(get_inst_proc_addr(instance, "xrComputeNewSceneMSFT", (PFN_xrVoidFunction*)&table->ComputeNewSceneMSFT));
(get_inst_proc_addr(instance, "xrGetSceneComputeStateMSFT", (PFN_xrVoidFunction*)&table->GetSceneComputeStateMSFT));
(get_inst_proc_addr(instance, "xrGetSceneComponentsMSFT", (PFN_xrVoidFunction*)&table->GetSceneComponentsMSFT));
(get_inst_proc_addr(instance, "xrLocateSceneComponentsMSFT", (PFN_xrVoidFunction*)&table->LocateSceneComponentsMSFT));
(get_inst_proc_addr(instance, "xrGetSceneMeshBuffersMSFT", (PFN_xrVoidFunction*)&table->GetSceneMeshBuffersMSFT));
// ---- XR_MSFT_scene_understanding_serialization extension commands
(get_inst_proc_addr(instance, "xrDeserializeSceneMSFT", (PFN_xrVoidFunction*)&table->DeserializeSceneMSFT));
(get_inst_proc_addr(instance, "xrGetSerializedSceneFragmentDataMSFT", (PFN_xrVoidFunction*)&table->GetSerializedSceneFragmentDataMSFT));
// ---- XR_FB_display_refresh_rate extension commands
(get_inst_proc_addr(instance, "xrEnumerateDisplayRefreshRatesFB", (PFN_xrVoidFunction*)&table->EnumerateDisplayRefreshRatesFB));
(get_inst_proc_addr(instance, "xrGetDisplayRefreshRateFB", (PFN_xrVoidFunction*)&table->GetDisplayRefreshRateFB));
(get_inst_proc_addr(instance, "xrRequestDisplayRefreshRateFB", (PFN_xrVoidFunction*)&table->RequestDisplayRefreshRateFB));
// ---- XR_FB_color_space extension commands
(get_inst_proc_addr(instance, "xrEnumerateColorSpacesFB", (PFN_xrVoidFunction*)&table->EnumerateColorSpacesFB));
(get_inst_proc_addr(instance, "xrSetColorSpaceFB", (PFN_xrVoidFunction*)&table->SetColorSpaceFB));
// ---- XR_VARJO_environment_depth_estimation extension commands
(get_inst_proc_addr(instance, "xrSetEnvironmentDepthEstimationVARJO", (PFN_xrVoidFunction*)&table->SetEnvironmentDepthEstimationVARJO));
// ---- XR_OCULUS_audio_device_guid extension commands
#if defined(XR_USE_PLATFORM_WIN32)
(get_inst_proc_addr(instance, "xrGetAudioOutputDeviceGuidOculus", (PFN_xrVoidFunction*)&table->GetAudioOutputDeviceGuidOculus));
#endif // defined(XR_USE_PLATFORM_WIN32)
#if defined(XR_USE_PLATFORM_WIN32)
(get_inst_proc_addr(instance, "xrGetAudioInputDeviceGuidOculus", (PFN_xrVoidFunction*)&table->GetAudioInputDeviceGuidOculus));
#endif // defined(XR_USE_PLATFORM_WIN32)
}
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,285 @@
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// *********** THIS FILE IS GENERATED - DO NOT EDIT ***********
// See utility_source_generator.py for modifications
// ************************************************************
// Copyright (c) 2017-2021, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Mark Young <marky@lunarg.com>
//
#pragma once
#include "common/xr_dependencies.h"
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
// Generated dispatch table
struct XrGeneratedDispatchTable {
// ---- Core 1.0 commands
PFN_xrGetInstanceProcAddr GetInstanceProcAddr;
PFN_xrEnumerateApiLayerProperties EnumerateApiLayerProperties;
PFN_xrEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_xrCreateInstance CreateInstance;
PFN_xrDestroyInstance DestroyInstance;
PFN_xrGetInstanceProperties GetInstanceProperties;
PFN_xrPollEvent PollEvent;
PFN_xrResultToString ResultToString;
PFN_xrStructureTypeToString StructureTypeToString;
PFN_xrGetSystem GetSystem;
PFN_xrGetSystemProperties GetSystemProperties;
PFN_xrEnumerateEnvironmentBlendModes EnumerateEnvironmentBlendModes;
PFN_xrCreateSession CreateSession;
PFN_xrDestroySession DestroySession;
PFN_xrEnumerateReferenceSpaces EnumerateReferenceSpaces;
PFN_xrCreateReferenceSpace CreateReferenceSpace;
PFN_xrGetReferenceSpaceBoundsRect GetReferenceSpaceBoundsRect;
PFN_xrCreateActionSpace CreateActionSpace;
PFN_xrLocateSpace LocateSpace;
PFN_xrDestroySpace DestroySpace;
PFN_xrEnumerateViewConfigurations EnumerateViewConfigurations;
PFN_xrGetViewConfigurationProperties GetViewConfigurationProperties;
PFN_xrEnumerateViewConfigurationViews EnumerateViewConfigurationViews;
PFN_xrEnumerateSwapchainFormats EnumerateSwapchainFormats;
PFN_xrCreateSwapchain CreateSwapchain;
PFN_xrDestroySwapchain DestroySwapchain;
PFN_xrEnumerateSwapchainImages EnumerateSwapchainImages;
PFN_xrAcquireSwapchainImage AcquireSwapchainImage;
PFN_xrWaitSwapchainImage WaitSwapchainImage;
PFN_xrReleaseSwapchainImage ReleaseSwapchainImage;
PFN_xrBeginSession BeginSession;
PFN_xrEndSession EndSession;
PFN_xrRequestExitSession RequestExitSession;
PFN_xrWaitFrame WaitFrame;
PFN_xrBeginFrame BeginFrame;
PFN_xrEndFrame EndFrame;
PFN_xrLocateViews LocateViews;
PFN_xrStringToPath StringToPath;
PFN_xrPathToString PathToString;
PFN_xrCreateActionSet CreateActionSet;
PFN_xrDestroyActionSet DestroyActionSet;
PFN_xrCreateAction CreateAction;
PFN_xrDestroyAction DestroyAction;
PFN_xrSuggestInteractionProfileBindings SuggestInteractionProfileBindings;
PFN_xrAttachSessionActionSets AttachSessionActionSets;
PFN_xrGetCurrentInteractionProfile GetCurrentInteractionProfile;
PFN_xrGetActionStateBoolean GetActionStateBoolean;
PFN_xrGetActionStateFloat GetActionStateFloat;
PFN_xrGetActionStateVector2f GetActionStateVector2f;
PFN_xrGetActionStatePose GetActionStatePose;
PFN_xrSyncActions SyncActions;
PFN_xrEnumerateBoundSourcesForAction EnumerateBoundSourcesForAction;
PFN_xrGetInputSourceLocalizedName GetInputSourceLocalizedName;
PFN_xrApplyHapticFeedback ApplyHapticFeedback;
PFN_xrStopHapticFeedback StopHapticFeedback;
// ---- XR_KHR_android_thread_settings extension commands
#if defined(XR_USE_PLATFORM_ANDROID)
PFN_xrSetAndroidApplicationThreadKHR SetAndroidApplicationThreadKHR;
#endif // defined(XR_USE_PLATFORM_ANDROID)
// ---- XR_KHR_android_surface_swapchain extension commands
#if defined(XR_USE_PLATFORM_ANDROID)
PFN_xrCreateSwapchainAndroidSurfaceKHR CreateSwapchainAndroidSurfaceKHR;
#endif // defined(XR_USE_PLATFORM_ANDROID)
// ---- XR_KHR_opengl_enable extension commands
#if defined(XR_USE_GRAPHICS_API_OPENGL)
PFN_xrGetOpenGLGraphicsRequirementsKHR GetOpenGLGraphicsRequirementsKHR;
#endif // defined(XR_USE_GRAPHICS_API_OPENGL)
// ---- XR_KHR_opengl_es_enable extension commands
#if defined(XR_USE_GRAPHICS_API_OPENGL_ES)
PFN_xrGetOpenGLESGraphicsRequirementsKHR GetOpenGLESGraphicsRequirementsKHR;
#endif // defined(XR_USE_GRAPHICS_API_OPENGL_ES)
// ---- XR_KHR_vulkan_enable extension commands
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrGetVulkanInstanceExtensionsKHR GetVulkanInstanceExtensionsKHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrGetVulkanDeviceExtensionsKHR GetVulkanDeviceExtensionsKHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrGetVulkanGraphicsDeviceKHR GetVulkanGraphicsDeviceKHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrGetVulkanGraphicsRequirementsKHR GetVulkanGraphicsRequirementsKHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
// ---- XR_KHR_D3D11_enable extension commands
#if defined(XR_USE_GRAPHICS_API_D3D11)
PFN_xrGetD3D11GraphicsRequirementsKHR GetD3D11GraphicsRequirementsKHR;
#endif // defined(XR_USE_GRAPHICS_API_D3D11)
// ---- XR_KHR_D3D12_enable extension commands
#if defined(XR_USE_GRAPHICS_API_D3D12)
PFN_xrGetD3D12GraphicsRequirementsKHR GetD3D12GraphicsRequirementsKHR;
#endif // defined(XR_USE_GRAPHICS_API_D3D12)
// ---- XR_KHR_visibility_mask extension commands
PFN_xrGetVisibilityMaskKHR GetVisibilityMaskKHR;
// ---- XR_KHR_win32_convert_performance_counter_time extension commands
#if defined(XR_USE_PLATFORM_WIN32)
PFN_xrConvertWin32PerformanceCounterToTimeKHR ConvertWin32PerformanceCounterToTimeKHR;
#endif // defined(XR_USE_PLATFORM_WIN32)
#if defined(XR_USE_PLATFORM_WIN32)
PFN_xrConvertTimeToWin32PerformanceCounterKHR ConvertTimeToWin32PerformanceCounterKHR;
#endif // defined(XR_USE_PLATFORM_WIN32)
// ---- XR_KHR_convert_timespec_time extension commands
#if defined(XR_USE_TIMESPEC)
PFN_xrConvertTimespecTimeToTimeKHR ConvertTimespecTimeToTimeKHR;
#endif // defined(XR_USE_TIMESPEC)
#if defined(XR_USE_TIMESPEC)
PFN_xrConvertTimeToTimespecTimeKHR ConvertTimeToTimespecTimeKHR;
#endif // defined(XR_USE_TIMESPEC)
// ---- XR_KHR_loader_init extension commands
PFN_xrInitializeLoaderKHR InitializeLoaderKHR;
// ---- XR_KHR_vulkan_enable2 extension commands
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrCreateVulkanInstanceKHR CreateVulkanInstanceKHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrCreateVulkanDeviceKHR CreateVulkanDeviceKHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrGetVulkanGraphicsDevice2KHR GetVulkanGraphicsDevice2KHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
#if defined(XR_USE_GRAPHICS_API_VULKAN)
PFN_xrGetVulkanGraphicsRequirements2KHR GetVulkanGraphicsRequirements2KHR;
#endif // defined(XR_USE_GRAPHICS_API_VULKAN)
// ---- XR_EXT_performance_settings extension commands
PFN_xrPerfSettingsSetPerformanceLevelEXT PerfSettingsSetPerformanceLevelEXT;
// ---- XR_EXT_thermal_query extension commands
PFN_xrThermalGetTemperatureTrendEXT ThermalGetTemperatureTrendEXT;
// ---- XR_EXT_debug_utils extension commands
PFN_xrSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
PFN_xrCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
PFN_xrDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
PFN_xrSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
PFN_xrSessionBeginDebugUtilsLabelRegionEXT SessionBeginDebugUtilsLabelRegionEXT;
PFN_xrSessionEndDebugUtilsLabelRegionEXT SessionEndDebugUtilsLabelRegionEXT;
PFN_xrSessionInsertDebugUtilsLabelEXT SessionInsertDebugUtilsLabelEXT;
// ---- XR_MSFT_spatial_anchor extension commands
PFN_xrCreateSpatialAnchorMSFT CreateSpatialAnchorMSFT;
PFN_xrCreateSpatialAnchorSpaceMSFT CreateSpatialAnchorSpaceMSFT;
PFN_xrDestroySpatialAnchorMSFT DestroySpatialAnchorMSFT;
// ---- XR_EXT_conformance_automation extension commands
PFN_xrSetInputDeviceActiveEXT SetInputDeviceActiveEXT;
PFN_xrSetInputDeviceStateBoolEXT SetInputDeviceStateBoolEXT;
PFN_xrSetInputDeviceStateFloatEXT SetInputDeviceStateFloatEXT;
PFN_xrSetInputDeviceStateVector2fEXT SetInputDeviceStateVector2fEXT;
PFN_xrSetInputDeviceLocationEXT SetInputDeviceLocationEXT;
// ---- XR_MSFT_spatial_graph_bridge extension commands
PFN_xrCreateSpatialGraphNodeSpaceMSFT CreateSpatialGraphNodeSpaceMSFT;
// ---- XR_EXT_hand_tracking extension commands
PFN_xrCreateHandTrackerEXT CreateHandTrackerEXT;
PFN_xrDestroyHandTrackerEXT DestroyHandTrackerEXT;
PFN_xrLocateHandJointsEXT LocateHandJointsEXT;
// ---- XR_MSFT_hand_tracking_mesh extension commands
PFN_xrCreateHandMeshSpaceMSFT CreateHandMeshSpaceMSFT;
PFN_xrUpdateHandMeshMSFT UpdateHandMeshMSFT;
// ---- XR_MSFT_controller_model extension commands
PFN_xrGetControllerModelKeyMSFT GetControllerModelKeyMSFT;
PFN_xrLoadControllerModelMSFT LoadControllerModelMSFT;
PFN_xrGetControllerModelPropertiesMSFT GetControllerModelPropertiesMSFT;
PFN_xrGetControllerModelStateMSFT GetControllerModelStateMSFT;
// ---- XR_MSFT_perception_anchor_interop extension commands
#if defined(XR_USE_PLATFORM_WIN32)
PFN_xrCreateSpatialAnchorFromPerceptionAnchorMSFT CreateSpatialAnchorFromPerceptionAnchorMSFT;
#endif // defined(XR_USE_PLATFORM_WIN32)
#if defined(XR_USE_PLATFORM_WIN32)
PFN_xrTryGetPerceptionAnchorFromSpatialAnchorMSFT TryGetPerceptionAnchorFromSpatialAnchorMSFT;
#endif // defined(XR_USE_PLATFORM_WIN32)
// ---- XR_MSFT_composition_layer_reprojection extension commands
PFN_xrEnumerateReprojectionModesMSFT EnumerateReprojectionModesMSFT;
// ---- XR_FB_swapchain_update_state extension commands
PFN_xrUpdateSwapchainFB UpdateSwapchainFB;
PFN_xrGetSwapchainStateFB GetSwapchainStateFB;
// ---- XR_MSFT_scene_understanding extension commands
PFN_xrEnumerateSceneComputeFeaturesMSFT EnumerateSceneComputeFeaturesMSFT;
PFN_xrCreateSceneObserverMSFT CreateSceneObserverMSFT;
PFN_xrDestroySceneObserverMSFT DestroySceneObserverMSFT;
PFN_xrCreateSceneMSFT CreateSceneMSFT;
PFN_xrDestroySceneMSFT DestroySceneMSFT;
PFN_xrComputeNewSceneMSFT ComputeNewSceneMSFT;
PFN_xrGetSceneComputeStateMSFT GetSceneComputeStateMSFT;
PFN_xrGetSceneComponentsMSFT GetSceneComponentsMSFT;
PFN_xrLocateSceneComponentsMSFT LocateSceneComponentsMSFT;
PFN_xrGetSceneMeshBuffersMSFT GetSceneMeshBuffersMSFT;
// ---- XR_MSFT_scene_understanding_serialization extension commands
PFN_xrDeserializeSceneMSFT DeserializeSceneMSFT;
PFN_xrGetSerializedSceneFragmentDataMSFT GetSerializedSceneFragmentDataMSFT;
// ---- XR_FB_display_refresh_rate extension commands
PFN_xrEnumerateDisplayRefreshRatesFB EnumerateDisplayRefreshRatesFB;
PFN_xrGetDisplayRefreshRateFB GetDisplayRefreshRateFB;
PFN_xrRequestDisplayRefreshRateFB RequestDisplayRefreshRateFB;
// ---- XR_FB_color_space extension commands
PFN_xrEnumerateColorSpacesFB EnumerateColorSpacesFB;
PFN_xrSetColorSpaceFB SetColorSpaceFB;
// ---- XR_VARJO_environment_depth_estimation extension commands
PFN_xrSetEnvironmentDepthEstimationVARJO SetEnvironmentDepthEstimationVARJO;
// ---- XR_OCULUS_audio_device_guid extension commands
#if defined(XR_USE_PLATFORM_WIN32)
PFN_xrGetAudioOutputDeviceGuidOculus GetAudioOutputDeviceGuidOculus;
#endif // defined(XR_USE_PLATFORM_WIN32)
#if defined(XR_USE_PLATFORM_WIN32)
PFN_xrGetAudioInputDeviceGuidOculus GetAudioInputDeviceGuidOculus;
#endif // defined(XR_USE_PLATFORM_WIN32)
};
// Prototype for dispatch table helper function
void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table,
XrInstance instance,
PFN_xrGetInstanceProcAddr get_inst_proc_addr);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,10 @@
{
"name": "OpenXR Extension Sample",
"version": "0.1.0-preview.1",
"libraryName": "MeshingFeaturePlugin",
"meshings": [
{
"id": "Sample Meshing"
}
]
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0c9c9f060f5697d479a50005d89b4316
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f62af97ab6a74f2891cacc6bb4602f10
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 27f4fdf38a48423cbd1c4227272bffee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
fileFormatVersion: 2
guid: 7f5e312052a84f64b9123ee877d7ac2e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 1
settings:
CPU: ARM64
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4f3058bf568349a2bdd188a87dff9a60
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d1ad06e24e624f68b0bbd6b71452894d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: b2394b75cd374ef7a96dc7ab33ea2b84
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: ARM
DontProcess: false
PlaceholderPath:
SDK: UWP
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b5788c2fc0b542389b29edd3d129f9e8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: d46969e9a9ce417c80b1dd42d3ae09eb
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: ARM64
DontProcess: false
PlaceholderPath:
SDK: UWP
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 38effe9126c74a748c3327b56fd1cb1d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 5e606c92c2ca423291eca28dbb9d4d43
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: X64
DontProcess: false
PlaceholderPath:
SDK: UWP
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 767508e5707d4539a2c17e6c7c5b01cd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c30a59a9fa1d4c92bc31a01f2eb3df7a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 3b04e62518ff4318b89da5aa6bfc7966
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 0
Exclude WindowsStoreApps: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: Windows
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
DontProcess: false
PlaceholderPath:
SDK: AnySDK
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant: