Skip to content

Commit

Permalink
Improve binding for function pointers to differentiate instance vs de…
Browse files Browse the repository at this point in the history
…vice fp
  • Loading branch information
xoofx committed Jun 27, 2024
1 parent e318fc1 commit 6f9730e
Show file tree
Hide file tree
Showing 20 changed files with 979 additions and 901 deletions.
97 changes: 79 additions & 18 deletions src/codegen/XenoAtom.Interop.CodeGen/vulkan/VulkanGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See license.txt file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Compression;
Expand Down Expand Up @@ -319,8 +320,20 @@ private void ProcessVulkanFunction(CSharpMethod csFunction)

var cppFunction = (CppFunction)csFunction.CppElement!;

pfn.BaseTypes.Add(new CSharpGenericTypeReference("IvkFunctionPointer", [pfn]));
var extensionKind = VulkanExtensionKind.Unknown;
if (_vulkanElementInfos.TryGetValue(cppFunction.Name, out var elementInfo))
{
extensionKind = elementInfo.ExtensionKind;
}

pfn.BaseTypes.Add(new CSharpGenericTypeReference(
extensionKind switch
{
VulkanExtensionKind.Instance => "IvkInstanceFunctionPointer",
VulkanExtensionKind.Device => "IvkDeviceFunctionPointer",
_ => "IvkCoreFunctionPointer",
}, [pfn]));

var csProperty = new CSharpProperty("Name")
{
ReturnType = new CSharpFreeType($"ReadOnlyMemoryUtf8"),
Expand Down Expand Up @@ -1027,8 +1040,9 @@ private bool TryGetVulkanCommand(string name, [NotNullWhen(true)] out VulkanComm
private void LoadVulkanRegistry(string registryPath)
{
var doc = XDocument.Load(registryPath);
LoadApiVersionsAndExtensions(doc);
LoadVulkanParametersFromRegistry(doc);
LoadApiVersionsAndExtensionsFromRegistry(doc);
LoadCommandParameterFromRegistry(doc);
LoadStructureTypesFromRegistry(doc);
}

private void AddVulkanVersionAndExtensionInfoToCSharpElement(CSharpElement element)
Expand Down Expand Up @@ -1078,7 +1092,7 @@ private void AddVulkanVersionAndExtensionInfoToCSharpElement(CSharpElement eleme
}
}

private void LoadApiVersionsAndExtensions(XDocument doc)
private void LoadApiVersionsAndExtensionsFromRegistry(XDocument doc)
{
var features = doc.Descendants("feature");
foreach (var feature in features)
Expand All @@ -1093,14 +1107,14 @@ private void LoadApiVersionsAndExtensions(XDocument doc)
foreach (var type in feature.Descendants("type"))
{
var name = type.Attribute("name")!.Value!;
var info = GetVulkanElementInfo(name);
var info = GetOrCreateVulkanElementInfo(name);
info.ApiVersion = version;
}

foreach (var command in feature.Descendants("command"))
{
var name = command.Attribute("name")!.Value!;
var info = GetVulkanElementInfo(name);
var info = GetOrCreateVulkanElementInfo(name);
info.ApiVersion = version;
}
}
Expand All @@ -1110,31 +1124,45 @@ private void LoadApiVersionsAndExtensions(XDocument doc)
{
foreach (var extension in extensions.Elements("extension"))
{
var extensionName = extension.Attribute("name")!.Value!;
VulkanExtensionKind extensionKind = VulkanExtensionKind.Unknown;
var extensionTypeAttr = extension.Attribute("type");
if (extensionTypeAttr is not null)
{
extensionKind = extensionTypeAttr.Value switch
{
"device" => VulkanExtensionKind.Device,
"instance" => VulkanExtensionKind.Instance,
_ => throw new InvalidOperationException($"The extension type {extensionTypeAttr.Value} is not supported")
};
}

var supportedApis = extension.Attribute("supported")!.Value!;
if (!supportedApis.Split(",").Contains("vulkan"))
{
continue;
}

var extensionName = extension.Attribute("name")!.Value!;


foreach (var type in extension.Descendants("type"))
{
var name = type.Attribute("name")!.Value!;
var info = GetVulkanElementInfo(name);
var info = GetOrCreateVulkanElementInfo(name);
info.ExtensionKind = extensionKind;
info.Extension = extensionName;
}

foreach (var command in extension.Descendants("command"))
{
var name = command.Attribute("name")!.Value!;
var info = GetVulkanElementInfo(name);
var info = GetOrCreateVulkanElementInfo(name);

info.ExtensionKind = extensionKind;
info.Extension = extensionName;
}
}
}
VulkanElementInfo GetVulkanElementInfo(string name)

VulkanElementInfo GetOrCreateVulkanElementInfo(string name)
{
if (_vulkanElementInfos.TryGetValue(name, out var info))
{
Expand All @@ -1145,8 +1173,9 @@ VulkanElementInfo GetVulkanElementInfo(string name)
return info;
}
}

private void LoadVulkanParametersFromRegistry(XDocument doc)


private void LoadCommandParameterFromRegistry(XDocument doc)
{
var commands = doc.Descendants("commands").First();

Expand All @@ -1155,10 +1184,31 @@ private void LoadVulkanParametersFromRegistry(XDocument doc)
{
string name;
string? alias = xmlCommand.Attribute("alias")?.Value;

if (alias != null)
{
name = xmlCommand.Attribute("name")!.Value;
_functionRegistry.Add(name, new VulkanCommand(name) { Alias = alias });

if (!_vulkanElementInfos.TryGetValue(name, out var info))
{
throw new InvalidOperationException($"Cannot find Vulkan element info for alias {name}");
}
// Add alias information
if (_vulkanElementInfos.TryGetValue(alias, out var aliasInfo))
{
aliasInfo.ExtensionKind = info.ExtensionKind;
aliasInfo.Extension = info.Extension;
aliasInfo.ApiVersion = info.ApiVersion;
}
else
{
_vulkanElementInfos.TryAdd(alias, info);
}

_functionRegistry.Add(name, new VulkanCommand(name)
{
Alias = alias,
});
continue;
}

Expand Down Expand Up @@ -1231,7 +1281,11 @@ private void LoadVulkanParametersFromRegistry(XDocument doc)
commandCount++;
}

Console.WriteLine($"Total commands: {commandCount} processed from the registry");
}

private void LoadStructureTypesFromRegistry(XDocument doc)
{
var types = doc.Descendants("types").FirstOrDefault();

if (types != null)
Expand Down Expand Up @@ -1263,8 +1317,6 @@ private void LoadVulkanParametersFromRegistry(XDocument doc)
}
}
}

