Skip to content

Conversation

@Exanite
Copy link
Contributor

@Exanite Exanite commented Nov 24, 2025

Summary of the PR

This PR focuses on implementing the naming-related improvements identified in #2457.
Depending on the scope of the tasks, some of these tasks may be pushed to another PR.

Important changes:

  • Naming convention used by PrettifyNames has been to be strictly pascal cased. This has implications for the rest of the codebase since the term, GL, exists outside of generated code.
    • Eg: GL becomes Gl. RGB becomes Rgb
  • Handle types are now named as -HandleEXT instead of -EXTHandle.
    • Eg: AccelerationStructureHandleKHR
  • Function pointer delegate types are now named as -DelegateEXT instead of EXTDelegate.
    • Eg: pfn struct BufferCallbackSOFT and pfn delegate BufferCallbackDelegateSOFT
  • Functions with data type suffixes following a number such as alGetSourcei64vDirectSOFT are now trimmed and prettified as GetSourcei64vDirectSOFT instead of GetSourcei64VDirectSOFT. Note the capitalization of v. This is because affixes are added after prettification.
  • Vendor suffixes are the only exception to the naming convention and are kept strictly uppercased.
  • OpenGL vendor suffix trimming is now generalized and can be configured and used for any Khronos API.
    • Notably, TrimEnumMemberImpliedVendors trims enum member vendor suffixes if it matches the enum type vendor suffix.
  • Struct properties are now prettified. They were previously ignored.
  • NativeName is a new attribute that saves the name output by ClangSharp. This for the most part isn't used by the generator, but can be useful for the end user.
  • NameAffix is a new attribute that allows prefixes/suffixes to be declared upfront and reordered. The idea is that mods add the attribute to identifiers and PrettifyNames applies the affixes during trimming and prettification.
  • A large portion of the trimming/PrettifyNames code has been rewritten.
    • NameTrimmer has been kept mostly the same.
    • INameTrimmer.Order is used to order the trimmers instead of the version.
    • PrettifyNames.Visitor's functionality is mostly the same, but also gathers name affix data.
    • MixKhronosData.Trim is almost all replaced by the name affix system. This is implemented in MixKhronosData.RewriterPhase3 (yes, there are 3 rewriters, but this keeps things simpler without adding much time cost).
    • Most usages of tuples have been replaced with record structs.
    • Most nullable collections (eg: List<string>?) have been made non-nullable. Most of these get allocated anyway and it makes the code more maintainable. If there is any performance issue (mainly concerning the Microsoft job), I will take the time to optimize it.
    • Prettification (as in calling the Prettify extension method) is now implemented as another trimmer. Prettification now happens before name conflict resolution and before name affixes are added.
  • Handle structs now have constructors since they were previously not possible to construct (field is readonly).
  • The StripAttributes mod can be used to remove attributes from the final bindings.
    • Currently the following are removed: NativeTypeName, NameAffix, Transformed

Related issues, Discord discussions, or proposals

Previous Vulkan PR (initial bindings generation): #2457
Discord thread: https://discord.com/channels/521092042781229087/1376331581198827520/1442651368207941643

Further Comments

Tasks not part of this PR

These are the tasks from my previous PR. These have been sorted and trimmed down to ensure that this PR remains focused. These may be added to this PR.

If you want to see the original, unmodified set of tasks, please see #2457.

These will also be part of a future PR.

  • Apply BoolType transformation to VkBool32 in structs. They currently are only handled for functions.
  • Add default field values to structs where it makes sense (eg: SType)
  • Ensure SupportedApiProfiles attributes are correct
    • Properly resolve API profiles for Flags/FlagBits types
    • Prefer name from NativeName for resolving API profiles

