123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862 |
- #if UNITY_EDITOR
- using System.Collections.Generic;
- using System.Reflection;
- using System.IO;
- using System;
- using System.Text;
- using System.Text.RegularExpressions;
- using UnityEditor;
- using UnityEditor.Build;
- using UnityEditor.Build.Reporting;
- using UnityEngine;
- using UnityEngine.UIElements;
-
- namespace Unity.Burst.Editor
- {
- internal enum DebugDataKind
- {
- LineOnly,
- Full
- }
-
- internal enum AvailX86Targets
- {
- SSE2 = (int)BurstTargetCpu.X86_SSE2,
- SSE4 = (int)BurstTargetCpu.X86_SSE4,
- }
-
- [Flags]
- internal enum BitsetX86Targets
- {
- SSE2 = 1 << AvailX86Targets.SSE2,
- SSE4 = 1 << AvailX86Targets.SSE4,
- }
-
- internal enum AvailX64Targets
- {
- SSE2 = (int)BurstTargetCpu.X64_SSE2,
- SSE4 = (int)BurstTargetCpu.X64_SSE4,
- AVX = (int)BurstTargetCpu.AVX,
- AVX2 = (int)BurstTargetCpu.AVX2,
- }
-
- [Flags]
- internal enum BitsetX64Targets
- {
- SSE2 = 1 << AvailX64Targets.SSE2,
- SSE4 = 1 << AvailX64Targets.SSE4,
- AVX = 1 << AvailX64Targets.AVX,
- AVX2 = 1 << AvailX64Targets.AVX2,
- }
-
- internal enum AvailArm64Targets
- {
- ARMV8A = BurstTargetCpu.ARMV8A_AARCH64,
- ARMV8A_HALFFP = BurstTargetCpu.ARMV8A_AARCH64_HALFFP,
- ARMV9A = BurstTargetCpu.ARMV9A,
- }
-
- [Flags]
- internal enum BitsetArm64Targets
- {
- ARMV8A = 1 << AvailArm64Targets.ARMV8A,
- ARMV8A_HALFFP = 1 << AvailArm64Targets.ARMV8A_HALFFP,
- ARMV9A = 1 << AvailArm64Targets.ARMV9A,
- }
-
- [AttributeUsage(AttributeTargets.Field)]
- internal class BurstMetadataSettingAttribute : Attribute { }
-
- [AttributeUsage(AttributeTargets.Field)]
- internal class BurstCommonSettingAttribute : Attribute {}
-
- class BurstPlatformLegacySettings : ScriptableObject
- {
- [SerializeField]
- internal bool DisableOptimisations;
- [SerializeField]
- internal bool DisableSafetyChecks;
- [SerializeField]
- internal bool DisableBurstCompilation;
-
- BurstPlatformLegacySettings(BuildTarget target)
- {
- DisableSafetyChecks = true;
- DisableBurstCompilation = false;
- DisableOptimisations = false;
- }
- }
-
- // To add a setting,
- // Add a
- // [SerializeField] internal type settingname;
- // Add a
- // internal static readonly string settingname_DisplayName = "Name of option to be displayed in the editor (and searched for)";
- // Add a
- // internal static readonly string settingname_ToolTip = "tool tip information to display when hovering mouse
- // If the setting should be restricted to e.g. Standalone platform :
- //
- // Add a
- // internal static bool settingname_Display(BuildTarget selectedTarget, string architecture) {}
- //
- // Add a
- // internal static bool settingname_Serialise(BuildTarget selectedTarget) {}
- class BurstPlatformAotSettings : ScriptableObject
- {
- [SerializeField]
- [BurstMetadataSetting] // We always need version to be in our saved settings!
- internal int Version;
- [SerializeField]
- internal bool EnableBurstCompilation;
- [SerializeField]
- internal bool EnableOptimisations;
- [SerializeField]
- internal bool EnableSafetyChecks;
- [SerializeField]
- internal bool EnableDebugInAllBuilds;
- [SerializeField]
- internal DebugDataKind DebugDataKind;
- [SerializeField]
- internal bool UsePlatformSDKLinker;
- [SerializeField]
- internal bool EnableArmv9SecurityFeatures;
- [SerializeField]
- internal AvailX86Targets CpuMinTargetX32;
- [SerializeField]
- internal AvailX86Targets CpuMaxTargetX32;
- [SerializeField]
- internal AvailX64Targets CpuMinTargetX64;
- [SerializeField]
- internal AvailX64Targets CpuMaxTargetX64;
- [SerializeField]
- internal BitsetX86Targets CpuTargetsX32;
- [SerializeField]
- internal BitsetX64Targets CpuTargetsX64;
- [SerializeField]
- internal BitsetArm64Targets CpuTargetsArm64;
- [SerializeField]
- internal OptimizeFor OptimizeFor;
- [SerializeField]
- [BurstCommonSetting]
- internal string DisabledWarnings;
-
- internal static readonly string EnableDebugInAllBuilds_DisplayName = "Force Debug Information";
- internal static readonly string EnableDebugInAllBuilds_ToolTip = "Generates debug information for the Burst-compiled code, irrespective of if Development Mode is ticked. This can be used to generate symbols for release builds for platforms that need it.";
-
- internal static readonly string DebugDataKind_DisplayName = "Debug Information Kind";
- internal static readonly string DebugDataKind_ToolTip = "Choose which kind of debug information you want present in builds with debug information enabled.";
-
- internal static readonly string EnableOptimisations_DisplayName = "Enable Optimizations";
- internal static readonly string EnableOptimisations_ToolTip = "Enables all optimizations for the currently selected platform.";
-
- internal static readonly string EnableBurstCompilation_DisplayName = "Enable Burst Compilation";
- internal static readonly string EnableBurstCompilation_ToolTip = "Enables burst compilation for the selected platform.";
-
- internal static readonly string OptimizeFor_DisplayName = "Optimize For";
- internal static readonly string OptimizeFor_ToolTip = "Choose what optimization setting to compile Burst code for.";
-
- internal static readonly string DisabledWarnings_DisplayName = "Disabled Warnings*";
- internal static readonly string DisabledWarnings_ToolTip = "Burst warnings to disable (separated by ;).";
-
- internal static readonly string UsePlatformSDKLinker_DisplayName = "Use Platform SDK Linker";
- internal static readonly string UsePlatformSDKLinker_ToolTip = "Enabling this option will disable cross compilation support for desktops, and will require platform specific tools for Windows/Linux/Mac - use only if you encounter problems with the burst builtin solution.";
-
- // We do not support this option anymore, so the easiest thing is to just not display it.
- internal static bool UsePlatformSDKLinker_Display(BuildTarget selectedTarget, string architecture) => false;
- internal static bool UsePlatformSDKLinker_Serialise(BuildTarget selectedTarget) => false;
-
- internal static readonly string CpuTargetsX32_DisplayName = "Target 32Bit CPU Architectures";
- internal static readonly string CpuTargetsX32_ToolTip = "Use this to specify the set of target architectures to support for the currently selected platform.";
- internal static bool CpuTargetsX32_Display(BuildTarget selectedTarget, string architecture)
- {
- return (IsStandalone(selectedTarget) || selectedTarget == BuildTarget.WSAPlayer) && Has32BitSupport(selectedTarget);
- }
- internal static bool CpuTargetsX32_Serialise(BuildTarget selectedTarget)
- {
- return (IsStandalone(selectedTarget) || selectedTarget == BuildTarget.WSAPlayer) && Has32BitSupportForSerialise(selectedTarget);
- }
-
- internal static readonly string CpuTargetsX64_DisplayName = "Target 64Bit CPU Architectures";
- internal static readonly string CpuTargetsX64_ToolTip = "Use this to specify the target architectures to support for the currently selected platform.";
- internal static bool CpuTargetsX64_Display(BuildTarget selectedTarget, string architecture)
- {
- return (IsStandalone(selectedTarget) || selectedTarget == BuildTarget.WSAPlayer)
- && Has64BitSupport(selectedTarget)
- && (selectedTarget != BuildTarget.StandaloneOSX || architecture != "arm64");
- }
- internal static bool CpuTargetsX64_Serialise(BuildTarget selectedTarget)
- {
- return IsStandalone(selectedTarget) || selectedTarget == BuildTarget.WSAPlayer;
- }
-
- internal static readonly string CpuTargetsArm64_DisplayName = "Target Arm 64Bit CPU Architectures";
- internal static readonly string CpuTargetsArm64_ToolTip = "Use this to specify the target architectures to support for the currently selected platform.";
- internal static bool CpuTargetsArm64_Display(BuildTarget selectedTarget, string architecture)
- {
- return selectedTarget == BuildTarget.Android;
- }
- internal static bool CpuTargetsArm64_Serialise(BuildTarget selectedTarget)
- {
- return selectedTarget == BuildTarget.Android;
- }
-
- internal static bool IsStandalone(BuildTarget target)
- {
- switch (target)
- {
- case BuildTarget.StandaloneLinux64:
- case BuildTarget.StandaloneWindows:
- case BuildTarget.StandaloneWindows64:
- case BuildTarget.StandaloneOSX:
- return true;
- default:
- return false;
- }
- }
-
- BurstPlatformAotSettings(BuildTarget target)
- {
- InitialiseDefaults();
- }
-
- private const int DefaultVersion = 4;
-
- internal void InitialiseDefaults()
- {
- Version = DefaultVersion;
- EnableSafetyChecks = false;
- EnableBurstCompilation = true;
- EnableOptimisations = true;
- EnableDebugInAllBuilds = false;
- DebugDataKind = DebugDataKind.Full;
- UsePlatformSDKLinker = false; // Only applicable for desktop targets (Windows/Mac/Linux)
- CpuMinTargetX32 = 0;
- CpuMaxTargetX32 = 0;
- CpuMinTargetX64 = 0;
- CpuMaxTargetX64 = 0;
- CpuTargetsX32 = BitsetX86Targets.SSE2 | BitsetX86Targets.SSE4;
- CpuTargetsX64 = BitsetX64Targets.SSE2 | BitsetX64Targets.AVX2;
- CpuTargetsArm64 = BitsetArm64Targets.ARMV8A;
- DisabledWarnings = "";
- OptimizeFor = OptimizeFor.Default;
- }
-
- internal static string GetPath(BuildTarget? target)
- {
- if (target.HasValue)
- {
- return "ProjectSettings/BurstAotSettings_" + target.ToString() + ".json";
- }
- else
- {
- return "ProjectSettings/CommonBurstAotSettings.json";
- }
- }
-
- internal static BuildTarget? ResolveTarget(BuildTarget? target)
- {
- if (!target.HasValue)
- {
- return target;
- }
-
- // Treat the 32/64 platforms the same from the point of view of burst settings
- // since there is no real way to distinguish from the platforms selector
- if (target == BuildTarget.StandaloneWindows64 || target == BuildTarget.StandaloneWindows)
- return BuildTarget.StandaloneWindows;
-
- // 32 bit linux support was deprecated
- if (target == BuildTarget.StandaloneLinux64)
- return BuildTarget.StandaloneLinux64;
-
- return target;
- }
-
- private static bool IsOutputPathToBuildFolder(BuildSummary summary) =>
- Directory.Exists(summary.outputPath) // Path to either an executable or the specified build folder.
- && summary.platform != BuildTarget.StandaloneOSX; // For MacOSX the folder pointed to is the .app folder
- // that is contained within the build folder.
-
- private static string FetchBuildFolder(BuildSummary summary)
- {
- // Trouble is that it differs based on the build target whether summary refers to:
- // - A specific executable.
- // - The folder being build to.
- // No matter what, we want to place the debug information directory inside of this build
- // folder.
- var outputPath = summary.outputPath;
- return IsOutputPathToBuildFolder(summary)
- ? outputPath // outputPath = <path-to-build-directory>
- : Path.GetDirectoryName(outputPath); // outputPath = <path-to-executable>
- }
-
- internal static readonly string BurstMiscPathPostFix = "_BurstDebugInformation_DoNotShip";
- internal static string FetchOutputPath(BuildSummary summary, string productName)
- {
- var burstMiscFolderName = $"{RemoveIllegalPathChars(productName)}{BurstMiscPathPostFix}";
-
- var finalOutputPath = FetchBuildFolder(summary);
-
- return Path.Combine(finalOutputPath, burstMiscFolderName);
- }
-
- private static readonly Regex IllegalPathChars = new Regex("[/:\\\\*<>|?\"]");
- private static string RemoveIllegalPathChars(string name) => IllegalPathChars.Replace(name, "");
-
- internal static BurstPlatformAotSettings GetOrCreateSettings(BuildTarget? target)
- {
- target = ResolveTarget(target);
- var settings = CreateInstance<BurstPlatformAotSettings>();
- settings.InitialiseDefaults();
- string path = GetPath(target);
-
- var fileExists = File.Exists(path);
- var upgraded = false;
- if (fileExists)
- {
- var json = File.ReadAllText(path);
- settings = SerialiseIn(target, json, out upgraded);
- }
-
- if (!fileExists || upgraded)
- {
- // If the settings file didn't previously exist,
- // or it did exist but we've just upgraded it to a new version,
- // save it to disk now.
- settings.Save(target);
- }
-
- // Overwrite the settings with any that are common and shared between all settings.
- if (target.HasValue)
- {
- var commonSettings = GetOrCreateSettings(null);
-
- var platformFields = typeof(BurstPlatformAotSettings).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
-
- foreach (var field in platformFields)
- {
- if (null != field.GetCustomAttribute<BurstCommonSettingAttribute>())
- {
- field.SetValue(settings, field.GetValue(commonSettings));
- }
- }
- }
-
- return settings;
- }
-
- delegate bool SerialiseItem(BuildTarget selectedPlatform);
-
- private static BurstPlatformAotSettings SerialiseIn(BuildTarget? target, string json, out bool upgraded)
- {
- var versioned = ScriptableObject.CreateInstance<BurstPlatformAotSettings>();
- EditorJsonUtility.FromJsonOverwrite(json, versioned);
-
- upgraded = false;
-
- if (versioned.Version == 0)
- {
- // Deal with pre versioned format
- var legacy = ScriptableObject.CreateInstance<BurstPlatformLegacySettings>();
- EditorJsonUtility.FromJsonOverwrite(json, legacy);
-
- // Legacy file, upgrade it
- versioned.InitialiseDefaults();
- versioned.EnableOptimisations = !legacy.DisableOptimisations;
- versioned.EnableBurstCompilation = !legacy.DisableBurstCompilation;
- versioned.EnableSafetyChecks = !legacy.DisableSafetyChecks;
-
- // Destroy the legacy object so Unity doesn't try to backup / restore it later during domain reload.
- ScriptableObject.DestroyImmediate(legacy);
-
- upgraded = true;
- }
-
- if (versioned.Version < 3)
- {
- // Upgrade the version first
- versioned.Version = 3;
-
- // Upgrade from min..max targets to bitset
- versioned.CpuTargetsX32 |= (BitsetX86Targets)(1 << (int)versioned.CpuMinTargetX32);
- versioned.CpuTargetsX32 |= (BitsetX86Targets)(1 << (int)versioned.CpuMaxTargetX32);
-
- versioned.CpuTargetsX64 |= (BitsetX64Targets)(1 << (int)versioned.CpuMinTargetX64);
- versioned.CpuTargetsX64 |= (BitsetX64Targets)(1 << (int)versioned.CpuMaxTargetX64);
-
- // Extra checks to add targets in the min..max range for 64-bit targets.
- switch (versioned.CpuMinTargetX64)
- {
- default:
- break;
- case AvailX64Targets.SSE2:
- switch (versioned.CpuMaxTargetX64)
- {
- default:
- break;
- case AvailX64Targets.AVX2:
- versioned.CpuTargetsX64 |= (BitsetX64Targets)(1 << (int)AvailX64Targets.AVX);
- goto case AvailX64Targets.AVX;
- case AvailX64Targets.AVX:
- versioned.CpuTargetsX64 |= (BitsetX64Targets)(1 << (int)AvailX64Targets.SSE4);
- break;
- }
- break;
- case AvailX64Targets.SSE4:
- switch (versioned.CpuMaxTargetX64)
- {
- default:
- break;
- case AvailX64Targets.AVX2:
- versioned.CpuTargetsX64 |= (BitsetX64Targets)(1 << (int)AvailX64Targets.AVX);
- break;
- }
- break;
- }
-
- // Wipe the old min/max targets
- versioned.CpuMinTargetX32 = 0;
- versioned.CpuMaxTargetX32 = 0;
- versioned.CpuMinTargetX64 = 0;
- versioned.CpuMaxTargetX64 = 0;
-
- upgraded = true;
- }
-
- if (versioned.Version < 4)
- {
- // Upgrade the version first.
- versioned.Version = 4;
-
- // When we upgrade we'll set the optimization level to default (which is, as expected, the default).
- versioned.OptimizeFor = OptimizeFor.Default;
-
- // This option has been removed as user-setting options, so switch them to false here.
- versioned.EnableSafetyChecks = false;
-
- upgraded = true;
- }
-
- // Otherwise should be a modern file with a valid version (we can use that to upgrade when the time comes)
- return versioned;
- }
-
- private static bool ShouldSerialiseOut(BuildTarget? target, FieldInfo field)
- {
- var method = typeof(BurstPlatformAotSettings).GetMethod(field.Name + "_Serialise", BindingFlags.Static | BindingFlags.NonPublic);
- if (method != null)
- {
- var shouldSerialise = (SerialiseItem)Delegate.CreateDelegate(typeof(SerialiseItem), method);
- if (!target.HasValue || !shouldSerialise(target.Value))
- {
- return false;
- }
- }
-
- // If we always need to write out the attribute, return now.
- if (null != field.GetCustomAttribute<BurstMetadataSettingAttribute>())
- {
- return true;
- }
-
- var isCommon = !target.HasValue;
- var hasCommonAttribute = null != field.GetCustomAttribute<BurstCommonSettingAttribute>();
-
- if ((isCommon && hasCommonAttribute) || (!isCommon && !hasCommonAttribute))
- {
- return true;
- }
-
- return false;
- }
-
- internal string SerialiseOut(BuildTarget? target)
- {
- // Version 2 and onwards serialise a custom object in order to avoid serialising all the settings.
- StringBuilder s = new StringBuilder();
- s.Append("{\n");
- s.Append(" \"MonoBehaviour\": {\n");
- var platformFields = typeof(BurstPlatformAotSettings).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
- int total = 0;
- for (int i = 0; i < platformFields.Length; i++)
- {
- if (ShouldSerialiseOut(target, platformFields[i]))
- {
- total++;
- }
- }
- for (int i = 0; i < platformFields.Length; i++)
- {
- if (ShouldSerialiseOut(target, platformFields[i]))
- {
- s.Append($" \"{platformFields[i].Name}\": ");
- if (platformFields[i].FieldType.IsEnum)
- s.Append((int)platformFields[i].GetValue(this));
- else if (platformFields[i].FieldType == typeof(string))
- s.Append($"\"{platformFields[i].GetValue(this)}\"");
- else if (platformFields[i].FieldType == typeof(bool))
- s.Append(((bool)platformFields[i].GetValue(this)) ? "true" : "false");
- else
- s.Append((int)platformFields[i].GetValue(this));
-
- total--;
- if (total != 0)
- s.Append(",");
- s.Append("\n");
- }
- }
- s.Append(" }\n");
- s.Append("}\n");
-
- return s.ToString();
- }
-
- internal void Save(BuildTarget? target)
- {
- if (target.HasValue)
- {
- target = ResolveTarget(target);
- }
-
- var path = GetPath(target);
-
- if (!AssetDatabase.IsOpenForEdit(path))
- {
- if (!AssetDatabase.MakeEditable(path))
- {
- Debug.LogWarning($"Burst could not save AOT settings file {path}");
- return;
- }
- }
-
- File.WriteAllText(path, SerialiseOut(target));
- }
-
- internal static SerializedObject GetCommonSerializedSettings()
- {
- return new SerializedObject(GetOrCreateSettings(null));
- }
-
- internal static SerializedObject GetSerializedSettings(BuildTarget target)
- {
- return new SerializedObject(GetOrCreateSettings(target));
- }
-
- internal static bool Has32BitSupport(BuildTarget target)
- {
- switch (target)
- {
- case BuildTarget.StandaloneWindows:
- case BuildTarget.WSAPlayer:
- return true;
- default:
- return false;
- }
- }
-
- internal static bool Has32BitSupportForSerialise(BuildTarget target)
- {
- switch (target)
- {
- case BuildTarget.StandaloneWindows:
- case BuildTarget.StandaloneWindows64:
- case BuildTarget.WSAPlayer:
- return true;
- default:
- return false;
- }
- }
-
- internal static bool Has64BitSupport(BuildTarget target)
- {
- switch (target)
- {
- case BuildTarget.StandaloneWindows64:
- case BuildTarget.WSAPlayer:
- case BuildTarget.StandaloneOSX:
- return true;
- default:
- return false;
- }
- }
-
- private static BurstTargetCpu GetCpu(int v)
- {
- // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
- var r = ((v > 0xFFFF) ? 1 : 0) << 4; v >>= r;
- var shift = ((v > 0xFF) ? 1 : 0) << 3; v >>= shift; r |= shift;
- shift = ((v > 0xF) ? 1 : 0) << 2; v >>= shift; r |= shift;
- shift = ((v > 0x3) ? 1 : 0) << 1; v >>= shift; r |= shift;
- r |= (v >> 1);
- return (BurstTargetCpu)r;
- }
-
- private static IEnumerable<Enum> GetFlags(Enum input)
- {
- foreach (Enum value in Enum.GetValues(input.GetType()))
- {
- if (input.HasFlag(value))
- {
- yield return value;
- }
- }
- }
-
- internal TargetCpus GetDesktopCpu32Bit()
- {
- var cpus = new TargetCpus();
-
- foreach (var target in GetFlags(CpuTargetsX32))
- {
- cpus.Cpus.Add(GetCpu((int)(BitsetX86Targets)target));
- }
-
- // If no targets were specified just default to the oldest CPU supported.
- if (cpus.Cpus.Count == 0)
- {
- cpus.Cpus.Add(BurstTargetCpu.X86_SSE2);
- }
-
- return cpus;
- }
-
- internal TargetCpus GetDesktopCpu64Bit()
- {
- var cpus = new TargetCpus();
-
- foreach (var target in GetFlags(CpuTargetsX64))
- {
- cpus.Cpus.Add(GetCpu((int)(BitsetX64Targets)target));
- }
-
- // If no targets were specified just default to the oldest CPU supported.
- if (cpus.Cpus.Count == 0)
- {
- cpus.Cpus.Add(BurstTargetCpu.X64_SSE2);
- }
-
- return cpus;
- }
-
- internal TargetCpus GetAndroidCpuArm64()
- {
- var cpus = new TargetCpus();
-
- foreach (var target in GetFlags(CpuTargetsArm64))
- {
- cpus.Cpus.Add(GetCpu((int)(BitsetArm64Targets)target));
- }
-
- // If no targets were specified just default to the oldest CPU supported.
- if (cpus.Cpus.Count == 0)
- {
- cpus.Cpus.Add(BurstTargetCpu.ARMV8A_AARCH64);
- }
-
- return cpus;
- }
- }
-
- static class BurstAotSettingsIMGUIRegister
- {
- class BurstAotSettingsProvider : SettingsProvider
- {
- SerializedObject[] m_PlatformSettings;
- SerializedProperty[][] m_PlatformProperties;
- DisplayItem[][] m_PlatformVisibility;
- GUIContent[][] m_PlatformToolTips;
- BuildPlatform[] m_ValidPlatforms;
- SerializedObject m_CommonPlatformSettings;
-
- delegate bool DisplayItem(BuildTarget selectedTarget, string architecture);
-
- static bool DefaultShow(BuildTarget selectedTarget, string architecture)
- {
- return true;
- }
- static bool DefaultHide(BuildTarget selectedTarget, string architecture)
- {
- return false;
- }
-
- public BurstAotSettingsProvider()
- : base("Project/Burst AOT Settings", SettingsScope.Project, null)
- {
- int a;
-
- m_ValidPlatforms = BuildPlatforms.instance.GetValidPlatforms(true).ToArray();
-
- var platformFields = typeof(BurstPlatformAotSettings).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
- int numPlatformFields = platformFields.Length;
- int numKeywords = numPlatformFields;
- var tempKeywords = new string[numKeywords];
-
- for (a = 0; a < numPlatformFields; a++)
- {
- tempKeywords[a] = typeof(BurstPlatformAotSettings).GetField(platformFields[a].Name + "_ToolTip", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string;
- }
-
- keywords = new HashSet<string>(tempKeywords);
-
- m_PlatformSettings = new SerializedObject[m_ValidPlatforms.Length];
- m_PlatformProperties = new SerializedProperty[m_ValidPlatforms.Length][];
- m_PlatformVisibility = new DisplayItem[m_ValidPlatforms.Length][];
- m_PlatformToolTips = new GUIContent[m_ValidPlatforms.Length][];
-
- m_CommonPlatformSettings = null;
- }
-
- public override void OnActivate(string searchContext, VisualElement rootElement)
- {
- var platformFields = typeof(BurstPlatformAotSettings).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
- for (int p = 0; p < m_ValidPlatforms.Length; p++)
- {
- InitialiseSettingsForCommon(platformFields);
- InitialiseSettingsForPlatform(p, platformFields);
- }
- }
-
- private void InitialiseSettingsForCommon(FieldInfo[] commonFields)
- {
- m_CommonPlatformSettings = BurstPlatformAotSettings.GetCommonSerializedSettings();
- }
-
- private void InitialiseSettingsForPlatform(int platform, FieldInfo[] platformFields)
- {
- if (m_ValidPlatforms[platform].targetGroup == BuildTargetGroup.Standalone)
- m_PlatformSettings[platform] = BurstPlatformAotSettings.GetSerializedSettings(EditorUserBuildSettings.selectedStandaloneTarget);
- else
- m_PlatformSettings[platform] = BurstPlatformAotSettings.GetSerializedSettings(m_ValidPlatforms[platform].defaultTarget);
-
- m_PlatformProperties[platform] = new SerializedProperty[platformFields.Length];
- m_PlatformToolTips[platform] = new GUIContent[platformFields.Length];
- m_PlatformVisibility[platform] = new DisplayItem[platformFields.Length];
- for (int i = 0; i < platformFields.Length; i++)
- {
- m_PlatformProperties[platform][i] = m_PlatformSettings[platform].FindProperty(platformFields[i].Name);
- var displayName = typeof(BurstPlatformAotSettings).GetField(platformFields[i].Name + "_DisplayName", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string;
- var toolTip = typeof(BurstPlatformAotSettings).GetField(platformFields[i].Name + "_ToolTip", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string;
- m_PlatformToolTips[platform][i] = EditorGUIUtility.TrTextContent(displayName, toolTip);
-
- var method = typeof(BurstPlatformAotSettings).GetMethod(platformFields[i].Name + "_Display", BindingFlags.Static | BindingFlags.NonPublic);
- if (method == null)
- {
- if (displayName == null)
- {
- m_PlatformVisibility[platform][i] = DefaultHide;
- }
- else
- {
- m_PlatformVisibility[platform][i] = DefaultShow;
- }
- }
- else
- {
- m_PlatformVisibility[platform][i] = (DisplayItem)Delegate.CreateDelegate(typeof(DisplayItem), method);
- }
- }
- }
-
- private string FetchStandaloneTargetName()
- {
- switch (EditorUserBuildSettings.selectedStandaloneTarget)
- {
- case BuildTarget.StandaloneOSX:
- return "Mac OS X"; // Matches the Build Settings Dialog names
- case BuildTarget.StandaloneWindows:
- case BuildTarget.StandaloneWindows64:
- return "Windows";
- default:
- return "Linux";
- }
- }
-
- public override void OnGUI(string searchContext)
- {
- var rect = EditorGUILayout.BeginVertical();
-
- EditorGUIUtility.labelWidth = rect.width / 2;
-
- int selectedPlatform = EditorGUILayout.BeginPlatformGrouping(m_ValidPlatforms, null);
-
- // During a build and other cases, the settings object can become invalid, if it does, we re-build it for the current platform
- // this fixes the settings failing to save if modified after a build has finished, and the settings were still open
- if (!m_PlatformSettings[selectedPlatform].isValid)
- {
- var platformFields = typeof(BurstPlatformAotSettings).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
- InitialiseSettingsForCommon(platformFields);
-
- // If the selected platform is invalid, it means all of them will be. So we do a pass to reinitialize all now.
- for (var platform = 0; platform < m_PlatformSettings.Length; platform++)
- {
- InitialiseSettingsForPlatform(platform, platformFields);
- }
- }
-
- var selectedTarget = m_ValidPlatforms[selectedPlatform].defaultTarget;
- if (m_ValidPlatforms[selectedPlatform].targetGroup == BuildTargetGroup.Standalone)
- selectedTarget = EditorUserBuildSettings.selectedStandaloneTarget;
-
- var buildTargetName = BuildPipeline.GetBuildTargetName(selectedTarget);
- var architecture = EditorUserBuildSettings.GetPlatformSettings(buildTargetName, "Architecture").ToLowerInvariant();
-
- if (m_ValidPlatforms[selectedPlatform].targetGroup == BuildTargetGroup.Standalone)
- {
- // Note burst treats Windows and Windows32 as the same target from a settings point of view (same for linux)
- // So we only display the standalone platform
- EditorGUILayout.LabelField(EditorGUIUtility.TrTextContent("Target Platform", "Shows the currently selected standalone build target, can be switched in the Build Settings dialog"), EditorGUIUtility.TrTextContent(FetchStandaloneTargetName()));
- }
-
- for (int i = 0; i < m_PlatformProperties[selectedPlatform].Length; i++)
- {
- if (m_PlatformVisibility[selectedPlatform][i](selectedTarget, architecture))
- {
- EditorGUILayout.PropertyField(m_PlatformProperties[selectedPlatform][i], m_PlatformToolTips[selectedPlatform][i]);
- }
- }
-
- if (m_ValidPlatforms[selectedPlatform].targetGroup == BuildTargetGroup.Android)
- EditorGUILayout.HelpBox("Armv9A (SVE2) target CPU architecture is experimental", MessageType.Warning);
-
- EditorGUILayout.EndPlatformGrouping();
-
- EditorGUILayout.EndVertical();
-
- EditorGUILayout.LabelField("* Shared setting common across all platforms");
-
- if (m_PlatformSettings[selectedPlatform].hasModifiedProperties)
- {
- m_PlatformSettings[selectedPlatform].ApplyModifiedPropertiesWithoutUndo();
-
- var commonAotSettings = ((BurstPlatformAotSettings)m_CommonPlatformSettings.targetObject);
- var platformAotSettings = ((BurstPlatformAotSettings)m_PlatformSettings[selectedPlatform].targetObject);
-
- var platformFields = typeof(BurstPlatformAotSettings).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
-
- foreach (var field in platformFields)
- {
- if (null != field.GetCustomAttribute<BurstCommonSettingAttribute>())
- {
- field.SetValue(commonAotSettings, field.GetValue(platformAotSettings));
-
- foreach (var platformSetting in m_PlatformSettings)
- {
- field.SetValue(platformSetting.targetObject, field.GetValue(commonAotSettings));
- }
- }
- }
-
- commonAotSettings.Save(null);
- platformAotSettings.Save(selectedTarget);
- }
- }
- }
-
- [SettingsProvider]
- public static SettingsProvider CreateBurstAotSettingsProvider()
- {
- return new BurstAotSettingsProvider();
- }
- }
- }
- #endif
|