Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
Datatype trimming (can't trim ext yet bc conflicts)
Browse files Browse the repository at this point in the history
  • Loading branch information
Perksey committed Nov 11, 2023
1 parent b4e71bf commit 8fbed2b
Show file tree
Hide file tree
Showing 10 changed files with 6,824 additions and 6,706 deletions.
2,662 changes: 1,328 additions & 1,334 deletions sources/OpenGL/IGL.gen.cs

Large diffs are not rendered by default.

10,644 changes: 5,278 additions & 5,366 deletions sources/OpenGL/gl/GL.gen.cs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions sources/SilkTouchX/Mods/Common/ModLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ModLoader
nameof(AddOpaqueStructs) => typeof(AddOpaqueStructs),
nameof(AddVTables) => typeof(AddVTables),
nameof(AddApiProfiles) => typeof(AddApiProfiles),
nameof(MixKhronosData) => typeof(MixKhronosData),
_ => null
};
}
182 changes: 182 additions & 0 deletions sources/SilkTouchX/Mods/MixKhronosData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SilkTouchX.Naming;

namespace SilkTouchX.Mods;

/// <summary>
/// A mod that reads Khronos specifications to influence codegen.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="cfg">The configuration.</param>
[ModConfiguration<Configuration>]
public partial class MixKhronosData(
ILogger<MixKhronosData> logger,
IOptionsSnapshot<MixKhronosData.Configuration> cfg
) : IMod, INameTrimmer
{
private Dictionary<string, HashSet<string>> _vendors = new();
private Dictionary<string, Configuration> _jobs = new();

/// <summary>
/// Khronos mod configuration.
/// </summary>
public record Configuration
{
/// <summary>
/// The path to the XML specification file.
/// </summary>
/// <remarks>
/// Can be null, in which case this is equivalent to just using OpenGL style trimmings on non-OpenGL bindings
/// which we do want to do in some cases (like OpenAL)
/// </remarks>
public string? SpecPath { get; init; }

/// <summary>
/// Whether OpenGL-style data type suffixes should be trimmed.
/// </summary>
public bool UseDataTypeTrimmings { get; init; }
}

/// <inheritdoc />
public Version Version { get; } = new(0, 0); // non-versioned (also needs to be zero for sorting)

/// <inheritdoc />
public async Task BeforeJobAsync(string key, SilkTouchConfiguration config)
{
var currentConfig = cfg.Get(key);
_jobs[key] = currentConfig;
var specPath = currentConfig.SpecPath;
if (specPath is null)
{
_vendors[key] = new HashSet<string>();
return;
}
logger.LogInformation("Reading Khronos XML from \"{}\"...", specPath);
await using var fs = File.OpenRead(specPath);
var xml = await XDocument.LoadAsync(fs, LoadOptions.None, default);

// Get all vendor names
_vendors[key] = (
xml.Element("registry")
?.Element("tags")
?.Elements("tag")
.Attributes("name")
.Select(x => x.Value) ?? Enumerable.Empty<string>()
)
.Concat(
xml.Element("registry")
?.Element("extensions")
?.Elements("extension")
.Attributes("name")
.Where(x => !x.Value.StartsWith("cl"))
.Select(x => x.Value[(x.Value.IndexOf('_') + 1)..])
?? Enumerable.Empty<string>()
)
.ToHashSet();
}

/// <inheritdoc />
public void Trim(
string? container,
string? hint,
string? jobKey,
Dictionary<string, (string Primary, List<string>? Secondary)>? names,
Dictionary<string, string>? prefixOverrides
)
{
if (names is null || jobKey is null)
{
return;
}

if (
!_vendors.TryGetValue(jobKey, out var vendors)
|| !_jobs.TryGetValue(jobKey, out var cfg)
)
{
throw new InvalidOperationException(
"BeforeJobAsync has not run yet! MixKhronosData must come before PrettifyNames in the mod list."
);
}

if (vendors.Count == 0)
{
logger.LogWarning(
"No vendor information present, assuming no XML was provided? Extension trimming will be skipped."
);
}

// Trim the extension vendor names
foreach (var (original, (current, previous)) in names)
{
foreach (var vendor in vendors)
{
if (!current.EndsWith(vendor))
{
continue;
}

var newPrev = previous ?? new List<string>();
newPrev.Add(current);
names[original] = (current[..^vendor.Length], newPrev);
break;
}
}

// Trim data types
if (!cfg.UseDataTypeTrimmings)
{
return;
}

foreach (var (original, (current, previous)) in names)
{
if (original == "glDisablei")
{
Debugger.Break();
}

if (
EndingsToTrim().Match(current) is not { Success: true } match
|| EndingsNotToTrim().IsMatch(current)
)
{
continue;
}

var newPrev = previous ?? new List<string>();
newPrev.Add(current);
names[original] = (current.Remove(match.Index), newPrev);
}
}

/// <summary>
/// This regex matches against known OpenGL function endings, picking them out from function names.
/// It is comprised of two parts - the main matching set (here, the main capturing group), and a negative
/// lookbehind workaround for difficult-to-match names. The primary set matches the actual function ending,
/// while the lookbehind asserts that the ending match will not overreach into the end of a word.
/// </summary>
[GeneratedRegex("(?<!xe)([fd]v?|u?[isb](64)?v?|v|i_v|fi)$")]
private static partial Regex EndingsToTrim();

/// <summary>
/// This regex acts like a whitelist for endings that could have been matched in some way by the main
/// expression, but should be exempt from trimming altogether.
/// </summary>
[GeneratedRegex(
"(sh|ib|[tdrey]s|[eE]n[vd]|bled|Attrib|Access|Boolean|Coord|Depth|Feedbacks|Finish|Flag|Groups|IDs|Indexed|"
+ "Instanced|Pixels|Queries|Status|Tess|Through|Uniforms|Varyings|Weight|Width|Bias|Id|Fixed|Pass|"
+ "Address|Configs|Thread|Subpass|Deferred)$"
)]
private static partial Regex EndingsNotToTrim();
}
4 changes: 3 additions & 1 deletion sources/SilkTouchX/Mods/PrettifyNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ var trimmer in trimmerProviders
.OrderBy(x => x.Version)
)
{
trimmer.Trim(null, cfg.GlobalPrefixHint, typeNames, cfg.PrefixOverrides);
trimmer.Trim(null, cfg.GlobalPrefixHint, key, typeNames, cfg.PrefixOverrides);
}
}