Future PRs

  • Update Curin's branch to use my new LocationTransformation code. The new renamer should be replaced with this. See the NameUtils.cs and Renamer.cs files on Curin's branch. Renamer.cs should be removed. NameUtils.cs should have the methods updated to use my LocationTransformation code instead (this should show up as a merge conflict).
    • PR opened and ready for review/merge
    • PR merged
    • Old renamer code removed
  • Reimplement the struct chaining API
  • Figure out why the members of the enum AttribMask in OpenGL are not getting rewritten.
    • Initial investigation shows that the fieldSymbol.ConstantValue is null, but why it is null is unclear. Maybe a Roslyn bug? Example member: DepthBufferBit = unchecked((uint)0x00000100). Note that similar expressions in Vulkan are fine, eg: unchecked((ulong)0x00000002UL). Maybe it is because the literal type and cast type are different.
    • Wait, are these the enums that we generate?
  • Figure out why the headers are getting mixed up when running multiple jobs at the same time.
    • Seems to be related to TransformFunctions.
  • Figure out why the SDL handle structs are getting named as Silk.NET.SDL.ConditionHandle.gen.cs instead of ConditionHandle.gen.cs when running multiple jobs at the same time.
  • Work on making the generator/mod configs more consistent and user friendly. This should be done before the generator is considered a public API.
  • Consider opening a ClangSharp PR to fix issue with SDL_MAX_SINT64 generation on Linux
  • Consider splitting ExtractNestedTyping and TransformHandles into a new set of Extract- mods.
    • This this mainly for maintainability for ExtractNestedTyping, but for TransformHandles it is useful for AddApiProfiles to be executed after all types are extracted, but not yet transformed.
    • Alternatively, make AddApiProfiles strictly work off of NativeName attributes.

New Tasks

Current Todos

Completed Todos

Newest groups at the top. Order within a group is chronological.

Note that I also wrote a summary at the top. The summary is more comprehensive, but this section can be useful getting additional context. Also see my commit descriptions if more context is needed.

INameTrimmer.Order

  • Add priority system to INameTrimmer.
    • I implemented the new name affixer system using trimmers, so this introduced 3 new trimmers in order to separate each stage properly. There is now a new INameTrimmer.Order property and internal TrimmerOrder enum.

Fix misc issues I noticed

  • VkVendorId members are not trimmed properly

Fix issues introduced by name affix system

  • Identify and fix issues introduced by name affixation. Also just identify and fix naming issues in general.
    • Data type trimming in OpenAL seems to be broken. Probably OpenGL as well.
    • Check if I need to reimplement vendor suffix removal for OpenGL. I probably do.
      • Discuss: I decided to change the vendor suffix removal for enum members so that it removes the member suffix if it matches the type suffix. This prevents cases where a member of a different suffix is added, causing all members to have their suffixes restored.
      • Discuss: The above change made it so that the member suffix removal code is usable for Vulkan so I enabled it for Vulkan as well. See PresentModeKHR to see how it looks (the KHR suffixed members have their suffixes removed, but EXT remains the same).
    • Reapply some of my MixKhronosData code removals to the current develop/3.0 branch and see what changes would be made. This is to ensure I don't accidentally remove functionality when deleting code.
  • Ensure other APIs are configured consistently with Vulkan. Eg: Ensure affix priorities are set, etc.

Name affix system

  • Properly trim prefixed/suffixed names, such as PFNVkDebugUtilsMessengerCallbackEXT and BufferTHandle
    • PFNVkDebugUtilsMessengerCallbackEXT prefix
    • PFNVkDebugUtilsMessengerCallbackDelegateEXT suffix
    • AccelerationStructureHandleKHR suffix
    • Extract vendor extensions from names and store into NameSuffix attributes.
    • Revert "hacky" THandle fix.
  • Consider renaming handle types as HandleEXT instead of EXTHandle for readability.
    • This is fairly doable. The above todos track this.

