More generation and WIP DXGI generation.

This commit is contained in:
Amer Koleci
2022-09-01 14:52:52 +02:00
parent 51e57995b7
commit d4e1960c9c
8 changed files with 1776 additions and 18 deletions

View File

@@ -42,7 +42,11 @@ public sealed class CodeWriter : IDisposable
{ {
_writer.WriteLine($"using {usingNamespace};"); _writer.WriteLine($"using {usingNamespace};");
} }
_writer.WriteLine();
_writer.WriteLine("#if NETSTANDARD2_0");
_writer.WriteLine("using MemoryMarshal = Win32.MemoryMarshal;");
_writer.WriteLine("#endif");
_writer.WriteLine(); _writer.WriteLine();
_writer.WriteLine($"namespace {ns};"); _writer.WriteLine($"namespace {ns};");

View File

@@ -10,7 +10,8 @@ public static class Program
{ {
private static readonly string[] jsons = new[] private static readonly string[] jsons = new[]
{ {
"Graphics.Dxgi.Common.json" "Graphics.Dxgi.Common.json",
"Graphics.Dxgi.json"
}; };
private static readonly Dictionary<string, string> s_csNameMappings = new() private static readonly Dictionary<string, string> s_csNameMappings = new()
@@ -29,12 +30,26 @@ public static class Program
{"Single", "float" }, {"Single", "float" },
{"Double", "double" }, {"Double", "double" },
{"IntPtr", "nint" },
{"UIntPtr", "nuint" },
{ "Foundation.BOOL", "Bool32" }, { "Foundation.BOOL", "Bool32" },
{ "Foundation.HRESULT", "HResult" },
{ "Foundation.LUID", "Luid" },
{ "Foundation.LARGE_INTEGER", "LargeInterger" },
// TODO: Understand those ->
{ "Foundation.HWND", "IntPtr" },
{ "Foundation.HANDLE", "IntPtr" },
{ "Foundation.POINT", "System.Drawing.Point" },
{ "Foundation.RECT", "RawRect" },
{ "Graphics.Gdi.HMONITOR", "IntPtr" },
}; };
private static readonly Dictionary<string, string> s_knownTypesPrefixes = new() private static readonly Dictionary<string, string> s_knownTypesPrefixes = new()
{ {
{ "DXGI_COLOR_SPACE_TYPE", "DXGI_COLOR_SPACE" }, { "DXGI_COLOR_SPACE_TYPE", "DXGI_COLOR_SPACE" },
{ "DXGI_COMPUTE_PREEMPTION_GRANULARITY", "DXGI_COMPUTE_PREEMPTION" },
}; };
private static readonly Dictionary<string, string> s_knownEnumValueNames = new() private static readonly Dictionary<string, string> s_knownEnumValueNames = new()
@@ -122,8 +137,19 @@ public static class Program
if (ShouldSkipConstant(constant)) if (ShouldSkipConstant(constant))
continue; continue;
string typeName = GetTypeName(constant.ValueType); string typeName = GetTypeName(constant.Type);
writer.WriteLine($"public const {typeName} {constant.Name} = {constant.Value};"); if (typeName == "Guid")
{
writer.WriteLine($"public static readonly Guid {constant.Name} = {FormatGuid(constant.Value.ToString())};");
}
else if (typeName == "HResult")
{
writer.WriteLine($"public static readonly HResult {constant.Name} = {constant.Value};");
}
else
{
writer.WriteLine($"public const {typeName} {constant.Name} = {constant.Value};");
}
} }
} }
writer.WriteLine(); writer.WriteLine();
@@ -150,16 +176,16 @@ public static class Program
private static void GenerateEnum(CodeWriter writer, ApiType enumType) private static void GenerateEnum(CodeWriter writer, ApiType enumType)
{ {
if (enumType.Flags)
{
writer.WriteLine("[Flags]");
}
string csTypeName = GetDataTypeName(enumType.Name, out string enumPrefix); string csTypeName = GetDataTypeName(enumType.Name, out string enumPrefix);
string baseTypeName = GetTypeName(enumType.IntegerBase); string baseTypeName = GetTypeName(enumType.IntegerBase);
AddCsMapping(writer.Api, enumType.Name, csTypeName); AddCsMapping(writer.Api, enumType.Name, csTypeName);
writer.WriteLine($"/// <unmanaged>{enumType.Name}</unmanaged>"); writer.WriteLine($"/// <unmanaged>{enumType.Name}</unmanaged>");
if (enumType.Flags)
{
writer.WriteLine("[Flags]");
}
using (writer.PushBlock($"public enum {csTypeName} : {baseTypeName}")) using (writer.PushBlock($"public enum {csTypeName} : {baseTypeName}"))
{ {
foreach (ApiEnumValue value in enumType.Values) foreach (ApiEnumValue value in enumType.Values)
@@ -237,19 +263,21 @@ public static class Program
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]"); writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
using (writer.PushBlock($"public Span<{fieldTypeName}> AsSpan()")) using (writer.PushBlock($"public Span<{fieldTypeName}> AsSpan()"))
{ {
writer.WriteUndindented("#if NET6_0_OR_GREATER");
writer.WriteLine($"return MemoryMarshal.CreateSpan(ref e0, {field.Type.Shape.Size});"); writer.WriteLine($"return MemoryMarshal.CreateSpan(ref e0, {field.Type.Shape.Size});");
writer.WriteUndindented("#else");
writer.WriteLine($"return new(Unsafe.AsPointer(ref e0), {field.Type.Shape.Size});");
writer.WriteUndindented("#endif");
} }
} }
} }
} }
else else
{ {
string unsafePrefix = string.Empty;
fieldTypeName = NormalizeTypeName(writer.Api, fieldTypeName); fieldTypeName = NormalizeTypeName(writer.Api, fieldTypeName);
writer.WriteLine($"public {fieldTypeName} {fieldValueName};"); if(fieldTypeName.EndsWith("*"))
{
unsafePrefix += "unsafe ";
}
writer.WriteLine($"public {unsafePrefix}{fieldTypeName} {fieldValueName};");
} }
} }
} }
@@ -434,6 +462,26 @@ public static class Program
return (char.IsNumber(prettyName[0])) ? "_" + prettyName : prettyName; return (char.IsNumber(prettyName[0])) ? "_" + prettyName : prettyName;
} }
private static string FormatGuid(string value)
{
var guid = Guid.Parse(value).ToString("N");
var a = "0x" + guid.Substring(0, 8);
var b = "0x" + guid.Substring(8, 4);
var c = "0x" + guid.Substring(12, 4);
var d = "0x" + guid.Substring(16, 2);
var e = "0x" + guid.Substring(18, 2);
var f = "0x" + guid.Substring(20, 2);
var g = "0x" + guid.Substring(22, 2);
var h = "0x" + guid.Substring(24, 2);
var i = "0x" + guid.Substring(26, 2);
var j = "0x" + guid.Substring(28, 2);
var k = "0x" + guid.Substring(30, 2);
return $"new Guid({a}, {b}, {c}, {d}, {e}, {f}, {g}, {h}, {i}, {j}, {k})";
}
private static string GetTypeName(ApiDataType dataType) private static string GetTypeName(ApiDataType dataType)
{ {
if (dataType.Kind == "ApiRef") if (dataType.Kind == "ApiRef")
@@ -446,7 +494,7 @@ public static class Program
} }
else if (dataType.Kind == "PointerTo") else if (dataType.Kind == "PointerTo")
{ {
throw new NotImplementedException(); return GetTypeName(dataType.Child) + "*";
} }
return GetTypeName(dataType.Name); return GetTypeName(dataType.Name);

View File

@@ -11,6 +11,10 @@ using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
#if NETSTANDARD2_0
using MemoryMarshal = Win32.MemoryMarshal;
#endif
namespace Win32.Graphics.Dxgi.Common; namespace Win32.Graphics.Dxgi.Common;
public static partial class Apis public static partial class Apis
@@ -1456,11 +1460,7 @@ public partial struct GammaControl
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<Rgb> AsSpan() public Span<Rgb> AsSpan()
{ {
#if NET6_0_OR_GREATER
return MemoryMarshal.CreateSpan(ref e0, 1025); return MemoryMarshal.CreateSpan(ref e0, 1025);
#else
return new(Unsafe.AsPointer(ref e0), 1025);
#endif
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
// Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
#if NETSTANDARD2_0
using MemoryMarshal = Win32.MemoryMarshal;
#endif
namespace Win32;
[StructLayout(LayoutKind.Explicit)]
[NativeTypeName("LARGE_INTEGER")]
public partial struct LargeInterger
{
[FieldOffset(0)]
public _Anonymous_e__Struct Anonymous;
[FieldOffset(0)]
[NativeTypeName("struct (anonymous struct at C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/um/winnt.h:879:5)")]
public _u_e__Struct u;
[FieldOffset(0)]
[NativeTypeName("LONGLONG")]
public long QuadPart;
[UnscopedRef]
public ref uint LowPart
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
#if NET7_0_OR_GREATER
return ref Anonymous.LowPart;
#else
return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.LowPart, 1));
#endif
}
}
[UnscopedRef]
public ref int HighPart
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
#if NET7_0_OR_GREATER
return ref Anonymous.HighPart;
#else
return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.HighPart, 1));
#endif
}
}
public partial struct _Anonymous_e__Struct
{
[NativeTypeName("DWORD")]
public uint LowPart;
[NativeTypeName("LONG")]
public int HighPart;
}
public partial struct _u_e__Struct
{
[NativeTypeName("DWORD")]
public uint LowPart;
[NativeTypeName("LONG")]
public int HighPart;
}
}

