Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .silktouch/openal-clangsharp.stout
Binary file not shown.
Binary file modified .silktouch/opengl-clangsharp.stout
Binary file not shown.
Binary file modified .silktouch/vulkan-clangsharp.stout
Binary file not shown.
2 changes: 1 addition & 1 deletion sources/OpenAL/OpenAL/Enums/ALCEnum.gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Silk.NET.OpenAL;

[NativeName("ALCEnum")]
[NativeName("ALCenum")]
public enum ALCEnum : uint
{
[NativeName("ALC_INVALID")]
Expand Down
2 changes: 1 addition & 1 deletion sources/OpenAL/OpenAL/Enums/ALEnum.gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Silk.NET.OpenAL;

[NativeName("ALEnum")]
[NativeName("ALenum")]
public enum ALEnum : uint
{
[NativeName("AL_NONE")]
Expand Down
2 changes: 1 addition & 1 deletion sources/OpenGL/OpenGL/Enums/GLEnum.gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Silk.NET.OpenGL;

[NativeName("GLEnum")]
[NativeName("GLenum")]
public enum GLEnum : uint
{
[NativeName("GL_DEPTH_BUFFER_BIT")]
Expand Down
101 changes: 63 additions & 38 deletions sources/SilkTouch/SilkTouch/Mods/MixKhronosData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,6 @@ public async Task InitializeAsync(IModContext ctx, CancellationToken ct = defaul
job.TypeMap.TryAdd("uint32_t", "uint");
job.TypeMap.TryAdd("int64_t", "long");
job.TypeMap.TryAdd("uint64_t", "ulong");
job.TypeMap.TryAdd("GLenum", "uint");
job.TypeMap.TryAdd("GLbitfield", "uint");
if (specPath is null)
{
// No metadata, can't continue. It'd be odd if the Khronos mod is being used in this case. There was once
Expand Down Expand Up @@ -1986,16 +1984,18 @@ public override SyntaxNode VisitDelegateDeclaration(DelegateDeclarationSyntax no
// Trimming is done by PrettifyNames, if PrettifyNames is configured to do so
public override SyntaxNode VisitEnumDeclaration(EnumDeclarationSyntax node)
{
var typeName = node.AttributeLists.GetNativeNameOrDefault(node.Identifier);
var groupInfo = job.Groups.GetValueOrDefault(typeName);
var nativeTypeName = node.AttributeLists.GetNativeNameOrDefault(node.Identifier);
var managedTypeName = node.Identifier.Text;

var typeVendor = job.Vendors.FirstOrDefault(typeName.EndsWith);
var groupInfo = job.Groups.GetValueOrDefault(managedTypeName);

var typeVendor = job.Vendors.FirstOrDefault(nativeTypeName.EndsWith);
var hasTypeSuffix = typeVendor != null;
var vendorAffixType = "KhronosVendor";

// Identify the namespace enum
// Eg: GLEnum, ALEnum
if (groupInfo?.Namespace != null && typeName == $"{groupInfo.Namespace}Enum")
if (groupInfo?.Namespace != null && nativeTypeName == $"{groupInfo.Namespace}enum")
{
node = node.WithAttributeLists(
node.AttributeLists.AddNamePrefix("KhronosNamespaceEnum", groupInfo.Namespace)
Expand Down Expand Up @@ -2023,7 +2023,8 @@ public override SyntaxNode VisitEnumDeclaration(EnumDeclarationSyntax node)
// Trimming both would cause conflicts.
// Trimming one but not the other would imply one is core and the other is not.
var hasMultipleVersions =
job.Groups.Count(x => x.Key.StartsWith(typeName[..^typeVendor.Length])) > 1;
job.Groups.Count(x => x.Key.StartsWith(nativeTypeName[..^typeVendor.Length]))
> 1;
var isSafeToTrimType = !hasMultipleVersions;

// Identify the affix for trimming if the type vendor suffix does not match the identified exclusive vendor suffix
Expand Down Expand Up @@ -2139,16 +2140,34 @@ public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
[SuppressMessage("ReSharper", "MoveLocalFunctionAfterJumpStatement")]
internal void ReadGroups(XDocument doc, JobData data, HashSet<string> vendors)
{
// For reference:
// Khronos XMLs specify enums in the following format
// <registry> - Top level element.
// <enums> - Main enum group.
// <enum> - Enum member.
//
// Each API has slight variations in how the XML is structured.
//
// Main enum group:
// Either has the "group" and "namespace" properties (OpenGL-style).
// Or has the "name" property.
//
// Enum member:
// The "group" property specifies a list of additional OpenGL-style groups the enum member belongs to.

// Designed to be compatible with OpenGL, EGL, WGL, GLX, and OpenCL.
// This will work for Vulkan as well, but for Vulkan the enums are actually "typedef enum"s in the headers and
// therefore the result of this function will go mostly ignored.
// This will work for Vulkan as well, but for Vulkan the enums are actually "typedef enum"s in the headers.
// This means that for Vulkan, this means that instead of using this information to directly generate the enums
// this information will mostly be used to enhance the enums scraped from the headers (eg: native name and bitmask information).
var anyNamespaced =
doc.Element("registry")?.Elements("enums").Attributes("namespace").Any() ?? false;
var anyGLStyleGroups =
doc.Element("registry")?.Elements("enums").Elements("enum").Attributes("group").Any()
?? false;
var likelyOpenCL = false; // OpenCL specific
var topLevelIntentionalExclusions = new HashSet<string>(); // OpenCL specific

// Parse enum groups
foreach (var block in doc.Element("registry")?.Elements("enums") ?? [])
{
// Is it a bitmask?
Expand All @@ -2162,11 +2181,14 @@ internal void ReadGroups(XDocument doc, JobData data, HashSet<string> vendors)
: null;
var nativeName = groupName;

// OpenGL-style enums have an uint base type
var baseType = anyGLStyleGroups ? "uint" : null;

// Create an ungrouped group as well i.e. GLEnum, WGLEnum, etc
if (enumNamespace is not null)
{
groupName ??= $"{enumNamespace}Enum";
nativeName ??= enumNamespace;
nativeName ??= $"{enumNamespace}enum";
}

// OpenCL enum name
Expand All @@ -2176,8 +2198,8 @@ internal void ReadGroups(XDocument doc, JobData data, HashSet<string> vendors)
}

// Vulkan/OpenXR enum name
nativeName ??= groupName;
groupName = groupName?.Replace("FlagBits", "Flags");
nativeName ??= groupName;

// Skip Vulkan API Constants since it is not an enum
if (block.Attribute("type")?.Value == "constants")
Expand Down Expand Up @@ -2207,7 +2229,28 @@ static bool IsUngroupable(string groupName) =>
FixupGroupNameForOpenCL(ref groupName, ref likelyOpenCL, ref isBitmask);
}

// Mark the enums
// Initialize the group before enum members are parsed below
// This ensures two things:
// 1. The native name is correct
// 2. Empty groups are recorded properly
if (
groupName != null
&& !IsUngroupable(groupName)
&& !data.Groups.ContainsKey(groupName)
)
{
data.Groups[groupName] = new EnumGroup(
groupName,
nativeName,
baseType,
[],
isBitmask,
VendorFromString(groupName, vendors),
enumNamespace
);
}

// Parse enum members
foreach (var @enum in block.Elements("enum"))
{
var enumName =
Expand All @@ -2225,7 +2268,7 @@ static bool IsUngroupable(string groupName) =>
data.EnumsToGroups[enumName] = enumToGroups = [];
}

// OpenGL-style groups
// Parse OpenGL-style groups
var glGroups = @enum
.Attribute("group")
?.Value.Split(
Expand All @@ -2236,12 +2279,12 @@ static bool IsUngroupable(string groupName) =>
// Get the vendor (if the enum name ends with a vendor that is).
var thisVendor = VendorFromString(enumName, vendors);

foreach (
var group in (groupName is null ? Enumerable.Empty<string>() : [groupName])
.Concat(glGroups ?? [])
.Concat(block.Attribute("group")?.Value is { Length: > 0 } g ? [g] : [])
.Distinct()
)
// Add the enum member to the namespace enum, the main enum group, and its additional OpenGL-style groups
var memberGroups = (groupName is null ? Enumerable.Empty<string>() : [groupName])
.Concat(block.Attribute("group")?.Value is { Length: > 0 } g ? [g] : [])
.Concat(glGroups ?? [])
.Distinct();
foreach (var group in memberGroups)
{
if (IsUngroupable(group))
{
Expand All @@ -2265,7 +2308,7 @@ var group in (groupName is null ? Enumerable.Empty<string>() : [groupName])
: new EnumGroup(
group,
group,
anyGLStyleGroups ? "GLenum" : null,
baseType,
[],
isBitmask,
thisVendor,
Expand All @@ -2276,24 +2319,6 @@ var group in (groupName is null ? Enumerable.Empty<string>() : [groupName])
enumToGroups.Add(group);
}
}

// Some enum groups don't have members, meaning that the code above won't catch them
if (
groupName != null
&& !IsUngroupable(groupName)
&& !data.Groups.ContainsKey(groupName)
)
{
data.Groups[groupName] = new EnumGroup(
groupName,
nativeName,
null,
[],
isBitmask,
VendorFromString(groupName, vendors),
enumNamespace
);
}
}

var allHandles = doc.Elements("registry")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkDataGraphPipelineDispatchFlagBitsARM")]
[NativeName("VkDataGraphPipelineDispatchFlagsARM")]
[Flags]
public enum DataGraphPipelineDispatchFlagsARM : ulong
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkImageFormatConstraintsFlagBitsFUCHSIA")]
[NativeName("VkImageFormatConstraintsFlagsFUCHSIA")]
[Flags]
public enum ImageFormatConstraintsFlagsFUCHSIA : uint
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkPrivateDataSlotCreateFlagBits")]
[NativeName("VkPrivateDataSlotCreateFlags")]
[Flags]
public enum PrivateDataSlotCreateFlags : uint
{
Expand Down
2 changes: 1 addition & 1 deletion sources/Vulkan/Vulkan/Enums/RefreshObjectFlagsKHR.gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkRefreshObjectFlagBitsKHR")]
[NativeName("VkRefreshObjectFlagsKHR")]
[Flags]
public enum RefreshObjectFlagsKHR : uint
{
Expand Down
2 changes: 1 addition & 1 deletion sources/Vulkan/Vulkan/Enums/SemaphoreCreateFlags.gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkSemaphoreCreateFlagBits")]
[NativeName("VkSemaphoreCreateFlags")]
[Flags]
public enum SemaphoreCreateFlags : uint
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkShaderModuleCreateFlagBits")]
[NativeName("VkShaderModuleCreateFlags")]
[Flags]
public enum ShaderModuleCreateFlags : uint
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkTensorViewCreateFlagBitsARM")]
[NativeName("VkTensorViewCreateFlagsARM")]
[Flags]
public enum TensorViewCreateFlagsARM : ulong
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Silk.NET.Vulkan;

[NativeName("VkWaylandSurfaceCreateFlagBitsKHR")]
[NativeName("VkWaylandSurfaceCreateFlagsKHR")]
[Flags]
public enum WaylandSurfaceCreateFlagsKHR : uint
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[NameAffix("Prefix", "KhronosNamespaceEnum", "GL")]
[NativeName("GLenum")]
[NameAffix("Prefix", "KhronosNamespaceEnum", "GL")]
public enum GLEnum
{
}
3 changes: 2 additions & 1 deletion tests/SilkTouch/SilkTouch/Khronos/MixKhronosDataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ public async Task IdentifiesNamespaceEnumPrefix()
.AddDocument(
"GLEnum.gen.cs",
"""
[NativeName("GLenum")]
public enum GLEnum { }
"""
)
Expand All @@ -448,7 +449,7 @@ public enum GLEnum { }
"GLEnum",
new MixKhronosData.EnumGroup(
"GLEnum",
"GLEnum",
"GLenum",
"Glenum",
[],
false,
Expand Down
Loading