Skip to content

Commit

Permalink
Add VkVersion
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Jun 27, 2024
1 parent bf8cb05 commit f5e9ed0
Show file tree
Hide file tree
Showing 7 changed files with 1,433 additions and 371 deletions.
94 changes: 80 additions & 14 deletions src/codegen/XenoAtom.Interop.CodeGen/vulkan/VulkanGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,47 @@ public override async Task Initialize(ApkManager apkHelper)
return csCompilation;
}

private static string GetApiVersionDefine(string apiVersion)
{
return $"VK_API_VERSION_{apiVersion.Replace(".", "_")}";
}

private void ApplyApiVersion(CSharpElement csElement)
{
if (csElement.CppElement is ICppMember cppMember)
{
var cppName = cppMember.Name;
if (_vulkanElementInfos.TryGetValue(cppName, out var elementInfo) && elementInfo.ApiVersion != null)
{
List<CSharpAttribute>? attributes = null;
if (csElement is CSharpEnum csEnum)
{
attributes = csEnum.Attributes;
}
else if (csElement is CSharpStruct csStruct)
{
attributes = csStruct.Attributes;
}
else if (csElement is CSharpMethod csMethod)
{
attributes = csMethod.Attributes;
}

if (attributes != null)
{
var apiVersion = GetApiVersionDefine(elementInfo.ApiVersion);
attributes.Add(new CSharpFreeAttribute($"VkVersion({apiVersion})"));
}
}
}
}