Console.WriteLine($"Total commands: {commandCount} processed from the registry");
}

[GeneratedRegex(@"^(\d+\.\d+\.\d+)")]
Expand Down Expand Up @@ -1844,6 +1896,15 @@ private record VulkanElementInfo
{
public string? ApiVersion { get; set; }

public VulkanExtensionKind ExtensionKind { get; set; }

public string? Extension { get; set; }
}

private enum VulkanExtensionKind
{
Unknown,
Instance,
Device,
}
}
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>, IvkFunctionPointer<vulkan.PFN_vk_icdNegotiateLoaderICDInterfaceVersion>
public readonly partial struct PFN_vk_icdNegotiateLoaderICDInterfaceVersion : IEquatable<vulkan.PFN_vk_icdNegotiateLoaderICDInterfaceVersion>, IvkCoreFunctionPointer<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>, IvkFunctionPointer<vulkan.PFN_vk_icdGetInstanceProcAddr>
public readonly partial struct PFN_vk_icdGetInstanceProcAddr : IEquatable<vulkan.PFN_vk_icdGetInstanceProcAddr>, IvkCoreFunctionPointer<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>, IvkFunctionPointer<vulkan.PFN_vk_icdGetPhysicalDeviceProcAddr>
public readonly partial struct PFN_vk_icdGetPhysicalDeviceProcAddr : IEquatable<vulkan.PFN_vk_icdGetPhysicalDeviceProcAddr>, IvkCoreFunctionPointer<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>, IvkFunctionPointer<vulkan.PFN_vk_icdEnumerateAdapterPhysicalDevices>
public readonly partial struct PFN_vk_icdEnumerateAdapterPhysicalDevices : IEquatable<vulkan.PFN_vk_icdEnumerateAdapterPhysicalDevices>, IvkCoreFunctionPointer<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>, IvkFunctionPointer<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>
public readonly partial struct PFN_vkNegotiateLoaderLayerInterfaceVersion : IEquatable<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>, IvkCoreFunctionPointer<vulkan.PFN_vkNegotiateLoaderLayerInterfaceVersion>
{
public PFN_vkNegotiateLoaderLayerInterfaceVersion(delegate*unmanaged[Stdcall]<vulkan.VkNegotiateLayerInterface*, vulkan.VkResult> value) => this.Value = value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public partial struct VkAndroidHardwareBufferFormatProperties2ANDROID()
public vulkan.VkChromaLocation suggestedYChromaOffset;
}