Expand All @@ -96,6 +96,7 @@ var trimmer in trimmerProviders
trimmer.Trim(
typeName,
cfg.GlobalPrefixHint,
key,
constNames,
cfg.PrefixOverrides
);
Expand All @@ -121,6 +122,7 @@ var trimmer in trimmerProviders
trimmer.Trim(
typeName,
cfg.GlobalPrefixHint,
key,
functionNames,
cfg.PrefixOverrides
);
Expand Down
2 changes: 2 additions & 0 deletions sources/SilkTouchX/Naming/INameTrimmer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ public interface INameTrimmer
/// The name of the container. e.g. if we're trimming enum members, this would be the enum type name.
/// </param>
/// <param name="hint">A prefix hint. Generally this is a global method prefix or what have you.</param>
/// <param name="jobKey">The job key.</param>
/// <param name="names">The names within the container.</param>
/// <param name="prefixOverrides">The prefix overrides.</param>
void Trim(
string? container,
string? hint,
string? jobKey,
Dictionary<string, (string Primary, List<string>? Secondary)>? names,
Dictionary<string, string>? prefixOverrides
);
Expand Down
9 changes: 8 additions & 1 deletion sources/SilkTouchX/Naming/NameTrimmer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class NameTrimmer : INameTrimmer
public void Trim(
string? container,
string? hint,
string? jobKey,
Dictionary<string, (string Primary, List<string>? Secondary)>? names,
Dictionary<string, string>? prefixOverrides
)
Expand Down Expand Up @@ -95,7 +96,13 @@ hint is null
}
var sec = secondary ?? new List<string>();
sec.Add(oldPrimary);
names![originalName] = (trimmingName[prefix.Length..], sec);
// this was trimmingName originally. given that we're using trimming name to determine a prefix but then
// using that prefix on the old primary, this could cause intended behaviour in some cases. there's probably
// a better way to do this. (this is working around glDisablei -> glDisable -> Disablei).
names![originalName] = (
oldPrimary[prefix.TakeWhile((x, i) => oldPrimary[i] == x).Count()..],
sec
);
}
}

Expand Down
20 changes: 17 additions & 3 deletions sources/SilkTouchX/Naming/NameTrimmerProviders.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Options;
using SilkTouchX.Mods;
Expand All @@ -21,11 +22,24 @@ public IEnumerable<INameTrimmer> GetTrimmers(string? key)

public class ModTrimmer<T>(T mod, IOptionsSnapshot<SilkTouchConfiguration> job)
: INameTrimmerProvider
where T : INameTrimmer
{
public IEnumerable<INameTrimmer> GetTrimmers(string? key) =>
job.Get(key).Mods?.Contains(typeof(T).Name) ?? false
? Enumerable.Repeat<INameTrimmer>(mod, 1)
? (
mod is INameTrimmer trimmer
? Enumerable.Repeat(trimmer, 1)
: Enumerable.Empty<INameTrimmer>()
)
.Concat(
mod is INameTrimmerProvider provider
? provider.GetTrimmers(key)
: Enumerable.Empty<INameTrimmer>()
)
.Distinct()
: Enumerable.Empty<INameTrimmer>();
}

public static bool IsModTrimmerApplicable(Type type) =>
type.IsAssignableTo(typeof(INameTrimmer))
|| type.IsAssignableTo(typeof(INameTrimmerProvider));
}
2 changes: 1 addition & 1 deletion sources/SilkTouchX/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ IConfiguration config
{
services.AddSingleton(loadedMods[m]);
services.AddSingleton<IMod>(s => (IMod)s.GetRequiredService(loadedMods[m]));
if (!loadedMods[m].IsAssignableTo(typeof(INameTrimmer)))
if (!NameTrimmerProviders.IsModTrimmerApplicable(loadedMods[m]))
{
continue;
}
Expand Down
4 changes: 4 additions & 0 deletions sources/SilkTouchX/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"Mods": [
"AddStdIncludes",
"AddApiProfiles",
"MixKhronosData",
"AddOpaqueStructs",
"UseSilkDSL",
"PrettifyNames",
Expand Down Expand Up @@ -97,6 +98,9 @@
"Names": [
"GLsync"
]
},
"MixKhronosData": {
"UseDataTypeTrimmings": true
}
}
}
Expand Down

0 comments on commit 8fbed2b

Please sign in to comment.