上传YomovSDK
This commit is contained in:
520
Packages/com.unity.xr.openxr/RuntimeDebugger/DebuggerState.cs
Normal file
520
Packages/com.unity.xr.openxr/RuntimeDebugger/DebuggerState.cs
Normal file
@@ -0,0 +1,520 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking.PlayerConnection;
|
||||
using CompressionLevel = System.IO.Compression.CompressionLevel;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.XR.OpenXR.Features.RuntimeDebugger.Editor")]
|
||||
namespace UnityEditor.XR.OpenXR.Features.RuntimeDebugger
|
||||
{
|
||||
internal class DebuggerState
|
||||
{
|
||||
public enum Command
|
||||
{
|
||||
kStartFunctionCall,
|
||||
kStartStruct,
|
||||
|
||||
kFloat,
|
||||
kString,
|
||||
kInt32,
|
||||
kInt64,
|
||||
kUInt32,
|
||||
kUInt64,
|
||||
|
||||
kEndStruct,
|
||||
kEndFunctionCall,
|
||||
|
||||
kCacheNotLargeEnough,
|
||||
|
||||
kLUTDefineTables,
|
||||
kLUTEntryUpdateStart,
|
||||
kLutEntryUpdateEnd,
|
||||
kLUTLookup,
|
||||
};
|
||||
|
||||
private const byte FileVersion = 2;
|
||||
private static readonly byte[] Header = new byte[] { 0xea, 0x24, 0x39, 0x5c, 0xe0, 0xac, 0x79, FileVersion };
|
||||
|
||||
internal static List<FunctionCall> _functionCalls = new List<FunctionCall>();
|
||||
private static List<byte> saveToFile = new List<byte>(Header);
|
||||
private static byte openedFileVersion = FileVersion;
|
||||
|
||||
internal static Dictionary<UInt32, Dictionary<UInt64, HandleDebugEvent>> xrLut = new Dictionary<UInt32, Dictionary<UInt64, HandleDebugEvent>>();
|
||||
internal static List<string> lutNames = new List<string>();
|
||||
|
||||
internal static void Clear()
|
||||
{
|
||||
_functionCalls.Clear();
|
||||
saveToFile.Clear();
|
||||
saveToFile.AddRange(Header);
|
||||
|
||||
openedFileVersion = FileVersion;
|
||||
}
|
||||
|
||||
private static Action _doneCallback;
|
||||
internal static UInt32 _lastPayloadSize;
|
||||
internal static UInt32 _frameCount;
|
||||
internal static UInt32 _lutSize;
|
||||
|
||||
internal static void SetDoneCallback(Action done)
|
||||
{
|
||||
_doneCallback = done;
|
||||
}
|
||||
|
||||
private static StringBuilder _sb = new StringBuilder();
|
||||
internal static string ReadString(BinaryReader r)
|
||||
{
|
||||
_sb.Clear();
|
||||
byte b;
|
||||
while ((b = r.ReadByte()) != (byte)0)
|
||||
{
|
||||
_sb.Append((Char)b);
|
||||
}
|
||||
return _sb.ToString();
|
||||
}
|
||||
|
||||
internal static void SaveToFile(string path)
|
||||
{
|
||||
using var stream = File.Open(path, FileMode.Create);
|
||||
using var gzip = new GZipStream(stream, CompressionLevel.Optimal);
|
||||
gzip.Write(saveToFile.ToArray(), 0, saveToFile.Count);
|
||||
}
|
||||
|
||||
internal static void LoadFromFile(string path)
|
||||
{
|
||||
xrLut.Clear();
|
||||
lutNames.Clear();
|
||||
lutNames.Add("All Calls");
|
||||
using var inStream = File.OpenRead(path);
|
||||
var gzip = new GZipStream(inStream, CompressionMode.Decompress);
|
||||
byte[] bytes;
|
||||
using (var outStream = new MemoryStream())
|
||||
{
|
||||
gzip.CopyTo(outStream);
|
||||
bytes = outStream.ToArray();
|
||||
}
|
||||
|
||||
var headerCounter = 0;
|
||||
while (headerCounter < 7)
|
||||
{
|
||||
if (Header[headerCounter] != bytes[headerCounter])
|
||||
{
|
||||
Debug.Log("Wrong file format.");
|
||||
return;
|
||||
}
|
||||
++headerCounter;
|
||||
}
|
||||
|
||||
openedFileVersion = bytes[7];
|
||||
if (openedFileVersion > FileVersion)
|
||||
{
|
||||
Debug.Log($"File created with newer version ({openedFileVersion} > {FileVersion}.");
|
||||
}
|
||||
|
||||
OnMessageEvent(new MessageEventArgs() {data = bytes.Skip(8).ToArray()});
|
||||
}
|
||||
|
||||
internal static void OnMessageEvent(MessageEventArgs args)
|
||||
{
|
||||
if (args == null || args.data == null)
|
||||
return;
|
||||
_lastPayloadSize = (UInt32)args.data.Length;
|
||||
_frameCount = 0;
|
||||
saveToFile.AddRange(args.data);
|
||||
try
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream(args.data))
|
||||
{
|
||||
using (BinaryReader r = new BinaryReader(ms, Encoding.UTF8))
|
||||
{
|
||||
while (r.BaseStream.Position != r.BaseStream.Length)
|
||||
{
|
||||
var command = (Command)r.ReadUInt32();
|
||||
switch (command)
|
||||
{
|
||||
case Command.kStartFunctionCall:
|
||||
var thread = ReadString(r);
|
||||
var funcName = ReadString(r);
|
||||
var funcCall = new FunctionCall(thread, funcName);
|
||||
_functionCalls.Add(funcCall);
|
||||
funcCall.Parse(r);
|
||||
|
||||
if (funcName == "xrBeginFrame")
|
||||
{
|
||||
++_frameCount;
|
||||
}
|
||||
break;
|
||||
case Command.kLUTDefineTables:
|
||||
lutNames.Clear();
|
||||
lutNames.Add("All Calls");
|
||||
var numLUTs = r.ReadUInt32();
|
||||
for (UInt32 lutIndex = 0; lutIndex < numLUTs; ++lutIndex)
|
||||
{
|
||||
xrLut[lutIndex] = new Dictionary<UInt64, HandleDebugEvent>();
|
||||
lutNames.Add(ReadString(r));
|
||||
}
|
||||
|
||||
break;
|
||||
case Command.kLUTEntryUpdateStart:
|
||||
var lutKey = r.ReadUInt32();
|
||||
var handle = r.ReadUInt64();
|
||||
var handleName = ReadString(r);
|
||||
|
||||
// struct command, skip it
|
||||
r.ReadUInt32();
|
||||
ReadString(r);
|
||||
ReadString(r);
|
||||
|
||||
var evt = new HandleDebugEvent(handleName, handle);
|
||||
evt.Parse(r);
|
||||
xrLut[lutKey][handle] = evt;
|
||||
break;
|
||||
case Command.kLutEntryUpdateEnd:
|
||||
break;
|
||||
case Command.kCacheNotLargeEnough:
|
||||
funcCall = new FunctionCall(r.ReadUInt32().ToString(), ReadString(r));
|
||||
_functionCalls.Add(funcCall);
|
||||
var result = ReadString(r);
|
||||
funcCall.displayName += " = " + result + " (cache not large enough)";
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
|
||||
_doneCallback?.Invoke();
|
||||
}
|
||||
|
||||
internal class DebugEvent : TreeViewItem
|
||||
{
|
||||
private static int idCounter = 1;
|
||||
private List<DebugEvent> childrenEvents = new List<DebugEvent>();
|
||||
protected string fieldname;
|
||||
|
||||
protected DebugEvent(string fieldname, string display)
|
||||
: base(idCounter++, 0, display)
|
||||
{
|
||||
this.fieldname = fieldname;
|
||||
}
|
||||
|
||||
public virtual DebugEvent Clone()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual string GetValue()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string var = displayName;
|
||||
|
||||
foreach (var child in childrenEvents)
|
||||
{
|
||||
var += "\n\t" + child.ToString().Replace("\n", "\n\t");
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
public void Parse(BinaryReader r)
|
||||
{
|
||||
DebugEvent parsedChild = null;
|
||||
bool endEvent = false;
|
||||
|
||||
do
|
||||
{
|
||||
if (parsedChild != null)
|
||||
{
|
||||
AddChildEvent(parsedChild);
|
||||
parsedChild.Parse(r);
|
||||
parsedChild = null;
|
||||
}
|
||||
|
||||
var command = (Command)r.ReadUInt32();
|
||||
switch (command)
|
||||
{
|
||||
case Command.kStartStruct:
|
||||
parsedChild = new StructDebugEvent(ReadString(r), ReadString(r));
|
||||
break;
|
||||
case Command.kLUTLookup:
|
||||
var lutKey = r.ReadUInt32();
|
||||
var fieldName = ReadString(r);
|
||||
var handle = r.ReadUInt64();
|
||||
|
||||
if (xrLut[lutKey].TryGetValue(handle, out var evt))
|
||||
{
|
||||
AddChildEvent(evt.Clone(fieldName));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddChildEvent(new UInt64DebugEvent(fieldName, handle));
|
||||
}
|
||||
break;
|
||||
case Command.kFloat:
|
||||
AddChildEvent(new FloatDebugEvent(ReadString(r), r.ReadSingle()));
|
||||
break;
|
||||
case Command.kString:
|
||||
AddChildEvent(new StringDebugEvent(ReadString(r), ReadString(r)));
|
||||
break;
|
||||
case Command.kInt32:
|
||||
AddChildEvent(new Int32DebugEvent(ReadString(r), r.ReadInt32()));
|
||||
break;
|
||||
case Command.kInt64:
|
||||
AddChildEvent(new Int64DebugEvent(ReadString(r), r.ReadInt64()));
|
||||
break;
|
||||
case Command.kUInt32:
|
||||
AddChildEvent(new UInt32DebugEvent(ReadString(r), r.ReadUInt32()));
|
||||
break;
|
||||
case Command.kUInt64:
|
||||
AddChildEvent(new UInt64DebugEvent(ReadString(r), r.ReadUInt64()));
|
||||
break;
|
||||
case Command.kEndStruct:
|
||||
endEvent = true;
|
||||
break;
|
||||
case Command.kEndFunctionCall:
|
||||
var result = ReadString(r);
|
||||
displayName += " = " + result;
|
||||
endEvent = true;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
while (!endEvent && r.BaseStream.Position != r.BaseStream.Length);
|
||||
}
|
||||
|
||||
// public IEnumerable<DebugEvent> GetChildren()
|
||||
// {
|
||||
// return childrenEvents;
|
||||
// }
|
||||
|
||||
public DebugEvent GetFirstChild()
|
||||
{
|
||||
return childrenEvents[0];
|
||||
}
|
||||
|
||||
private DebugEvent AddChildEvent(DebugEvent evt)
|
||||
{
|
||||
childrenEvents.Add(evt);
|
||||
AddChild(evt);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected DebugEvent AddClonedChildren(DebugEvent clone)
|
||||
{
|
||||
foreach (var evt in childrenEvents)
|
||||
{
|
||||
clone.AddChildEvent(evt.Clone());
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
internal class HandleDebugEvent : DebugEvent
|
||||
{
|
||||
private string niceDisplay;
|
||||
private UInt64 handle;
|
||||
|
||||
public HandleDebugEvent(string niceDisplay, UInt64 handle)
|
||||
: base("", $"{niceDisplay} = {handle}")
|
||||
{
|
||||
this.niceDisplay = niceDisplay;
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return niceDisplay;
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
var evt = new HandleDebugEvent(niceDisplay, handle);
|
||||
evt.displayName = displayName;
|
||||
return AddClonedChildren(evt);
|
||||
}
|
||||
|
||||
public DebugEvent Clone(string fieldName)
|
||||
{
|
||||
var ret = Clone();
|
||||
ret.displayName = $"{fieldName} = {niceDisplay} ({handle})";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
internal class FunctionCall : DebugEvent
|
||||
{
|
||||
public string threadId { get; }
|
||||
public string returnVal { get; set; }
|
||||
|
||||
public FunctionCall(string threadId, string displayName)
|
||||
: base("", displayName)
|
||||
{
|
||||
this.threadId = threadId;
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return AddClonedChildren(new FunctionCall(threadId, displayName));
|
||||
}
|
||||
}
|
||||
|
||||
internal class StructDebugEvent : DebugEvent
|
||||
{
|
||||
public string structname { get; }
|
||||
public StructDebugEvent(string fieldname, string structname)
|
||||
: base(fieldname, $"{fieldname} = {structname}")
|
||||
{
|
||||
this.structname = structname;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return structname;
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return AddClonedChildren(new StructDebugEvent(fieldname, structname));
|
||||
}
|
||||
}
|
||||
|
||||
internal class FloatDebugEvent : DebugEvent
|
||||
{
|
||||
public float value { get; }
|
||||
public FloatDebugEvent(string displayName, float val)
|
||||
: base(displayName, displayName + " = " + val)
|
||||
{
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return new FloatDebugEvent(fieldname, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class StringDebugEvent : DebugEvent
|
||||
{
|
||||
public string value { get; }
|
||||
public StringDebugEvent(string displayName, string val)
|
||||
: base(displayName, displayName + " = " + val)
|
||||
{
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return new StringDebugEvent(fieldname, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int32DebugEvent : DebugEvent
|
||||
{
|
||||
public Int32 value { get; }
|
||||
public Int32DebugEvent(string displayName, Int32 val)
|
||||
: base(displayName, displayName + " = " + val)
|
||||
{
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return new Int32DebugEvent(fieldname, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int64DebugEvent : DebugEvent
|
||||
{
|
||||
public Int64 value { get; }
|
||||
public Int64DebugEvent(string displayName, Int64 val)
|
||||
: base(displayName, displayName + " = " + val)
|
||||
{
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return new Int64DebugEvent(fieldname, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class UInt32DebugEvent : DebugEvent
|
||||
{
|
||||
public UInt32 value { get; }
|
||||
public UInt32DebugEvent(string displayName, UInt32 val)
|
||||
: base(displayName, displayName + " = " + val)
|
||||
{
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return new UInt32DebugEvent(fieldname, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class UInt64DebugEvent : DebugEvent
|
||||
{
|
||||
public UInt64 value { get; }
|
||||
public UInt64DebugEvent(string displayName, UInt64 val)
|
||||
: base(displayName, displayName + " = " + val)
|
||||
{
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public override string GetValue()
|
||||
{
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
public override DebugEvent Clone()
|
||||
{
|
||||
return new UInt64DebugEvent(fieldname, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15350e969b159e747a2d967827002b40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Packages/com.unity.xr.openxr/RuntimeDebugger/Editor.meta
Normal file
8
Packages/com.unity.xr.openxr/RuntimeDebugger/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 246e578028c2be145beff6c79a4f193b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.XR.OpenXR.Features.RuntimeDebugger;
|
||||
|
||||
namespace UnityEditor.XR.OpenXR.Features.RuntimeDebugger
|
||||
{
|
||||
[CustomEditor(typeof(RuntimeDebuggerOpenXRFeature))]
|
||||
internal class RuntimeDebuggerOpenXRFeatureEditor : Editor
|
||||
{
|
||||
private SerializedProperty cacheSize;
|
||||
private SerializedProperty perThreadCacheSize;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
cacheSize = serializedObject.FindProperty("cacheSize");
|
||||
perThreadCacheSize = serializedObject.FindProperty("perThreadCacheSize");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(cacheSize);
|
||||
EditorGUILayout.PropertyField(perThreadCacheSize);
|
||||
|
||||
if (GUILayout.Button("Open Debugger Window"))
|
||||
{
|
||||
RuntimeDebuggerWindow.Init();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac3a007820947a349b40fa3f0dcfaae8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEditor.Networking.PlayerConnection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking.PlayerConnection;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
|
||||
using UnityEngine.XR.OpenXR.Features.RuntimeDebugger;
|
||||
|
||||
namespace UnityEditor.XR.OpenXR.Features.RuntimeDebugger
|
||||
{
|
||||
internal class DebuggerTreeView : TreeView
|
||||
{
|
||||
private int _mode;
|
||||
public new string searchString { get; set; }
|
||||
private bool deep = false;
|
||||
|
||||
public DebuggerTreeView(TreeViewState state, int mode, string search = "")
|
||||
: base(state)
|
||||
{
|
||||
_mode = mode;
|
||||
searchString = search;
|
||||
Reload();
|
||||
}
|
||||
|
||||
public void ReloadDeepSearch()
|
||||
{
|
||||
deep = true;
|
||||
Reload();
|
||||
deep = false;
|
||||
}
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
var root = new TreeViewItem(0, -1, "Root");
|
||||
if (_mode == 0)
|
||||
{
|
||||
foreach (var t in DebuggerState._functionCalls)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchString) || (deep ? t.ToString() : t.displayName).IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
root.AddChild(t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DebuggerState.xrLut.TryGetValue((UInt32)_mode - 1, out var lut))
|
||||
{
|
||||
foreach (var t in lut.Values)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchString) || (deep ? t.ToString() : t.displayName).IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
root.AddChild(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (root.hasChildren)
|
||||
SetupDepthsFromParentsAndChildren(root);
|
||||
else
|
||||
root.AddChild(new TreeViewItem(0));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override void KeyEvent()
|
||||
{
|
||||
if (Event.current.commandName == "Copy")
|
||||
{
|
||||
StringBuilder copy = new StringBuilder("");
|
||||
foreach (var id in state.selectedIDs)
|
||||
{
|
||||
copy.Append(FindItem(id, rootItem).ToString());
|
||||
copy.Append("\n");
|
||||
}
|
||||
|
||||
EditorGUIUtility.systemCopyBuffer = copy.ToString();
|
||||
}
|
||||
base.KeyEvent();
|
||||
}
|
||||
}
|
||||
|
||||
internal class RuntimeDebuggerWindow : EditorWindow
|
||||
{
|
||||
private static class Styles
|
||||
{
|
||||
public static GUIStyle s_Wrap;
|
||||
}
|
||||
|
||||
private static void InitStyles()
|
||||
{
|
||||
if (Styles.s_Wrap != null)
|
||||
return;
|
||||
|
||||
Styles.s_Wrap = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
wordWrap = true,
|
||||
alignment = TextAnchor.MiddleLeft,
|
||||
padding = new RectOffset(0, 5, 1, 1)
|
||||
};
|
||||
}
|
||||
|
||||
[MenuItem("Window/Analysis/OpenXR Runtime Debugger")]
|
||||
[MenuItem("Window/XR/OpenXR/Runtime Debugger")]
|
||||
internal static void Init()
|
||||
{
|
||||
RuntimeDebuggerWindow w = EditorWindow.GetWindow<RuntimeDebuggerWindow>() as RuntimeDebuggerWindow;
|
||||
w.titleContent = new GUIContent("OpenXR Runtime Debugger");
|
||||
w.Show();
|
||||
}
|
||||
|
||||
private IConnectionState state;
|
||||
void OnEnable()
|
||||
{
|
||||
state = PlayerConnectionGUIUtility.GetConnectionState(this);
|
||||
EditorConnection.instance.Initialize();
|
||||
EditorConnection.instance.Register(RuntimeDebuggerOpenXRFeature.kPlayerToEditorSendDebuggerOutput, DebuggerState.OnMessageEvent);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
EditorConnection.instance.Unregister(RuntimeDebuggerOpenXRFeature.kPlayerToEditorSendDebuggerOutput, DebuggerState.OnMessageEvent);
|
||||
state.Dispose();
|
||||
}
|
||||
|
||||
private Vector2 scrollpos = new Vector2();
|
||||
private List<TreeViewState> treeViewState = new List<TreeViewState>();
|
||||
private DebuggerTreeView treeView;
|
||||
private SearchField searchField = null;
|
||||
private string searchString = "";
|
||||
private int viewMode = 0;
|
||||
|
||||
private string _lastRefreshStats;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
DebuggerState.Clear();
|
||||
treeView = null;
|
||||
searchField = new SearchField();
|
||||
treeViewState.Clear();
|
||||
_lastRefreshStats = "";
|
||||
scrollpos = Vector2.zero;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
InitStyles();
|
||||
if (searchField == null)
|
||||
searchField = new SearchField();
|
||||
var debuggerFeatureInfo = FeatureHelpers.GetFeatureWithIdForActiveBuildTarget("com.unity.openxr.features.runtimedebugger");
|
||||
|
||||
if (!debuggerFeatureInfo.enabled)
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("OpenXR Runtime Debugger must be enabled for this build target.", Styles.s_Wrap);
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button("Enable Runtime Debugger"))
|
||||
{
|
||||
debuggerFeatureInfo.enabled = true;
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PlayerConnectionGUILayout.ConnectionTargetSelectionDropdown(state);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Refresh"))
|
||||
{
|
||||
DebuggerState.SetDoneCallback(() =>
|
||||
{
|
||||
if (treeViewState.Count != DebuggerState.lutNames.Count)
|
||||
{
|
||||
treeViewState.Clear();
|
||||
for (int i = 0; i < DebuggerState.lutNames.Count; ++i)
|
||||
{
|
||||
treeViewState.Add(new TreeViewState());
|
||||
}
|
||||
}
|
||||
|
||||
treeView = new DebuggerTreeView(treeViewState[viewMode], viewMode, searchString);
|
||||
searchField = new SearchField();
|
||||
|
||||
var debugger = OpenXRSettings.ActiveBuildTargetInstance.GetFeature<RuntimeDebuggerOpenXRFeature>();
|
||||
if (debugger != null)
|
||||
_lastRefreshStats = $"Last payload size: {DebuggerState._lastPayloadSize} ({((100.0f * DebuggerState._lastPayloadSize / debugger.cacheSize)):F2}% cache full) Number of Frames: {DebuggerState._frameCount}";
|
||||
else
|
||||
_lastRefreshStats = $"Last payload size: {DebuggerState._lastPayloadSize} Number of Frames: {DebuggerState._frameCount}";
|
||||
});
|
||||
|
||||
_lastRefreshStats = "Refreshing ...";
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
var debugger = OpenXRSettings.Instance.GetFeature<RuntimeDebuggerOpenXRFeature>();
|
||||
if (debugger.enabled)
|
||||
{
|
||||
debugger.RecvMsg(new MessageEventArgs());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorConnection.instance.Send(RuntimeDebuggerOpenXRFeature.kEditorToPlayerRequestDebuggerOutput, new byte[] { byte.MinValue });
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(EditorGUIUtility.IconContent("d_SaveAs")))
|
||||
{
|
||||
string path = EditorUtility.SaveFilePanel("Save OpenXR Dump", "", state.connectionName, "openxrdump");
|
||||
if (path.Length != 0)
|
||||
{
|
||||
DebuggerState.SaveToFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button(EditorGUIUtility.IconContent("d_FolderOpened Icon")))
|
||||
{
|
||||
string path = EditorUtility.OpenFilePanelWithFilters("Load OpenXR Dump", "", new[] { "OpenXR Dump", "openxrdump" });
|
||||
if (path.Length != 0)
|
||||
{
|
||||
Clear();
|
||||
|
||||
DebuggerState.SetDoneCallback(() =>
|
||||
{
|
||||
if (treeViewState.Count != DebuggerState.lutNames.Count)
|
||||
{
|
||||
treeViewState.Clear();
|
||||
for (int i = 0; i < DebuggerState.lutNames.Count; ++i)
|
||||
{
|
||||
treeViewState.Add(new TreeViewState());
|
||||
}
|
||||
}
|
||||
|
||||
treeView = new DebuggerTreeView(treeViewState[viewMode], viewMode, searchString);
|
||||
|
||||
_lastRefreshStats = $"Last payload size: {DebuggerState._lastPayloadSize} Number of Frames: {DebuggerState._frameCount}";
|
||||
});
|
||||
|
||||
DebuggerState.LoadFromFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Label($"Connections: {EditorConnection.instance.ConnectedPlayers.Count}");
|
||||
GUILayout.Label(_lastRefreshStats);
|
||||
if (treeView != null)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
var newSearchString = searchField.OnGUI(treeView.searchString);
|
||||
if (newSearchString != treeView.searchString)
|
||||
{
|
||||
treeView.searchString = newSearchString;
|
||||
treeView.Reload();
|
||||
}
|
||||
|
||||
if (searchField.HasFocus())
|
||||
{
|
||||
if (Event.current.keyCode == KeyCode.Return)
|
||||
{
|
||||
treeView.ReloadDeepSearch();
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Deep Search"))
|
||||
{
|
||||
treeView.ReloadDeepSearch();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
int newViewMode = 0;
|
||||
if (DebuggerState.lutNames.Count > 0)
|
||||
{
|
||||
newViewMode = EditorGUILayout.Popup(viewMode, DebuggerState.lutNames.ToArray());
|
||||
}
|
||||
if (newViewMode != viewMode)
|
||||
{
|
||||
viewMode = newViewMode;
|
||||
treeView = new DebuggerTreeView(treeViewState[viewMode], viewMode, searchString);
|
||||
scrollpos = Vector2.zero;
|
||||
}
|
||||
|
||||
var treeViewRect = EditorGUILayout.BeginVertical(GUILayout.ExpandHeight(true));
|
||||
if (treeView != null)
|
||||
{
|
||||
treeView.OnGUI(treeViewRect);
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee07143892e1a224eb2d596269f30752
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Unity.XR.OpenXR.Features.RuntimeDebugger.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:784a7033de40af04db4f8c4de440f481",
|
||||
"GUID:4847341ff46394e83bb78fbd0652937e",
|
||||
"GUID:96aa6ba065960476598f8f643e7252b6"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd9e9bbf90e916b4b890adf062c6c2a4
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,2 @@
|
||||
DisableFormat: true
|
||||
SortIncludes: false
|
||||
@@ -0,0 +1,485 @@
|
||||
diff --git a/specification/scripts/creflectiongenerator.py b/specification/scripts/creflectiongenerator.py
|
||||
index a1beca84a..fa08160ee 100644
|
||||
--- a/specification/scripts/creflectiongenerator.py
|
||||
+++ b/specification/scripts/creflectiongenerator.py
|
||||
@@ -35,11 +35,13 @@ class CommandData:
|
||||
class StructData:
|
||||
"""Represents a OpenXR struct type"""
|
||||
|
||||
- def __init__(self, typeName, structTypeName, members, protect):
|
||||
+ def __init__(self, typeName, structTypeName, members, arrays, protect, parent):
|
||||
self.typeName = typeName
|
||||
self.members = members
|
||||
+ self.arrays = arrays
|
||||
self.structTypeName = structTypeName
|
||||
self.protect = protect
|
||||
+ self.parent = parent
|
||||
|
||||
@property
|
||||
def protect_value(self) -> bool:
|
||||
@@ -64,12 +66,42 @@ class BitmaskData:
|
||||
class EnumData:
|
||||
"""Represents a OpenXR group enum type"""
|
||||
|
||||
- def __init__(self, typeName, typeNamePrefix, typeNameSuffix, enumTuples):
|
||||
+ def __init__(self, typeName, typeNamePrefix, typeNameSuffix, enumTuples, protect):
|
||||
self.typeName = typeName
|
||||
self.typeNamePrefix = typeNamePrefix
|
||||
self.typeNameSuffix = typeNameSuffix
|
||||
self.enumTuples = enumTuples
|
||||
+ self.protect = protect
|
||||
+
|
||||
+ @property
|
||||
+ def protect_value(self):
|
||||
+ return self.protect is not None
|
||||
+
|
||||
+ @property
|
||||
+ def protect_string(self):
|
||||
+ if self.protect:
|
||||
+ return " && ".join("defined({})".format(x) for x in self.protect)
|
||||
+
|
||||
+class CCmd:
|
||||
+ """Represents an OpenXR function"""
|
||||
+
|
||||
+ def __init__(self, cmdName, returnType, members, members_non_array, arrays, sig, protect):
|
||||
+ self.cmdName = cmdName
|
||||
+ self.returnType = returnType
|
||||
+ self.members = members
|
||||
+ self.members_non_array = members_non_array
|
||||
+ self.arrays = arrays
|
||||
+ self.sig = sig
|
||||
+ self.protect = protect
|
||||
+
|
||||
+ @property
|
||||
+ def protect_value(self):
|
||||
+ return self.protect is not None
|
||||
|
||||
+ @property
|
||||
+ def protect_string(self):
|
||||
+ if self.protect:
|
||||
+ return " && ".join("defined({})".format(x) for x in self.protect)
|
||||
|
||||
class CReflectionOutputGenerator(OutputGenerator):
|
||||
"""Generate specified API interfaces in a specific style, such as a C header"""
|
||||
@@ -81,6 +113,8 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
self.commands = []
|
||||
self.enums = []
|
||||
self.bitmasks = []
|
||||
+ self.cmds = []
|
||||
+ self.handles = []
|
||||
self.protects = set()
|
||||
self.template: Optional[JinjaTemplate] = None
|
||||
self.parents = {}
|
||||
@@ -97,14 +131,42 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
if x.protect == protect and x.structTypeName is not None]
|
||||
return ret
|
||||
|
||||
+ def getCmdsForProtect(self, protect=None):
|
||||
+ return [x for x in self.cmds
|
||||
+ if x.protect == protect]
|
||||
+
|
||||
+ def getEnumsForProtect(self, protect=None):
|
||||
+ return [x for x in self.enums
|
||||
+ if x.protect == protect]
|
||||
+
|
||||
+ def getCmdsForProtect(self, protect=None):
|
||||
+ return [x for x in self.cmds
|
||||
+ if x.protect == protect]
|
||||
+
|
||||
+ def getEnumsForProtect(self, protect=None):
|
||||
+ return [x for x in self.enums
|
||||
+ if x.protect == protect]
|
||||
+
|
||||
def endFile(self):
|
||||
assert self.template
|
||||
assert self.registry
|
||||
file_data = ''
|
||||
|
||||
+ # UNITY: specialization filter
|
||||
+ self.cmds = [x for x in self.cmds if x.cmdName not in ('xrGetInstanceProcAddr')]
|
||||
+ self.structs = [x for x in self.structs if x.typeName not in ('XrBaseInStructure', 'XrBaseOutStructure', 'XrEventDataBuffer', 'XrDebugUtilsMessengerCreateInfoEXT', 'XrSpatialGraphNodeSpaceCreateInfoMSFT', 'XrInteractionProfileAnalogThresholdVALVE', 'XrWorldMeshBufferML')]
|
||||
+
|
||||
unprotected_structs = self._get_structs_for_protect()
|
||||
protected_structs = [(x, self._get_structs_for_protect(protect=x))
|
||||
for x in sorted(self.protects)]
|
||||
+ base_structs = list(set([x.parent for x in self.structs if x.parent is not None]))
|
||||
+ basic_structs = [x for x in self.structs if x.structTypeName is None and x.typeName not in base_structs]
|
||||
+
|
||||
+ unprotected_cmds = self.getCmdsForProtect()
|
||||
+ protected_cmds = [(x, self.getCmdsForProtect(x)) for x in sorted(self.protects)]
|
||||
+
|
||||
+ unprotected_enums = self.getEnumsForProtect()
|
||||
+ protected_enums = [(x, self.getEnumsForProtect(x)) for x in sorted(self.protects)]
|
||||
# drop empty collections
|
||||
protected_structs = [(x, y) for x, y in protected_structs if y]
|
||||
|
||||
@@ -138,7 +200,15 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
unprotectedStructs=unprotected_structs,
|
||||
protectedStructs=protected_structs,
|
||||
structs=self.structs,
|
||||
+ basic_structs=basic_structs,
|
||||
+ base_structs=base_structs,
|
||||
+ unprotectedCmds=unprotected_cmds,
|
||||
+ protectedCmds=protected_cmds,
|
||||
+ cmds=self.cmds,
|
||||
+ unprotectedEnums=unprotected_enums,
|
||||
+ protectedEnums=protected_enums,
|
||||
enums=self.enums,
|
||||
+ handles=self.handles,
|
||||
bitmasks=self.bitmasks,
|
||||
extensions=extensions,
|
||||
polymorphic_struct_families=polymorphic_struct_families,
|
||||
@@ -159,6 +229,8 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
# If the type is a struct type, generate it using the
|
||||
# special-purpose generator.
|
||||
self.genStruct(typeinfo, name, alias)
|
||||
+ if category == 'handle':
|
||||
+ self.handles.append(name)
|
||||
|
||||
parent_struct = typeElem.get('parentstruct')
|
||||
if parent_struct is not None:
|
||||
@@ -174,12 +246,75 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
|
||||
self.commands.append(CommandData(name, self.featureName))
|
||||
|
||||
+ def genCmd(self, cmd, cmdinfo, alias):
|
||||
+ OutputGenerator.genCmd(self, cmd, cmdinfo, alias)
|
||||
+
|
||||
+ if alias:
|
||||
+ return
|
||||
+
|
||||
+ #print(f'{dump(cmd.elem)}')
|
||||
+
|
||||
+ ret = cmd.elem.find('proto').find('type').text
|
||||
+ #print(ret)
|
||||
+
|
||||
+ members = []
|
||||
+ members_non_array = []
|
||||
+ sig = ''
|
||||
+
|
||||
+
|
||||
+ arrays = {}
|
||||
+ for m in cmd.elem.findall('./param[@len]'):
|
||||
+ lenName = m.get('len')
|
||||
+ if lenName != 'null-terminated':
|
||||
+ if m.find('type').text == 'char' and 'null-terminated' not in lenName:
|
||||
+ continue
|
||||
+ lenName = lenName.replace(',null-terminated','')
|
||||
+ print(f"{m.find('name').text} len={lenName}")
|
||||
+ arrays[m.find('name').text] = lenName
|
||||
+
|
||||
+ for m in cmd.elem.iterfind('param'):
|
||||
+ sig += ', ' + self.makeCParamDecl(m, 0)
|
||||
+ member = m.find('name').text
|
||||
+ members.append(m.find('name').text)
|
||||
+ if member not in arrays:
|
||||
+ members_non_array.append(m.find('name').text)
|
||||
+
|
||||
+ sig = sig[2:]
|
||||
+
|
||||
+ #import pprint
|
||||
+ #pprint.pprint(members)
|
||||
+
|
||||
+ protect = set()
|
||||
+ if self.featureExtraProtect:
|
||||
+ protect.update(self.featureExtraProtect.split(','))
|
||||
+ localProtect = cmd.elem.get('protect')
|
||||
+ if localProtect:
|
||||
+ protect.update(localProtect.split(','))
|
||||
+
|
||||
+ if protect:
|
||||
+ protect = tuple(protect)
|
||||
+ else:
|
||||
+ protect = None
|
||||
+
|
||||
+ self.cmds.append(CCmd(cmd.elem.attrib['name'], ret, members, members_non_array, arrays, sig, protect))
|
||||
+
|
||||
+
|
||||
def genStruct(self, typeinfo, typeName, alias):
|
||||
OutputGenerator.genStruct(self, typeinfo, typeName, alias)
|
||||
|
||||
if alias:
|
||||
return
|
||||
|
||||
+ arrays = {}
|
||||
+ for m in typeinfo.elem.findall('./member[@len]'):
|
||||
+ lenName = m.get('len')
|
||||
+ if lenName != 'null-terminated':
|
||||
+ if m.find('type').text == 'char' and 'null-terminated' not in lenName:
|
||||
+ continue
|
||||
+ lenName = lenName.replace(',null-terminated','')
|
||||
+ print(f"{m.find('name').text} len={lenName}")
|
||||
+ arrays[m.find('name').text] = lenName
|
||||
+
|
||||
structTypeEnum = None
|
||||
members = []
|
||||
for member in typeinfo.getMembers():
|
||||
@@ -188,7 +323,8 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
if self.conventions.is_structure_type_member(memberType, memberName):
|
||||
structTypeEnum = member.get("values")
|
||||
|
||||
- members.append(memberName)
|
||||
+ if memberName not in arrays:
|
||||
+ members.append(memberName)
|
||||
|
||||
protect = set()
|
||||
if self.featureExtraProtect:
|
||||
@@ -202,7 +338,9 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
else:
|
||||
protect = None
|
||||
|
||||
- self.structs.append(StructData(typeName, structTypeEnum, members, protect))
|
||||
+ parent = typeinfo.elem.get('parentstruct')
|
||||
+
|
||||
+ self.structs.append(StructData(typeName, structTypeEnum, members, arrays, protect, parent))
|
||||
if protect:
|
||||
self.protects.add(protect)
|
||||
|
||||
@@ -242,4 +380,16 @@ class CReflectionOutputGenerator(OutputGenerator):
|
||||
continue
|
||||
enumTuples.append((getElemName(elem), strVal))
|
||||
|
||||
- self.enums.append(EnumData(groupName, expandPrefix, expandSuffix, enumTuples))
|
||||
+ protect = set()
|
||||
+ if self.featureExtraProtect:
|
||||
+ protect.update(self.featureExtraProtect.split(','))
|
||||
+ localProtect = groupinfo.elem.get('protect')
|
||||
+ if localProtect:
|
||||
+ protect.update(localProtect.split(','))
|
||||
+
|
||||
+ if protect:
|
||||
+ protect = tuple(protect)
|
||||
+ else:
|
||||
+ protect = None
|
||||
+
|
||||
+ self.enums.append(EnumData(groupName, expandPrefix, expandSuffix, enumTuples, protect))
|
||||
diff --git a/specification/scripts/template_openxr_reflection.h b/specification/scripts/template_openxr_reflection.h
|
||||
index 11ec318d1..9ddbbc8e1 100644
|
||||
--- a/specification/scripts/template_openxr_reflection.h
|
||||
+++ b/specification/scripts/template_openxr_reflection.h
|
||||
@@ -12,7 +12,7 @@
|
||||
**
|
||||
*/
|
||||
|
||||
-#include "openxr.h"
|
||||
+// #include "openxr.h"
|
||||
|
||||
/*
|
||||
This file contains expansion macros (X Macros) for OpenXR enumerations and structures.
|
||||
@@ -30,6 +30,13 @@ Example of how to use expansion macros to make an enum-to-string function:
|
||||
XR_ENUM_STR(XrResult);
|
||||
*/
|
||||
|
||||
+#define XR_LIST_HANDLES(_) \
|
||||
+//# for handle in handles
|
||||
+ _(/*{handle}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
//# for enum in enums
|
||||
|
||||
#define XR_LIST_ENUM_/*{enum.typeName}*/(_) \
|
||||
@@ -40,6 +47,39 @@ XR_ENUM_STR(XrResult);
|
||||
|
||||
//# endfor
|
||||
|
||||
+//## Used when making structure type macros
|
||||
+/*% macro makeEnumTypes(typedEnums) -%*/
|
||||
+//# for enum in typedEnums
|
||||
+ _(/*{enum.typeName}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+/*% endmacro %*/
|
||||
+
|
||||
+#define XR_LIST_ENUM_TYPES_CORE(_) \
|
||||
+/*{ makeEnumTypes(unprotectedEnums) }*/
|
||||
+
|
||||
+
|
||||
+//# for protect, enumTypes in protectedEnums if enumTypes|length > 0
|
||||
+
|
||||
+/*{ protect_begin(enumTypes[0]) }*/
|
||||
+#define XR_LIST_ENUM_TYPES_/*{protect | join("_")}*/(_) \
|
||||
+/*{ makeEnumTypes(enumTypes) }*/
|
||||
+#else
|
||||
+#define XR_LIST_ENUM_TYPES_/*{protect | join("_")}*/(_)
|
||||
+#endif
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+
|
||||
+#define XR_LIST_ENUM_TYPES(_) \
|
||||
+ XR_LIST_ENUM_TYPES_CORE(_) \
|
||||
+//# for protect, enumTypes in protectedEnums if enumTypes|length > 0
|
||||
+ XR_LIST_ENUM_TYPES_/*{protect | join("_")}*/(_) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
//# for bitmask in bitmasks
|
||||
|
||||
#define XR_LIST_BITS_/*{bitmask.typeName}*/(_)/*{" \\" if bitmask.maskTuples}*/
|
||||
@@ -61,6 +101,16 @@ XR_ENUM_STR(XrResult);
|
||||
//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
//# endfor
|
||||
|
||||
+//# for struct in structs
|
||||
+
|
||||
+#define XR_LIST_STRUCT_ARRAYS_/*{struct.typeName}*/(_) \
|
||||
+//# for memberName, lenName in struct.arrays.items()
|
||||
+ _(/*{memberName}*/, /*{lenName}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+//# endfor
|
||||
+
|
||||
//## Used when making structure type macros
|
||||
/*% macro makeStructTypes(typedStructs, funcName="_") -%*/
|
||||
//# for struct in typedStructs
|
||||
@@ -98,6 +148,62 @@ XR_ENUM_STR(XrResult);
|
||||
//# endfor
|
||||
|
||||
|
||||
+
|
||||
+#define XR_LIST_BASE_STRUCTS(_) \
|
||||
+//# for structTypeName in base_structs
|
||||
+ _(/*{structTypeName}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# for structName in base_structs
|
||||
+
|
||||
+#define XR_LIST_BASE_STRUCT_TYPES_CORE_/*{structName}*/(_) \
|
||||
+//# for struct in unprotectedStructs if struct.parent == structName
|
||||
+ _(/*{struct.typeName}*/, /*{struct.structTypeName}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# for protect, structTypes in protectedStructs
|
||||
+/*{ protect_begin(structTypes[0]) }*/
|
||||
+#define XR_LIST_BASE_STRUCT_TYPES_/*{structName}*/_/*{protect | join("_")}*/(_) \
|
||||
+//# for struct in structTypes if struct.parent == structName
|
||||
+ _(/*{struct.typeName}*/, /*{struct.structTypeName}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+#else
|
||||
+#define XR_LIST_BASE_STRUCT_TYPES_/*{structName}*/_/*{protect | join("_")}*/(_)
|
||||
+#endif
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+#define XR_LIST_BASE_STRUCT_TYPES_/*{structName}*/(_) \
|
||||
+ XR_LIST_BASE_STRUCT_TYPES_CORE_/*{structName}*/(_) \
|
||||
+//# for protect, structTypes in protectedStructs
|
||||
+ XR_LIST_BASE_STRUCT_TYPES_/*{structName}*/_/*{protect | join("_")}*/(_) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+
|
||||
+
|
||||
+#define XR_LIST_BASIC_STRUCTS(_) \
|
||||
+//# for s in basic_structs
|
||||
+ _(/*{s.typeName}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+
|
||||
//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
|
||||
/// Calls your macro with the name and extension number of all known
|
||||
@@ -126,4 +232,82 @@ XR_ENUM_STR(XrResult);
|
||||
|
||||
//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
|
||||
+
|
||||
+//## Used when making cmd type macros
|
||||
+/*% macro makeCmdTypes(cmds) -%*/
|
||||
+//# for cmd in cmds
|
||||
+ _(/*{cmd.cmdName}*/, /*{cmd.sig}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+/*% endmacro %*/
|
||||
+
|
||||
+#define XR_LIST_FUNCS_CORE(_) \
|
||||
+/*{ makeCmdTypes(unprotectedCmds) }*/
|
||||
+
|
||||
+
|
||||
+//# for protect, cmdTypes in protectedCmds if cmdTypes|length > 0
|
||||
+
|
||||
+/*{ protect_begin(cmdTypes[0]) }*/
|
||||
+#define XR_LIST_FUNCS_/*{protect | join("_")}*/(_) \
|
||||
+/*{ makeCmdTypes(cmdTypes) }*/
|
||||
+#else
|
||||
+#define XR_LIST_FUNCS_/*{protect | join("_")}*/(_)
|
||||
+#endif
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+
|
||||
+#define XR_LIST_FUNCS(_) \
|
||||
+ XR_LIST_FUNCS_CORE(_) \
|
||||
+//# for protect, cmdTypes in protectedCmds if cmdTypes|length > 0
|
||||
+ XR_LIST_FUNCS_/*{protect | join("_")}*/(_) \
|
||||
+//# endfor
|
||||
+
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# for cmd in cmds
|
||||
+
|
||||
+#define XR_LIST_FUNC_/*{cmd.cmdName}*/(_) \
|
||||
+//# for member in cmd.members_non_array
|
||||
+ _(/*{member}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+//# for cmd in cmds
|
||||
+
|
||||
+#define XR_LIST_FUNC_ARRAYS_/*{cmd.cmdName}*/(_) \
|
||||
+//# for member, len_member in cmd.arrays.items()
|
||||
+ _(/*{member}*/, /*{len_member}*/) \
|
||||
+//# endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+//# for cmd in cmds
|
||||
+
|
||||
+#define XR_LIST_FUNC_PARAM_NAMES_/*{cmd.cmdName}*/(_) \
|
||||
+ _(/*{', '.join(cmd.members)}*/) \
|
||||
+
|
||||
+//## Preceding line intentionally left blank to absorb the trailing backslash
|
||||
+
|
||||
+//# endfor
|
||||
+
|
||||
+//# for cmd in cmds
|
||||
+#define XR_BEFORE_/*{cmd.cmdName}*/(funcName)
|
||||
+//#endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank
|
||||
+
|
||||
+//# for cmd in cmds
|
||||
+#define XR_AFTER_/*{cmd.cmdName}*/(funcName)
|
||||
+//#endfor
|
||||
+
|
||||
+//## Preceding line intentionally left blank
|
||||
+
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef XR_USE_PLATFORM_ANDROID
|
||||
#include <jni.h>
|
||||
#include <sys/system_properties.h>
|
||||
#endif
|
||||
|
||||
#ifdef XR_USE_GRAPHICS_API_D3D11
|
||||
#include <d3d11_4.h>
|
||||
#endif
|
||||
|
||||
#ifdef XR_USE_GRAPHICS_API_D3D12
|
||||
#include <d3d12.h>
|
||||
#endif
|
||||
|
||||
#ifdef XR_USE_GRAPHICS_API_OPENGL
|
||||
#if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#ifdef XR_USE_PLATFORM_XCB
|
||||
#include <xcb/glx.h>
|
||||
#endif
|
||||
#ifdef XR_USE_PLATFORM_WIN32
|
||||
#include <GL/gl.h>
|
||||
#include <wingdi.h> // For HGLRC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
|
||||
#ifdef XR_USE_GRAPHICS_API_VULKAN
|
||||
#ifdef XR_USE_PLATFORM_WIN32
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif
|
||||
#if defined(XR_USE_PLATFORM_ANDROID) && !defined(XR_USE_UNITY)
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
@@ -0,0 +1,585 @@
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// Block-based dynamic allocator via ring-buffer.
|
||||
// Ring buffer that stores "blocks" which dynamically grow and wrap.
|
||||
// If a section grows large enough that it overlaps another section, the other section is forgotten.
|
||||
// 8 bit alignment, bring your own synchronization.
|
||||
// Must call Create first, and Destroy when done. Must create a section before writing.
|
||||
// This probably isn't perfect.. some tests are at the bottom and it seems to be stable for the usecase.
|
||||
struct RingBuf
|
||||
{
|
||||
enum OverflowMode
|
||||
{
|
||||
kOverflowModeWrap,
|
||||
kOverflowModeTruncate,
|
||||
kOverflowModeGrowDouble,
|
||||
};
|
||||
|
||||
uint8_t* data;
|
||||
uint32_t cacheSize;
|
||||
OverflowMode overflowMode;
|
||||
|
||||
// must be pointer because of thread_local compiler bug
|
||||
std::deque<uint32_t>* offsets;
|
||||
|
||||
void Create(uint32_t csize, OverflowMode overflowMode)
|
||||
{
|
||||
this->overflowMode = overflowMode;
|
||||
if (data == nullptr)
|
||||
{
|
||||
data = (uint8_t*)malloc(csize);
|
||||
cacheSize = csize;
|
||||
offsets = new std::deque<uint32_t>();
|
||||
}
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SetOverflowMode(OverflowMode overflowMode)
|
||||
{
|
||||
this->overflowMode = overflowMode;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (offsets != nullptr)
|
||||
{
|
||||
offsets->clear();
|
||||
offsets->push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
if (data != nullptr)
|
||||
{
|
||||
free(data);
|
||||
data = nullptr;
|
||||
delete (offsets);
|
||||
cacheSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateNewBlock()
|
||||
{
|
||||
if (offsets != nullptr)
|
||||
offsets->push_back(offsets->back());
|
||||
}
|
||||
|
||||
void DropLastBlock()
|
||||
{
|
||||
if (offsets != nullptr)
|
||||
offsets->pop_back();
|
||||
}
|
||||
|
||||
uint8_t* GetForWrite(uint32_t size)
|
||||
{
|
||||
uint8_t* ret{nullptr};
|
||||
|
||||
if (offsets == nullptr)
|
||||
return nullptr;
|
||||
if (size > cacheSize && overflowMode == kOverflowModeWrap)
|
||||
return nullptr;
|
||||
if (offsets->size() < 2)
|
||||
return nullptr;
|
||||
|
||||
uint32_t head = offsets->front();
|
||||
uint32_t tail = offsets->back();
|
||||
offsets->pop_back();
|
||||
|
||||
// need to wrap
|
||||
if (tail + size > cacheSize)
|
||||
{
|
||||
if (overflowMode == kOverflowModeWrap)
|
||||
{
|
||||
// section grew larger than full buffer and overwrote itself, abort.
|
||||
if (offsets->size() == 1)
|
||||
return nullptr;
|
||||
|
||||
if (offsets->back() != tail)
|
||||
offsets->push_back(tail);
|
||||
|
||||
uint32_t front = offsets->front();
|
||||
while (front != 0)
|
||||
{
|
||||
offsets->pop_front();
|
||||
front = offsets->front();
|
||||
}
|
||||
offsets->pop_front();
|
||||
|
||||
offsets->push_back(0);
|
||||
|
||||
head = offsets->front();
|
||||
tail = offsets->back();
|
||||
}
|
||||
else if (overflowMode == kOverflowModeGrowDouble)
|
||||
{
|
||||
while (tail + size > cacheSize)
|
||||
{
|
||||
// grow
|
||||
uint32_t newCacheSize = cacheSize * 2;
|
||||
uint8_t* newData = (uint8_t*)malloc(newCacheSize);
|
||||
memcpy(newData, data, cacheSize);
|
||||
free(data);
|
||||
data = newData;
|
||||
cacheSize = newCacheSize;
|
||||
}
|
||||
}
|
||||
else if (overflowMode == kOverflowModeTruncate)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// need to free space / forget sections
|
||||
if (tail <= head && head != 0)
|
||||
{
|
||||
while (tail + size > head)
|
||||
{
|
||||
offsets->pop_front();
|
||||
|
||||
head = offsets->front();
|
||||
tail = offsets->back();
|
||||
|
||||
if (offsets->size() == 1)
|
||||
break;
|
||||
|
||||
if (*(offsets->begin() + 1) == 0)
|
||||
{
|
||||
offsets->pop_front();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offsets->push_back(tail + size);
|
||||
ret = &data[tail];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool HasDataForRead()
|
||||
{
|
||||
return offsets != nullptr && offsets->size() > 1 && offsets[0] != offsets[1];
|
||||
}
|
||||
|
||||
// returns true if there is more data to read
|
||||
// in practice there may be two reads necessary to get all the data, from mid to end and from beginning to mid.
|
||||
// reading is a one time operation - data is cleared after read.
|
||||
bool GetForReadAndClear(uint8_t** ptr, uint32_t* size)
|
||||
{
|
||||
if (offsets == nullptr)
|
||||
{
|
||||
*ptr = nullptr;
|
||||
*size = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t head = offsets->front();
|
||||
*ptr = &data[head];
|
||||
|
||||
uint32_t max = 0;
|
||||
for (auto it = offsets->begin(); it != offsets->end();)
|
||||
{
|
||||
if (*it > max)
|
||||
max = *it;
|
||||
else if (max == 0)
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
it = offsets->erase(it);
|
||||
}
|
||||
|
||||
*size = max - head;
|
||||
|
||||
return offsets->size() > 1 && size != 0;
|
||||
}
|
||||
|
||||
bool GetForRead(uint8_t** ptr, uint32_t* size)
|
||||
{
|
||||
if (overflowMode == kOverflowModeGrowDouble && offsets != nullptr)
|
||||
{
|
||||
*ptr = data;
|
||||
*size = offsets->back();
|
||||
return false;
|
||||
}
|
||||
*ptr = nullptr;
|
||||
*size = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MoveFrom(RingBuf& other)
|
||||
{
|
||||
if (other.HasDataForRead() && offsets != nullptr)
|
||||
{
|
||||
CreateNewBlock();
|
||||
uint8_t* ptr{};
|
||||
uint32_t size{};
|
||||
bool more = false;
|
||||
do
|
||||
{
|
||||
more = other.GetForReadAndClear(&ptr, &size);
|
||||
uint8_t* dst = GetForWrite(size);
|
||||
if (dst != nullptr)
|
||||
{
|
||||
memcpy(dst, ptr, size);
|
||||
}
|
||||
} while (more);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Write(Command c)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(Command));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(Command*)wbuf = c;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(LUT l)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(LUT));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(LUT*)wbuf = l;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(std::thread::id id)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << id;
|
||||
Write(ss.str());
|
||||
}
|
||||
|
||||
void Write(const std::string& s)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(char) * ((uint32_t)s.size() + 1));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
memcpy(wbuf, s.c_str(), sizeof(char) * (uint32_t)s.size());
|
||||
wbuf[s.size()] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(float f)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(float));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(float*)wbuf = f;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(int32_t i)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(int32_t));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(int32_t*)wbuf = i;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(int64_t i)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(int64_t));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(int64_t*)wbuf = i;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(uint32_t u)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(uint32_t));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(uint32_t*)wbuf = u;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(uint64_t u)
|
||||
{
|
||||
uint8_t* wbuf = GetForWrite(sizeof(uint64_t));
|
||||
if (wbuf != nullptr)
|
||||
{
|
||||
*(uint64_t*)wbuf = u;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//#define CACHE_SIZE 1024 * 1024 * 1
|
||||
//
|
||||
//int tests()
|
||||
//{
|
||||
// RingBuf buf{};
|
||||
// buf.Create(CACHE_SIZE);
|
||||
//
|
||||
// uint8_t* ptr;
|
||||
// uint32_t size;
|
||||
//
|
||||
// // Check that starts out empty
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 0);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Write
|
||||
// buf.CreateNewBlock();
|
||||
// auto* wbuf = buf.GetForWrite(4);
|
||||
// *(uint32_t*)wbuf = 0x12345678;
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 4);
|
||||
// assert(*(uint32_t*)ptr == 0x12345678);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Write 2
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(4);
|
||||
// *(uint32_t*)wbuf = 0x12345678;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// *(uint64_t*)wbuf = 0x123456789abcdef0;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 12);
|
||||
// assert(*(uint32_t*)ptr == 0x12345678);
|
||||
// assert(*(uint64_t*)(ptr + 4) == 0x123456789abcdef0);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Full buf
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 16);
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == CACHE_SIZE);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Wrap buf, perfectly lines up
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 16);
|
||||
// for (int i = 0; i < (CACHE_SIZE - 16); ++i)
|
||||
// wbuf[i] = 3;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 4;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == true);
|
||||
// assert(size == CACHE_SIZE - 8);
|
||||
// assert(ptr[0] == 2);
|
||||
// assert(ptr[8] == 3);
|
||||
// assert(ptr[size - 1] == 3);
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 8);
|
||||
// assert(ptr[0] == 4);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Wrap buf, not perfect
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 20);
|
||||
// for (int i = 0; i < (CACHE_SIZE - 20); ++i)
|
||||
// wbuf[i] = 3;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 4;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == true);
|
||||
// assert(size == CACHE_SIZE - 12);
|
||||
// assert(ptr[0] == 2);
|
||||
// assert(ptr[8] == 3);
|
||||
// assert(ptr[size - 1] == 3);
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 8);
|
||||
// assert(ptr[0] == 4);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Wrap, and fit more in previous first spot
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 16);
|
||||
// for (int i = 0; i < (CACHE_SIZE - 16); ++i)
|
||||
// wbuf[i] = 3;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(4);
|
||||
// for (int i = 0; i < 4; ++i)
|
||||
// wbuf[i] = 4;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(4);
|
||||
// for (int i = 0; i < 4; ++i)
|
||||
// wbuf[i] = 5;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == true);
|
||||
// assert(size == CACHE_SIZE - 8);
|
||||
// assert(ptr[0] == 2);
|
||||
// assert(ptr[8] == 3);
|
||||
// assert(ptr[size - 1] == 3);
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 8);
|
||||
// assert(ptr[0] == 4);
|
||||
// assert(ptr[4] == 5);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Wrap, and consume first two entries
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 16);
|
||||
// for (int i = 0; i < (CACHE_SIZE - 16); ++i)
|
||||
// wbuf[i] = 3;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(4);
|
||||
// for (int i = 0; i < 4; ++i)
|
||||
// wbuf[i] = 4;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 5;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == true);
|
||||
// assert(size == CACHE_SIZE - 8 - 8);
|
||||
// assert(ptr[0] == 3);
|
||||
// assert(ptr[size - 1] == 3);
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 12);
|
||||
// assert(ptr[0] == 4);
|
||||
// assert(ptr[4] == 5);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Wrap, and consume first three entries
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 16);
|
||||
// for (int i = 0; i < (CACHE_SIZE - 16); ++i)
|
||||
// wbuf[i] = 3;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(4);
|
||||
// for (int i = 0; i < 4; ++i)
|
||||
// wbuf[i] = 4;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 5;
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 6;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 20);
|
||||
// assert(ptr[0] == 4);
|
||||
// assert(ptr[4] == 5);
|
||||
// assert(ptr[12] == 6);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Section wraps, perfectly
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// buf.GetForWrite(CACHE_SIZE);
|
||||
// for (int i = 0; i < (CACHE_SIZE); ++i)
|
||||
// wbuf[i] = 2;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == CACHE_SIZE);
|
||||
// assert(ptr[0] == 2);
|
||||
// assert(ptr[CACHE_SIZE - 1] == 2);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // Section wraps, not perfect
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 1;
|
||||
// buf.CreateNewBlock();
|
||||
// buf.GetForWrite(CACHE_SIZE - 16);
|
||||
// for (int i = 0; i < (CACHE_SIZE - 16); ++i)
|
||||
// wbuf[i] = 2;
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// wbuf[i] = 2;
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == true);
|
||||
// assert(size == CACHE_SIZE - 8);
|
||||
// assert(ptr[0] == 2);
|
||||
// assert(ptr[size - 1] == 2);
|
||||
//
|
||||
// assert(buf.GetForReadAndClear(&ptr, &size) == false);
|
||||
// assert(size == 8);
|
||||
// assert(ptr[0] == 2);
|
||||
// buf.Reset();
|
||||
//
|
||||
// // section wraps on itself
|
||||
// buf.CreateNewBlock();
|
||||
// wbuf = buf.GetForWrite(CACHE_SIZE - 8);
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
//
|
||||
// wbuf = buf.GetForWrite(8);
|
||||
// assert(wbuf == nullptr);
|
||||
//
|
||||
// return 0;
|
||||
//}
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "platform_includes.h"
|
||||
|
||||
#include <openxr/openxr_platform_defines.h>
|
||||
|
||||
// 32-bit builds don't have type-safe handles so we can't distinguish them
|
||||
#define XR_TYPE_SAFE_HANDLES (XR_PTR_SIZE == 8)
|
||||
|
||||
#if !defined(XR_DEFINE_ATOM)
|
||||
#if XR_TYPE_SAFE_HANDLES
|
||||
#define XR_DEFINE_ATOM(object) typedef struct object##_T* object;
|
||||
#else
|
||||
#define XR_DEFINE_ATOM(object) typedef uint64_t object;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define XR_NO_PROTOTYPES
|
||||
#include <openxr/openxr.h>
|
||||
#include <openxr/openxr_loader_negotiation.h>
|
||||
#include <openxr/openxr_platform.h>
|
||||
|
||||
#include "openxr/openxr_reflection_full.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
|
||||
#include "api_exports.h"
|
||||
|
||||
#define CATCH_MISSING_TEMPLATES 0
|
||||
|
||||
static void SendString(const char* fieldName, const char* t);
|
||||
|
||||
template <typename T>
|
||||
void SendToCSharp(const char* fieldname, T t)
|
||||
#if !CATCH_MISSING_TEMPLATES
|
||||
{
|
||||
SendString(fieldname, "<Unknown>");
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void SendToCSharp(const char* fieldname, T* t)
|
||||
#if !CATCH_MISSING_TEMPLATES
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "0x%p", t);
|
||||
SendString(fieldname, buf);
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
// Arrays of base structs
|
||||
template <typename structType>
|
||||
bool SendToCSharpBaseStructArray(const char* fieldname, structType t, int lenParam)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Nullptrs
|
||||
void SendToCSharpNullPtr(const char* fieldname)
|
||||
{
|
||||
SendString(fieldname, "nullptr");
|
||||
}
|
||||
|
||||
// These includes are order-sensitive
|
||||
// clang-format off
|
||||
#include "serialize_data.h"
|
||||
#include "serialize_data_access.h"
|
||||
|
||||
#include "serialize_primitives.h"
|
||||
#include "serialize_enums.h"
|
||||
#include "serialize_handles.h"
|
||||
#include "serialize_atoms.h"
|
||||
#include "serialize_nextptr.h"
|
||||
#include "serialize_external.h"
|
||||
#include "serialize_structs.h"
|
||||
#include "serialize_todo.h"
|
||||
#include "serialize_nextptr_impl.h"
|
||||
|
||||
#include "serialize_funcs_specialization.h"
|
||||
#include "serialize_funcs.h"
|
||||
// clang-format on
|
||||
|
||||
extern "C" XrResult UNITY_INTERFACE_EXPORT XRAPI_PTR xrGetInstanceProcAddr(XrInstance instance, const char* name, PFN_xrVoidFunction* function)
|
||||
{
|
||||
StartFunctionCall("xrGetInstanceProcAddr");
|
||||
SendToCSharp("instance", instance);
|
||||
SendToCSharp("name", name);
|
||||
SendToCSharp("function", "<func>");
|
||||
|
||||
XR_LIST_FUNCS(GEN_FUNC_LOAD)
|
||||
|
||||
EndFunctionCall("xrGetInstanceProcAddr", "UNKNOWN FUNC");
|
||||
|
||||
return orig_xrGetInstanceProcAddr(instance, name, function);
|
||||
}
|
||||
|
||||
extern "C" PFN_xrGetInstanceProcAddr UNITY_INTERFACE_EXPORT XRAPI_PTR HookXrInstanceProcAddr(PFN_xrGetInstanceProcAddr func, uint32_t cacheSize, uint32_t perThreadCacheSize)
|
||||
{
|
||||
ResetLUT();
|
||||
s_CacheSize = cacheSize;
|
||||
s_PerThreadCacheSize = perThreadCacheSize;
|
||||
s_MainDataStore.SetOverflowMode(RingBuf::kOverflowModeTruncate);
|
||||
orig_xrGetInstanceProcAddr = func;
|
||||
return xrGetInstanceProcAddr;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#if XR_TYPE_SAFE_HANDLES
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrSystemId t)
|
||||
{
|
||||
SendToCSharp(fieldname, (uint64_t)t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrSystemId* t)
|
||||
{
|
||||
if (t == nullptr)
|
||||
SendToCSharpNullPtr(fieldname);
|
||||
else
|
||||
SendToCSharp(fieldname, (uint64_t)*t);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,314 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
enum Command
|
||||
{
|
||||
kStartFunctionCall,
|
||||
kStartStruct,
|
||||
|
||||
kFloat,
|
||||
kString,
|
||||
kInt32,
|
||||
kInt64,
|
||||
kUInt32,
|
||||
kUInt64,
|
||||
|
||||
kEndStruct,
|
||||
kEndFunctionCall,
|
||||
|
||||
kCacheNotLargeEnough,
|
||||
|
||||
kLUTDefineTables,
|
||||
kLUTEntryUpdateStart,
|
||||
kLutEntryUpdateEnd,
|
||||
kLUTLookup,
|
||||
|
||||
kEndData = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum LUT
|
||||
{
|
||||
kXrPath,
|
||||
kXrAction,
|
||||
kXrActionSet,
|
||||
kXrSpace,
|
||||
|
||||
kLUTPadding = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
static const char* const kLutNames[] = {
|
||||
"XrPaths",
|
||||
"XrActions",
|
||||
"XrActionSets",
|
||||
"XrSpaces",
|
||||
};
|
||||
|
||||
#include "ringbuf.h"
|
||||
|
||||
static std::mutex s_DataMutex;
|
||||
|
||||
// These get set from c# in HookXrInstanceProcAddr
|
||||
static uint32_t s_CacheSize = 0;
|
||||
static uint32_t s_PerThreadCacheSize = 0;
|
||||
static uint32_t s_LUTCacheSize = 256; // TODO:
|
||||
|
||||
// Accessing this must be protected with s_DataMutex.
|
||||
// Only add into these at kEndFunctionCall to avoid mixing with other threads.
|
||||
static RingBuf s_MainDataStore = {};
|
||||
|
||||
static RingBuf s_LUTDataStore = {};
|
||||
|
||||
// Thread local storage of serialized commands.
|
||||
// On EndFunctionCall they'll be moved into the static storage w/ mutex lock.
|
||||
thread_local RingBuf s_ThreadLocalDataStore = {};
|
||||
|
||||
static void StartFunctionCall(const char* funcName)
|
||||
{
|
||||
if (s_ThreadLocalDataStore.cacheSize != s_PerThreadCacheSize)
|
||||
{
|
||||
s_ThreadLocalDataStore.Destroy();
|
||||
s_ThreadLocalDataStore.Create(s_PerThreadCacheSize, RingBuf::kOverflowModeWrap);
|
||||
}
|
||||
|
||||
s_ThreadLocalDataStore.CreateNewBlock();
|
||||
s_ThreadLocalDataStore.Write(kStartFunctionCall);
|
||||
s_ThreadLocalDataStore.Write(std::this_thread::get_id());
|
||||
s_ThreadLocalDataStore.Write(funcName);
|
||||
}
|
||||
|
||||
static void StartStruct(const char* fieldName, const char* structName)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kStartStruct);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(structName);
|
||||
}
|
||||
|
||||
static void SendFloat(const char* fieldName, float t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kFloat);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(t);
|
||||
}
|
||||
|
||||
static void SendString(const char* fieldName, const char* t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kString);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(t);
|
||||
}
|
||||
|
||||
static void SendInt32(const char* fieldName, int32_t t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kInt32);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(t);
|
||||
}
|
||||
|
||||
static void SendInt64(const char* fieldName, int64_t t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kInt64);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(t);
|
||||
}
|
||||
|
||||
static void SendUInt32(const char* fieldName, uint32_t t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kUInt32);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(t);
|
||||
}
|
||||
|
||||
static void SendUInt64(const char* fieldName, uint64_t t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kUInt64);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write(t);
|
||||
}
|
||||
|
||||
static void EndStruct()
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kEndStruct);
|
||||
}
|
||||
|
||||
static void EndFunctionCall(const char* funcName, const char* result)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kEndFunctionCall);
|
||||
s_ThreadLocalDataStore.Write(result);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(s_DataMutex);
|
||||
|
||||
if (s_MainDataStore.cacheSize != s_CacheSize)
|
||||
{
|
||||
s_MainDataStore.Destroy();
|
||||
s_MainDataStore.Create(s_CacheSize, RingBuf::kOverflowModeTruncate);
|
||||
}
|
||||
|
||||
if (!s_MainDataStore.MoveFrom(s_ThreadLocalDataStore))
|
||||
{
|
||||
s_MainDataStore.CreateNewBlock();
|
||||
s_MainDataStore.Write(kCacheNotLargeEnough);
|
||||
s_MainDataStore.Write(std::this_thread::get_id());
|
||||
s_MainDataStore.Write(funcName);
|
||||
s_MainDataStore.Write(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResetLUT()
|
||||
{
|
||||
s_LUTDataStore.Destroy();
|
||||
s_LUTDataStore.Create(s_LUTCacheSize, RingBuf::kOverflowModeGrowDouble);
|
||||
s_LUTDataStore.CreateNewBlock();
|
||||
|
||||
// Setup LUTS
|
||||
s_LUTDataStore.Write(kLUTDefineTables);
|
||||
uint32_t numLuts = (uint32_t)(sizeof(kLutNames) / sizeof(kLutNames[0]));
|
||||
s_LUTDataStore.Write(numLuts);
|
||||
for (uint32_t i = 0; i < numLuts; ++i)
|
||||
{
|
||||
s_LUTDataStore.Write(kLutNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void StoreInLUT(const char* funcName)
|
||||
{
|
||||
if (s_LUTDataStore.cacheSize < s_LUTCacheSize)
|
||||
{
|
||||
ResetLUT();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(s_DataMutex); // TODO: probably have a different mutex for LUT data store
|
||||
s_LUTDataStore.MoveFrom(s_ThreadLocalDataStore);
|
||||
}
|
||||
|
||||
// We hijacked the function that was already started.
|
||||
// Start a function call for the real call which happens next.
|
||||
StartFunctionCall(funcName);
|
||||
}
|
||||
|
||||
static void SendXrPathCreate(const char* funcName, XrPath path, const char* string)
|
||||
{
|
||||
s_ThreadLocalDataStore.Reset();
|
||||
s_ThreadLocalDataStore.CreateNewBlock();
|
||||
s_ThreadLocalDataStore.Write(kLUTEntryUpdateStart);
|
||||
s_ThreadLocalDataStore.Write(kXrPath);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)path);
|
||||
s_ThreadLocalDataStore.Write(string);
|
||||
StartStruct("", "");
|
||||
EndStruct();
|
||||
|
||||
StoreInLUT(funcName);
|
||||
}
|
||||
|
||||
static void SendXrPath(const char* fieldName, XrPath t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kLUTLookup);
|
||||
s_ThreadLocalDataStore.Write(kXrPath);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char*, const XrActionCreateInfo*);
|
||||
static void SendXrActionCreate(const char* funcName, XrAction action, const XrActionCreateInfo* createInfo)
|
||||
{
|
||||
s_ThreadLocalDataStore.Reset();
|
||||
s_ThreadLocalDataStore.CreateNewBlock();
|
||||
s_ThreadLocalDataStore.Write(kLUTEntryUpdateStart);
|
||||
s_ThreadLocalDataStore.Write(kXrAction);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)action);
|
||||
s_ThreadLocalDataStore.Write(createInfo->actionName);
|
||||
SendToCSharp("", createInfo);
|
||||
|
||||
StoreInLUT(funcName);
|
||||
}
|
||||
|
||||
static void SendXrAction(const char* fieldName, XrAction t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kLUTLookup);
|
||||
s_ThreadLocalDataStore.Write(kXrAction);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char*, const XrActionSetCreateInfo*);
|
||||
static void SendXrActionSetCreate(const char* funcName, XrActionSet actionSet, const XrActionSetCreateInfo* createInfo)
|
||||
{
|
||||
s_ThreadLocalDataStore.Reset();
|
||||
s_ThreadLocalDataStore.CreateNewBlock();
|
||||
s_ThreadLocalDataStore.Write(kLUTEntryUpdateStart);
|
||||
s_ThreadLocalDataStore.Write(kXrActionSet);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)actionSet);
|
||||
s_ThreadLocalDataStore.Write(createInfo->actionSetName);
|
||||
SendToCSharp("", createInfo);
|
||||
|
||||
StoreInLUT(funcName);
|
||||
}
|
||||
|
||||
static void SendXrActionSet(const char* fieldName, XrActionSet t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kLUTLookup);
|
||||
s_ThreadLocalDataStore.Write(kXrActionSet);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char*, const XrActionSpaceCreateInfo*);
|
||||
static void SendXrActionSpaceCreate(const char* funcName, const XrActionSpaceCreateInfo* createInfo, XrSpace* space)
|
||||
{
|
||||
s_ThreadLocalDataStore.Reset();
|
||||
s_ThreadLocalDataStore.CreateNewBlock();
|
||||
s_ThreadLocalDataStore.Write(kLUTEntryUpdateStart);
|
||||
s_ThreadLocalDataStore.Write(kXrSpace);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)*space);
|
||||
s_ThreadLocalDataStore.Write("Action Space");
|
||||
SendToCSharp("", createInfo);
|
||||
|
||||
StoreInLUT(funcName);
|
||||
}
|
||||
|
||||
#define GENERATE_REFERENCE_SPACE_STRING(enumentry, enumvalue) \
|
||||
case enumvalue: \
|
||||
return #enumentry; \
|
||||
break;
|
||||
|
||||
static const char* GetReferenceSpaceString(XrReferenceSpaceType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
XR_LIST_ENUM_XrReferenceSpaceType(GENERATE_REFERENCE_SPACE_STRING) default : return "Reference Space Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char*, const XrReferenceSpaceCreateInfo*);
|
||||
static void SendXrReferenceSpaceCreate(const char* funcName, const XrReferenceSpaceCreateInfo* createInfo, XrSpace* space)
|
||||
{
|
||||
s_ThreadLocalDataStore.Reset();
|
||||
s_ThreadLocalDataStore.CreateNewBlock();
|
||||
s_ThreadLocalDataStore.Write(kLUTEntryUpdateStart);
|
||||
s_ThreadLocalDataStore.Write(kXrSpace);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)*space);
|
||||
s_ThreadLocalDataStore.Write(GetReferenceSpaceString(createInfo->referenceSpaceType));
|
||||
SendToCSharp("", createInfo);
|
||||
|
||||
StoreInLUT(funcName);
|
||||
}
|
||||
|
||||
static void SendXrSpace(const char* fieldName, XrSpace t)
|
||||
{
|
||||
s_ThreadLocalDataStore.Write(kLUTLookup);
|
||||
s_ThreadLocalDataStore.Write(kXrSpace);
|
||||
s_ThreadLocalDataStore.Write(fieldName);
|
||||
s_ThreadLocalDataStore.Write((uint64_t)t);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
|
||||
extern "C" void UNITY_INTERFACE_EXPORT StartDataAccess()
|
||||
{
|
||||
s_DataMutex.lock();
|
||||
}
|
||||
|
||||
extern "C" bool UNITY_INTERFACE_EXPORT GetDataForRead(uint8_t** ptr, uint32_t* size)
|
||||
{
|
||||
s_MainDataStore.SetOverflowMode(RingBuf::kOverflowModeWrap);
|
||||
return s_MainDataStore.GetForReadAndClear(ptr, size);
|
||||
}
|
||||
|
||||
extern "C" bool UNITY_INTERFACE_EXPORT GetLUTData(uint8_t** ptr, uint32_t* size, uint32_t offset)
|
||||
{
|
||||
bool ret = s_LUTDataStore.GetForRead(ptr, size);
|
||||
if (*size <= offset)
|
||||
{
|
||||
*ptr = nullptr;
|
||||
*size = 0;
|
||||
return false;
|
||||
}
|
||||
*ptr = *ptr + offset;
|
||||
*size = *size - offset;
|
||||
s_LUTDataStore.DropLastBlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" void UNITY_INTERFACE_EXPORT EndDataAccess()
|
||||
{
|
||||
s_MainDataStore.Reset();
|
||||
s_DataMutex.unlock();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#define SEND_TO_CSHARP_ENUM_INDIVIDUAL(enumentry, enumvalue) \
|
||||
case enumvalue: \
|
||||
SendToCSharp(fieldname, #enumentry); \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_ENUMS(enumname) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, enumname t) \
|
||||
{ \
|
||||
switch (t) \
|
||||
{ \
|
||||
XR_LIST_ENUM_##enumname(SEND_TO_CSHARP_ENUM_INDIVIDUAL) default : SendToCSharp(fieldname, "UNKNOWN"); \
|
||||
} \
|
||||
}
|
||||
|
||||
XR_LIST_ENUM_TYPES(SEND_TO_CSHARP_ENUMS)
|
||||
|
||||
#define SEND_TO_CSHARP_ENUMS_PTR(enumname) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, enumname* t) \
|
||||
{ \
|
||||
if (t == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
switch (*t) \
|
||||
{ \
|
||||
XR_LIST_ENUM_##enumname(SEND_TO_CSHARP_ENUM_INDIVIDUAL) default : SendToCSharp(fieldname, "UNKNOWN"); \
|
||||
} \
|
||||
}
|
||||
|
||||
XR_LIST_ENUM_TYPES(SEND_TO_CSHARP_ENUMS_PTR)
|
||||
|
||||
#define XR_ENUM_CASE_STR(name, val) \
|
||||
case name: \
|
||||
return #name;
|
||||
#define XR_ENUM_STR(enumType) \
|
||||
const char* XrEnumStr(enumType e) \
|
||||
{ \
|
||||
switch (e) \
|
||||
{ \
|
||||
XR_LIST_ENUM_##enumType(XR_ENUM_CASE_STR) default : return "Unknown"; \
|
||||
} \
|
||||
}
|
||||
|
||||
XR_ENUM_STR(XrResult);
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#if XR_USE_GRAPHICS_API_D3D11
|
||||
//struct ID3D11Texture2D;
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, LUID t)
|
||||
{
|
||||
StartStruct(fieldname, "LUID");
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "0x%x", t.LowPart);
|
||||
SendToCSharp("LowPart", buf);
|
||||
snprintf(buf, 32, "0x%x", t.HighPart);
|
||||
SendToCSharp("HighPart", buf);
|
||||
EndStruct();
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, D3D_FEATURE_LEVEL t)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, 32, "0x%x", t);
|
||||
SendToCSharp(fieldname, buf);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
// Begin Declaration of original functions
|
||||
static PFN_xrGetInstanceProcAddr orig_xrGetInstanceProcAddr;
|
||||
|
||||
#define GEN_ORIG_FUNC_PTRS(f, ...) \
|
||||
static PFN_##f orig_##f;
|
||||
|
||||
XR_LIST_FUNCS(GEN_ORIG_FUNC_PTRS)
|
||||
// End Declaration of original functions
|
||||
|
||||
#define GEN_PARAMS(...) \
|
||||
__VA_ARGS__
|
||||
|
||||
#define SEND_PARAM_TO_CSHARP(param) \
|
||||
SendToCSharp(#param, param);
|
||||
|
||||
#define SEND_ARRAY_TO_CSHARP(param, lenParam) \
|
||||
if (!SendToCSharpBaseStructArray(#param, param, lenParam)) \
|
||||
{ \
|
||||
for (uint32_t i = 0; i < lenParam; ++i) \
|
||||
SendToCSharp(#param, param[i]); \
|
||||
}
|
||||
|
||||
#define GEN_FUNCS(f, ...) \
|
||||
extern "C" XrResult UNITY_INTERFACE_EXPORT XRAPI_PTR f(__VA_ARGS__) \
|
||||
{ \
|
||||
XR_BEFORE_##f(#f); \
|
||||
StartFunctionCall(#f); \
|
||||
XrResult result = orig_##f(XR_LIST_FUNC_PARAM_NAMES_##f(GEN_PARAMS)); \
|
||||
XR_AFTER_##f(#f); \
|
||||
uint32_t lastCount = 0; \
|
||||
XR_LIST_FUNC_##f(SEND_PARAM_TO_CSHARP); \
|
||||
XR_LIST_FUNC_ARRAYS_##f(SEND_ARRAY_TO_CSHARP); \
|
||||
EndFunctionCall(#f, XrEnumStr(result)); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
XR_LIST_FUNCS(GEN_FUNCS)
|
||||
|
||||
#define GEN_FUNC_LOAD(f, ...) \
|
||||
if (strcmp(#f, name) == 0) \
|
||||
{ \
|
||||
auto ret = orig_xrGetInstanceProcAddr(instance, name, (PFN_xrVoidFunction*)&orig_##f); \
|
||||
if (ret == XR_SUCCESS) \
|
||||
*function = (PFN_xrVoidFunction)&f; \
|
||||
EndFunctionCall(#f, XrEnumStr(ret)); \
|
||||
return ret; \
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
//XrResult UNITY_INTERFACE_EXPORT XRAPI_PTR xrLoadControllerModelMSFT(XrSession session, XrControllerModelKeyMSFT modelKey, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, uint8_t* buffer)
|
||||
#undef XR_BEFORE_xrLoadControllerModelMSFT
|
||||
#define XR_BEFORE_xrLoadControllerModelMSFT(funcName) \
|
||||
{ \
|
||||
StartFunctionCall(funcName); \
|
||||
XrResult result = orig_xrLoadControllerModelMSFT(session, modelKey, bufferCapacityInput, bufferCountOutput, buffer); \
|
||||
SendToCSharp("session", session); \
|
||||
SendToCSharp("modelKey", modelKey); \
|
||||
SendToCSharp("bufferCapacityInput", bufferCapacityInput); \
|
||||
SendToCSharp("bufferCountOutput", bufferCountOutput); \
|
||||
SendToCSharp("buffer", "<TODO>"); \
|
||||
EndFunctionCall("xrLoadControllerModelMSFT", XrEnumStr(result)); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
//XrResult UNITY_INTERFACE_EXPORT XRAPI_PTR xrStringToPath(XrInstance instance, const char* pathString, XrPath* path)
|
||||
#undef XR_AFTER_xrStringToPath
|
||||
#define XR_AFTER_xrStringToPath(funcName) \
|
||||
{ \
|
||||
/* Cache off path -> string for later lookup .. send it off to c# for UI */ \
|
||||
if (XR_SUCCEEDED(result)) \
|
||||
SendXrPathCreate(funcName, *path, pathString); \
|
||||
}
|
||||
|
||||
//typedef XrResult (XRAPI_PTR *PFN_xrCreateAction)(XrActionSet actionSet, const XrActionCreateInfo* createInfo, XrAction* action);
|
||||
#undef XR_AFTER_xrCreateAction
|
||||
#define XR_AFTER_xrCreateAction(funcName) \
|
||||
{ \
|
||||
if (XR_SUCCEEDED(result)) \
|
||||
SendXrActionCreate(funcName, *action, createInfo); \
|
||||
}
|
||||
|
||||
//typedef XrResult (XRAPI_PTR *PFN_xrCreateActionSet)(XrInstance instance, const XrActionSetCreateInfo* createInfo, XrActionSet* actionSet);
|
||||
#undef XR_AFTER_xrCreateActionSet
|
||||
#define XR_AFTER_xrCreateActionSet(funcName) \
|
||||
{ \
|
||||
if (XR_SUCCEEDED(result)) \
|
||||
SendXrActionSetCreate(funcName, *actionSet, createInfo); \
|
||||
}
|
||||
|
||||
// typedef XrResult (XRAPI_PTR *PFN_xrCreateActionSpace)(XrSession session, const XrActionSpaceCreateInfo* createInfo, XrSpace* space);
|
||||
#undef XR_AFTER_xrCreateActionSpace
|
||||
#define XR_AFTER_xrCreateActionSpace(funcName) \
|
||||
{ \
|
||||
if (XR_SUCCEEDED(result)) \
|
||||
SendXrActionSpaceCreate(funcName, createInfo, space); \
|
||||
}
|
||||
|
||||
// typedef XrResult (XRAPI_PTR *PFN_xrCreateReferenceSpace)(XrSession session, const XrReferenceSpaceCreateInfo* createInfo, XrSpace* space);
|
||||
#undef XR_AFTER_xrCreateReferenceSpace
|
||||
#define XR_AFTER_xrCreateReferenceSpace(funcName) \
|
||||
{ \
|
||||
if (XR_SUCCEEDED(result)) \
|
||||
SendXrReferenceSpaceCreate(funcName, createInfo, space); \
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
// Handles are defined as uin64_t on 32-bit builds. They already have a template defined, so we need to exclude this block from 32-bit builds.
|
||||
// (and remember that _WIN32 is defined on 64-bit windows builds)
|
||||
#if XR_TYPE_SAFE_HANDLES
|
||||
|
||||
typedef struct XrActionSpecialize_t* XrActionSpecialize;
|
||||
#define XrAction XrActionSpecialize
|
||||
typedef struct XrActionSetSpecialize_t* XrActionSetSpecialize;
|
||||
#define XrActionSet XrActionSetSpecialize
|
||||
typedef struct XrSpaceSpecialize_t* XrSpaceSpecialize;
|
||||
#define XrSpace XrSpaceSpecialize
|
||||
|
||||
#define SEND_TO_CSHARP_HANDLES(handlename) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, handlename t) \
|
||||
{ \
|
||||
SendToCSharp(fieldname, (uint64_t)t); \
|
||||
}
|
||||
|
||||
XR_LIST_HANDLES(SEND_TO_CSHARP_HANDLES)
|
||||
|
||||
#define SEND_TO_CSHARP_HANDLES_PTRS(handlename) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, handlename* t) \
|
||||
{ \
|
||||
if (t != nullptr) \
|
||||
SendToCSharp(fieldname, (uint64_t)*t); \
|
||||
else \
|
||||
SendToCSharp(fieldname, (uint64_t)0); \
|
||||
}
|
||||
|
||||
XR_LIST_HANDLES(SEND_TO_CSHARP_HANDLES_PTRS)
|
||||
|
||||
#undef XrAction
|
||||
#undef XrActionSet
|
||||
#undef XrSpace
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrBaseOutStructure* t);
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrBaseInStructure const* t);
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, void* t)
|
||||
{
|
||||
if (t != nullptr && strcmp(fieldname, "next") == 0)
|
||||
{
|
||||
SendToCSharp(fieldname, reinterpret_cast<XrBaseOutStructure*>(t));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToCSharp(fieldname, (uint64_t)t);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, void const* t)
|
||||
{
|
||||
if (t != nullptr && strcmp(fieldname, "next") == 0)
|
||||
{
|
||||
SendToCSharp(fieldname, reinterpret_cast<XrBaseInStructure const*>(t));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToCSharp(fieldname, (uint64_t)t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#define SEND_NEXT_PTR(structname, structtype) \
|
||||
case structtype: \
|
||||
SendToCSharp("next", reinterpret_cast<structname*>(next)); \
|
||||
break;
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrBaseOutStructure* t)
|
||||
{
|
||||
auto* next = t;
|
||||
do
|
||||
{
|
||||
switch (next->type)
|
||||
{
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_NEXT_PTR)
|
||||
default:
|
||||
SendToCSharp("next", next->type);
|
||||
continue;
|
||||
}
|
||||
} while ((next = static_cast<XrBaseOutStructure*>(next->next)) != nullptr);
|
||||
}
|
||||
|
||||
#define SEND_NEXT_PTR_CONST(structname, structtype) \
|
||||
case structtype: \
|
||||
SendToCSharp("next", reinterpret_cast<structname const*>(next)); \
|
||||
break;
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrBaseInStructure const* t)
|
||||
{
|
||||
auto* next = t;
|
||||
do
|
||||
{
|
||||
switch (next->type)
|
||||
{
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_NEXT_PTR_CONST)
|
||||
default:
|
||||
SendToCSharp("next", next->type);
|
||||
continue;
|
||||
}
|
||||
} while ((next = static_cast<XrBaseInStructure const*>(next->next)) != nullptr);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, int32_t t)
|
||||
{
|
||||
SendInt32(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, int32_t* t)
|
||||
{
|
||||
if (t != nullptr)
|
||||
SendInt32(fieldname, *t);
|
||||
else
|
||||
SendToCSharpNullPtr(fieldname);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, int64_t t)
|
||||
{
|
||||
SendInt64(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, uint32_t t)
|
||||
{
|
||||
SendUInt32(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, uint32_t* t)
|
||||
{
|
||||
if (t != nullptr)
|
||||
SendUInt32(fieldname, *t);
|
||||
else
|
||||
SendToCSharpNullPtr(fieldname);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, uint64_t t)
|
||||
{
|
||||
SendUInt64(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, float t)
|
||||
{
|
||||
SendFloat(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, float* t)
|
||||
{
|
||||
if (t != nullptr)
|
||||
SendFloat(fieldname, *t);
|
||||
else
|
||||
SendToCSharpNullPtr(fieldname);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, char* t)
|
||||
{
|
||||
if (t != nullptr)
|
||||
SendString(fieldname, t);
|
||||
else
|
||||
SendToCSharpNullPtr(fieldname);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, char const* t)
|
||||
{
|
||||
if (t != nullptr)
|
||||
SendString(fieldname, t);
|
||||
else
|
||||
SendToCSharpNullPtr(fieldname);
|
||||
}
|
||||
|
||||
#if XR_TYPE_SAFE_HANDLES
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrPath t)
|
||||
{
|
||||
SendXrPath(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrPath* t)
|
||||
{
|
||||
SendXrPath(fieldname, *t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrAction t)
|
||||
{
|
||||
SendXrAction(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrAction* t)
|
||||
{
|
||||
SendXrAction(fieldname, *t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrActionSet t)
|
||||
{
|
||||
SendXrActionSet(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrActionSet* t)
|
||||
{
|
||||
SendXrActionSet(fieldname, *t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrSpace t)
|
||||
{
|
||||
SendXrSpace(fieldname, t);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrSpace* t)
|
||||
{
|
||||
SendXrSpace(fieldname, *t);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,130 @@
|
||||
#pragma once
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_DECL(structType) \
|
||||
template <> \
|
||||
bool SendToCSharpBaseStructArray<structType*>(const char* fieldname, structType* t, int lenParam);
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_PTR_DECL(structType) \
|
||||
template <> \
|
||||
bool SendToCSharpBaseStructArray<structType**>(const char* fieldname, structType** t, int lenParam);
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_CONST_PTR_DECL(structType) \
|
||||
template <> \
|
||||
bool SendToCSharpBaseStructArray<structType const* const*>(const char* fieldname, structType const* const* t, int lenParam);
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_DECL)
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_PTR_DECL)
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_CONST_PTR_DECL)
|
||||
|
||||
#define SEND_TO_CSHARP_STRUCT_DECL(structType, ...) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structType t);
|
||||
|
||||
#define SEND_TO_CSHARP_STRUCT_PTR_DECL(structType, ...) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structType* t);
|
||||
|
||||
#define SEND_TO_CSHARP_STRUCT_CONST_PTR(structType, ...) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structType const* t);
|
||||
|
||||
// Fwd declare base structs
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_STRUCT_DECL)
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_STRUCT_PTR_DECL)
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_STRUCT_CONST_PTR)
|
||||
|
||||
// Fwd declare basic structs
|
||||
XR_LIST_BASIC_STRUCTS(SEND_TO_CSHARP_STRUCT_DECL)
|
||||
|
||||
XR_LIST_BASIC_STRUCTS(SEND_TO_CSHARP_STRUCT_PTR_DECL)
|
||||
|
||||
XR_LIST_BASIC_STRUCTS(SEND_TO_CSHARP_STRUCT_CONST_PTR)
|
||||
|
||||
// Fwd declare full structs
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_TO_CSHARP_STRUCT_DECL)
|
||||
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_TO_CSHARP_STRUCT_PTR_DECL)
|
||||
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_TO_CSHARP_STRUCT_CONST_PTR)
|
||||
|
||||
#define SEND_TO_CSHARP_INDIVIDUAL_FIELDS(structname) \
|
||||
SendToCSharp(#structname, t.structname);
|
||||
|
||||
#define SEND_TO_CSHARP_INDIVIDUAL_FIELDS_PTR(structname) \
|
||||
SendToCSharp(#structname, t->structname);
|
||||
|
||||
#define SEND_TO_CSHARP_ARRAYS(structname, structlen) \
|
||||
if (!SendToCSharpBaseStructArray(#structname, t.structname, t.structlen)) \
|
||||
{ \
|
||||
for (uint32_t i = 0; i < t.structlen; ++i) \
|
||||
SendToCSharp(#structname, t.structname[i]); \
|
||||
}
|
||||
|
||||
#define SEND_TO_CSHARP_ARRAYS_PTR(structname, structlen) \
|
||||
if (!SendToCSharpBaseStructArray(#structname, t->structname, t->structlen)) \
|
||||
{ \
|
||||
for (uint32_t i = 0; i < t->structlen; ++i) \
|
||||
SendToCSharp(#structname, t->structname[i]); \
|
||||
}
|
||||
|
||||
#define SEND_TO_CSHARP_STRUCTS(structname, ...) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structname t) \
|
||||
{ \
|
||||
StartStruct(fieldname, #structname); \
|
||||
XR_LIST_STRUCT_##structname(SEND_TO_CSHARP_INDIVIDUAL_FIELDS); \
|
||||
XR_LIST_STRUCT_ARRAYS_##structname(SEND_TO_CSHARP_ARRAYS); \
|
||||
EndStruct(); \
|
||||
}
|
||||
|
||||
#define SEND_TO_CSHARP_STRUCTS_PTRS(structname, ...) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structname* t) \
|
||||
{ \
|
||||
if (t == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
StartStruct(fieldname, #structname); \
|
||||
XR_LIST_STRUCT_##structname(SEND_TO_CSHARP_INDIVIDUAL_FIELDS_PTR); \
|
||||
XR_LIST_STRUCT_ARRAYS_##structname(SEND_TO_CSHARP_ARRAYS_PTR); \
|
||||
EndStruct(); \
|
||||
}
|
||||
|
||||
#define SEND_TO_CSHARP_STRUCTS_CONST_PTRS(structname, ...) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, const structname* t) \
|
||||
{ \
|
||||
if (t == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
StartStruct(fieldname, #structname); \
|
||||
XR_LIST_STRUCT_##structname(SEND_TO_CSHARP_INDIVIDUAL_FIELDS_PTR); \
|
||||
XR_LIST_STRUCT_ARRAYS_##structname(SEND_TO_CSHARP_ARRAYS_PTR); \
|
||||
EndStruct(); \
|
||||
}
|
||||
|
||||
// Basic Structs
|
||||
XR_LIST_BASIC_STRUCTS(SEND_TO_CSHARP_STRUCTS)
|
||||
|
||||
XR_LIST_BASIC_STRUCTS(SEND_TO_CSHARP_STRUCTS_PTRS)
|
||||
|
||||
XR_LIST_BASIC_STRUCTS(SEND_TO_CSHARP_STRUCTS_CONST_PTRS)
|
||||
|
||||
// Full Structs
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_TO_CSHARP_STRUCTS)
|
||||
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_TO_CSHARP_STRUCTS_PTRS)
|
||||
|
||||
XR_LIST_STRUCTURE_TYPES(SEND_TO_CSHARP_STRUCTS_CONST_PTRS)
|
||||
|
||||
#include "serialize_structs_base.h"
|
||||
@@ -0,0 +1,188 @@
|
||||
#pragma once
|
||||
|
||||
#define BASE_TO_TYPE(typeName, typeType) \
|
||||
case typeType: \
|
||||
{ \
|
||||
typeName* realType = reinterpret_cast<typeName*>(&t); \
|
||||
SendToCSharp(fieldname, realType); \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT(structType) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structType t) \
|
||||
{ \
|
||||
switch (t.type) \
|
||||
{ \
|
||||
XR_LIST_BASE_STRUCT_TYPES_##structType(BASE_TO_TYPE); \
|
||||
case XR_TYPE_UNKNOWN: \
|
||||
default: \
|
||||
SendToCSharp(fieldname, "<Unknown>"); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT)
|
||||
|
||||
#define BASE_TO_TYPE_PTR(typeName, typeType) \
|
||||
case typeType: \
|
||||
{ \
|
||||
typeName* realType = reinterpret_cast<typeName*>(t); \
|
||||
SendToCSharp(fieldname, realType); \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_PTR(structType) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structType* t) \
|
||||
{ \
|
||||
if (t == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
switch (t->type) \
|
||||
{ \
|
||||
XR_LIST_BASE_STRUCT_TYPES_##structType(BASE_TO_TYPE_PTR); \
|
||||
case XR_TYPE_UNKNOWN: \
|
||||
default: \
|
||||
SendToCSharp(fieldname, t->type); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_PTR)
|
||||
|
||||
#define BASE_TO_TYPE_CONST_PTR(typeName, typeType) \
|
||||
case typeType: \
|
||||
{ \
|
||||
typeName const* realType = reinterpret_cast<typeName const*>(t); \
|
||||
SendToCSharp(fieldname, realType); \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_CONST_PTR(structType) \
|
||||
template <> \
|
||||
void SendToCSharp<>(const char* fieldname, structType const* t) \
|
||||
{ \
|
||||
if (t == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
switch (t->type) \
|
||||
{ \
|
||||
XR_LIST_BASE_STRUCT_TYPES_##structType(BASE_TO_TYPE_CONST_PTR); \
|
||||
case XR_TYPE_UNKNOWN: \
|
||||
default: \
|
||||
SendToCSharp(fieldname, "<Unknown>"); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_CONST_PTR)
|
||||
|
||||
// If we serializing a base struct array such as XrSwapchainImageBaseHeader,
|
||||
// we can only loop over the array of the real type.
|
||||
|
||||
#define BASE_TO_TYPE_ARRAY(typeName, typeType) \
|
||||
case typeType: \
|
||||
{ \
|
||||
typeName* realTypeArray = reinterpret_cast<typeName*>(t); \
|
||||
for (int i = 0; i < lenParam; ++i) \
|
||||
SendToCSharp(fieldname, realTypeArray[i]); \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_ARRAY(structType) \
|
||||
template <> \
|
||||
bool SendToCSharpBaseStructArray<structType*>(const char* fieldname, structType* t, int lenParam) \
|
||||
{ \
|
||||
if (t == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
switch (t[0].type) \
|
||||
{ \
|
||||
XR_LIST_BASE_STRUCT_TYPES_##structType(BASE_TO_TYPE_ARRAY); \
|
||||
case XR_TYPE_UNKNOWN: \
|
||||
default: \
|
||||
SendToCSharp(fieldname, "<Unknown>"); \
|
||||
break; \
|
||||
} \
|
||||
return true; \
|
||||
}
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_ARRAY)
|
||||
|
||||
#define BASE_TO_TYPE_ARRAY_PTR(typeName, typeType) \
|
||||
case typeType: \
|
||||
{ \
|
||||
typeName** realTypeArray = reinterpret_cast<typeName**>(t); \
|
||||
SendToCSharp(fieldname, realTypeArray[i]); \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_ARRAY_PTR(structType) \
|
||||
template <> \
|
||||
bool SendToCSharpBaseStructArray<structType**>(const char* fieldname, structType** t, int lenParam) \
|
||||
{ \
|
||||
if (t == nullptr || t[0] == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
for (int i = 0; i < lenParam; ++i) \
|
||||
{ \
|
||||
switch (t[i]->type) \
|
||||
{ \
|
||||
XR_LIST_BASE_STRUCT_TYPES_##structType(BASE_TO_TYPE_ARRAY_PTR); \
|
||||
case XR_TYPE_UNKNOWN: \
|
||||
default: \
|
||||
SendToCSharp(fieldname, "<Unknown>"); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
return true; \
|
||||
}
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_ARRAY_PTR)
|
||||
|
||||
#define BASE_TO_TYPE_ARRAY_CONST_PTR(typeName, typeType) \
|
||||
case typeType: \
|
||||
{ \
|
||||
typeName const* const* realTypeArray = reinterpret_cast<typeName const* const*>(t); \
|
||||
SendToCSharp(fieldname, realTypeArray[i]); \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define SEND_TO_CSHARP_BASE_STRUCT_ARRAY_CONST_PTR(structType) \
|
||||
template <> \
|
||||
bool SendToCSharpBaseStructArray<structType const* const*>(const char* fieldname, structType const* const* t, int lenParam) \
|
||||
{ \
|
||||
if (t == nullptr || t[0] == nullptr) \
|
||||
{ \
|
||||
SendToCSharpNullPtr(fieldname); \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
for (int i = 0; i < lenParam; ++i) \
|
||||
{ \
|
||||
switch (t[i]->type) \
|
||||
{ \
|
||||
XR_LIST_BASE_STRUCT_TYPES_##structType(BASE_TO_TYPE_ARRAY_CONST_PTR); \
|
||||
case XR_TYPE_UNKNOWN: \
|
||||
default: \
|
||||
SendToCSharp(fieldname, "<Unknown>"); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
return true; \
|
||||
}
|
||||
|
||||
XR_LIST_BASE_STRUCTS(SEND_TO_CSHARP_BASE_STRUCT_ARRAY_CONST_PTR)
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrEventDataBuffer* t)
|
||||
{
|
||||
XrEventDataBaseHeader* evt = reinterpret_cast<XrEventDataBaseHeader*>(t);
|
||||
SendToCSharp("varying", evt);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrDebugUtilsMessengerCreateInfoEXT const* t)
|
||||
{
|
||||
SendToCSharp(fieldname, "<TODO: XrDebugUtilsMessengerCreateInfoEXT>");
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrSpatialGraphNodeSpaceCreateInfoMSFT const* t)
|
||||
{
|
||||
SendToCSharp(fieldname, "<TODO: XrSpatialGraphNodeSpaceCreateInfoMSFT>");
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrInteractionProfileAnalogThresholdVALVE* t)
|
||||
{
|
||||
SendToCSharp(fieldname, "<TODO: XrInteractionProfileAnalogThresholdVALVE>");
|
||||
}
|
||||
|
||||
template <>
|
||||
void SendToCSharp<>(const char* fieldname, XrWorldMeshBufferML* t)
|
||||
{
|
||||
SendToCSharp(fieldname, "<TODO: XrWorldMeshBufferML>");
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Networking.PlayerConnection;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
using UnityEditor.XR.OpenXR.Features.RuntimeDebugger;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.RuntimeDebugger
|
||||
{
|
||||
/// <summary>
|
||||
/// A runtime debugger feature. Intercepts all OpenXR calls and forwards them over player connection to an editor window.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "Runtime Debugger",
|
||||
BuildTargetGroups = new[] {BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Enables debugging of OpenXR calls and dumping runtime info.",
|
||||
DocumentationLink = "",
|
||||
FeatureId = "com.unity.openxr.features.runtimedebugger",
|
||||
OpenxrExtensionStrings = "",
|
||||
Version = "1")]
|
||||
#endif
|
||||
public class RuntimeDebuggerOpenXRFeature : OpenXRFeature
|
||||
{
|
||||
internal static readonly Guid kEditorToPlayerRequestDebuggerOutput = new Guid("B3E6DED1-C6C7-411C-BE58-86031A0877E7");
|
||||
internal static readonly Guid kPlayerToEditorSendDebuggerOutput = new Guid("B3E6DED1-C6C7-411C-BE58-86031A0877E8");
|
||||
|
||||
/// <summary>
|
||||
/// Size of main-thread cache on device for runtime debugger in bytes.
|
||||
/// </summary>
|
||||
public UInt32 cacheSize = 1024 * 1024;
|
||||
|
||||
/// <summary>
|
||||
/// Size of per-thread cache on device for runtime debugger in bytes.
|
||||
/// </summary>
|
||||
public UInt32 perThreadCacheSize = 50 * 1024;
|
||||
|
||||
private UInt32 lutOffset = 0;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IntPtr HookGetInstanceProcAddr(IntPtr func)
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
PlayerConnection.instance.Register(kEditorToPlayerRequestDebuggerOutput, RecvMsg);
|
||||
#endif
|
||||
|
||||
// Reset
|
||||
Native_StartDataAccess();
|
||||
Native_EndDataAccess();
|
||||
lutOffset = 0;
|
||||
|
||||
return Native_HookGetInstanceProcAddr(func, cacheSize, perThreadCacheSize);
|
||||
}
|
||||
|
||||
internal void RecvMsg(MessageEventArgs args)
|
||||
{
|
||||
Native_StartDataAccess();
|
||||
|
||||
// LUT for actions / handles
|
||||
Native_GetLUTData(out var lutPtr, out var lutSize, lutOffset);
|
||||
byte[] lutData = new Byte[lutSize];
|
||||
if (lutSize > 0)
|
||||
{
|
||||
lutOffset = lutSize;
|
||||
Marshal.Copy(lutPtr, lutData, 0, (int)lutSize);
|
||||
}
|
||||
|
||||
// ring buffer on native side, so might get two chunks of data
|
||||
Native_GetDataForRead(out var ptr1, out var size1);
|
||||
Native_GetDataForRead(out var ptr2, out var size2);
|
||||
|
||||
byte[] data = new byte[size1 + size2];
|
||||
if (size1 > 0)
|
||||
Marshal.Copy(ptr1, data, 0, (int)size1);
|
||||
if (size2 > 0)
|
||||
Marshal.Copy(ptr2, data, (int)size1, (int)size2);
|
||||
|
||||
Native_EndDataAccess();
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
PlayerConnection.instance.Send(kPlayerToEditorSendDebuggerOutput, lutData);
|
||||
PlayerConnection.instance.Send(kPlayerToEditorSendDebuggerOutput, data);
|
||||
#else
|
||||
DebuggerState.OnMessageEvent(new MessageEventArgs() {playerId = 0, data = lutData});
|
||||
DebuggerState.OnMessageEvent(new MessageEventArgs() { playerId = 0, data = data});
|
||||
#endif
|
||||
}
|
||||
|
||||
private const string Library = "openxr_runtime_debugger";
|
||||
[DllImport(Library, EntryPoint = "HookXrInstanceProcAddr")]
|
||||
private static extern IntPtr Native_HookGetInstanceProcAddr(IntPtr func, UInt32 cacheSize, UInt32 perThreadCacheSize);
|
||||
|
||||
[DllImport(Library, EntryPoint = "GetDataForRead")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
private static extern bool Native_GetDataForRead(out IntPtr ptr, out UInt32 size);
|
||||
|
||||
[DllImport(Library, EntryPoint = "GetLUTData")]
|
||||
private static extern void Native_GetLUTData(out IntPtr ptr, out UInt32 size, UInt32 offset);
|
||||
|
||||
[DllImport(Library, EntryPoint = "StartDataAccess")]
|
||||
private static extern void Native_StartDataAccess();
|
||||
|
||||
[DllImport(Library, EntryPoint = "EndDataAccess")]
|
||||
private static extern void Native_EndDataAccess();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 056125dd64c0ed540b40a4af74f7b495
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Unity.XR.OpenXR.Features.RuntimeDebugger",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Unity.XR.OpenXR",
|
||||
"Unity.XR.OpenXR.Editor"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
""
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 784a7033de40af04db4f8c4de440f481
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91198f1ea5384e828a74bd7bdc66afb3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 263aafbdc7e14fe09a16e55bf1be8a81
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/android/arm64/libopenxr_runtime_debugger.so
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/android/arm64/libopenxr_runtime_debugger.so
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,82 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c46bc5d3bad84f108dc4405b097380e5
|
||||
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:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61db20b39b784897b126852067c5815a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/android/x64/libopenxr_runtime_debugger.so
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/android/x64/libopenxr_runtime_debugger.so
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,82 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb2f8fd312e042178b4a8fe9207d1152
|
||||
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: X86_64
|
||||
- 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:
|
||||
8
Packages/com.unity.xr.openxr/RuntimeDebugger/osx.meta
Normal file
8
Packages/com.unity.xr.openxr/RuntimeDebugger/osx.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd2fb41e02bd4a298fcfefffe0e0ccef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/osx/openxr_runtime_debugger.dylib
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/osx/openxr_runtime_debugger.dylib
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32cc0620a1d7401694b572ba1df2bd28
|
||||
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: 1
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: OSX
|
||||
- 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: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65905945bf17474786eeab33b4d9a4f2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 529aa76aac4a4923909c689fe65e8e27
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/universalwindows/arm32/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/universalwindows/arm32/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5acbca3f877e4a0d99aa2a1279d20e86
|
||||
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:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f987c5ad0c74022bbdb94dcdaaed9cd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/universalwindows/arm64/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/universalwindows/arm64/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea3b2e779884423f9f4080e9b4942503
|
||||
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:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1439eb8c9e3a4467983d65eebc86dbca
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/universalwindows/x64/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/universalwindows/x64/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b155abe2cde470cb1bd71e62036a0e4
|
||||
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:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a354aa937e924d57b3217da49aaf4c9a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 484bfb2da6b648cba1e36eb02dad9680
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/windows/x64/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
BIN
Packages/com.unity.xr.openxr/RuntimeDebugger/windows/x64/openxr_runtime_debugger.dll
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4e82c52b69445c28d34c7172248a92d
|
||||
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: x86_64
|
||||
- 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:
|
||||
Reference in New Issue
Block a user