Name metadata

  • Add NativeName attribute
  • Ensure NativeName attribute is added by all mods that generate new types/members
    • Technically not strictly required, but nice from a API consistency standpoint.
    • MixKhronosData
      • Enum members
      • Enum declarations
        • Vulkan (uses FlagBits version of enum names since it is more helpful when googling)
        • Discuss validity in other Khronos APIs (some APIs don't have actual enums)
          • Eg: GLEnum and the other OpenGL enums
    • ExtractNestedTyping
      • Function pointers
      • Others?
    • TransformHandles

Name prettification

Fix bugs from original PR

  • Enums containing negative values should not have an unsigned backing type.

Handle struct improvements

  • Handle structs don't have an easy way of being constructed (field is readonly and no constructor).

Things to watch for during review

I regenerated all of the bindings, but on Linux. I'll probably commit the Windows version before undrafting for consistency.

  • SDL: VaListTagHandle is a handle struct that generates on Linux, but not Windows. This struct breaks global prefix determination, so I added SDL as a global prefix hint for PrettifyNames in the generator config.
  • OpenAL: ContextErrorCode was replaced with ErrorCode. This also happened in the previous PR, but I didn't commit it. ContextErrorCode was originally added during the OpenAL PR. This happens on both Linux and Windows. Maybe this is a Mac specific inconsistency? Or was this enum manually added?

This looks like it's from some sort of built-in renamer.
Don't think we'll ever use this since we have a custom renamer.
Not sure why these were not being coerced when the Vulkan PR was merged, but they started getting coerced in this PR.
This technically is a good thing since it means the coerce backing types code is now working as previously intended.
However, the previously intended implementation missed an edge case, which this commit fixes.
This is because the structs were impossible to reasonably construct before.
Technically this is from my update PR into Curin's branch (curin#101), but is effectively the same as backporting the changes from Curin's branch.
Exact commit that I copied the changes from: 0cc698a
VaListTagHandle is an extra handle struct that seems to generate on Linux (and not on Windows) and breaks global prefix determination.
OpenAL: ContextErrorCode seems to always be replaced with ErrorCode, even on Windows. Not sure why. This also happened during the last PR, but I didn't commit it.
Honestly, what I wrote is a complete guess, I'll likely revisit these once I understand them more.
@Exanite Exanite force-pushed the feature/vulkan-bindings-3.0-improvements branch 2 times, most recently from b1c03ee to f75dd7f Compare December 6, 2025 10:21
Copy link
Contributor Author

@Exanite Exanite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial self code review. PR is not yet ready for review or merge.

openal-soft-al.h
--methodClassName
AL
Al
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced most usages of AL and GL with Al and Gl (I still need to double check comments since my renames don't catch that).
However, I did not change namespaces, so they still use OpenAL/GL instead of OpenAl/Gl.

This is more consistent with the rest of the bindings, but I'm not sure if we want to make an exception here and use GL instead. Notably SDL is already lowercased as Sdl so I didn't change that.


namespace Silk.NET.OpenAL;

[NativeName("_flLateReverbPan_e__FixedBuffer")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how I feel about this native name. Probably fine?

[InlineArray(3)]
public partial struct EfxEaxReverbPropertiesFlLateReverbPan
{
[NativeName("e0")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not sure how I feel about this native name. Probably fine?

[NativeTypeName("const EFXEAXREVERBPROPERTIES")]
public static ref readonly EfxEaxReverbProperties Generic
[NativeName("EFX_REVERB_PRESET_GENERIC_")]
public static ref readonly EfxEaxReverbProperties EfxReverbPresetGeneric
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to investigate this.

@@ -37,42 +37,43 @@ public static partial class NameUtils
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
);

private static readonly IStringTransformer[] _prettifyTransformers = [new NameTransformer()];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This avoids an allocation due to the params keyword every time Prettify is called.

/// </summary>
/// <param name="node">The original method.</param>
/// <returns>The modified method.</returns>
public static MethodDeclarationSyntax WithRenameSafeAttributeLists(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Attribute related code in ModUtils has been moved to AttributeUtils

/// <inheritdoc />
public void Trim(NameTrimmerContext context)
{
if (context.Names is null || context.JobKey is null)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of Trim was replaced by RewriterPhase3 below

@@ -1800,7 +1505,7 @@ public bool TryGetSymbolMetadata(
/// while the lookbehind asserts that the ending match will not overreach into the end of a word.
/// </summary>
// NOTE: LET THIS BE A LESSON! Do NOT add x (fixed) here, these will frequently conflict with integer overloads.
[GeneratedRegex("(?<!xe)([fdh]v?|u?[isb](64)?v?|v|i_v|fi|hi)$")]
[GeneratedRegex("(?<!xe)((?<!Rewin)[dhf]v?|u?[isb](64)?v?|v|i_v|fi|hi)$")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewindv in OpenAL was getting trimmed as Rewin

private static readonly char[] _listSeparators = { ',', '|', '+' };

private static readonly Dictionary<string, string> _defaultEnumNativeTypeNameMaps =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dictionary was effectively unused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant