add bindings

This commit is contained in:
2026-07-12 16:21:19 +02:00
commit edb45f2a10
11 changed files with 7070 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
recovery
build
BeefSpace_User.toml
BeefSpace_Lock.toml
+3
View File
@@ -0,0 +1,3 @@
[submodule "SPIRV-Cross"]
path = SPIRV-Cross
url = https://github.com/KhronosGroup/SPIRV-Cross.git
+70
View File
@@ -0,0 +1,70 @@
FileVersion = 1
[Project]
Name = "SpirVCross"
TargetType = "BeefLib"
StartupObject = "SpirVCross.Program"
[Dependencies]
corlib = "*"
"CxxBuildTool.git" = {Git = "https://git.unicon-gmbh.de/Rune/CxxBuildTool.git"}
[Configs.Debug.Win32]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Debug.Win64]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Debug.Linux32]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Debug.Linux64]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Debug.macOS]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Release.Win32]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Release.Win64]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Release.Linux32]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Release.Linux64]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Release.macOS]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Paranoid.Win32]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Paranoid.Win64]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Paranoid.Linux32]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Paranoid.Linux64]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Paranoid.macOS]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Test.Win32]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Test.Win64]
LibPaths = ["$(BuildDir)/spirv_cross.lib"]
[Configs.Test.Linux32]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Test.Linux64]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
[Configs.Test.macOS]
LibPaths = ["$(BuildDir)/spirv_cross.a"]
+8
View File
@@ -0,0 +1,8 @@
FileVersion = 1
[Workspace]
StartupProject = "SpirVCross"
[Projects]
SpirVCross = {Path = "."}
"CxxBuildTool.git" = {Git = "https://git.unicon-gmbh.de/Rune/CxxBuildTool.git"}
Submodule
+1
Submodule SPIRV-Cross added at 6c09849fe8
+9
View File
@@ -0,0 +1,9 @@
FileVersion = 1
[Project]
Name = "SpirVCross.Setup"
StartupObject = "SpirVCross.Setup.Program"
[Dependencies]
corlib = "*"
"Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/Rune/Cpp2Beef.git"}
+9
View File
@@ -0,0 +1,9 @@
FileVersion = 1
ExtraPlatforms = ["Linux32", "Linux64", "macOS"]
[Workspace]
StartupProject = "SpirVCross.Setup"
[Projects]
"SpirVCross.Setup" = {Path = "."}
"Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/Rune/Cpp2Beef.git"}
+218
View File
@@ -0,0 +1,218 @@
using System;
using System.IO;
using System.Collections;
using System.Diagnostics;
using Cpp2Beef;
using LibClang;
namespace SpirVCross.Setup;
class SpriVCrossGenerator : Cpp2BeefGenerator, this(Span<char8*> args)
{
protected override Span<char8*> Args => args;
protected override Flags Flags => .None;
StreamWriter spvWriter = new .()..Create("../src/SpirV.bf")..Write("""
// This file was generated by Cpp2Beef
using System;
using System.Interop;
namespace SpirVCross;
""") ~ delete _;
StreamWriter spvcWriter = new .()..Create("../src/SpirVCross.bf")..Write("""
// This file was generated by Cpp2Beef
using System;
using System.Interop;
namespace SpirVCross;
""") ~ delete _;
protected override StreamWriter GetWriterForHeader(StringView header)
{
// Here you define the target file to which a cursor should be written
// Returning null skips the cursor
if (header.EndsWith("spirv_cross_c.h"))
return spvcWriter;
if (header.EndsWith("spirv.h"))
return spvWriter;
return null;
}
protected override bool IsOutParam(CXCursor arg, CXCursor method)
{
let type = Clang.GetCursorType(arg);
if (type.kind != .Pointer) return false;
let spelling = GetTypeSpelling!(Clang.GetPointeeType(type));
return handles.ContainsAlt(spelling);
}
HashSet<String> handles = new .(16) ~ DeleteContainerAndItems!(_);
protected override void HandleCursor(CXCursor cursor)
{
switch (cursor.kind)
{
case .TypedefDecl:
let spelling = GetCursorSpelling!(cursor);
if (spelling == "spvc_bool")
return;
if (spelling.EndsWith("_flags"))
{
BeginCursor(cursor);
AccessSpecifier(cursor);
str.Append("typealias ");
GetNameInBindings(cursor, str);
str.Append(" = ");
GetNameInBindings(cursor, str);
str.Length--;
str.Append("Bits;");
return;
}
let type = Clang.GetTypedefDeclUnderlyingType(cursor);
let typeSpelling = GetTypeSpelling!(type);
if (!(typeSpelling.StartsWith("struct spvc_") || typeSpelling.StartsWith("const struct spvc_")) || !typeSpelling.EndsWith("_s *"))
break;
BeginCursor(cursor);
AccessSpecifier(cursor);
str.Append("struct ");
GetNameInBindings(cursor, str);
str.Append(" : int {}");
handles.Add(new .(spelling));
return;
case .StructDecl:
let spelling = GetCursorSpelling!(cursor);
if (spelling.EndsWith("_s"))
return;
default:
}
base.HandleCursor(cursor);
}
protected override void GetNameInBindings(CXCursor cursor, String outString)
{
switch (cursor.kind)
{
case .EnumDecl:
let spelling = GetCursorSpelling!(cursor);
if (spelling.StartsWith("Spv") && spelling.EndsWith('_'))
{
outString.Append(spelling[..<^1]);
return;
}
fallthrough;
case .StructDecl, .UnionDecl, .TypedefDecl:
let spelling = GetCursorSpelling!(cursor);
if (!spelling.StartsWith("spvc_"))
break;
UpperSnakeCase2PascalCase(spelling, outString);
return;
case .EnumConstantDecl:
var parentSpelling = GetCursorSpelling!(Clang.GetCursorSemanticParent(cursor));
var spelling = GetCursorSpelling!(cursor);
if (parentSpelling.StartsWith("spvc_"))
{
bool bit = false;
if (parentSpelling.EndsWith("_flag_bits"))
{
parentSpelling.RemoveFromEnd("_flag_bits".Length);
bit = true;
}
if (spelling.EndsWith("_INT_MAX") || spelling.EndsWith("_MAX_INT"))
outString.Append("//");
if (spelling.StartsWith(parentSpelling, .OrdinalIgnoreCase))
spelling.RemoveFromStart(parentSpelling.Length);
else
break;
if (bit && spelling.EndsWith("_BIT"))
spelling.RemoveFromEnd(4);
if (spelling[0] == '_' && spelling[1].IsDigit)
outString.Append('_');
UpperSnakeCase2PascalCase(spelling, outString);
}
else if (parentSpelling.StartsWith("Spv"))
{
if (parentSpelling == "SpvOp_")
parentSpelling = "Spv";
if (parentSpelling.EndsWith('_'))
parentSpelling.RemoveFromEnd(1);
StringView suffix = null;
if (parentSpelling.EndsWith("Shift"))
suffix = "Shift";
else if (parentSpelling.EndsWith("Mask"))
suffix = "Mask";
parentSpelling.RemoveFromEnd(suffix.Length);
if (spelling.StartsWith(parentSpelling))
spelling.RemoveFromStart(parentSpelling.Length);
if (spelling.EndsWith(suffix))
spelling.RemoveFromEnd(suffix.Length);
else if (spelling.StartsWith(suffix))
spelling.RemoveFromStart(suffix.Length);
if (spelling == "Max")
outString.Append("//");
if (spelling[0].IsDigit)
outString.Append('_');
outString.Append(spelling);
}
else break;
return;
case .FunctionDecl:
if (!IsInstanceMethod(cursor)) break;
let arg = Clang.Cursor_GetArgument(cursor, 0);
let handle = GetTypeSpelling!(Clang.GetCursorType(arg));
var spelling = GetCursorSpelling!(cursor);
Runtime.Assert(spelling.StartsWith(handle));
spelling.RemoveFromStart(handle.Length + 1);
UpperSnakeCase2PascalCase(spelling, outString);
return;
default:
}
base.GetNameInBindings(cursor, outString);
}
protected override void WriteToken(CXToken token)
{
let spelling = GetTokenSpelling!(token);
if (Clang.GetTokenKind(token) == .Identifier && spelling == "spvc_bool")
str.Append("SpvcBool");
else if (Clang.GetTokenKind(token) == .Literal && spelling.Length == 9 && spelling.StartsWith("0x"))
str.Append("0x0", spelling[2...]);
else
base.WriteToken(token);
}
bool IsInstanceMethod(CXCursor cursor)
{
if (Clang.Cursor_GetNumArguments(cursor) < 1)
return false;
let arg = Clang.Cursor_GetArgument(cursor, 0);
let type = GetTypeSpelling!(Clang.GetCursorType(arg));
return handles.ContainsAlt(type);
}
protected override void Method_Parameters(CXCursor cursor)
{
if (IsInstanceMethod(cursor))
str.Append("this ");
base.Method_Parameters(cursor);
}
}
class Program
{
public static int Main(String[] args)
{
scope SpriVCrossGenerator(char8*[?]("--language=c")).Generate("../SPIRV-Cross/spirv_cross_c.h");
return 0;
}
}
+31
View File
@@ -0,0 +1,31 @@
using System;
using System.Interop;
using CxxBuildTool;
namespace SpirVCross;
struct SpvcBool : c_uchar
{
[Inline] public static operator bool(Self s) => s != SPVC_FALSE;
[Inline] public static operator Self(bool s) => s ? SPVC_TRUE : SPVC_FALSE;
}
extension SpvcResult
{
[NoShow(false), SkipCall, Warn("SpvcResult discarded")]
public void ReturnValueDiscarded();
}
static
{
[OnCompile(.TypeDone)]
private static void Build()
{
if (!Compiler.IsBuilding) return;
CxxBuildTool.Ninja(Compiler.ProjectDir + "/SPIRV-Cross", Compiler.BuildDir + "/" + Compiler.ProjectName, "spirv_cross", "",
"spirv_cfg.cpp", "spirv_cross_c.cpp", "spirv_glsl.cpp", "spirv_parser.cpp",
"spirv_cpp.cpp", "spirv_cross_parsed_ir.cpp", "spirv_hlsl.cpp", "spirv_reflect.cpp",
"spirv_cross.cpp", "spirv_cross_util.cpp", "spirv_msl.cpp");
}
}
+5616
View File
File diff suppressed because it is too large Load Diff
+1101
View File
File diff suppressed because it is too large Load Diff