finalized

This commit is contained in:
2026-04-14 14:01:37 +02:00
parent 777e60c8a6
commit 2310ab969f
4 changed files with 7932 additions and 837 deletions

View File

@@ -59,7 +59,7 @@ static class Metadata
}
}
public void WriteToStream(String strBuffer, StreamWriter writer, StringView decl, params Span<(StringView sig, enum { Method, Property, Cases } mode)> methodSigs)
public void WriteToStream(String strBuffer, StreamWriter writer, StringView decl, params Span<(StringView sig, enum { Method, Property, UniqueProperty, Cases } mode)> methodSigs)
{
strBuffer.Clear();
strBuffer.Append(decl, "\n{\n");
@@ -67,7 +67,8 @@ static class Metadata
{
if (@sig.Index != 0) strBuffer.Append('\n');
StringView indent;
strBuffer.Append("\t", sig.sig);
if (!sig.sig.IsNull)
strBuffer.Append("\tpublic ", sig.sig);
switch (sig.mode)
{
case .Method:
@@ -79,7 +80,7 @@ static class Metadata
{
""");
case .Property:
case .Property, .UniqueProperty:
indent = "\t\t\t";
strBuffer.Append("""
@@ -92,7 +93,6 @@ static class Metadata
""");
case .Cases:
indent = "\t";
strBuffer.Length--;
}
for (let kv in this)
{
@@ -105,22 +105,25 @@ static class Metadata
{
case .Cases:
if (val != null)
strBuffer.Append(" = ");
case .Method, .Property:
strBuffer.Append(": return ");
strBuffer.Append(" = ", val);
strBuffer.Append(";\n");
case .Method:
strBuffer.Append(":", val);
case .Property, .UniqueProperty:
strBuffer.Append(": return ", val, ";\n");
}
strBuffer.Append(val, ";\n");
}
switch (sig.mode)
{
case .Method:
strBuffer.Append("""
default: return default;
default:
Runtime.FatalError("Index out of range");
}
}
""");
case .Property:
case .Property, .UniqueProperty:
strBuffer.Append("""
default: return default;
}
@@ -128,8 +131,47 @@ static class Metadata
}
""");
if (_ == .UniqueProperty)
{
writer.Write(strBuffer);
strBuffer.Clear();
var iter = sig.sig.Split(' ');
StringView type = iter.GetNext();
bool string = false;
if (type == "String") { type = "StringView"; string = true; }
StringView name = iter.GetNext();
strBuffer.Append("""
[Optimize] public static Self For
""", name, "(", type, """
val)
{
Self output = 0;
""");
if (string) strBuffer.Append("\t\tint hash = val.GetHashCode();\n");
for (let kv in this)
{
if (kv.value.predicate != null && *kv.value.predicate != .AlreadyWritten)
continue;
let val = kv.value.underlying.[Friend]mVal[@sig.Index];
if (val == null) continue;
strBuffer.Append("\t\tif (");
if (string)
strBuffer.AppendF($"hash == {val.GetHashCode()} && ");
strBuffer.Append("val == ", val, ") output = ", kv.key, ";\n");
}
strBuffer.Append("""
return output;
}
""");
}
case .Cases:
}
writer.Write(strBuffer);
strBuffer.Clear();
}
strBuffer.Append("}\n\n");
writer.Write(strBuffer);
@@ -138,13 +180,17 @@ static class Metadata
public enum ApiVersion { Cases, FeatureStruct }
public static append EnumMetadata<ApiVersion> apiVersion;
public enum Extensions { Cases, Name, Tag, Kind, MinVersion, PromotedTo, Dependencies }
public enum Extensions { Cases, Name, Tag, Kind, MinVersion, PromotedTo, FeatureStruct, DependencyCount, GetDependency }
public static append EnumMetadata<Extensions> extensions;
public enum Features { Cases, ApiVersion, ExtensionStruct }
public enum Features { Cases, ApiVersion, Extension }
public static append EnumMetadata<Features> features;
public enum TypeEnum { Type }
public static append EnumMetadata<TypeEnum> vkStructureType;
public static append EnumMetadata<TypeEnum> vkObjectType;
public enum Formats { Size, ComponentCount, GetComponent }
public static append EnumMetadata<Formats> vkFormat;
public enum CasesOnlyEnum { Cases }
public static append EnumMetadata<CasesOnlyEnum> vkFormatComponentNumericFormat;
}
class VulkanFeature
@@ -352,6 +398,9 @@ class RegistryParser : XmlParser
Extensions,
Extension,
Require,
Formats,
Format,
}
append List<Element> eStack = .(16);
@@ -436,7 +485,10 @@ class RegistryParser : XmlParser
append String handle_parent = .(64);
EnumFeature curEnum;
int ext_number = -1;
append String ext_tag = .(16);
append String ext_name = .(64);
class Param
{
@@ -468,6 +520,9 @@ class RegistryParser : XmlParser
return param;
}
String format_name = command_rettype;
append List<String> format_components = .(4);
public override void StartElementHandler(char8* nameC, char8** attsC)
{
HandleCData();
@@ -589,8 +644,20 @@ class RegistryParser : XmlParser
eStack.Add(.Ignore);
}
case .Require:
if (vkTypes.TryGetValue(atts["name"], let value))
let name = atts["name"];
if (vkTypes.TryGetValue(name, let value))
{
if (eStack[^2] == .Extension &&
name.StartsWith("VkPhysicalDevice") &&
name.EndsWith(ext_tag) &&
name[..<^ext_tag.Length].EndsWith("Features"))
{
strBuf.Clear();
strBuf.Append(name, ".SType");
Metadata.extensions.For(ext_name).At(.FeatureStruct) = new:alloc .(strBuf);
}
vkOutput.Add(value);
}
eStack.Add(.Ignore);
default:
eStack.Add(.Type);
@@ -749,12 +816,13 @@ class RegistryParser : XmlParser
FeatureComment();
ext_number = int.Parse(atts["number"]);
let name = atts["name"];
if (!name.StartsWith("VK")) break;
var value = Metadata.extensions.For(name);
ext_name.Set(atts["name"]);
ext_tag.Set(atts.GetValueOrDefault("author"));
if (!ext_name.StartsWith("VK")) break;
var value = Metadata.extensions.For(ext_name);
value.At(.Cases) = new:alloc .(atts["number"]);
value.At(.Tag) = new:alloc $"\"{atts.GetValueOrDefault("author")}\"";
value.At(.Name) = new:alloc $"nameof({name})";
value.At(.Tag) = new:alloc $"\"{ext_tag}\"";
value.At(.Name) = new:alloc $"nameof({ext_name})";
if (atts.TryGetValue("promotedto", let promotedto) && promotedto.StartsWith("VK_VERSION_"))
value.At(.PromotedTo) = new:alloc $".{promotedto}";
switch (atts["type"])
@@ -766,13 +834,23 @@ class RegistryParser : XmlParser
command_rettype.Clear();
if (atts.TryGetValue("depends", let depends))
{
strBuf.Set("Self[?](");
List<StringView> dependencies = scope .(8);
strBuf.Clear();
cdata.Clear();
char8 lastOp = '\0';
void Handle(char8 c)
{
mixin Version() { Runtime.Assert(command_rettype.IsEmpty); command_rettype.Set(cdata); }
mixin Extension() { strBuf.Append(cdata, ", "); }
mixin Version()
{
Runtime.Assert(command_rettype.IsEmpty);
command_rettype.Set(cdata);
}
mixin Extension()
{
int index = strBuf.Length;
strBuf.Append(cdata);
dependencies.Add(strBuf[index...]);
}
if (!cdata.IsEmpty)
{
@@ -808,17 +886,51 @@ class RegistryParser : XmlParser
Handle(c);
}
Handle(lastOp);
if (!strBuf.EndsWith('('))
value.At(.DependencyCount) = new:alloc .(dependencies.Count.ToString(..scope .(8)));
if (!dependencies.IsEmpty)
{
strBuf.Length -= 2;
strBuf.Append(')');
value.At(.Dependencies) = new:alloc .(strBuf);
cdata.Set("""
switch (idx)
{
""");
for (let dep in dependencies)
{
cdata.Append("\t\t\tcase ");
@dep.Index.ToString(cdata);
cdata.Append(": return ", dep, ";\n");
}
cdata.Append("""
default: Runtime.FatalError("Index out of range");
}
""");
value.At(.GetDependency) = new:alloc .(cdata);
}
cdata.Clear();
}
if (command_rettype.IsEmpty)
command_rettype.Set("VK_VERSION_1_0");
value.At(.MinVersion) = new:alloc $".{command_rettype}";
case "require": eStack.Add(.Require); FeatureComment();
case "formats": eStack.Add(.Formats);
case "format" when eStack.Back == .Formats:
format_name.Set(atts["name"]);
format_components.Clear();
let clazz = atts["class"];
if (clazz.EndsWith("-bit"))
Metadata.vkFormat.For(format_name).At(.Size) = new:alloc .(clazz[...^5]);
eStack.Add(.Format);
case "component" when eStack.Back == .Format:
let name = atts["name"];
let bits = atts["bits"];
let numericFormat = atts["numericFormat"];
format_components.Add(new $".(.{name}, {(bits == "compressed") ? "null" : bits}, .{numericFormat})");
Metadata.vkFormatComponentNumericFormat.For(numericFormat).At(.Cases) = null;
eStack.Add(.Ignore);
default: eStack.Add(.Ignore);
}
}
@@ -989,9 +1101,8 @@ class RegistryParser : XmlParser
}
else
{
mode = .ExtensionStruct;
strBuf.Append(type_name);
strBuf.Append(".SType");
mode = .Extension;
strBuf.Append(".ForFeatureStruct(", type_name, ".SType)");
}
String outputStr = new:alloc .(strBuf);
for (let field in fields)
@@ -1491,6 +1602,29 @@ class RegistryParser : XmlParser
}
vkCommands.Add(feature.name, feature);
case .Format:
let value = Metadata.vkFormat.For(format_name);
value.At(.ComponentCount) = new:alloc .(format_components.Count.ToString(..scope .(1)));
strBuf.Clear();
strBuf.Append("""
switch (idx)
{
""");
for (let componet in format_components)
{
strBuf.Append("\t\t\tcase ");
@componet.Index.ToString(strBuf);
strBuf.Append(": return ", componet, ";\n");
delete componet;
}
strBuf.Append("""
default: Runtime.FatalError("Index out of range");
}
""");
value.At(.GetComponent) = new:alloc .(strBuf);
default:
}
}
@@ -1666,6 +1800,7 @@ class Program
public void LoadInstance(VkInstance instance) mut
{
this.vkGetDeviceProcAddr = (.)(void*)vkGetInstanceProcAddr(instance, nameof(vkGetDeviceProcAddr));
""");
LoadFunc("vkGetInstanceProcAddr", "instance", .Instance);
@@ -1748,28 +1883,38 @@ class Program
String strBuffer = scope .(1024);
Metadata.apiVersion.WriteToStream(strBuffer, writer, "enum VulkanApiVersion",
(null, .Cases),
("public VkStructureType FeatureStruct", .Property));
("VkStructureType FeatureStruct", .UniqueProperty));
Metadata.extensions.WriteToStream(strBuffer, writer, "enum VulkanExtension",
(null, .Cases),
("public String Name", .Property),
("public String Tag", .Property),
("public Kind Kind", .Property),
("public VulkanApiVersion MinVersion", .Property),
("public VulkanApiVersion PromotedTo", .Property),
("public Span<VulkanExtension> Dependencies", .Property));
("String Name", .UniqueProperty),
("String Tag", .Property),
("Kind Kind", .Property),
("VulkanApiVersion MinVersion", .Property),
("VulkanApiVersion PromotedTo", .Property),
("VkStructureType FeatureStruct", .UniqueProperty),
("int DependencyCount", .Property),
("VulkanExtension GetDependency(int idx)", .Method));
Metadata.features.Values.GetNextRef()->At(.Cases) = "1";
Metadata.features.WriteToStream(strBuffer, writer, "enum VulkanFeature",
(null, .Cases),
("public VulkanApiVersion ApiVersion", .Property),
("public VkStructureType ExtensionStruct", .Property));
("VulkanApiVersion ApiVersion", .Property),
("VulkanExtension Extension", .Property));
writer.Write("""
namespace Vulkan;
""");
Metadata.vkStructureType.WriteToStream(strBuffer, writer, "extension VkStructureType",
("public Type Type", .Property));
("Type Type", .UniqueProperty));
Metadata.vkObjectType.WriteToStream(strBuffer, writer, "extension VkObjectType",
("public Type Type", .Property));
("Type Type", .UniqueProperty));
Metadata.vkFormatComponentNumericFormat.WriteToStream(strBuffer, writer, "extension VkFormat { extension Component { public enum NumericFormat",
(null, .Cases));
writer.Write("}}");
Metadata.vkFormat.WriteToStream(strBuffer, writer, "extension VkFormat",
("int? Size", .Property),
("int ComponentCount", .Property),
("Component GetComponent(int idx)", .Method));
}
return 0;

