Exemplo n.º 1
0
        // Generate the constants
        private static void GenerateConstants(ProcessedSpec spec)
        {
            // Open constants file and class
            using var file  = new SourceFile("Constants.cs");
            using var block = file.PushBlock("public static class VkConstants");

            // Write the constants
            block.WriteLine("/* API Constants */");
            foreach (var @const in spec.Constants.Values)
            {
                var typestr = @const.Type switch {
                    ConstantValue.ValueType.Float => "float",
                    ConstantValue.ValueType.Int => "uint",
                    _ => "ulong"
                };
                var valstr = (@const.Type == ConstantValue.ValueType.Float)
                                        ? $"{@const.ValueFloat}f"
                                        : $"{@const.ValueInt}";
                block.WriteLine($"public const {typestr} {@const.Name} = {valstr};");
            }
            block.WriteLine();

            // Write the extension values
            block.WriteLine("/* Extensions */");
            foreach (var ext in spec.Extensions.Values)
            {
                var upper    = ext.Name.Substring("VK_".Length).ToUpperInvariant();
                var namename = upper + "_EXTENSION_NAME";
                var versname = upper + "_SPEC_VERSION";
                block.WriteLine($"public const string {namename} = \"{ext.Name}\";");
                block.WriteLine($"public const uint {versname} = {ext.Version};");
            }
        }
    }
Exemplo n.º 2
0
        // Generate the function tables
        private static void GenerateCommands(ProcessedSpec spec)
        {
            // Generate instance table
            using (var file = new SourceFile("InstanceFunctionTable.cs"))
                using (var table = file.PushBlock("public unsafe sealed partial class InstanceFunctionTable")) {
                    // Global functions
                    table.WriteLine("/* Global Functions */");
                    foreach (var cmd in spec.Commands.Values.Where(cmd => cmd.Scope == CommandType.CommandScope.Global))
                    {
                        table.WriteLine($"public static readonly {cmd.TypeString} {cmd.Name} = null;");
                    }
                    table.WriteLine();

                    // Instance functions
                    table.WriteLine("/* Instance Functions */");
                    foreach (var cmd in spec.Commands.Values.Where(cmd => cmd.Scope == CommandType.CommandScope.Instance))
                    {
                        table.WriteLine($"public readonly {cmd.TypeString} {cmd.Name} = null;");
                    }
                    table.WriteLine();

                    // Null ctor
                    table.WriteLine("/// <summary>Creates a new function table with all null pointers.</summary>");
                    table.WriteLine("public InstanceFunctionTable() { }");
                    table.WriteLine();

                    // Real ctor
                    table.WriteLine("/// <summary>Creates a new function table and loads the functions.</summary>");
                    table.WriteLine("/// <param name=\"inst\">The instance to load the functions for.</param>");
                    table.WriteLine("/// <param name=\"version\">The core API version that the instance was created with.</param>");
                    using (var ctor = table.PushBlock("public InstanceFunctionTable(VulkanHandle<VkInstance> inst, VkVersion version)")) {
                        ctor.WriteLine("void* addr = null;");
                        ctor.WriteLine("CoreVersion = version;");
                        ctor.WriteLine();

                        foreach (var cmd in spec.Commands.Values.Where(cmd => cmd.Scope == CommandType.CommandScope.Instance))
                        {
                            if (cmd.Spec.Alias is not null)
                            {
                                ctor.WriteLine($"{cmd.Name} = {cmd.Spec.Alias.Name};");
                                ctor.WriteLine($"if (({cmd.Name} == null) && TryLoadFunc(inst, \"{cmd.Name}\", out addr)) {{");
                                ctor.WriteLine($"\t{cmd.Name} = ({cmd.TypeString})addr;");
                                ctor.WriteLine("}");
                            }
                            else if (cmd.IsCore)
                            {
                                if (cmd.Spec.FeatureLevel ! > 10)
                                {
                                    ctor.WriteLine($"if (version >= VkVersion.VK_VERSION_1_{cmd.Spec.FeatureLevel % 10}) {{");
                                    ctor.WriteLine($"\t{cmd.Name} = ({cmd.TypeString})LoadFunc(inst, \"{cmd.Name}\");");
                                    ctor.WriteLine("}");
                                }
                                else
                                {
                                    ctor.WriteLine($"{cmd.Name} = ({cmd.TypeString})LoadFunc(inst, \"{cmd.Name}\");");
                                }
                            }
Exemplo n.º 3
0
        // Perform generation
        public static bool Generate(ProcessedSpec spec)
        {
            // Ensure output directories are created
            try {
                if (!Directory.Exists(ArgParse.OutputPath))
                {
                    Directory.CreateDirectory(ArgParse.OutputPath);
                }
                foreach (var vendor in spec.Vendors)
                {
                    if (!vendor.Value.IsCore)
                    {
                        var vdir = Path.Combine(ArgParse.OutputPath, vendor.Key);
                        if (!Directory.Exists(vdir))
                        {
                            Directory.CreateDirectory(vdir);
                        }
                    }
                }
            }
            catch (Exception e) {
                Program.PrintError($"Failed to generate output directories - {e.Message}");
                return(false);
            }

            // Create the constants
            try {
                GenerateConstants(spec);
            }
            catch (Exception e) {
                Program.PrintError($"Failed to generate constants - {e.Message}");
                return(false);
            }
            Program.Print("Generated constants");

            // Create the function tables
            try {
                GenerateCommands(spec);
            }
            catch (Exception e) {
                Program.PrintError($"Failed to generate function tables - {e.Message}");
                return(false);
            }
            Program.Print("Generated function tables");

            // Generate the vendor types
            foreach (var vendor in spec.Vendors.Values)
            {
                try {
                    GenerateBitmasks(vendor);
                }
                catch (Exception e) {
                    Program.PrintError($"Failed to generate bitmasks for '{vendor.Tag}' - {e.Message}");
                    return(false);
                }

                try {
                    GenerateHandles(vendor);
                }
                catch (Exception e) {
                    Program.PrintError($"Failed to generate handles for '{vendor.Tag}' - {e.Message}");
                    return(false);
                }

                try {
                    GenerateEnums(vendor);
                }
                catch (Exception e) {
                    Program.PrintError($"Failed to generate enums for '{vendor.Tag}' - {e.Message}");
                    return(false);
                }

                try {
                    GenerateStructs(vendor);
                }
                catch (Exception e) {
                    Program.PrintError($"Failed to generate structs for '{vendor.Tag}' - {e.Message}");
                    return(false);
                }

                Program.Print($"Generated types for vendor '{vendor.Tag}'");
            }

            return(true);
        }