Esempio n. 1
0
        private void GenerateCommmands(CppCompilation compilation, string outputPath, string flavour)
        {
            Debug.WriteLine("Generating Commands...");

            bool   isBrowser = false;
            string dllName;

            if (flavour == "Browser")
            {
                isBrowser = true;
                dllName   = "libWebGPU";
            }
            else if (flavour == "Dawn")
            {
                dllName = "dawn_proc.dll";
            }
            else
            {
                throw new Exception($"Flavour ${flavour} not supported");
            }

            using (StreamWriter file = File.CreateText(Path.Combine(outputPath, "Commands.cs")))
            {
                file.WriteLine("using System;");
                file.WriteLine("using System.Diagnostics;");
                file.WriteLine("using System.Runtime.InteropServices;\n");
                file.WriteLine("namespace WaveEngine.Bindings.WebGPU");
                file.WriteLine("{");
                file.WriteLine("\tpublic static unsafe partial class WebGPUNative");
                file.WriteLine("\t{");
                file.WriteLine($"\t\tprivate const string dllName = \"{dllName}\";");

                foreach (var command in compilation.Functions)
                {
                    string convertedType = Helpers.ConvertToCSharpType(command.ReturnType, false);

                    if (!isBrowser || !emscriptenUnsupportedCommands.Contains(command.Name))
                    {
                        file.WriteLine("\n\t\t[DllImport(dllName)]");
                        file.WriteLine($"\t\tpublic static extern {convertedType} {command.Name}({Helpers.GetParametersSignature(command)});");
                    }
                }

                file.WriteLine("\t}");
                file.WriteLine("}");
            }
        }
Esempio n. 2
0
        private void GenerateDelegates(CppCompilation compilation, string outputPath)
        {
            Debug.WriteLine("Generating Delegates...");

            var delegates = compilation.Typedefs
                            .Where(t => t.TypeKind == CppTypeKind.Typedef &&
                                   t.ElementType is CppPointerType &&
                                   ((CppPointerType)t.ElementType).ElementType.TypeKind == CppTypeKind.Function)
                            .ToList();

            using (StreamWriter file = File.CreateText(Path.Combine(outputPath, "Delegates.cs")))
            {
                file.WriteLine("using System;\n");
                file.WriteLine("namespace WaveEngine.Bindings.WebGPU");
                file.WriteLine("{");

                foreach (var funcPointer in delegates)
                {
                    CppFunctionType pointerType = ((CppPointerType)funcPointer.ElementType).ElementType as CppFunctionType;

                    var returnType = Helpers.ConvertToCSharpType(pointerType.ReturnType);
                    file.Write($"\tpublic unsafe delegate {returnType} {funcPointer.Name}(");

                    if (pointerType.Parameters.Count > 0)
                    {
                        file.Write("\n");

                        for (int i = 0; i < pointerType.Parameters.Count; i++)
                        {
                            if (i > 0)
                            {
                                file.Write(",\n");
                            }

                            var parameter     = pointerType.Parameters[i];
                            var convertedType = Helpers.ConvertToCSharpType(parameter.Type);
                            file.Write($"\t\t {convertedType} {parameter.Name}");
                        }
                    }

                    file.Write(");\n\n");
                }

                file.WriteLine("}");
            }
        }
Esempio n. 3
0
        private void GenerateStructs(CppCompilation compilation, string outputPath)
        {
            Debug.WriteLine("Generating Structs...");

            using (StreamWriter file = File.CreateText(Path.Combine(outputPath, "Structs.cs")))
            {
                file.WriteLine("using System;");
                file.WriteLine("using System.Runtime.InteropServices;\n");
                file.WriteLine("namespace WaveEngine.Bindings.WebGPU");
                file.WriteLine("{");

                var structs = compilation.Classes.Where(c => c.ClassKind == CppClassKind.Struct && c.IsDefinition == true);

                foreach (var structure in structs)
                {
                    file.WriteLine("\t[StructLayout(LayoutKind.Sequential)]");
                    file.WriteLine($"\tpublic unsafe struct {structure.Name}");
                    file.WriteLine("\t{");
                    foreach (var member in structure.Fields)
                    {
                        string type = Helpers.ConvertToCSharpType(member.Type);

                        if (type == "bool")
                        {
                            // This is to marshal bool as one byte
                            // https://stackoverflow.com/questions/28514373/what-is-the-size-of-a-boolean-in-c-does-it-really-take-4-bytes/28515361
                            // https://stackoverflow.com/questions/11416433/marshalling-non-blittable-structs-from-c-sharp-to-c
                            // https://stackoverflow.com/questions/32110152/c-sharp-marshalling-bool
                            file.WriteLine($"\t\t[MarshalAs(UnmanagedType.I1)]");
                        }
                        file.WriteLine($"\t\tpublic {type} {member.Name};");
                    }

                    file.WriteLine("\t}\n");
                }
                file.WriteLine("}\n");
            }
        }