public readonly partial struct PFN_vkCreateAndroidSurfaceKHR : IEquatable<vulkan.PFN_vkCreateAndroidSurfaceKHR>, IvkFunctionPointer<vulkan.PFN_vkCreateAndroidSurfaceKHR>
public readonly partial struct PFN_vkCreateAndroidSurfaceKHR : IEquatable<vulkan.PFN_vkCreateAndroidSurfaceKHR>, IvkInstanceFunctionPointer<vulkan.PFN_vkCreateAndroidSurfaceKHR>
{
public PFN_vkCreateAndroidSurfaceKHR(delegate*unmanaged[Stdcall]<vulkan.VkInstance, vulkan.VkAndroidSurfaceCreateInfoKHR*, vulkan.VkAllocationCallbacks*, vulkan.VkSurfaceKHR*, vulkan.VkResult> value) => this.Value = value;

Expand Down Expand Up @@ -391,7 +391,7 @@ public vulkan.VkResult Invoke(vulkan.VkInstance instance, in vulkan.VkAndroidSur
}
}

public readonly partial struct PFN_vkGetAndroidHardwareBufferPropertiesANDROID : IEquatable<vulkan.PFN_vkGetAndroidHardwareBufferPropertiesANDROID>, IvkFunctionPointer<vulkan.PFN_vkGetAndroidHardwareBufferPropertiesANDROID>
public readonly partial struct PFN_vkGetAndroidHardwareBufferPropertiesANDROID : IEquatable<vulkan.PFN_vkGetAndroidHardwareBufferPropertiesANDROID>, IvkDeviceFunctionPointer<vulkan.PFN_vkGetAndroidHardwareBufferPropertiesANDROID>
{
public PFN_vkGetAndroidHardwareBufferPropertiesANDROID(delegate*unmanaged[Stdcall]<vulkan.VkDevice, vulkan.AHardwareBuffer, vulkan.VkAndroidHardwareBufferPropertiesANDROID*, vulkan.VkResult> value) => this.Value = value;

Expand Down Expand Up @@ -443,7 +443,7 @@ public vulkan.VkResult Invoke(vulkan.VkDevice device, vulkan.AHardwareBuffer buf
public bool IsNull => (nint)Value == 0;
}

public readonly partial struct PFN_vkGetMemoryAndroidHardwareBufferANDROID : IEquatable<vulkan.PFN_vkGetMemoryAndroidHardwareBufferANDROID>, IvkFunctionPointer<vulkan.PFN_vkGetMemoryAndroidHardwareBufferANDROID>
public readonly partial struct PFN_vkGetMemoryAndroidHardwareBufferANDROID : IEquatable<vulkan.PFN_vkGetMemoryAndroidHardwareBufferANDROID>, IvkDeviceFunctionPointer<vulkan.PFN_vkGetMemoryAndroidHardwareBufferANDROID>
{
public PFN_vkGetMemoryAndroidHardwareBufferANDROID(delegate*unmanaged[Stdcall]<vulkan.VkDevice, vulkan.VkMemoryGetAndroidHardwareBufferInfoANDROID*, vulkan.AHardwareBuffer*, vulkan.VkResult> value) => this.Value = value;

Expand Down
Loading

0 comments on commit 6f9730e

Please sign in to comment.