91
src/Vortice.Win32/Luid.cs Normal file
View File

@@ -0,0 +1,91 @@
// Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
using System.Runtime.CompilerServices;
namespace Win32;
/// <summary>
/// A locally unique identifier for a graphics device.
/// </summary>
public readonly struct Luid : IEquatable<Luid>
#if NET6_0_OR_GREATER
, ISpanFormattable
#endif
{
/// <summary>
/// The low bits of the luid.
/// </summary>
private readonly uint lowPart;
/// <summary>
/// The high bits of the luid.
/// </summary>
private readonly int highPart;
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Luid other)
{
return
this.lowPart == other.lowPart &&
this.highPart == other.highPart;
}
/// <inheritdoc/>
public override bool Equals(object? other)
{
return other is Luid luid && Equals(luid);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
{
return HashCode.Combine(lowPart, highPart);
}
/// <inheritdoc/>
public override string ToString()
{
return (((long)this.highPart) << 32 | this.lowPart).ToString();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public string ToString(string? format, IFormatProvider? formatProvider)
{
return (((long)this.highPart) << 32 | this.lowPart).ToString(format, formatProvider);
}
/// <inheritdoc/>
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
{
return (((long)this.highPart) << 32 | this.lowPart).TryFormat(destination, out charsWritten, format, provider);
}
#endif
/// <summary>
/// Check whether two <see cref="Luid"/> values are equal.
/// </summary>
/// <param name="a">The first <see cref="Luid"/> value to compare.</param>
/// <param name="b">The second <see cref="Luid"/> value to compare.</param>
/// <returns>Whether <paramref name="a"/> and <paramref name="b"/> are the same.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Luid a, Luid b)
{
return a.Equals(b);
}
/// <summary>
/// Check whether two <see cref="Luid"/> values are different.
/// </summary>
/// <param name="a">The first <see cref="Luid"/> value to compare.</param>
/// <param name="b">The second <see cref="Luid"/> value to compare.</param>
/// <returns>Whether <paramref name="a"/> and <paramref name="b"/> are different.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Luid a, Luid b)
{
return !a.Equals(b);
}
}

View File

@@ -0,0 +1,39 @@
// Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
#if NETSTANDARD2_0
using System.Runtime.CompilerServices;
namespace Win32;
internal static class MemoryMarshal
{
/// <inheritdoc cref="global::System.Runtime.InteropServices.MemoryMarshal.GetReference{T}(Span{T})"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T GetReference<T>(Span<T> span)
{
return ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(span);
}
/// <inheritdoc cref="global::System.Runtime.InteropServices.MemoryMarshal.GetReference{T}(ReadOnlySpan{T})"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T GetReference<T>(ReadOnlySpan<T> span)
{
return ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(span);
}
/// <summary>
/// Creates a new <see cref="Span{T}"/> from a given reference.
/// </summary>
/// <typeparam name="T">The type of reference to wrap.</typeparam>
/// <param name="value">The target reference.</param>
/// <param name="length">The length of the <see cref="Span{T}"/> to create.</param>
/// <returns>A new <see cref="Span{T}"/> wrapping <paramref name="value"/>.</returns>
public static unsafe Span<T> CreateSpan<T>(ref T value, int length)
{
return new(Unsafe.AsPointer(ref value), length);
}
}
#endif

View File

@@ -0,0 +1,63 @@
// Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
using System.Diagnostics;
using System.Drawing;
namespace Win32;
/// <summary>
/// Defines an integer rectangle (Left, Top, Right, Bottom)
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
[DebuggerDisplay("Left: {Left}, Top: {Top}, Right: {Right}, Bottom: {Bottom}")]
public readonly struct RawRect
{
public RawRect(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
/// <summary>
/// The left position.
/// </summary>
public readonly int Left;
/// <summary>
/// The top position.
/// </summary>
public readonly int Top;
/// <summary>
/// The right position
/// </summary>
public readonly int Right;
/// <summary>
/// The bottom position.
/// </summary>
public readonly int Bottom;
/// <inheritdoc/>
public override string ToString()
{
return $"{nameof(Left)}: {Left}, {nameof(Top)}: {Top}, {nameof(Right)}: {Right}, {nameof(Bottom)}: {Bottom}";
}
/// <summary>
/// Performs an implicit conversion from <see cre ="RawRect"/> to <see cref="Rectangle" />.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator Rectangle(RawRect value) => Rectangle.FromLTRB(value.Left, value.Top, value.Right, value.Bottom);
/// <summary>
/// Performs an implicit conversion from <see cre ="Rectangle"/> to <see cref="RawRect" />.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator RawRect(Rectangle value) => new(value.Left, value.Top, value.Right, value.Bottom);
}