Esempio n. 4
0
        private void GenerateCommmands(CppCompilation compilation, string outputPath)
        {
            Debug.WriteLine("Generating Commands...");

            using (StreamWriter file = File.CreateText(Path.Combine(outputPath, "Commands.cs")))
            {
                file.WriteLine("using System;");
                file.WriteLine("using System.Diagnostics;");
                file.WriteLine("using System.Runtime.InteropServices;\n");
                file.WriteLine("namespace WaveEngine.Bindings.WebGPU");
                file.WriteLine("{");
                file.WriteLine("\tpublic static unsafe partial class WebGPUNative");
                file.WriteLine("\t{");
                file.WriteLine("\t\tprivate static Func<IntPtr, string, IntPtr> s_getProcAddress;\n");
                file.WriteLine("\t\tprivate static IntPtr p_device;\n");
                file.WriteLine("\t\tprivate const CallingConvention CallConv = CallingConvention.Winapi;\n");

                foreach (var command in compilation.Functions)
                {
                    string convertedType = Helpers.ConvertToCSharpType(command.ReturnType, false);

                    file.WriteLine("\t\t[UnmanagedFunctionPointer(CallConv)]");

                    // Delegate
                    file.WriteLine($"\t\tprivate delegate {convertedType} {command.Name}Delegate({Helpers.GetParametersSignature(command)});");

                    // internal function
                    file.WriteLine($"\t\tprivate static {command.Name}Delegate {command.Name}_ptr;");

                    // public function
                    file.WriteLine($"\t\tpublic static {convertedType} {command.Name}({Helpers.GetParametersSignature(command)})");
                    file.WriteLine($"\t\t\t=> {command.Name}_ptr({Helpers.GetParametersSignature(command, false)});\n");
                }

                file.WriteLine($"\n\t\tpublic static void LoadFuncionPointers(IntPtr device, Func<IntPtr, string, IntPtr> getProcAddress)");
                file.WriteLine("\t\t{");
                file.WriteLine("\t\t\ts_getProcAddress = getProcAddress;\n");
                file.WriteLine("\t\t\tp_device = device;\n");

                foreach (var command in compilation.Functions)
                {
                    file.WriteLine($"\t\t\tLoadFunction(\"{command.Name}\",  out {command.Name}_ptr);");
                }

                file.WriteLine("\t\t}\n");

                file.WriteLine("\t\tprivate static void LoadFunction<T>(string name, out T field)");
                file.WriteLine("\t\t{");
                file.WriteLine("\t\t\tIntPtr funcPtr = s_getProcAddress(p_device, name);");
                file.WriteLine("\t\t\tif (funcPtr != IntPtr.Zero)");
                file.WriteLine("\t\t\t{");
                file.WriteLine("\t\t\t\tfield = Marshal.GetDelegateForFunctionPointer<T>(funcPtr);");
                file.WriteLine("\t\t\t}");
                file.WriteLine("\t\t\telse");
                file.WriteLine("\t\t\t{");
                file.WriteLine("\t\t\t\tDebug.WriteLine($\"WARING: Function { name} not found in WebGPU implementation.\");");
                file.WriteLine("\t\t\t\tfield = default(T);");
                file.WriteLine("\t\t\t}");
                file.WriteLine("\t\t}");

                file.WriteLine("\t}");
                file.WriteLine("}");
            }
        }