private void ProcessStruct(CSharpStruct csStruct)
{
var cppName = ((ICppMember)csStruct.CppElement!).Name;

ApplyApiVersion(csStruct);

if (_structsAsRecord.Contains(cppName))
{
csStruct.IsRecord = true;
Expand All @@ -258,6 +295,8 @@ private void ProcessStruct(CSharpStruct csStruct)

private void ProcessVulkanEnum(CSharpEnum csEnum)
{
ApplyApiVersion(csEnum);

// We only need to modify flags in this method
if (!csEnum.Name.Contains("FlagBits", StringComparison.Ordinal))
{
Expand Down Expand Up @@ -314,11 +353,33 @@ private void ProcessVulkanEnum(CSharpEnum csEnum)
[GeneratedRegex($"{CommonVkExt}")]
private static partial Regex RegexCommandExt();


private VulkanExtensionKind GetFunctionExtensionKind(CSharpMethod csFunction, string name)
{
if (_vulkanElementInfos.TryGetValue(name, out var elementInfo))
{
if (elementInfo.ExtensionKind != VulkanExtensionKind.Unknown)
{
return elementInfo.ExtensionKind;
}
}

if (csFunction.Parameters.Count > 0 && csFunction.Parameters[0].ParameterType is CSharpNamedType namedType)
{
return namedType.Name == "VkInstance" || namedType.Name == "VkPhysicalDevice"
? VulkanExtensionKind.Instance
: VulkanExtensionKind.Device;
}

return VulkanExtensionKind.Unknown;
}

private void ProcessVulkanFunction(CSharpMethod csFunction)
{
// Apply doc to the function
ApplyDocumentation(csFunction);
AddVulkanVersionAndExtensionInfoToCSharpElement(csFunction);
ApplyApiVersion(csFunction);

if (!_structFunctionPointers.TryGetValue(csFunction.Name, out var pfn))
{
Expand All @@ -328,20 +389,22 @@ private void ProcessVulkanFunction(CSharpMethod csFunction)

var cppFunction = (CppFunction)csFunction.CppElement!;

var extensionKind = VulkanExtensionKind.Unknown;
if (_vulkanElementInfos.TryGetValue(cppFunction.Name, out var elementInfo))
{
extensionKind = elementInfo.ExtensionKind;
}
var extensionKind = GetFunctionExtensionKind(csFunction, cppFunction.Name);

pfn.BaseTypes.Add(new CSharpGenericTypeReference(
extensionKind switch
{
VulkanExtensionKind.Instance => "IvkInstanceFunctionPointer",
VulkanExtensionKind.Device => "IvkDeviceFunctionPointer",
_ => GlobalCommands.Contains(cppFunction.Name) ? "IvkGlobalFunctionPointer" : "IvkCoreFunctionPointer",
VulkanExtensionKind.Global => "IvkGlobalFunctionPointer",
_ => "IvkFunctionPointer",
}, [pfn]));


if (extensionKind == VulkanExtensionKind.Unknown)
{
Console.WriteLine($"Warning, cannot find extension kind for function {csFunction.Name}");
}

var csProperty = new CSharpProperty("Name")
{
ReturnType = new CSharpFreeType($"ReadOnlyMemoryUtf8"),
Expand Down Expand Up @@ -518,6 +581,7 @@ private void CreateNewFunctionOverload(CSharpMethod csFunction, VulkanCommand co
newMethod.Modifiers &= ~CSharpModifiers.Partial;
// We remove all attributes as we are calling to call the interop method from the body
newMethod.Attributes.Clear();
ApplyApiVersion(newMethod);

// We go down from the last parameter to the first one to replace the array parameters with Span
for (var index = paramsToProcess.Length - 1; index >= 0; index--)
Expand Down Expand Up @@ -1124,6 +1188,10 @@ private void LoadApiVersionsAndExtensionsFromRegistry(XDocument doc)
var name = command.Attribute("name")!.Value!;
var info = GetOrCreateVulkanElementInfo(name);
info.ApiVersion = version;
if (GlobalCommands.Contains(name))
{
info.ExtensionKind = VulkanExtensionKind.Global;
}
}
}

Expand Down Expand Up @@ -1205,12 +1273,10 @@ private void LoadCommandParameterFromRegistry(XDocument doc)
if (_vulkanElementInfos.TryGetValue(alias, out var aliasInfo))
{
aliasInfo.ExtensionKind = info.ExtensionKind;
aliasInfo.Extension = info.Extension;
aliasInfo.ApiVersion = info.ApiVersion;
}
else
{
_vulkanElementInfos.TryAdd(alias, info);
aliasInfo.Extension ??= info.Extension;

// If the alias has no api version, we use the one from the original extension
aliasInfo.ApiVersion ??= info.ApiVersion;
}

_functionRegistry.Add(name, new VulkanCommand(name)
Expand Down Expand Up @@ -1911,7 +1977,7 @@ private record VulkanElementInfo

private enum VulkanExtensionKind
{
Unknown,
Unknown = 0,
Global,
Instance,
Device,
Expand Down
29 changes: 29 additions & 0 deletions src/vulkan/XenoAtom.Interop.vulkan.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,33 @@ public unsafe void TestListExtensions()
}
}
}

[TestMethod]
public void TestVkVersion()
{
var version = new VkVersion(VK_API_VERSION_1_0);
Assert.AreEqual(1, version.Major);
Assert.AreEqual(0, version.Minor);
Assert.AreEqual(0, version.Patch);
Assert.AreEqual("1.0.0", version.ToString());

version = new VkVersion(1, 1, 0);
Assert.AreEqual(1, version.Major);
Assert.AreEqual(1, version.Minor);
Assert.AreEqual(0, version.Patch);
Assert.AreEqual("1.1.0", version.ToString());

version = new VkVersion(1, 2, 3);
Assert.AreEqual(1, version.Major);
Assert.AreEqual(2, version.Minor);
Assert.AreEqual(3, version.Patch);
Assert.AreEqual("1.2.3", version.ToString());

version = VK_API_VERSION_1_0;
VkVersion version2 = VK_API_VERSION_1_0;
Assert.AreEqual(version, version2);

version = VK_API_VERSION_1_1;
Assert.AreNotEqual(version, version2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ public partial struct VkIcdSurfaceImagePipe
/// <summary>
/// Typedefs for loader/ICD interface
/// </summary>
public readonly partial struct PFN_vk_icdNegotiateLoaderICDInterfaceVersion : IEquatable<vulkan.PFN_vk_icdNegotiateLoaderICDInterfaceVersion>, IvkCoreFunctionPointer<vulkan.PFN_vk_icdNegotiateLoaderICDInterfaceVersion>
public readonly partial struct PFN_vk_icdNegotiateLoaderICDInterfaceVersion : IEquatable<vulkan.PFN_vk_icdNegotiateLoaderICDInterfaceVersion>, IvkFunctionPointer<vulkan.PFN_vk_icdNegotiateLoaderICDInterfaceVersion>
{
public PFN_vk_icdNegotiateLoaderICDInterfaceVersion(delegate*unmanaged[Stdcall]<uint*, vulkan.VkResult> value) => this.Value = value;

Expand Down Expand Up @@ -320,7 +320,7 @@ public vulkan.VkResult Invoke(uint* pVersion)
public bool IsNull => (nint)Value == 0;
}

public readonly partial struct PFN_vk_icdGetInstanceProcAddr : IEquatable<vulkan.PFN_vk_icdGetInstanceProcAddr>, IvkCoreFunctionPointer<vulkan.PFN_vk_icdGetInstanceProcAddr>
public readonly partial struct PFN_vk_icdGetInstanceProcAddr : IEquatable<vulkan.PFN_vk_icdGetInstanceProcAddr>, IvkInstanceFunctionPointer<vulkan.PFN_vk_icdGetInstanceProcAddr>
{
public PFN_vk_icdGetInstanceProcAddr(delegate*unmanaged[Stdcall]<vulkan.VkInstance, byte*, vulkan.PFN_vkVoidFunction> value) => this.Value = value;

Expand Down Expand Up @@ -357,7 +357,7 @@ public vulkan.PFN_vkVoidFunction Invoke(vulkan.VkInstance instance, byte* pName)
public bool IsNull => (nint)Value == 0;
}

public readonly partial struct PFN_vk_icdGetPhysicalDeviceProcAddr : IEquatable<vulkan.PFN_vk_icdGetPhysicalDeviceProcAddr>, IvkCoreFunctionPointer<vulkan.PFN_vk_icdGetPhysicalDeviceProcAddr>
public readonly partial struct PFN_vk_icdGetPhysicalDeviceProcAddr : IEquatable<vulkan.PFN_vk_icdGetPhysicalDeviceProcAddr>, IvkInstanceFunctionPointer<vulkan.PFN_vk_icdGetPhysicalDeviceProcAddr>
{
public PFN_vk_icdGetPhysicalDeviceProcAddr(delegate*unmanaged[Stdcall]<vulkan.VkInstance, byte*, vulkan.PFN_vkVoidFunction> value) => this.Value = value;

Expand Down Expand Up @@ -394,7 +394,7 @@ public vulkan.PFN_vkVoidFunction Invoke(vulkan.VkInstance instance, byte* pName)
public bool IsNull => (nint)Value == 0;
}

public readonly partial struct PFN_vk_icdEnumerateAdapterPhysicalDevices : IEquatable<vulkan.PFN_vk_icdEnumerateAdapterPhysicalDevices>, IvkCoreFunctionPointer<vulkan.PFN_vk_icdEnumerateAdapterPhysicalDevices>
public readonly partial struct PFN_vk_icdEnumerateAdapterPhysicalDevices : IEquatable<vulkan.PFN_vk_icdEnumerateAdapterPhysicalDevices>, IvkInstanceFunctionPointer<vulkan.PFN_vk_icdEnumerateAdapterPhysicalDevices>
{
public PFN_vk_icdEnumerateAdapterPhysicalDevices(delegate*unmanaged[Stdcall]<vulkan.VkInstance, ulong, uint*, vulkan.VkPhysicalDevice*, vulkan.VkResult> value) => this.Value = value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ public partial struct VkEnumerateInstanceVersionChain
/// <summary>
/// Version negotiation functions
/// </summary>
public readonly partial struct PFN_vkNegotiateLoaderLayerInterfaceVersion : IEquatable<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>, IvkCoreFunctionPointer<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>
public readonly partial struct PFN_vkNegotiateLoaderLayerInterfaceVersion : IEquatable<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>, IvkFunctionPointer<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>
{
public PFN_vkNegotiateLoaderLayerInterfaceVersion(delegate*unmanaged[Stdcall]<vulkan.VkNegotiateLayerInterface*, vulkan.VkResult> value) => this.Value = value;

Expand Down
Loading

0 comments on commit f5e9ed0

Please sign in to comment.