add features

This commit is contained in:
Rune
2026-03-30 14:39:44 +02:00
parent 486babcf0d
commit 777e60c8a6
8 changed files with 1437 additions and 146 deletions

View File

@@ -1,6 +1,9 @@
FileVersion = 1
Dependencies = {corlib = "*", Expat = "*"}
[Project]
Name = "Vulkan.Setup"
StartupObject = "Vulkan.Setup.Program"
[Dependencies]
corlib = "*"
"Expat.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Expat.git"}

View File

@@ -1,5 +1,8 @@
FileVersion = 1
Projects = {"Vulkan.Setup" = {Path = "."}, Expat = {Path = "../../../RandomStuff/Cpp2Beef/Bindings/Expat"}}
[Workspace]
StartupProject = "Vulkan.Setup"
[Projects]
"Vulkan.Setup" = {Path = "."}
"Expat.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Expat.git"}

View File

@@ -0,0 +1,6 @@
FileVersion = 1
[Locks."Expat.git".Git]
URL = "https://git.unicon-gmbh.de/BeefBindings/Expat.git"
Tag = ""
Hash = "97c80cd88dd68f4a70922c7b0bad0b27f86aa3c6"

View File

@@ -99,12 +99,13 @@ static class Metadata
if (kv.value.predicate != null && *kv.value.predicate != .AlreadyWritten)
continue;
let val = kv.value.underlying.[Friend]mVal[@sig.Index];
if (val == null) continue;
if (val == null && sig.mode != .Cases) continue;
strBuffer.Append(indent, "case ", kv.key);
switch (sig.mode)
{
case .Cases:
strBuffer.Append(" = ");
if (val != null)
strBuffer.Append(" = ");
case .Method, .Property:
strBuffer.Append(": return ");
}
@@ -135,10 +136,12 @@ static class Metadata
}
}
public enum PureEnum { Cases }
public static append EnumMetadata<PureEnum> apiVersion;
public enum ApiVersion { Cases, FeatureStruct }
public static append EnumMetadata<ApiVersion> apiVersion;
public enum Extensions { Cases, Name, Tag, Kind, MinVersion, PromotedTo, Dependencies }
public static append EnumMetadata<Extensions> extensions;
public enum Features { Cases, ApiVersion, ExtensionStruct }
public static append EnumMetadata<Features> features;
public enum TypeEnum { Type }
public static append EnumMetadata<TypeEnum> vkStructureType;
public static append EnumMetadata<TypeEnum> vkObjectType;
@@ -441,7 +444,7 @@ class RegistryParser : XmlParser
public append String type;
public append String length;
public append String call;
public enum { None = 0, Optional = 1, Const = 2, OutParam = 4, OutArrayLen = 8, OutArrayPtr = 16 } flags;
public enum { None = 0, Optional = 1, Const = 2, OutParam = 4, OutArrayLen = 8, OutArrayPtr = 16, SpanLen = 32, SpanPtr = 64 } flags;
public void Clear()
{
@@ -562,8 +565,8 @@ class RegistryParser : XmlParser
case "define":
strBuf.Clear();
eStack.Add(.Type_Define);
case (.)default:
/*if (atts.TryGetValue("requires", let requires) && requires != "stdint" && requires != "vk_platform" && !requires.StartsWith("vk_video/"))
/*case (.)default:
if (atts.TryGetValue("requires", let requires) && requires != "stdint" && requires != "vk_platform" && !requires.StartsWith("vk_video/"))
{
PregeneratedFeature feature = new:alloc .() { kind = .TypeAlias };
InitTypeFeature(feature);
@@ -580,8 +583,8 @@ class RegistryParser : XmlParser
}
feature.content = new:alloc .(strBuf);
vkOutput.Add(feature);
}*/
fallthrough;
}
fallthrough;*/
default:
eStack.Add(.Ignore);
}
@@ -732,7 +735,15 @@ class RegistryParser : XmlParser
case "name": eStack.Add(.Name);
case "extensions": eStack.Add(.Extensions);
case "feature": eStack.Add(.Feature); FeatureComment();
case "feature":
switch (eStack.Back)
{
case .Registry:
eStack.Add(.Feature);
FeatureComment();
default:
eStack.Add(.Ignore);
}
case "extension":
eStack.Add(.Extension);
FeatureComment();
@@ -957,6 +968,39 @@ class RegistryParser : XmlParser
PregeneratedFeature feature = new:alloc .() { kind = .HasBody };
InitTypeFeature(feature);
if (type_name.StartsWith("VkPhysicalDevice") && type_name.Contains("Features") && type_name != "VkPhysicalDeviceFeatures2")
{
Metadata.Features mode;
strBuf.Clear();
if (type_name == "VkPhysicalDeviceFeatures")
{
mode = .ApiVersion;
strBuf.Append(".VK_VERSION_1_0");
}
else if (type_name.StartsWith("VkPhysicalDeviceVulkan1"))
{
mode = .ApiVersion;
strBuf.Append(".VK_VERSION_1_");
for (let c in type_name["VkPhysicalDeviceVulkan1".Length...])
{
if (!c.IsDigit) continue;
strBuf.Append(c);
}
}
else
{
mode = .ExtensionStruct;
strBuf.Append(type_name);
strBuf.Append(".SType");
}
String outputStr = new:alloc .(strBuf);
for (let field in fields)
{
if (field.type != "VkBool32") continue;
Metadata.features.For(field.name, &feature.kind).At(mode) = outputStr;
}
}
{
Dictionary<StringView, (int lens, Field field, Field lenField)> dict = scope .((.)fields.Count);
for (let field in fields)
@@ -964,6 +1008,8 @@ class RegistryParser : XmlParser
if (field.flags.HasFlag(.CommentOnly)) continue;
dict.Add(field.name, (0, field, null));
if (field.length.IsEmpty) continue;
if (field.length.EndsWith(",null-terminated"))
field.length.Length -= (",null-terminated".Length);
if (!dict.TryGetRef(field.length, ?, let value)) continue;
value.lens++;
value.lenField = field;
@@ -1049,7 +1095,10 @@ class RegistryParser : XmlParser
continue;
}
strBuf.Append("\tpublic ", field.type, " ", field.name);
strBuf.Append("\tpublic ");
if (@field.Count == 3 && @field.Index == 2 && type_name.EndsWith('2') && !handles.ContainsKey(field.type))
strBuf.Append("using public ");
strBuf.Append(field.type, " ", field.name);
if (field.values.IsEmpty)
strBuf.Append(" = ", DefaultValueForType(field.type));
else
@@ -1167,14 +1216,25 @@ class RegistryParser : XmlParser
}
else
strBuf.Replace("#define", "static { public const let ");
if (feature.name.StartsWith("VK_API_VERSION_") && feature.name[^1].IsDigit)
Metadata.apiVersion.For(scope String(feature.name)..Replace("_API_", "_")).At(.Cases) = feature.name;
feature.content = new:alloc .(strBuf);
if (feature.name.StartsWith("VK_API_VERSION_") && feature.name[^1].IsDigit)
{
let value = Metadata.apiVersion.For(scope String(feature.name)..Replace("_API_", "_"));
value.At(.Cases) = feature.name;
strBuf.Set("VkPhysicalDeviceVulkan");
for (let c in feature.name["VK_API_VERSION_".Length...])
if (c != '_')
strBuf.Append(c);
strBuf.Append("Features.SType");
if (strBuf == "VkPhysicalDeviceVulkan10Features.SType")
strBuf.Set("VkPhysicalDeviceFeatures2.SType");
value.At(.FeatureStruct) = new:alloc .(strBuf);
}
vkTypes.Add(feature.name, feature);
case .Type_FuncPtr:
PregeneratedFeature feature = new:alloc .() { kind = .HasBody };
InitTypeFeature(feature);
strBuf.Replace("const ", "");
strBuf.Replace("const ", "/***/ ");
strBuf.Replace("(VKAPI_PTR *", "");
strBuf.Replace(")(", "(");
strBuf.Remove(0, "typedef".Length);
@@ -1193,19 +1253,37 @@ class RegistryParser : XmlParser
{
defer { lastParam = param; }
param.call.Set(param.name);
if (param.flags.HasFlag(.Const) || !param.type.EndsWith('*')) continue;
if (lastParam?.name == param.length && lastParam?.flags.HasFlag(.OutParam) == true)
if (!param.type.EndsWith('*')) continue;
if (lastParam != null)
{
lastParam.flags |= .OutArrayLen;
param.flags |= .OutArrayPtr;
hasOutArray = true;
continue;
}
if (lastParam?.flags.HasFlag(.OutArrayPtr) == true)
{
param.flags |= .OutArrayPtr;
continue;
if (lastParam.name == param.length)
{
if (lastParam.flags.HasFlag(.OutParam))
{
lastParam.flags |= .OutArrayLen;
param.flags |= .OutArrayPtr;
hasOutArray = true;
}
else
{
lastParam.flags |= .SpanLen;
param.flags |= .SpanPtr;
}
continue;
}
if (lastParam.flags.HasFlag(.OutArrayPtr))
{
param.flags |= .OutArrayPtr;
continue;
}
if (lastParam.flags.HasFlag(.SpanPtr))
{
parameters[@param.Index - 2].flags &= ~.SpanLen;
lastParam.flags &= ~.SpanPtr;
}
}
if (param.flags.HasFlag(.Const)) continue;
param.type.Length--;
param.type.Insert(0, "out ");
param.call.Insert(0, "out ");
@@ -1227,6 +1305,23 @@ class RegistryParser : XmlParser
strBuf.Append(");");
feature.content = new:alloc .(strBuf);
for (let param in parameters)
{
if (param.flags.HasFlag(.SpanLen))
{
param.call.Set("(.)");
param.call.Append(parameters[@param.Index + 1].name);
param.call.Append(".Length");
}
if (param.flags.HasFlag(.SpanPtr))
{
param.call.Append(".Ptr");
param.type.Length--;
param.type.Insert(0, "Span<");
param.type.Append('>');
}
}
int handleIndex = -1;
handle: do
{
@@ -1266,7 +1361,7 @@ class RegistryParser : XmlParser
for (let param in parameters)
{
int idx = @param.Index;
if (idx == handleIndex) continue;
if (idx == handleIndex || param.flags.HasFlag(.SpanLen)) continue;
if (handleIndex != -1 || idx != 0) strBuf.Append(", ");
strBuf.Append(param.type, " ", param.name);
@@ -1303,7 +1398,7 @@ class RegistryParser : XmlParser
{
int idx = @param.Index;
if (idx == handleIndex) continue;
if (param.flags.HasFlag(.OutArrayLen)) continue;
if (param.flags.HasFlag(.OutArrayLen) || param.flags.HasFlag(.SpanLen)) continue;
if (writeComma) strBuf.Append(", ");
writeComma = true;
@@ -1652,7 +1747,8 @@ class Program
""");
String strBuffer = scope .(1024);
Metadata.apiVersion.WriteToStream(strBuffer, writer, "enum VulkanApiVersion",
(null, .Cases));
(null, .Cases),
("public VkStructureType FeatureStruct", .Property));
Metadata.extensions.WriteToStream(strBuffer, writer, "enum VulkanExtension",
(null, .Cases),
("public String Name", .Property),
@@ -1661,6 +1757,10 @@ class Program
("public VulkanApiVersion MinVersion", .Property),
("public VulkanApiVersion PromotedTo", .Property),
("public Span<VulkanExtension> Dependencies", .Property));
Metadata.features.WriteToStream(strBuffer, writer, "enum VulkanFeature",
(null, .Cases),
("public VulkanApiVersion ApiVersion", .Property),
("public VkStructureType ExtensionStruct", .Property));
writer.Write("""
namespace Vulkan;