View File

@@ -2,6 +2,7 @@
using System;
using System.Interop;
using System.Collections;
namespace Vulkan;
@@ -17,7 +18,7 @@ static
#if BF_PLATFORM_WINDOWS
.Stdcall;
#else
.Cdecl;
.Unspecified;
#endif
public const let VK_NULL_HANDLE = 0;
@@ -29,11 +30,43 @@ extension VkResult
public void ReturnValueDiscarded();
}
extension VkFormat
{
public struct Component : this(Channel channel, int? bits, NumericFormat numericFormat)
{
public enum Channel { R, G, B, A, D, S }
}
//public struct ChromaSubsamplingInfo : this(int luma, int chroma1, int chroma2);
}
namespace Vulkan.Metadata;
extension VulkanExtension
{
public enum Kind { Instance, Device }
public struct DependencyIterator : IEnumerator<VulkanExtension>
{
public VulkanExtension ext;
public int index;
public int count;
public this(VulkanExtension ext)
{
this.ext = ext;
this.index = 0;
this.count = ext.DependencyCount;
}
public Result<VulkanExtension> GetNext() mut
{
if (index >= count) return .Err;
return .Ok(ext.GetDependency(index++));
}
}
public DependencyIterator Dependencies => .(this);
}
namespace Vulkan.External;

View File

@@ -801,6 +801,7 @@ struct VulkanLoadedFunctions
public void LoadInstance(VkInstance instance) mut
{
this.vkGetDeviceProcAddr = (.)(void*)vkGetInstanceProcAddr(instance, nameof(vkGetDeviceProcAddr));
vkDestroyInstance = (.)(void*)vkGetInstanceProcAddr(instance, nameof(vkDestroyInstance));
vkEnumeratePhysicalDevices = (.)(void*)vkGetInstanceProcAddr(instance, nameof(vkEnumeratePhysicalDevices));
vkGetInstanceProcAddr = (.)(void*)vkGetInstanceProcAddr(instance, nameof(vkGetInstanceProcAddr));

File diff suppressed because it is too large Load Diff