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.Clear();
strBuffer.Append(decl, "\n{\n"); strBuffer.Append(decl, "\n{\n");
@@ -67,7 +67,8 @@ static class Metadata
{ {
if (@sig.Index != 0) strBuffer.Append('\n'); if (@sig.Index != 0) strBuffer.Append('\n');
StringView indent; StringView indent;
strBuffer.Append("\t", sig.sig); if (!sig.sig.IsNull)
strBuffer.Append("\tpublic ", sig.sig);
switch (sig.mode) switch (sig.mode)
{ {
case .Method: case .Method:
@@ -79,7 +80,7 @@ static class Metadata
{ {
"""); """);
case .Property: case .Property, .UniqueProperty:
indent = "\t\t\t"; indent = "\t\t\t";
strBuffer.Append(""" strBuffer.Append("""
@@ -92,7 +93,6 @@ static class Metadata
"""); """);
case .Cases: case .Cases:
indent = "\t"; indent = "\t";
strBuffer.Length--;
} }
for (let kv in this) for (let kv in this)
{ {
@@ -105,22 +105,25 @@ static class Metadata
{ {
case .Cases: case .Cases:
if (val != null) if (val != null)
strBuffer.Append(" = "); strBuffer.Append(" = ", val);
case .Method, .Property: strBuffer.Append(";\n");
strBuffer.Append(": return "); case .Method:
strBuffer.Append(":", val);
case .Property, .UniqueProperty:
strBuffer.Append(": return ", val, ";\n");
} }
strBuffer.Append(val, ";\n");
} }
switch (sig.mode) switch (sig.mode)
{ {
case .Method: case .Method:
strBuffer.Append(""" strBuffer.Append("""
default: return default; default:
Runtime.FatalError("Index out of range");
} }
} }
"""); """);
case .Property: case .Property, .UniqueProperty:
strBuffer.Append(""" strBuffer.Append("""
default: return default; 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: case .Cases:
} }
writer.Write(strBuffer);
strBuffer.Clear();
} }
strBuffer.Append("}\n\n"); strBuffer.Append("}\n\n");
writer.Write(strBuffer); writer.Write(strBuffer);
@@ -138,13 +180,17 @@ static class Metadata
public enum ApiVersion { Cases, FeatureStruct } public enum ApiVersion { Cases, FeatureStruct }
public static append EnumMetadata<ApiVersion> apiVersion; 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 static append EnumMetadata<Extensions> extensions;
public enum Features { Cases, ApiVersion, ExtensionStruct } public enum Features { Cases, ApiVersion, Extension }
public static append EnumMetadata<Features> features; public static append EnumMetadata<Features> features;
public enum TypeEnum { Type } public enum TypeEnum { Type }
public static append EnumMetadata<TypeEnum> vkStructureType; public static append EnumMetadata<TypeEnum> vkStructureType;
public static append EnumMetadata<TypeEnum> vkObjectType; 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 class VulkanFeature
@@ -352,6 +398,9 @@ class RegistryParser : XmlParser
Extensions, Extensions,
Extension, Extension,
Require, Require,
Formats,
Format,
} }
append List<Element> eStack = .(16); append List<Element> eStack = .(16);
@@ -436,7 +485,10 @@ class RegistryParser : XmlParser
append String handle_parent = .(64); append String handle_parent = .(64);
EnumFeature curEnum; EnumFeature curEnum;
int ext_number = -1; int ext_number = -1;
append String ext_tag = .(16);
append String ext_name = .(64);
class Param class Param
{ {
@@ -468,6 +520,9 @@ class RegistryParser : XmlParser
return param; return param;
} }
String format_name = command_rettype;
append List<String> format_components = .(4);
public override void StartElementHandler(char8* nameC, char8** attsC) public override void StartElementHandler(char8* nameC, char8** attsC)
{ {
HandleCData(); HandleCData();
@@ -589,8 +644,20 @@ class RegistryParser : XmlParser
eStack.Add(.Ignore); eStack.Add(.Ignore);
} }
case .Require: 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); vkOutput.Add(value);
}
eStack.Add(.Ignore); eStack.Add(.Ignore);
default: default:
eStack.Add(.Type); eStack.Add(.Type);
@@ -749,12 +816,13 @@ class RegistryParser : XmlParser
FeatureComment(); FeatureComment();
ext_number = int.Parse(atts["number"]); ext_number = int.Parse(atts["number"]);
let name = atts["name"]; ext_name.Set(atts["name"]);
if (!name.StartsWith("VK")) break; ext_tag.Set(atts.GetValueOrDefault("author"));
var value = Metadata.extensions.For(name); if (!ext_name.StartsWith("VK")) break;
var value = Metadata.extensions.For(ext_name);
value.At(.Cases) = new:alloc .(atts["number"]); value.At(.Cases) = new:alloc .(atts["number"]);
value.At(.Tag) = new:alloc $"\"{atts.GetValueOrDefault("author")}\""; value.At(.Tag) = new:alloc $"\"{ext_tag}\"";
value.At(.Name) = new:alloc $"nameof({name})"; value.At(.Name) = new:alloc $"nameof({ext_name})";
if (atts.TryGetValue("promotedto", let promotedto) && promotedto.StartsWith("VK_VERSION_")) if (atts.TryGetValue("promotedto", let promotedto) && promotedto.StartsWith("VK_VERSION_"))
value.At(.PromotedTo) = new:alloc $".{promotedto}"; value.At(.PromotedTo) = new:alloc $".{promotedto}";
switch (atts["type"]) switch (atts["type"])
@@ -766,13 +834,23 @@ class RegistryParser : XmlParser
command_rettype.Clear(); command_rettype.Clear();
if (atts.TryGetValue("depends", let depends)) if (atts.TryGetValue("depends", let depends))
{ {
strBuf.Set("Self[?]("); List<StringView> dependencies = scope .(8);
strBuf.Clear();
cdata.Clear(); cdata.Clear();
char8 lastOp = '\0'; char8 lastOp = '\0';
void Handle(char8 c) void Handle(char8 c)
{ {
mixin Version() { Runtime.Assert(command_rettype.IsEmpty); command_rettype.Set(cdata); } mixin Version()
mixin Extension() { strBuf.Append(cdata, ", "); } {
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) if (!cdata.IsEmpty)
{ {
@@ -808,17 +886,51 @@ class RegistryParser : XmlParser
Handle(c); Handle(c);
} }
Handle(lastOp); Handle(lastOp);
if (!strBuf.EndsWith('(')) value.At(.DependencyCount) = new:alloc .(dependencies.Count.ToString(..scope .(8)));
if (!dependencies.IsEmpty)
{ {
strBuf.Length -= 2; cdata.Set("""
strBuf.Append(')');
value.At(.Dependencies) = new:alloc .(strBuf); 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) if (command_rettype.IsEmpty)
command_rettype.Set("VK_VERSION_1_0"); command_rettype.Set("VK_VERSION_1_0");
value.At(.MinVersion) = new:alloc $".{command_rettype}"; value.At(.MinVersion) = new:alloc $".{command_rettype}";
case "require": eStack.Add(.Require); FeatureComment(); 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); default: eStack.Add(.Ignore);
} }
} }
@@ -989,9 +1101,8 @@ class RegistryParser : XmlParser
} }
else else
{ {
mode = .ExtensionStruct; mode = .Extension;
strBuf.Append(type_name); strBuf.Append(".ForFeatureStruct(", type_name, ".SType)");
strBuf.Append(".SType");
} }
String outputStr = new:alloc .(strBuf); String outputStr = new:alloc .(strBuf);
for (let field in fields) for (let field in fields)
@@ -1491,6 +1602,29 @@ class RegistryParser : XmlParser
} }
vkCommands.Add(feature.name, feature); 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: default:
} }
} }
@@ -1666,6 +1800,7 @@ class Program
public void LoadInstance(VkInstance instance) mut public void LoadInstance(VkInstance instance) mut
{ {
this.vkGetDeviceProcAddr = (.)(void*)vkGetInstanceProcAddr(instance, nameof(vkGetDeviceProcAddr));
"""); """);
LoadFunc("vkGetInstanceProcAddr", "instance", .Instance); LoadFunc("vkGetInstanceProcAddr", "instance", .Instance);
@@ -1748,28 +1883,38 @@ class Program
String strBuffer = scope .(1024); String strBuffer = scope .(1024);
Metadata.apiVersion.WriteToStream(strBuffer, writer, "enum VulkanApiVersion", Metadata.apiVersion.WriteToStream(strBuffer, writer, "enum VulkanApiVersion",
(null, .Cases), (null, .Cases),
("public VkStructureType FeatureStruct", .Property)); ("VkStructureType FeatureStruct", .UniqueProperty));
Metadata.extensions.WriteToStream(strBuffer, writer, "enum VulkanExtension", Metadata.extensions.WriteToStream(strBuffer, writer, "enum VulkanExtension",
(null, .Cases), (null, .Cases),
("public String Name", .Property), ("String Name", .UniqueProperty),
("public String Tag", .Property), ("String Tag", .Property),
("public Kind Kind", .Property), ("Kind Kind", .Property),
("public VulkanApiVersion MinVersion", .Property), ("VulkanApiVersion MinVersion", .Property),
("public VulkanApiVersion PromotedTo", .Property), ("VulkanApiVersion PromotedTo", .Property),
("public Span<VulkanExtension> Dependencies", .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", Metadata.features.WriteToStream(strBuffer, writer, "enum VulkanFeature",
(null, .Cases), (null, .Cases),
("public VulkanApiVersion ApiVersion", .Property), ("VulkanApiVersion ApiVersion", .Property),
("public VkStructureType ExtensionStruct", .Property)); ("VulkanExtension Extension", .Property));
writer.Write(""" writer.Write("""
namespace Vulkan; namespace Vulkan;
"""); """);
Metadata.vkStructureType.WriteToStream(strBuffer, writer, "extension VkStructureType", Metadata.vkStructureType.WriteToStream(strBuffer, writer, "extension VkStructureType",
("public Type Type", .Property)); ("Type Type", .UniqueProperty));
Metadata.vkObjectType.WriteToStream(strBuffer, writer, "extension VkObjectType", 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; return 0;

View File

@@ -2,6 +2,7 @@
using System; using System;
using System.Interop; using System.Interop;
using System.Collections;
namespace Vulkan; namespace Vulkan;
@@ -17,7 +18,7 @@ static
#if BF_PLATFORM_WINDOWS #if BF_PLATFORM_WINDOWS
.Stdcall; .Stdcall;
#else #else
.Cdecl; .Unspecified;
#endif #endif
public const let VK_NULL_HANDLE = 0; public const let VK_NULL_HANDLE = 0;
@@ -29,11 +30,43 @@ extension VkResult
public void ReturnValueDiscarded(); 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; namespace Vulkan.Metadata;
extension VulkanExtension extension VulkanExtension
{ {
public enum Kind { Instance, Device } 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; namespace Vulkan.External;

View File

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

File diff suppressed because it is too large Load Diff