Beispiel #1
0
        private static void GenerateStructAndUnions(CppCompilation compilation, string outputPath)
        {
            // Generate Structures
            using var writer = new CodeWriter(Path.Combine(outputPath, "Structures.cs"),
                                              "System",
                                              "System.Runtime.InteropServices",
                                              "ImGuiID = System.UInt32",
                                              "ImTextureID = System.IntPtr",
                                              "ImDrawIdx = System.UInt16",
                                              "ImGuiCol = System.Int32",
                                              "ImGuiCond = System.Int32",
                                              "ImGuiDir = System.Int32",
                                              "ImGuiKey = System.Int32",
                                              "ImGuiStyleVar = System.Int32",
                                              "ImGuiSortDirection = System.Int32",
                                              "ImGuiDataAuthority = System.Int32",
                                              "ImGuiLayoutType = System.Int32",
                                              "ImGuiMouseCursor = System.Int32",
                                              "ImPoolIdx = System.Int32",
                                              "ImGuiTableColumnIdx = System.SByte",
                                              "ImGuiTableDrawChannelIdx = System.Byte",
                                              "ImFileHandle = System.IntPtr",
                                              "ImVec1 = System.Single",
                                              "ImVec2 = System.Numerics.Vector2",
                                              "ImVec3 = System.Numerics.Vector3",
                                              "ImVec4 = System.Numerics.Vector4",
                                              "ImColor = System.Numerics.Vector4"
                                              );

            List <CppClass> generatedClasses = new List <CppClass>();

            List <CppClass> handleClasses = new List <CppClass>();

            // Print All classes, structs
            foreach (var cppClass in compilation.Classes)
            {
                if (cppClass.ClassKind == CppClassKind.Class || cppClass.SizeOf == 0)
                {
                    continue;
                }

                if (s_csNameMappings.ContainsKey(cppClass.Name))
                {
                    continue;
                }

                if (s_knowntructs.Contains(cppClass.Name))
                {
                    continue;
                }

                generatedClasses.Add(cppClass);

                bool hasBitField = false;
                foreach (CppField cppField in cppClass.Fields)
                {
                    if (cppField.IsBitField)
                    {
                        hasBitField = true;
                        //Console.WriteLine($"==== BitField : {cppClass.Name}." + cppField.Name);
                        break;
                    }
                }

                if (hasBitField)
                {
                    continue;
                }

                //union
                if (false ||
                    cppClass.Name == "ImGuiStoragePair" ||
                    cppClass.Name == "ImGuiStyleMod")
                {
                    continue;
                }

                bool isUnion = cppClass.ClassKind == CppClassKind.Union;

                string csName     = cppClass.Name;
                bool   isReadOnly = false;

                if (s_handleMappings.TryGetValue(cppClass.Name + "*", out var handleName))
                {
                    handleClasses.Add(cppClass);
                }

                Console.WriteLine($"Generating struct {cppClass.Name}");
                string modifier = "public partial";
                GenerateStructures(writer, cppClass, isUnion, csName, isReadOnly, modifier);

                writer.WriteLine();
            }

            GenerateHandles(compilation, handleClasses, outputPath);

            CheckSize(writer, generatedClasses);
        }
Beispiel #2
0
        private static void GenerateCommands(CppCompilation compilation, string outputPath)
        {
            // Generate Functions
            using var writer = new CodeWriter(Path.Combine(outputPath, "Commands.cs"),
                                              "System",
                                              "System.Runtime.InteropServices",
                                              "ImGuiID = System.UInt32",
                                              "ImTextureID = System.IntPtr",
                                              "ImDrawIdx = System.UInt16",
                                              "ImFileHandle = System.IntPtr",
                                              "ImVec1 = System.Single",
                                              "ImVec2 = System.Numerics.Vector2",
                                              "ImVec3 = System.Numerics.Vector3",
                                              "ImVec4 = System.Numerics.Vector4",
                                              "ImColor = System.Numerics.Vector4"
                                              );

            var commands = new Dictionary <string, CppFunction>();

            foreach (var cppFunction in compilation.Functions)
            {
                var  csName = cppFunction.Name;
                bool skip   = false;
                foreach (var str in s_knowntructs)
                {
                    if (csName.StartsWith(str))
                    {
                        skip = true;
                        break;
                    }
                }

                if (skip)
                {
                    continue;
                }

                foreach (var param in cppFunction.Parameters)
                {
                    var paramType = GetCsTypeName(param.Type, false);
                    if (paramType.Equals("va_list"))
                    {
                        skip = true;
                    }
                }

                if (skip)
                {
                    continue;
                }

                commands.Add(cppFunction.Name, cppFunction);
            }

            using (writer.PushBlock($"unsafe partial class ImGui"))
            {
                foreach (var command in commands)
                {
                    var cppFunction = command.Value;


                    var funName = cppFunction.Name;
                    if (funName.StartsWith("ig"))
                    {
                        funName = funName.Substring(2);
                    }

                    var signature = GetFunctionPointer(cppFunction);
                    writer.WriteLine($"static {signature} {funName}_ptr;");


                    var returnType = GetCsTypeName(cppFunction.ReturnType, false);
                    if (s_handleMappings.TryGetValue(returnType, out var handleName))
                    {
                        returnType = handleName;
                    }

                    var argumentsString = "";

                    bool voidRet = returnType == "void";

                    bool   outToReturn = false;
                    string declStr     = "";
                    string retStr      = "";
                    if (voidRet && GetOutParameterToReturn(cppFunction, out var retType, out declStr, out retStr))
                    {
                        outToReturn     = true;
                        returnType      = retType;
                        argumentsString = GetParameterSignature(cppFunction, 1);
                    }
Beispiel #3
0
        private static void GenerateHandles(CppCompilation compilation, List <CppClass> handleClasses, string outputPath)
        {
            using var writer = new CodeWriter(Path.Combine(outputPath, "Handles.cs"),
                                              "System",
                                              "System.Runtime.InteropServices",
                                              "ImGuiID = System.UInt32",
                                              "ImTextureID = System.IntPtr",
                                              "ImDrawIdx = System.UInt16",
                                              "ImGuiCol = System.Int32",
                                              "ImGuiCond = System.Int32",
                                              "ImGuiDir = System.Int32",
                                              "ImGuiKey = System.Int32",
                                              "ImGuiStyleVar = System.Int32",
                                              "ImGuiSortDirection = System.Int32",
                                              "ImGuiDataAuthority = System.Int32",
                                              "ImGuiLayoutType = System.Int32",
                                              "ImGuiMouseCursor = System.Int32",
                                              "ImPoolIdx = System.Int32",
                                              "ImGuiTableColumnIdx = System.SByte",
                                              "ImGuiTableDrawChannelIdx = System.Byte",
                                              "ImFileHandle = System.IntPtr",
                                              "ImVec1 = System.Single",
                                              "ImVec2 = System.Numerics.Vector2",
                                              "ImVec3 = System.Numerics.Vector3",
                                              "ImVec4 = System.Numerics.Vector4",
                                              "ImColor = System.Numerics.Vector4",
                                              "System.Runtime.CompilerServices"
                                              );

            foreach (var cppClass in handleClasses)
            {
                var csName     = cppClass.Name;
                var handleName = s_handleMappings[csName + "*"];

                Console.WriteLine($"Generating Handle {cppClass.Name}Ptr");

                using (writer.PushBlock($"public unsafe partial struct {handleName}"))
                {
                    writer.WriteLine($"private unsafe {csName}* self;");
                    writer.WriteLine($"public {handleName}({csName}* native) => self = native;");
                    writer.WriteLine($"public static implicit operator bool({handleName} handle) => handle.self != null;");
                    writer.WriteLine($"public static implicit operator {handleName}({csName}* native) => new {handleName}(native);");
                    writer.WriteLine($"public static implicit operator {csName}*({handleName} handle) => handle.self;");

                    foreach (CppField cppField in cppClass.Fields)
                    {
                        string csFieldName = NormalizeFieldName(cppField.Name);

                        if (!s_csNameMappings.TryGetValue(cppField.Type.GetDisplayName(), out var csFieldType))
                        {
                            csFieldType = GetCsTypeName(cppField.Type, false);
                        }

                        if (cppField.Type is CppArrayType arrayType)
                        {
                            bool canUseFixed = false;
                            if (arrayType.ElementType is CppPrimitiveType)
                            {
                                canUseFixed = true;
                            }
                            else if (arrayType.ElementType is CppTypedef typedef &&
                                     typedef.ElementType is CppPrimitiveType)
                            {
                                canUseFixed = true;
                            }

                            var elementTypeName = GetCsTypeName(arrayType.ElementType, false);

                            string wrap = "RangeAccessor";
                            if (canUseFixed)
                            {
                                writer.WriteLine($"public {wrap}<{elementTypeName}> {csFieldName} => ({elementTypeName}*)Unsafe.AsPointer(ref self->{csFieldName}[0]);");
                            }
                            else
                            {
                                writer.WriteLine($"public {wrap}<{elementTypeName}> {csFieldName} => ({elementTypeName}*)Unsafe.AsPointer(ref self->{csFieldName}_0);");
                            }

                            continue;
                        }

                        if (cppField.Type is CppPointerType pointerType)
                        {
                            if (s_handleMappings.TryGetValue(csFieldType, out var p_HandleName))
                            {
                                writer.WriteLine($"public {p_HandleName} {csFieldName} => self->{csFieldName};");

                                continue;
                            }
                        }

                        writer.WriteLine($"public ref {csFieldType} {csFieldName} => ref self->{csFieldName};");
                    }


                    foreach (var cppFunction in compilation.Functions)
                    {
                        if (!cppFunction.Name.StartsWith(csName + "_"))
                        {
                            continue;
                        }

                        if (cppFunction.Name.StartsWith(csName + "__"))
                        {
                            continue;
                        }

                        var returnType = GetCsTypeName(cppFunction.ReturnType, false);
                        if (s_handleMappings.TryGetValue(returnType, out var p_handleName))
                        {
                            returnType = p_handleName;
                        }

                        var argumentsString = "";

                        bool isStatic = false;
                        if (cppFunction.Parameters.Count == 0)
                        {
                            isStatic = true;
                        }

                        bool   voidRet     = returnType == "void";
                        bool   outToReturn = false;
                        string declStr     = "";
                        string retStr      = "";
                        if (voidRet && GetOutParameterToReturn(cppFunction, out var retType, out declStr, out retStr))
                        {
                            outToReturn = true;
                            returnType  = retType;

                            if (cppFunction.Parameters.Count > 1)
                            {
                                if (cppFunction.Parameters[1].Name != "self")
                                {
                                    isStatic = true;
                                }
                            }
                        }
Beispiel #4
0
        private static void GenerateStructures(CodeWriter writer, CppClass cppClass, bool isUnion, string csName, bool isReadOnly, string modifier)
        {
            if (isUnion)
            {
                writer.WriteLine("[StructLayout(LayoutKind.Explicit)]");
            }
            else
            {
                writer.WriteLine("[StructLayout(LayoutKind.Sequential)]");
            }

            using (writer.PushBlock($"{modifier} struct {csName}"))
            {
                if (generateSizeOfStructs && cppClass.SizeOf > 0)
                {
                    writer.WriteLine($"public static readonly int SizeInBytes = {cppClass.SizeOf};");
                    writer.WriteLine();
                }

                foreach (CppField cppField in cppClass.Fields)
                {
                    string csFieldName = NormalizeFieldName(cppField.Name);

                    if (isUnion)
                    {
                        writer.WriteLine("[FieldOffset(0)]");
                    }

                    if (cppField.Type is CppArrayType arrayType)
                    {
                        bool canUseFixed = false;
                        if (arrayType.ElementType is CppPrimitiveType)
                        {
                            canUseFixed = true;
                        }
                        else if (arrayType.ElementType is CppTypedef typedef &&
                                 typedef.ElementType is CppPrimitiveType)
                        {
                            canUseFixed = true;
                        }

                        if (canUseFixed)
                        {
                            var csFieldType = GetCsTypeName(arrayType.ElementType, false);

                            if (string.IsNullOrEmpty(csFieldType))
                            {
                                Console.WriteLine("");
                            }
                            writer.WriteLine($"public unsafe fixed {csFieldType} {csFieldName}[{arrayType.Size}];");
                        }
                        else
                        {
                            var unsafePrefix = string.Empty;
                            var csFieldType  = GetCsTypeName(arrayType.ElementType, false);
                            if (csFieldType.EndsWith('*'))
                            {
                                unsafePrefix = "unsafe ";
                            }

                            for (var i = 0; i < arrayType.Size; i++)
                            {
                                writer.WriteLine($"public {unsafePrefix}{csFieldType} {csFieldName}_{i};");
                            }
                        }
                    }
                    else
                    {
                        if (!s_csNameMappings.TryGetValue(cppField.Type.GetDisplayName(), out var csFieldType))
                        {
                            csFieldType = GetCsTypeName(cppField.Type, false);
                        }
                        else
                        {
                            Console.Write("");
                        }


                        //                         if (csFieldType.Equals("ImGuiDockNodeSettings*") ||
                        //                             csFieldType.Equals("ImGuiDockRequest*"))
                        //                         {
                        //                             csFieldType = "IntPtr";
                        //                         }

                        string fieldPrefix = isReadOnly ? "readonly " : string.Empty;
                        if (csFieldType.EndsWith('*'))
                        {
                            fieldPrefix += "unsafe ";
                        }

                        writer.WriteLine($"public {fieldPrefix}{csFieldType} {csFieldName};");
                    }
                }
            }
        }
        private static void GenerateCommands(CppCompilation compilation, string outputPath)
        {
            // Generate Functions
            using var writer = new CodeWriter(Path.Combine(outputPath, "Commands.cs"),
                                              "System"
                                              );

            var commands         = new Dictionary <string, CppFunction>();
            var instanceCommands = new Dictionary <string, CppFunction>();
            var deviceCommands   = new Dictionary <string, CppFunction>();

            foreach (var cppFunction in compilation.Functions)
            {
                var  returnType      = GetCsTypeName(cppFunction.ReturnType, false);
                bool canUseOut       = s_outReturnFunctions.Contains(cppFunction.Name);
                var  csName          = cppFunction.Name;
                var  argumentsString = GetParameterSignature(cppFunction, canUseOut);

                if (disableCalliFunction)
                {
                    writer.WriteLine("[UnmanagedFunctionPointer(CallingConvention.StdCall)]");
                    writer.WriteLine($"public unsafe delegate {returnType} {csName}Delegate({argumentsString});");
                    writer.WriteLine();
                }

                commands.Add(csName, cppFunction);

                if (cppFunction.Parameters.Count > 0)
                {
                    var firstParameter = cppFunction.Parameters[0];
                    if (firstParameter.Type is CppTypedef typedef)
                    {
                        if (typedef.Name == "VkInstance" ||
                            typedef.Name == "VkPhysicalDevice" ||
                            IsInstanceFunction(cppFunction.Name))
                        {
                            instanceCommands.Add(csName, cppFunction);
                        }
                        else
                        {
                            deviceCommands.Add(csName, cppFunction);
                        }
                    }
                }
            }

            using (writer.PushBlock($"unsafe partial class Vulkan"))
            {
                foreach (var command in commands)
                {
                    var cppFunction = command.Value;

                    if (disableCalliFunction)
                    {
                        writer.WriteLine($"private static {command.Key}Delegate {command.Key}_ptr;");
                    }
                    else
                    {
                        writer.WriteLine($"private static IntPtr {command.Key}_ptr;");
                        writer.WriteLine($"[Calli]");
                    }

                    var  returnType      = GetCsTypeName(cppFunction.ReturnType, false);
                    bool canUseOut       = s_outReturnFunctions.Contains(cppFunction.Name);
                    var  argumentsString = GetParameterSignature(cppFunction, canUseOut);

                    using (writer.PushBlock($"public static {returnType} {cppFunction.Name}({argumentsString})"))
                    {
                        if (disableCalliFunction)
                        {
                            if (returnType != "void")
                            {
                                writer.Write("return ");
                            }

                            writer.Write($"{command.Key}_ptr(");
                            var index = 0;
                            foreach (var cppParameter in cppFunction.Parameters)
                            {
                                var paramCsName = GetParameterName(cppParameter.Name);
                                if (canUseOut && CanBeUsedAsOutput(cppParameter.Type, out var cppTypeDeclaration))
                                {
                                    writer.Write("out ");
                                }

                                writer.Write($"{paramCsName}");
                                if (index < cppFunction.Parameters.Count - 1)
                                {
                                    writer.Write(", ");
                                }

                                index++;
                            }

                            writer.WriteLine($");");
                        }
                        else
                        {
                            writer.WriteLine("throw new NotImplementedException();");
                        }
                    }
                    writer.WriteLine();
                }

                WriteCommands(writer, "GenLoadInstance", instanceCommands);
                WriteCommands(writer, "GenLoadDevice", deviceCommands);
            }
        }
Beispiel #6
0
        public static void GenerateEnums(CppCompilation compilation, string outputPath)
        {
            using var writer = new CodeWriter(Path.Combine(outputPath, "Enumerations.cs"), "System");
            var createdEnums = new Dictionary <string, string>();

            foreach (var cppEnum in compilation.Enums)
            {
                var isBitmask =
                    cppEnum.Name.EndsWith("FlagBits") ||
                    cppEnum.Name.EndsWith("FlagBitsEXT") ||
                    cppEnum.Name.EndsWith("FlagBitsKHR") ||
                    cppEnum.Name.EndsWith("FlagBitsNV") ||
                    cppEnum.Name.EndsWith("FlagBitsAMD") ||
                    cppEnum.Name.EndsWith("FlagBitsMVK") ||
                    cppEnum.Name.EndsWith("FlagBitsNN");
                if (isBitmask)
                {
                    writer.WriteLine("[Flags]");
                }

                string csName         = GetCsCleanName(cppEnum.Name);
                string enumNamePrefix = GetEnumNamePrefix(cppEnum.Name);

                // Rename FlagBits in Flags.
                if (isBitmask)
                {
                    csName = csName.Replace("FlagBits", "Flags");
                    AddCsMapping(cppEnum.Name, csName);
                }

                // Remove extension suffix from enum item values
                string extensionPrefix = "";

                if (csName.EndsWith("EXT"))
                {
                    extensionPrefix = "EXT";
                }
                else if (csName.EndsWith("NV"))
                {
                    extensionPrefix = "NV";
                }
                else if (csName.EndsWith("KHR"))
                {
                    extensionPrefix = "KHR";
                }

                createdEnums.Add(csName, cppEnum.Name);
                using (writer.PushBlock($"public enum {csName}"))
                {
                    if (isBitmask &&
                        !cppEnum.Items.Any(item => GetPrettyEnumName(item.Name, enumNamePrefix) == "None"))
                    {
                        writer.WriteLine("None = 0,");
                    }

                    foreach (var enumItem in cppEnum.Items)
                    {
                        if (enumItem.Name.EndsWith("_BEGIN_RANGE") ||
                            enumItem.Name.EndsWith("_END_RANGE") ||
                            enumItem.Name.EndsWith("_RANGE_SIZE") ||
                            enumItem.Name.EndsWith("_BEGIN_RANGE_EXT") ||
                            enumItem.Name.EndsWith("_BEGIN_RANGE_KHR") ||
                            enumItem.Name.EndsWith("_BEGIN_RANGE_NV") ||
                            enumItem.Name.EndsWith("_BEGIN_RANGE_AMD") ||
                            enumItem.Name.EndsWith("_END_RANGE_EXT") ||
                            enumItem.Name.EndsWith("_END_RANGE_KHR") ||
                            enumItem.Name.EndsWith("_END_RANGE_NV") ||
                            enumItem.Name.EndsWith("_END_RANGE_AMD") ||
                            enumItem.Name.EndsWith("_RANGE_SIZE_EXT") ||
                            enumItem.Name.EndsWith("_RANGE_SIZE_KHR") ||
                            enumItem.Name.EndsWith("_RANGE_SIZE_NV") ||
                            enumItem.Name.EndsWith("_RANGE_SIZE_AMD") ||
                            enumItem.Name.EndsWith("_MAX_ENUM") ||
                            enumItem.Name.EndsWith("_MAX_ENUM_EXT") ||
                            enumItem.Name.EndsWith("_MAX_ENUM_KHR") ||
                            enumItem.Name.EndsWith("_MAX_ENUM_NV") ||
                            enumItem.Name.EndsWith("_MAX_ENUM_AMD") ||
                            enumItem.Name.EndsWith("_MAX_ENUM_INTEL") ||
                            enumItem.Name == "VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT" ||
                            enumItem.Name == "VK_STENCIL_FRONT_AND_BACK" ||
                            enumItem.Name == "VK_PIPELINE_CREATE_DISPATCH_BASE")
                        {
                            continue;
                        }

                        var enumItemName = GetEnumItemName(cppEnum, enumItem.Name, enumNamePrefix);

                        if (!string.IsNullOrEmpty(extensionPrefix) && enumItemName.EndsWith(extensionPrefix))
                        {
                            enumItemName = enumItemName.Remove(enumItemName.Length - extensionPrefix.Length);
                        }

                        //writer.WriteLine("/// <summary>");
                        //writer.WriteLine($"/// {enumItem.Name}");
                        //writer.WriteLine("/// </summary>");
                        if (enumItem.ValueExpression is CppRawExpression rawExpression)
                        {
                            var enumValueName = GetEnumItemName(cppEnum, rawExpression.Text, enumNamePrefix);
                            if (enumItemName == "SurfaceCapabilities2EXT")
                            {
                                continue;
                            }

                            if (!string.IsNullOrEmpty(extensionPrefix) && enumValueName.EndsWith(extensionPrefix))
                            {
                                enumValueName = enumValueName.Remove(enumValueName.Length - extensionPrefix.Length);

                                if (enumItemName == enumValueName)
                                {
                                    continue;
                                }
                            }


                            writer.WriteLine($"{enumItemName} = {enumValueName},");
                        }
                        else
                        {
                            writer.WriteLine($"{enumItemName} = {enumItem.Value},");
                        }
                    }

                    if (csName == "VkColorComponentFlags")
                    {
                        writer.WriteLine($"All = R | G | B | A");
                    }
                }

                writer.WriteLine();
            }

            // Map missing flags with typedefs to VkFlags
            foreach (var typedef in compilation.Typedefs)
            {
                if (typedef.Name.StartsWith("PFN_") ||
                    typedef.Name.Equals("VkBool32", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.Equals("VkFlags", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                if (typedef.ElementType is CppPointerType)
                {
                    continue;
                }

                if (createdEnums.ContainsKey(typedef.Name))
                {
                    continue;
                }

                if (typedef.Name.EndsWith("Flags", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.EndsWith("FlagsKHR", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.EndsWith("FlagsEXT", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.EndsWith("FlagsNV", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.EndsWith("FlagsAMD", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.EndsWith("FlagsMVK", StringComparison.OrdinalIgnoreCase) ||
                    typedef.Name.EndsWith("FlagsNN", StringComparison.OrdinalIgnoreCase))
                {
                    writer.WriteLine("[Flags]");
                    using (writer.PushBlock($"public enum {typedef.Name}"))
                    {
                        writer.WriteLine("None = 0,");
                    }
                    writer.WriteLine();
                }
            }
        }
        private static void GenerateConstants(CppCompilation compilation, string outputPath)
        {
            using var writer = new CodeWriter(Path.Combine(outputPath, "Constants.cs"));
            writer.WriteLine("/// <summary>");
            writer.WriteLine("/// Provides Vulkan specific constants for special values, layer names and extension names.");
            writer.WriteLine("/// </summary>");
            using (writer.PushBlock("public static partial class Vulkan"))
            {
                foreach (var cppMacro in compilation.Macros)
                {
                    if (string.IsNullOrEmpty(cppMacro.Value) ||
                        cppMacro.Name.EndsWith("_H_", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VKAPI_CALL", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VKAPI_PTR", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VULKAN_CORE_H_", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VK_TRUE", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VK_FALSE", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VK_MAKE_VERSION", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.StartsWith("VK_ENABLE_BETA_EXTENSIONS", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.StartsWith("VK_VERSION_", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.StartsWith("VK_API_VERSION_", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VK_NULL_HANDLE", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VK_DEFINE_HANDLE", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.Equals("VK_DEFINE_NON_DISPATCHABLE_HANDLE", StringComparison.OrdinalIgnoreCase) ||
                        cppMacro.Name.StartsWith("VK_USE_PLATFORM_", StringComparison.OrdinalIgnoreCase)
                        )
                    {
                        continue;
                    }

                    string csName = GetPrettyEnumName(cppMacro.Name, "VK_");

                    string modifier   = "const";
                    string csDataType = "string";
                    var    macroValue = NormalizeEnumValue(cppMacro.Value);
                    if (macroValue.EndsWith("F", StringComparison.OrdinalIgnoreCase))
                    {
                        csDataType = "float";
                    }
                    else if (macroValue.EndsWith("UL", StringComparison.OrdinalIgnoreCase))
                    {
                        csDataType = "ulong";
                    }
                    else if (macroValue.EndsWith("U", StringComparison.OrdinalIgnoreCase))
                    {
                        csDataType = "uint";
                    }
                    else if (uint.TryParse(macroValue, out _))
                    {
                        csDataType = "uint";
                    }

                    if (cppMacro.Name == "VK_QUEUE_FAMILY_EXTERNAL" ||
                        cppMacro.Name == "VK_QUEUE_FAMILY_FOREIGN_EXT")
                    {
                        csDataType = "uint";
                    }
                    else if (cppMacro.Name == "VK_LUID_SIZE_KHR" ||
                             cppMacro.Name == "VK_SHADER_UNUSED_NV" ||
                             cppMacro.Name == "VK_QUEUE_FAMILY_EXTERNAL_KHR" ||
                             cppMacro.Name == "VK_MAX_DRIVER_NAME_SIZE_KHR" ||
                             cppMacro.Name == "VK_MAX_DRIVER_INFO_SIZE_KHR" ||
                             cppMacro.Name == "VK_MAX_DEVICE_GROUP_SIZE_KHR"
                             )
                    {
                        csDataType = "uint";
                        macroValue = GetCsCleanName(cppMacro.Value);
                    }

                    AddCsMapping(cppMacro.Name, csName);

                    writer.WriteLine("/// <summary>");
                    if (cppMacro.Name == "VK_HEADER_VERSION_COMPLETE")
                    {
                        modifier   = "static readonly";
                        csDataType = "VkVersion";
                    }

                    writer.WriteLine($"/// {cppMacro.Name} = {cppMacro.Value}");
                    writer.WriteLine("/// </summary>");
                    if (cppMacro.Name == "VK_HEADER_VERSION_COMPLETE")
                    {
                        writer.WriteLine($"public {modifier} {csDataType} {csName} = new VkVersion({cppMacro.Tokens[2]}, {cppMacro.Tokens[4]}, HeaderVersion);");
                    }
                    else
                    {
                        writer.WriteLine($"public {modifier} {csDataType} {csName} = {macroValue};");
                    }
                }
            }
        }