浏览代码

Vulkan backend (#12737)

* Ported the old Vulkan PR

* chop-chop

* Support for external objects in vulkan backend

* Fixed structure type

* Removed debug code

* sln fix

* Don't force vulkan on windows
Nikita Tsukanov 1 年之前
父节点
当前提交
3a1a69b145
共有 57 个文件被更改,包括 6238 次插入49 次删除
  1. 1 0
      Avalonia.Desktop.slnf
  2. 6 0
      Avalonia.sln
  3. 2 1
      Avalonia.sln.DotSettings
  4. 1 0
      build/CoreLibraries.props
  5. 10 2
      samples/ControlCatalog.NetCore/Program.cs
  6. 19 1
      samples/GpuInterop/Program.cs
  7. 1 1
      samples/GpuInterop/VulkanDemo/VulkanContent.cs
  8. 7 2
      samples/GpuInterop/VulkanDemo/VulkanContext.cs
  9. 52 24
      samples/GpuInterop/VulkanDemo/VulkanImage.cs
  10. 30 2
      samples/GpuInterop/VulkanDemo/VulkanSemaphorePair.cs
  11. 7 12
      samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs
  12. 1 0
      src/Avalonia.Base/Avalonia.Base.csproj
  13. 3 0
      src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs
  14. 8 0
      src/Avalonia.Base/Platform/PlatformGraphicsExternalMemory.cs
  15. 17 0
      src/Avalonia.Vulkan/Avalonia.Vulkan.csproj
  16. 33 0
      src/Avalonia.Vulkan/IVulkanContextExternalObjectsFeature.cs
  17. 41 0
      src/Avalonia.Vulkan/IVulkanDevice.cs
  18. 15 0
      src/Avalonia.Vulkan/IVulkanPlatformSurface.cs
  19. 20 0
      src/Avalonia.Vulkan/IVulkanRenderTarget.cs
  20. 107 0
      src/Avalonia.Vulkan/Interop/VulkanCommandBuffer.cs
  21. 71 0
      src/Avalonia.Vulkan/Interop/VulkanCommandBufferPool.cs
  22. 37 0
      src/Avalonia.Vulkan/Interop/VulkanDebugLogger.cs
  23. 166 0
      src/Avalonia.Vulkan/Interop/VulkanDevice.Create.cs
  24. 66 0
      src/Avalonia.Vulkan/Interop/VulkanDevice.cs
  25. 328 0
      src/Avalonia.Vulkan/Interop/VulkanDisplay.cs
  26. 40 0
      src/Avalonia.Vulkan/Interop/VulkanFence.cs
  27. 197 0
      src/Avalonia.Vulkan/Interop/VulkanImage.cs
  28. 179 0
      src/Avalonia.Vulkan/Interop/VulkanInstance.cs
  29. 69 0
      src/Avalonia.Vulkan/Interop/VulkanKhrSurface.cs
  30. 67 0
      src/Avalonia.Vulkan/Interop/VulkanMemoryHelper.cs
  31. 58 0
      src/Avalonia.Vulkan/Interop/VulkanSemaphore.cs
  32. 46 0
      src/Avalonia.Vulkan/UnmanagedInterop/Utf8BufferArray.cs
  33. 154 0
      src/Avalonia.Vulkan/UnmanagedInterop/VulkanDeviceApi.cs
  34. 2190 0
      src/Avalonia.Vulkan/UnmanagedInterop/VulkanEnums.cs
  35. 29 0
      src/Avalonia.Vulkan/UnmanagedInterop/VulkanGlobalApi.cs
  36. 82 0
      src/Avalonia.Vulkan/UnmanagedInterop/VulkanInstanceApi.cs
  37. 767 0
      src/Avalonia.Vulkan/UnmanagedInterop/VulkanStructs.cs
  38. 19 0
      src/Avalonia.Vulkan/VulkanBindings.cs
  39. 73 0
      src/Avalonia.Vulkan/VulkanContext.cs
  40. 34 0
      src/Avalonia.Vulkan/VulkanException.cs
  41. 311 0
      src/Avalonia.Vulkan/VulkanExternalObjectsFeature.cs
  42. 19 0
      src/Avalonia.Vulkan/VulkanImageInfo.cs
  43. 107 0
      src/Avalonia.Vulkan/VulkanKhrSurfaceRenderTarget.cs
  44. 73 0
      src/Avalonia.Vulkan/VulkanOptions.cs
  45. 103 0
      src/Avalonia.Vulkan/VulkanPlatformGraphics.cs
  46. 29 0
      src/Avalonia.X11/Vulkan/VulkanNativeInterop.cs
  47. 94 0
      src/Avalonia.X11/Vulkan/VulkanSupport.cs
  48. 17 2
      src/Avalonia.X11/X11Platform.cs
  49. 124 0
      src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaExternalObjectsFeature.cs
  50. 86 0
      src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs
  51. 105 0
      src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs
  52. 4 0
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  53. 27 0
      src/Windows/Avalonia.Win32/Vulkan/VulkanNativeInterop.cs
  54. 71 0
      src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs
  55. 9 0
      src/Windows/Avalonia.Win32/Win32GlManager.cs
  56. 5 1
      src/Windows/Avalonia.Win32/Win32PlatformOptions.cs
  57. 1 1
      src/Windows/Avalonia.Win32/WindowImpl.cs

+ 1 - 0
Avalonia.Desktop.slnf

@@ -30,6 +30,7 @@
       "src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj",
       "src\\Avalonia.Native\\Avalonia.Native.csproj",
       "src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj",
+      "src\\Avalonia.Vulkan\\Avalonia.Vulkan.csproj",
       "src\\Avalonia.ReactiveUI\\Avalonia.ReactiveUI.csproj",
       "src\\Avalonia.Remote.Protocol\\Avalonia.Remote.Protocol.csproj",
       "src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj",

+ 6 - 0
Avalonia.sln

@@ -298,6 +298,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnloadableAssemblyLoadConte
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnloadableAssemblyLoadContextPlug", "samples\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContextPlug\UnloadableAssemblyLoadContextPlug.csproj", "{DA5F1FF9-4259-4C54-B443-85CFA226EE6A}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Vulkan", "src\Avalonia.Vulkan\Avalonia.Vulkan.csproj", "{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}"
+EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.RenderTests.WpfCompare", "tests\Avalonia.RenderTests.WpfCompare\Avalonia.RenderTests.WpfCompare.csproj", "{9AE1B827-21AC-4063-AB22-C8804B7F931E}"
 EndProject
 Global
@@ -676,6 +678,10 @@ Global
 		{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Release|Any CPU.Build.0 = Release|Any CPU
 		{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}.Release|Any CPU.ActiveCfg = Release|Any CPU

+ 2 - 1
Avalonia.sln.DotSettings

@@ -39,4 +39,5 @@
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/UserDictionary/Words/=Activatable/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/UserDictionary/Words/=Fcitx/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+	<s:Boolean x:Key="/Default/UserDictionary/Words/=Fcitx/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/UserDictionary/Words/=swapchain/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 1 - 0
build/CoreLibraries.props

@@ -5,6 +5,7 @@
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.OpenGL/Avalonia.OpenGL.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Metal/Avalonia.Metal.csproj" />
+      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Vulkan/Avalonia.Vulkan.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj" />

+ 10 - 2
samples/ControlCatalog.NetCore/Program.cs

@@ -13,7 +13,7 @@ using Avalonia.LinuxFramebuffer.Output;
 using Avalonia.LogicalTree;
 using Avalonia.Rendering.Composition;
 using Avalonia.Threading;
-
+using Avalonia.Vulkan;
 using ControlCatalog.Pages;
 
 namespace ControlCatalog.NetCore
@@ -133,7 +133,15 @@ namespace ControlCatalog.NetCore
                 {
                     EnableMultiTouch = true,
                     UseDBusMenu = true,
-                    EnableIme = true
+                    EnableIme = true,
+                })
+
+                .With(new VulkanOptions
+                {
+                    VulkanInstanceCreationOptions = new ()
+                    {
+                        UseDebug = true
+                    }
                 })
                 .With(new CompositionOptions()
                 {

+ 19 - 1
samples/GpuInterop/Program.cs

@@ -1,5 +1,8 @@
 global using System.Reactive.Disposables;
 using Avalonia;
+using Avalonia.Logging;
+using Avalonia.Vulkan;
+
 namespace GpuInterop
 {
     public class Program
@@ -10,6 +13,21 @@ namespace GpuInterop
         public static AppBuilder BuildAvaloniaApp() =>
             AppBuilder.Configure<App>()
                 .UsePlatformDetect()
-                .LogToTrace();
+                .With(new Win32PlatformOptions
+                {
+                    RenderingMode = new []
+                    {
+                        Win32RenderingMode.Vulkan
+                    }
+                })
+                .With(new X11PlatformOptions(){RenderingMode =new[] { X11RenderingMode.Vulkan } })
+                .With(new VulkanOptions()
+                {
+                    VulkanInstanceCreationOptions = new VulkanInstanceCreationOptions()
+                    {
+                        UseDebug = true
+                    }
+                })
+                .LogToTrace(LogEventLevel.Debug, "Vulkan");
     }
 }

+ 1 - 1
samples/GpuInterop/VulkanDemo/VulkanContent.cs

@@ -397,7 +397,7 @@ unsafe class VulkanContent : IDisposable
             Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)size.Width / size.Height,
                 0.01f, 1000);
         
-        _colorAttachment = new VulkanImage(_context, (uint)Format.R8G8B8A8Unorm, size, false);
+        _colorAttachment = new VulkanImage(_context, (uint)Format.R8G8B8A8Unorm, size, false, Array.Empty<string>());
         CreateDepthAttachment(size);
 
         var api = _context.Api;

+ 7 - 2
samples/GpuInterop/VulkanDemo/VulkanContext.cs

@@ -101,8 +101,10 @@ public unsafe class VulkanContext : IDisposable
 
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
-                if (!gpuInterop.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes
+                if (!(gpuInterop.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes
                         .D3D11TextureGlobalSharedHandle)
+                    || gpuInterop.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes
+                        .VulkanOpaqueNtHandle))
                    )
                     return (null, "Image sharing is not supported by the current backend");
                 requireDeviceExtensions.Add(KhrExternalMemoryWin32.ExtensionName);
@@ -240,10 +242,13 @@ public unsafe class VulkanContext : IDisposable
                         }
                     });
                     
+                    
 
                     D3DDevice? d3dDevice = null;
                     if (physicalDeviceIDProperties.DeviceLuidvalid &&
-                        RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+                        RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
+                        !gpuInterop.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueNtHandle)
+                        )
                         d3dDevice = D3DMemoryHelper.CreateDeviceByLuid(
                             new Span<byte>(physicalDeviceIDProperties.DeviceLuid, 8));
 

+ 52 - 24
samples/GpuInterop/VulkanDemo/VulkanImage.cs

@@ -1,5 +1,7 @@
 using System;
+using System.Collections.Generic;
 using System.IO;
+using System.Linq;
 using System.Runtime.InteropServices;
 using Avalonia;
 using Avalonia.Platform;
@@ -44,7 +46,7 @@ public unsafe class VulkanImage : IDisposable
         public uint CurrentLayout => (uint) _currentLayout;
 
         public VulkanImage(VulkanContext vk, uint format, PixelSize size,
-            bool exportable, uint mipLevels = 0)
+            bool exportable, IReadOnlyList<string> supportedHandleTypes)
         {
             _vk = vk;
             _instance = vk.Instance;
@@ -62,8 +64,12 @@ public unsafe class VulkanImage : IDisposable
             //MipLevels = MipLevels != 0 ? MipLevels : (uint)Math.Floor(Math.Log(Math.Max(Size.Width, Size.Height), 2));
 
             var handleType = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
-                ExternalMemoryHandleTypeFlags.D3D11TextureBit :
+                (supportedHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle)
+                 && !supportedHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueNtHandle) ?
+                    ExternalMemoryHandleTypeFlags.D3D11TextureBit :
+                    ExternalMemoryHandleTypeFlags.OpaqueWin32Bit) :
                 ExternalMemoryHandleTypeFlags.OpaqueFDBit;
+            
             var externalMemoryCreateInfo = new ExternalMemoryImageCreateInfo
             {
                 SType = StructureType.ExternalMemoryImageCreateInfo,
@@ -96,35 +102,37 @@ public unsafe class VulkanImage : IDisposable
             Api.GetImageMemoryRequirements(_device, InternalHandle,
                 out var memoryRequirements);
 
-
-            var fdExport = new ExportMemoryAllocateInfo
-            {
-                HandleTypes = handleType, SType = StructureType.ExportMemoryAllocateInfo
-            };
             var dedicatedAllocation = new MemoryDedicatedAllocateInfoKHR
             {
                 SType = StructureType.MemoryDedicatedAllocateInfoKhr,
                 Image = image
             };
+            
+            var fdExport = new ExportMemoryAllocateInfo
+            {
+                HandleTypes = handleType, SType = StructureType.ExportMemoryAllocateInfo,
+                PNext = &dedicatedAllocation
+            };
+
             ImportMemoryWin32HandleInfoKHR handleImport = default;
-            if (exportable && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            if (handleType == ExternalMemoryHandleTypeFlags.D3D11TextureBit && exportable)
             {
-                 _d3dTexture2D = D3DMemoryHelper.CreateMemoryHandle(vk.D3DDevice!, size, Format);
-                 using var dxgi = _d3dTexture2D.QueryInterface<SharpDX.DXGI.Resource1>();
-                 
-                 handleImport = new ImportMemoryWin32HandleInfoKHR
-                 {
-                     PNext = &dedicatedAllocation,
-                     SType = StructureType.ImportMemoryWin32HandleInfoKhr,
-                     HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureBit,
-                     Handle = dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write),
-                 };
+                _d3dTexture2D = D3DMemoryHelper.CreateMemoryHandle(vk.D3DDevice, size, Format);
+                using var dxgi = _d3dTexture2D.QueryInterface<SharpDX.DXGI.Resource1>();
+
+                handleImport = new ImportMemoryWin32HandleInfoKHR
+                {
+                    PNext = &dedicatedAllocation,
+                    SType = StructureType.ImportMemoryWin32HandleInfoKhr,
+                    HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureBit,
+                    Handle = dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write),
+                };
             }
 
             var memoryAllocateInfo = new MemoryAllocateInfo
             {
                 PNext =
-                    exportable ? RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? &handleImport : &fdExport : null,
+                    exportable ? handleImport.Handle != IntPtr.Zero  ? &handleImport : &fdExport : null,
                 SType = StructureType.MemoryAllocateInfo,
                 AllocationSize = memoryRequirements.Size,
                 MemoryTypeIndex = (uint)VulkanMemoryHelper.FindSuitableMemoryTypeIndex(
@@ -187,14 +195,34 @@ public unsafe class VulkanImage : IDisposable
             return fd;
         }
         
+        public IntPtr ExportOpaqueNtHandle()
+        {
+            if (!Api.TryGetDeviceExtension<KhrExternalMemoryWin32>(_instance, _device, out var ext))
+                throw new InvalidOperationException();
+            var info = new MemoryGetWin32HandleInfoKHR()
+            {
+                Memory = _imageMemory,
+                SType = StructureType.MemoryGetWin32HandleInfoKhr,
+                HandleType = ExternalMemoryHandleTypeFlags.OpaqueWin32Bit
+            };
+            ext.GetMemoryWin32Handle(_device, info, out var fd).ThrowOnError();
+            return fd;
+        }
+        
         public IPlatformHandle Export()
         {
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
-                using var dxgi = _d3dTexture2D!.QueryInterface<Resource1>();
-                return new PlatformHandle(
-                    dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write),
-                    KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle);
+                if (_d3dTexture2D != null)
+                {
+                    using var dxgi = _d3dTexture2D!.QueryInterface<Resource1>();
+                    return new PlatformHandle(
+                        dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write),
+                        KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle);
+                }
+
+                return new PlatformHandle(ExportOpaqueNtHandle(),
+                    KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueNtHandle);
             }
             else
                 return new PlatformHandle(new IntPtr(ExportFd()),
@@ -203,7 +231,7 @@ public unsafe class VulkanImage : IDisposable
 
         public ImageTiling Tiling => ImageTiling.Optimal;
 
-        
+        public bool IsDirectXBacked => _d3dTexture2D != null;
         
         internal void TransitionLayout(CommandBuffer commandBuffer,
             ImageLayout fromLayout, AccessFlags fromAccessFlags,

+ 30 - 2
samples/GpuInterop/VulkanDemo/VulkanSemaphorePair.cs

@@ -1,4 +1,6 @@
 using System;
+using System.Runtime.InteropServices;
+using Avalonia.Platform;
 using Silk.NET.Vulkan;
 using Silk.NET.Vulkan.Extensions.KHR;
 using SilkNetDemo;
@@ -16,7 +18,9 @@ class VulkanSemaphorePair : IDisposable
         var semaphoreExportInfo = new ExportSemaphoreCreateInfo
         {
             SType = StructureType.ExportSemaphoreCreateInfo,
-            HandleTypes = ExternalSemaphoreHandleTypeFlags.OpaqueFDBit
+            HandleTypes = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
+                ExternalSemaphoreHandleTypeFlags.OpaqueWin32Bit :
+                ExternalSemaphoreHandleTypeFlags.OpaqueFDBit
         };
 
         var semaphoreCreateInfo = new SemaphoreCreateInfo
@@ -46,6 +50,30 @@ class VulkanSemaphorePair : IDisposable
         ext.GetSemaphoreF(_resources.Device, info, out var fd).ThrowOnError();
         return fd;
     }
+    
+    public IntPtr ExportWin32(bool renderFinished)
+    {
+        if (!_resources.Api.TryGetDeviceExtension<KhrExternalSemaphoreWin32>(_resources.Instance, _resources.Device,
+                out var ext))
+            throw new InvalidOperationException();
+        var info = new SemaphoreGetWin32HandleInfoKHR()
+        {
+            SType = StructureType.SemaphoreGetWin32HandleInfoKhr,
+            Semaphore = renderFinished ? RenderFinishedSemaphore : ImageAvailableSemaphore,
+            HandleType = ExternalSemaphoreHandleTypeFlags.OpaqueWin32Bit
+        };
+        ext.GetSemaphoreWin32Handle(_resources.Device, info, out var fd).ThrowOnError();
+        return fd;
+    }
+
+    public IPlatformHandle Export(bool renderFinished)
+    {
+        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            return new PlatformHandle(ExportWin32(renderFinished),
+                KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueNtHandle);
+        return new PlatformHandle(new IntPtr(ExportFd(renderFinished)),
+            KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor);
+    }
 
     internal Semaphore ImageAvailableSemaphore { get; }
     internal Semaphore RenderFinishedSemaphore { get; }
@@ -55,4 +83,4 @@ class VulkanSemaphorePair : IDisposable
         _resources.Api.DestroySemaphore(_resources.Device, ImageAvailableSemaphore, null);
         _resources.Api.DestroySemaphore(_resources.Device, RenderFinishedSemaphore, null);
     }
-}
+}

+ 7 - 12
samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs

@@ -52,7 +52,7 @@ class VulkanSwapchainImage : ISwapchainImage
         _interop = interop;
         _target = target;
         Size = size;
-        _image = new VulkanImage(vk, (uint)Format.R8G8B8A8Unorm, size, true);
+        _image = new VulkanImage(vk, (uint)Format.R8G8B8A8Unorm, size, true, interop.SupportedImageHandleTypes);
         _semaphorePair = new VulkanSemaphorePair(vk, true);
     }
 
@@ -83,7 +83,7 @@ class VulkanSwapchainImage : ISwapchainImage
             ImageLayout.Undefined, AccessFlags.None,
             ImageLayout.ColorAttachmentOptimal, AccessFlags.ColorAttachmentReadBit);
 
-        if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+        if(_image.IsDirectXBacked)
             buffer.Submit(null,null,null, null, new VulkanCommandBufferPool.VulkanCommandBuffer.KeyedMutexSubmitInfo
             {
                 AcquireKey = 0,
@@ -111,8 +111,7 @@ class VulkanSwapchainImage : ISwapchainImage
         _image.TransitionLayout(buffer.InternalHandle, ImageLayout.TransferSrcOptimal, AccessFlags.TransferWriteBit);
 
         
-        
-        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+        if (_image.IsDirectXBacked)
         {
             buffer.Submit(null, null, null, null,
                 new VulkanCommandBufferPool.VulkanCommandBuffer.KeyedMutexSubmitInfo
@@ -123,15 +122,11 @@ class VulkanSwapchainImage : ISwapchainImage
         else
             buffer.Submit(null, null, new[] { _semaphorePair.RenderFinishedSemaphore });
 
-        if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+        if (!_image.IsDirectXBacked)
         {
-            _availableSemaphore ??= _interop.ImportSemaphore(new PlatformHandle(
-                new IntPtr(_semaphorePair.ExportFd(false)),
-                KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor));
+            _availableSemaphore ??= _interop.ImportSemaphore(_semaphorePair.Export(false));
             
-            _renderCompletedSemaphore ??= _interop.ImportSemaphore(new PlatformHandle(
-                new IntPtr(_semaphorePair.ExportFd(true)),
-                KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor));
+            _renderCompletedSemaphore ??= _interop.ImportSemaphore(_semaphorePair.Export(true));
         }
 
         _importedImage ??= _interop.ImportImage(_image.Export(),
@@ -143,7 +138,7 @@ class VulkanSwapchainImage : ISwapchainImage
                 MemorySize = _image.MemorySize
             });
 
-        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+        if (_image.IsDirectXBacked)
             _lastPresent = _target.UpdateWithKeyedMutexAsync(_importedImage, 1, 0);
         else
             _lastPresent = _target.UpdateWithSemaphoresAsync(_importedImage, _renderCompletedSemaphore!, _availableSemaphore!);

+ 1 - 0
src/Avalonia.Base/Avalonia.Base.csproj

@@ -34,6 +34,7 @@
     <InternalsVisibleTo Include="Avalonia.Markup.Xaml, PublicKey=$(AvaloniaPublicKey)" />
     <InternalsVisibleTo Include="Avalonia.Markup.Xaml.Loader, PublicKey=$(AvaloniaPublicKey)" />
     <InternalsVisibleTo Include="Avalonia.OpenGL, PublicKey=$(AvaloniaPublicKey)" />
+    <InternalsVisibleTo Include="Avalonia.Vulkan, PublicKey=$(AvaloniaPublicKey)" />
     <InternalsVisibleTo Include="Avalonia.Skia, PublicKey=$(AvaloniaPublicKey)" />
     <InternalsVisibleTo Include="Avalonia.Controls.ColorPicker, PublicKey=$(AvaloniaPublicKey)" />
     <InternalsVisibleTo Include="Avalonia.Controls.DataGrid, PublicKey=$(AvaloniaPublicKey)" />

+ 3 - 0
src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs

@@ -56,5 +56,8 @@ namespace Avalonia.Platform.Interop
                 ArrayPool<byte>.Shared.Return(bytes);
             }
         }
+
+        public static implicit operator IntPtr(Utf8Buffer b) => b.handle;
+        public static unsafe implicit operator byte*(Utf8Buffer b) => (byte*)b.handle;
     }
 }

+ 8 - 0
src/Avalonia.Base/Platform/PlatformGraphicsExternalMemory.cs

@@ -35,6 +35,14 @@ public static class KnownPlatformGraphicsExternalImageHandleTypes
     /// A POSIX file descriptor that's exported by Vulkan using VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT or in a compatible way
     /// </summary>
     public const string VulkanOpaquePosixFileDescriptor = nameof(VulkanOpaquePosixFileDescriptor);
+    
+    /// <summary>
+    /// A NT handle that's been exported by Vulkan using VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT or in a compatible way
+    /// </summary>
+    public const string VulkanOpaqueNtHandle = nameof(VulkanOpaqueNtHandle);
+    
+    // A global shared handle that's been exported by Vulkan using VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT or in a compatible way
+    public const string VulkanOpaqueKmtHandle = nameof(VulkanOpaqueKmtHandle);
 }
 
 /// <summary>

+ 17 - 0
src/Avalonia.Vulkan/Avalonia.Vulkan.csproj

@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
+        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
+      <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" />
+    </ItemGroup>
+
+    <Import Project="..\..\build\DevAnalyzers.props" />
+    <Import Project="..\..\build\SourceGenerators.props" />
+    <Import Project="..\..\build\TrimmingEnable.props" />
+    <Import Project="..\..\build\NullableEnable.props" />
+</Project>

+ 33 - 0
src/Avalonia.Vulkan/IVulkanContextExternalObjectsFeature.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Metadata;
+using Avalonia.Platform;
+using Avalonia.Rendering.Composition;
+
+namespace Avalonia.Vulkan;
+
+[Unstable]
+public interface IVulkanContextExternalObjectsFeature
+{
+    IReadOnlyList<string> SupportedImageHandleTypes { get; }
+    IReadOnlyList<string> SupportedSemaphoreTypes { get; }
+    byte[]? DeviceUuid { get; }
+    byte[]? DeviceLuid { get; }
+    CompositionGpuImportedImageSynchronizationCapabilities GetSynchronizationCapabilities(string imageHandleType);
+    IVulkanExternalImage ImportImage(IPlatformHandle handle, PlatformGraphicsExternalImageProperties properties);
+    IVulkanExternalSemaphore ImportSemaphore(IPlatformHandle handle);
+}
+
+[Unstable]
+public interface IVulkanExternalSemaphore : IDisposable
+{
+    ulong Handle { get; }
+    void SubmitWaitSemaphore();
+    void SubmitSignalSemaphore();
+}
+
+[Unstable]
+public interface IVulkanExternalImage : IDisposable
+{
+    VulkanImageInfo Info { get; }
+}

+ 41 - 0
src/Avalonia.Vulkan/IVulkanDevice.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Metadata;
+using Avalonia.Platform;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+public interface IVulkanDevice : IDisposable, IOptionalFeatureProvider
+{
+    public IntPtr Handle { get; }
+    public IntPtr PhysicalDeviceHandle { get; }
+    public IntPtr MainQueueHandle { get; }
+    public uint GraphicsQueueFamilyIndex { get; }
+    public IVulkanInstance Instance { get; }
+    bool IsLost { get; }
+    public IDisposable Lock();
+    public IEnumerable<string> EnabledExtensions { get; }
+}
+
+public interface IVulkanInstance
+{
+    public IntPtr Handle { get; }
+    public IntPtr GetInstanceProcAddress(IntPtr instance, string name);
+    public IntPtr GetDeviceProcAddress(IntPtr device, string name);
+    public IEnumerable<string> EnabledExtensions { get; }
+}
+
+[NotClientImplementable]
+public interface IVulkanPlatformGraphicsContext : IPlatformGraphicsContext
+{
+    IVulkanDevice Device { get; }
+    IVulkanInstance Instance { get; }
+    internal VulkanInstanceApi InstanceApi { get; }
+    internal VulkanDeviceApi DeviceApi { get; }
+    internal VkDevice DeviceHandle { get; }
+    internal VkPhysicalDevice PhysicalDeviceHandle { get; }
+    internal VkInstance InstanceHandle { get; }
+    internal VkQueue MainQueueHandle { get; }
+    internal uint GraphicsQueueFamilyIndex { get; }
+    IVulkanRenderTarget CreateRenderTarget(IEnumerable<object> surfaces);
+}

+ 15 - 0
src/Avalonia.Vulkan/IVulkanPlatformSurface.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace Avalonia.Vulkan;
+public interface IVulkanKhrSurfacePlatformSurface : IDisposable
+{
+    double Scaling { get; }
+    PixelSize Size { get; }
+    ulong CreateSurface(IVulkanPlatformGraphicsContext context);
+}
+
+public interface IVulkanKhrSurfacePlatformSurfaceFactory
+{
+    bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface);
+    IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object surface);
+}

+ 20 - 0
src/Avalonia.Vulkan/IVulkanRenderTarget.cs

@@ -0,0 +1,20 @@
+using System;
+using Avalonia.Metadata;
+
+namespace Avalonia.Vulkan;
+
+[NotClientImplementable]
+public interface IVulkanRenderTarget : IDisposable
+{
+    IVulkanRenderSession BeginDraw();
+}
+
+[NotClientImplementable]
+public interface IVulkanRenderSession : IDisposable
+{
+    double Scaling { get; }
+    PixelSize Size { get; }
+    public bool IsYFlipped { get; }
+    VulkanImageInfo ImageInfo { get; }
+    bool IsRgba { get; }
+}

+ 107 - 0
src/Avalonia.Vulkan/Interop/VulkanCommandBuffer.cs

@@ -0,0 +1,107 @@
+using System;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan.Interop;
+
+internal class VulkanCommandBuffer : IDisposable
+{
+    private readonly VulkanCommandBufferPool _pool;
+    private VkCommandBuffer _handle;
+    private readonly IVulkanPlatformGraphicsContext _context;
+    private VulkanFence _fence;
+    private bool _hasEnded;
+    private bool _hasStarted;
+    public VkCommandBuffer Handle => _handle;
+
+    public VulkanCommandBuffer(VulkanCommandBufferPool pool, VkCommandBuffer handle, IVulkanPlatformGraphicsContext context)
+    {
+        _pool = pool;
+        _handle = handle;
+        _context = context;
+        _fence = new VulkanFence(context, VkFenceCreateFlags.VK_FENCE_CREATE_SIGNALED_BIT);
+    }
+
+    public unsafe void Dispose()
+    {
+        if (_fence.Handle.Handle != 0)
+            _fence.Wait();
+        _fence.Dispose();
+        if (_handle.Handle != IntPtr.Zero)
+        {
+            VkCommandBuffer buf = _handle;
+            _context.DeviceApi.FreeCommandBuffers(_context.DeviceHandle, _pool.Handle, 1, &buf);
+            _handle = default;
+        }
+    }
+
+    public bool IsFinished => _fence.IsSignaled;
+
+    public void BeginRecording()
+    {
+        if (_hasStarted)
+            return;
+
+        var beginInfo = new VkCommandBufferBeginInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+            flags = VkCommandBufferUsageFlags.VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
+        };
+
+        _context.DeviceApi.BeginCommandBuffer(_handle, ref beginInfo).ThrowOnError("vkBeginCommandBuffer");
+        _hasStarted = true;
+    }
+
+    public void EndRecording()
+    {
+        if (_hasStarted && !_hasEnded)
+        {
+            _context.DeviceApi.EndCommandBuffer(_handle).ThrowOnError("vkEndCommandBuffer");
+            _hasEnded = true;
+        }
+    }
+
+    public void Submit()
+    {
+        Submit(null, null, null);
+    }
+    
+    public unsafe void Submit(
+        ReadOnlySpan<VulkanSemaphore> waitSemaphores,
+        ReadOnlySpan<VkPipelineStageFlags> waitDstStageMask,
+        ReadOnlySpan<VulkanSemaphore> signalSemaphores,
+        VulkanFence? fence = null)
+    {
+        
+        EndRecording();
+        VkFence fenceHandle = (fence ?? _fence).Handle;
+        _context.DeviceApi.ResetFences(_context.DeviceHandle, 1, &fenceHandle)
+            .ThrowOnError("vkResetFences");
+        
+        var pWaitSempaphores = stackalloc VkSemaphore[waitSemaphores.Length];
+        for (var c = 0; c < waitSemaphores.Length; c++)
+            pWaitSempaphores[c] = waitSemaphores[c].Handle;
+        
+        var pSignalSemaphores = stackalloc VkSemaphore[signalSemaphores.Length];
+        for (var c = 0; c < signalSemaphores.Length; c++)
+            pSignalSemaphores[c] = signalSemaphores[c].Handle;
+
+        VkCommandBuffer commandBuffer = _handle;
+        fixed (VkPipelineStageFlags* flags = waitDstStageMask)
+        {
+            var submitInfo = new VkSubmitInfo
+            {
+                sType = VkStructureType.VK_STRUCTURE_TYPE_SUBMIT_INFO,
+                waitSemaphoreCount = (uint)waitSemaphores.Length,
+                pWaitSemaphores = pWaitSempaphores,
+                signalSemaphoreCount = (uint)signalSemaphores.Length,
+                pSignalSemaphores = pSignalSemaphores,
+                commandBufferCount = 1,
+                pCommandBuffers = &commandBuffer,
+                pWaitDstStageMask = flags
+            };
+            _context.DeviceApi.QueueSubmit(_context.MainQueueHandle, 1, &submitInfo, fenceHandle)
+                .ThrowOnError("vkQueueSubmit");
+        }
+        _pool.AddSubmittedCommandBuffer(this);
+    }
+}

+ 71 - 0
src/Avalonia.Vulkan/Interop/VulkanCommandBufferPool.cs

@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan.Interop;
+
+internal class VulkanCommandBufferPool : IDisposable
+{
+    private readonly IVulkanPlatformGraphicsContext _context;
+    private readonly Queue<VulkanCommandBuffer> _commandBuffers = new();
+    private VkCommandPool _handle;
+    public VkCommandPool Handle => _handle;
+
+    public VulkanCommandBufferPool(IVulkanPlatformGraphicsContext context)
+    {
+        _context = context;
+        var createInfo = new VkCommandPoolCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+            flags = VkCommandPoolCreateFlags.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
+            queueFamilyIndex = context.GraphicsQueueFamilyIndex
+        };
+        _context.DeviceApi.CreateCommandPool(_context.DeviceHandle, ref createInfo, IntPtr.Zero, out _handle)
+            .ThrowOnError("vkCreateCommandPool");
+    }
+
+    public void FreeUsedCommandBuffers()
+    {
+        while (_commandBuffers.Count > 0)
+            _commandBuffers.Dequeue().Dispose();
+    }
+    
+    public void FreeFinishedCommandBuffers()
+    {
+        while (_commandBuffers.Count > 0)
+        {
+            var next = _commandBuffers.Peek();
+            if(!next.IsFinished)
+                return;
+            _commandBuffers.Dequeue();
+            next.Dispose();
+        }
+    }
+
+    public void Dispose()
+    {
+        FreeUsedCommandBuffers();
+        
+        if (_handle.Handle != 0)
+            _context.DeviceApi.DestroyCommandPool(_context.DeviceHandle, _handle, IntPtr.Zero);
+        _handle = default;
+    }
+
+    public unsafe VulkanCommandBuffer CreateCommandBuffer()
+    {
+        var commandBufferAllocateInfo = new VkCommandBufferAllocateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+            commandPool = _handle,
+            commandBufferCount = 1,
+            level = VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY
+        };
+        VkCommandBuffer bufferHandle = default;
+        _context.DeviceApi.AllocateCommandBuffers(_context.DeviceHandle, ref commandBufferAllocateInfo,
+            &bufferHandle).ThrowOnError("vkAllocateCommandBuffers");
+
+        return new VulkanCommandBuffer(this, bufferHandle, _context);
+    }
+    
+    public void AddSubmittedCommandBuffer(VulkanCommandBuffer buffer) => _commandBuffers.Enqueue(buffer);
+}

+ 37 - 0
src/Avalonia.Vulkan/Interop/VulkanDebugLogger.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Runtime.InteropServices;
+using Avalonia.Logging;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan.Interop;
+
+unsafe static class VulkanDebugLogger
+{
+    private static VkDebugUtilsMessengerCallbackEXTDelegate s_Delegate = WriteLogEvent;
+    public static IntPtr CallbackPtr { get;  } = Marshal.GetFunctionPointerForDelegate(s_Delegate);
+
+    private static uint WriteLogEvent(VkDebugUtilsMessageSeverityFlagsEXT messageSeverity,
+        VkDebugUtilsMessageTypeFlagsEXT messagetypes,
+        VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+        void* puserdata)
+    {
+        var level = messageSeverity switch
+        {
+            VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT => LogEventLevel.Error,
+            VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT =>
+                LogEventLevel.Warning,
+            VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT =>
+                LogEventLevel.Verbose,
+            VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT => LogEventLevel
+                .Information,
+            _ => LogEventLevel.Information
+        };
+        if (Logger.TryGet(level, "Vulkan", out var logger))
+        {
+            var msg  =Marshal.PtrToStringAnsi((nint)pCallbackData->pMessage);
+            logger.Log("Vulkan", "Vulkan: {0}", msg);
+        }
+        
+        return 0;
+    }
+}

+ 166 - 0
src/Avalonia.Vulkan/Interop/VulkanDevice.Create.cs

@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan.Interop;
+
+internal unsafe partial class VulkanDevice
+{
+    public static IVulkanDevice Create(IVulkanInstance instance,
+        VulkanDeviceCreationOptions options, VulkanPlatformSpecificOptions platformOptions)
+    {
+        uint deviceCount = 0;
+        var api = new VulkanInstanceApi(instance);
+        var vkInstance = new VkInstance(instance.Handle);
+        api.EnumeratePhysicalDevices(vkInstance, ref deviceCount, null)
+            .ThrowOnError("vkEnumeratePhysicalDevices");
+
+        if (deviceCount == 0)
+            throw new VulkanException("No devices found");
+
+        var devices = stackalloc VkPhysicalDevice[(int)deviceCount];
+        api.EnumeratePhysicalDevices(vkInstance, ref deviceCount, devices)
+            .ThrowOnError("vkEnumeratePhysicalDevices");
+
+        var surfaceForProbePtr = platformOptions.DeviceCheckSurfaceFactory?.Invoke(api.Instance);
+        var surfaceForProbe = surfaceForProbePtr.HasValue && surfaceForProbePtr.Value != 0
+            ? new VkSurfaceKHR(surfaceForProbePtr.Value)
+            : (VkSurfaceKHR?)null;
+
+        DeviceInfo? compatibleDevice = null, discreteDevice = null;
+
+        for (var c = 0; c < deviceCount; c++)
+        {
+            var info = CheckDevice(api, devices[c], options, surfaceForProbe);
+            if (info != null)
+            {
+                compatibleDevice ??= info;
+                if (info.Value.Type == VkPhysicalDeviceType.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
+                    discreteDevice ??= info;
+            }
+
+            if (compatibleDevice != null && (discreteDevice != null || !options.PreferDiscreteGpu))
+                break;
+        }
+
+        if (options.PreferDiscreteGpu && discreteDevice != null)
+            compatibleDevice = discreteDevice;
+
+        if (compatibleDevice == null)
+            throw new VulkanException("No compatible devices found");
+
+        var dev = compatibleDevice.Value;
+
+        var queuePriorities = stackalloc float[(int)dev.QueueCount];
+        for (var c = 0; c < dev.QueueCount; c++)
+            queuePriorities[c] = 1f;
+
+        var queueCreateInfo = new VkDeviceQueueCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+            queueFamilyIndex = dev.QueueFamilyIndex,
+            queueCount = dev.QueueCount,
+            pQueuePriorities = queuePriorities,
+        };
+
+        var enableExtensions =
+            new HashSet<string>(options.DeviceExtensions.Concat(VulkanExternalObjectsFeature.RequiredDeviceExtensions));
+
+        var enabledExtensions = enableExtensions
+            .Intersect(dev.Extensions).Append(VK_KHR_swapchain).Distinct().ToArray();
+
+        using var pEnabledExtensions = new Utf8BufferArray(enabledExtensions);
+
+        var createInfo = new VkDeviceCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+            queueCreateInfoCount = 1,
+            pQueueCreateInfos = &queueCreateInfo,
+            ppEnabledExtensionNames = pEnabledExtensions,
+            enabledExtensionCount = pEnabledExtensions.UCount,
+        };
+
+        api.CreateDevice(dev.PhysicalDevice, ref createInfo, IntPtr.Zero, out var createdDevice)
+            .ThrowOnError("vkCreateDevice");
+
+        api.GetDeviceQueue(createdDevice, dev.QueueFamilyIndex, 0, out var createdQueue);
+
+        return new VulkanDevice(api.Instance, createdDevice, dev.PhysicalDevice, createdQueue,
+            dev.QueueFamilyIndex, enabledExtensions);
+
+    }
+
+    struct DeviceInfo
+    {
+        public VkPhysicalDevice PhysicalDevice;
+        public uint QueueFamilyIndex;
+        public VkPhysicalDeviceType Type;
+        public List<string> Extensions;
+        public uint QueueCount;
+    }
+
+    static List<string> GetDeviceExtensions(VulkanInstanceApi instance, VkPhysicalDevice physicalDevice)
+    {
+        uint propertyCount = 0;
+        instance.EnumerateDeviceExtensionProperties(physicalDevice, null, ref propertyCount, null);
+        var extensionProps = new VkExtensionProperties[propertyCount];
+        var extensions = new List<string>((int)propertyCount);
+        if (propertyCount != 0)
+            fixed (VkExtensionProperties* ptr = extensionProps)
+            {
+                instance.EnumerateDeviceExtensionProperties(physicalDevice, null, ref propertyCount, ptr);
+
+                for (var c = 0; c < propertyCount; c++)
+                    extensions.Add(Marshal.PtrToStringAnsi(new IntPtr(ptr[c].extensionName))!);
+            }
+
+        return extensions;
+    }
+
+    private const string VK_KHR_swapchain = "VK_KHR_swapchain";
+
+    static unsafe DeviceInfo? CheckDevice(VulkanInstanceApi instance, VkPhysicalDevice physicalDevice,
+        VulkanDeviceCreationOptions options, VkSurfaceKHR? surface)
+    {
+        instance.GetPhysicalDeviceProperties(physicalDevice, out var properties);
+
+        var supportedExtensions = GetDeviceExtensions(instance, physicalDevice);
+        if (!supportedExtensions.Contains(VK_KHR_swapchain))
+            return null;
+        
+        uint familyCount = 0;
+        instance.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref familyCount, null);
+        var familyProperties = stackalloc VkQueueFamilyProperties[(int)familyCount];
+        instance.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref familyCount, familyProperties);
+        var requredFlags = VkQueueFlags.VK_QUEUE_GRAPHICS_BIT;
+        if (options.RequireComputeBit)
+            requredFlags |= VkQueueFlags.VK_QUEUE_COMPUTE_BIT;
+
+        for (var c = 0; c < familyCount; c++)
+        {
+            if ((familyProperties[c].queueFlags & requredFlags) != requredFlags)
+                continue;
+            if (surface.HasValue)
+            {
+                instance.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, (uint)c, surface.Value, out var supported)
+                    .ThrowOnError("vkGetPhysicalDeviceSurfaceSupportKHR");
+                if (supported == 0)
+                    continue;
+            }
+
+            return new DeviceInfo
+            {
+                PhysicalDevice = physicalDevice,
+                Extensions = supportedExtensions,
+                Type = properties.deviceType,
+                QueueFamilyIndex = (uint)c,
+                QueueCount = familyProperties[c].queueCount
+            };
+
+        }
+
+        return null;
+    }
+}

+ 66 - 0
src/Avalonia.Vulkan/Interop/VulkanDevice.cs

@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Reactive;
+using System.Threading;
+using Avalonia.Platform;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+namespace Avalonia.Vulkan.Interop;
+
+internal partial class VulkanDevice : IVulkanDevice
+{
+    private readonly VkDevice _handle;
+    private readonly VkPhysicalDevice _physicalDeviceHandle;
+    private readonly VkQueue _mainQueue;
+    private readonly uint _graphicsQueueIndex;
+    private readonly object _lock = new();
+    private Thread? _lockedByThread;
+    private int _lockCount;
+
+    private VulkanDevice(IVulkanInstance instance, VkDevice handle, VkPhysicalDevice physicalDeviceHandle,
+        VkQueue mainQueue, uint graphicsQueueIndex, string[] enabledExtensions)
+    {
+        _handle = handle;
+        _physicalDeviceHandle = physicalDeviceHandle;
+        _mainQueue = mainQueue;
+        _graphicsQueueIndex = graphicsQueueIndex;
+        Instance = instance;
+        EnabledExtensions = enabledExtensions;
+    }
+
+    T CheckAccess<T>(T f)
+    {
+        if (_lockedByThread != Thread.CurrentThread)
+            throw new InvalidOperationException("This class is only usable when locked");
+        return f;
+    }
+
+    public IDisposable Lock()
+    {
+        Monitor.Enter(_lock);
+        _lockCount++;
+        _lockedByThread = Thread.CurrentThread;
+        return Disposable.Create(() =>
+        {
+            _lockCount--;
+            if (_lockCount == 0)
+                _lockedByThread = null;
+            Monitor.Exit(_lock);
+        });
+    }
+
+    public IEnumerable<string> EnabledExtensions { get; }
+
+    public bool IsLost => false;
+    public IntPtr Handle => _handle.Handle;
+    public IntPtr PhysicalDeviceHandle => _physicalDeviceHandle.Handle;
+    public IntPtr MainQueueHandle => CheckAccess(_mainQueue).Handle;
+    public uint GraphicsQueueFamilyIndex => _graphicsQueueIndex;
+    public IVulkanInstance Instance { get; }
+    public void Dispose()
+    {
+        // TODO
+    }
+
+    public object? TryGetFeature(Type featureType) => null;
+}

+ 328 - 0
src/Avalonia.Vulkan/Interop/VulkanDisplay.cs

@@ -0,0 +1,328 @@
+using System;
+using System.Linq;
+using System.Threading;
+using Avalonia.Vulkan.UnmanagedInterop;
+// ReSharper disable FieldCanBeMadeReadOnly.Local
+// ReSharper disable IdentifierTypo
+// ReSharper disable StringLiteralTypo
+
+namespace Avalonia.Vulkan.Interop;
+
+internal class VulkanDisplay : IDisposable
+{
+    private IVulkanPlatformGraphicsContext _context;
+    private VulkanSemaphorePair _semaphorePair;
+    private uint _nextImage;
+    private readonly VulkanKhrSurface _surface;
+    private VkSurfaceFormatKHR _surfaceFormat;
+    private VkSwapchainKHR _swapchain;
+    private VkExtent2D _swapchainExtent;
+    private VkImage[] _swapchainImages = Array.Empty<VkImage>();
+    private VkImageView[] _swapchainImageViews = Array.Empty<VkImageView>();
+    public VulkanCommandBufferPool CommandBufferPool { get; private set; }
+    public PixelSize Size { get; private set; }
+    
+    private VulkanDisplay(IVulkanPlatformGraphicsContext context, VulkanKhrSurface surface, VkSwapchainKHR swapchain,
+        VkExtent2D swapchainExtent)
+    {
+        _context = context;
+        _surface = surface;
+        _swapchain = swapchain;
+        _swapchainExtent = swapchainExtent;
+        _semaphorePair = new VulkanSemaphorePair(_context);
+        CommandBufferPool = new VulkanCommandBufferPool(_context);
+        CreateSwapchainImages();
+    }
+
+    internal VkSurfaceFormatKHR SurfaceFormat
+    {
+        get
+        {
+            if (_surfaceFormat.format == VkFormat.VK_FORMAT_UNDEFINED)
+                _surfaceFormat = _surface.GetSurfaceFormat();
+            return _surfaceFormat;
+        }
+    }
+
+    private static unsafe VkSwapchainKHR CreateSwapchain(IVulkanPlatformGraphicsContext context,
+        VulkanKhrSurface surface, out VkExtent2D swapchainExtent, VulkanDisplay? oldDisplay = null)
+    {
+        while (!surface.CanSurfacePresent())
+            Thread.Sleep(16);
+        context.InstanceApi.GetPhysicalDeviceSurfaceCapabilitiesKHR(context.PhysicalDeviceHandle,
+                surface.Handle, out var capabilities)
+            .ThrowOnError("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
+        uint presentModesCount = 0;
+        context.InstanceApi.GetPhysicalDeviceSurfacePresentModesKHR(context.PhysicalDeviceHandle,
+                surface.Handle, ref presentModesCount, null)
+            .ThrowOnError("vkGetPhysicalDeviceSurfacePresentModesKHR");
+
+        var modes = new VkPresentModeKHR[(int)presentModesCount];
+        fixed (VkPresentModeKHR* pModes = modes)
+            context.InstanceApi.GetPhysicalDeviceSurfacePresentModesKHR(context.PhysicalDeviceHandle,
+                    surface.Handle, ref presentModesCount, pModes)
+                .ThrowOnError("vkGetPhysicalDeviceSurfacePresentModesKHR");
+        
+        var imageCount = capabilities.minImageCount + 1;
+        if (capabilities.maxImageCount > 0 && imageCount > capabilities.maxImageCount)
+            imageCount = capabilities.maxImageCount;
+        
+        var surfaceFormat = surface.GetSurfaceFormat();
+
+        bool supportsIdentityTransform = capabilities.supportedTransforms.HasAllFlags(
+            VkSurfaceTransformFlagsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR);
+
+        bool isRotated =
+            capabilities.currentTransform.HasAllFlags(VkSurfaceTransformFlagsKHR.VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR)
+            || capabilities.currentTransform.HasAllFlags(VkSurfaceTransformFlagsKHR
+                .VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR);
+
+        if (capabilities.currentExtent.width != uint.MaxValue) 
+            swapchainExtent = capabilities.currentExtent;
+        else
+        {
+            var surfaceSize = surface.Size;
+
+            var width = Math.Max(capabilities.minImageExtent.width,
+                Math.Min(capabilities.maxImageExtent.width, (uint)surfaceSize.Width));
+            var height = Math.Max(capabilities.minImageExtent.height,
+                Math.Min(capabilities.maxImageExtent.height, (uint)surfaceSize.Height));
+
+            swapchainExtent = new VkExtent2D
+            {
+                width = width,
+                height = height
+            };
+        }
+        VkPresentModeKHR presentMode;
+        if (modes.Contains(VkPresentModeKHR.VK_PRESENT_MODE_MAILBOX_KHR))
+            presentMode = VkPresentModeKHR.VK_PRESENT_MODE_MAILBOX_KHR;
+        else if (modes.Contains(VkPresentModeKHR.VK_PRESENT_MODE_FIFO_KHR))
+            presentMode = VkPresentModeKHR.VK_PRESENT_MODE_FIFO_KHR;
+        else
+            presentMode = VkPresentModeKHR.VK_PRESENT_MODE_IMMEDIATE_KHR;
+
+        var swapchainCreateInfo = new VkSwapchainCreateInfoKHR
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+            surface = surface.Handle,
+            minImageCount = imageCount,
+            imageFormat = surfaceFormat.format,
+            imageColorSpace = surfaceFormat.colorSpace,
+            imageExtent = swapchainExtent,
+            imageUsage = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                         VkImageUsageFlags.VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+            imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE,
+            imageArrayLayers = 1,
+            preTransform = supportsIdentityTransform && isRotated
+                ? VkSurfaceTransformFlagsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
+                : capabilities.currentTransform,
+            compositeAlpha = VkCompositeAlphaFlagsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+            presentMode = presentMode,
+            clipped = 1,
+            oldSwapchain = oldDisplay?._swapchain ?? default
+        };
+        context.DeviceApi.CreateSwapchainKHR(context.DeviceHandle, ref swapchainCreateInfo, IntPtr.Zero,
+            out var swapchain).ThrowOnError("vkCreateSwapchainKHR");
+        oldDisplay?.DestroySwapchain();
+        return swapchain;
+    }
+
+    private void DestroySwapchain()
+    {
+        if(_swapchain.Handle != 0)
+            _context.DeviceApi.DestroySwapchainKHR(_context.DeviceHandle, _swapchain, IntPtr.Zero);
+        _swapchain = default;
+    }
+
+    internal static VulkanDisplay CreateDisplay(IVulkanPlatformGraphicsContext context, VulkanKhrSurface surface)
+    {
+        var swapchain = CreateSwapchain(context, surface, out var extent);
+        return new VulkanDisplay(context, surface, swapchain, extent);
+    }
+
+    private void DestroyCurrentImageViews()
+    {
+        if (_swapchainImageViews.Length <= 0) 
+            return;
+        foreach (var imageView in _swapchainImageViews)
+            _context.DeviceApi.DestroyImageView(_context.DeviceHandle, imageView, IntPtr.Zero);
+
+        _swapchainImageViews = Array.Empty<VkImageView>();
+        
+    }
+    
+    private unsafe void CreateSwapchainImages()
+    {
+        DestroyCurrentImageViews();
+        Size = new PixelSize((int)_swapchainExtent.width, (int)_swapchainExtent.height);
+        uint imageCount = 0;
+        _context.DeviceApi.GetSwapchainImagesKHR(_context.DeviceHandle, _swapchain, ref imageCount, null)
+            .ThrowOnError("vkGetSwapchainImagesKHR");
+        _swapchainImages = new VkImage[imageCount];
+        fixed (VkImage* pImages = _swapchainImages)
+            _context.DeviceApi.GetSwapchainImagesKHR(_context.DeviceHandle, _swapchain, ref imageCount,
+                pImages).ThrowOnError("vkGetSwapchainImagesKHR");
+        _swapchainImageViews = new VkImageView[imageCount];
+        for (var c = 0; c < imageCount; c++)
+            _swapchainImageViews[c] = CreateSwapchainImageView(_swapchainImages[c], SurfaceFormat.format);
+    }
+
+    private VkImageView CreateSwapchainImageView(VkImage swapchainImage, VkFormat format)
+    {
+        var imageViewCreateInfo = new VkImageViewCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            subresourceRange =
+            {
+                aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT,
+                levelCount = 1,
+                layerCount = 1
+            },
+            format = format,
+            image = swapchainImage,
+            viewType = VkImageViewType.VK_IMAGE_VIEW_TYPE_2D,
+        };
+        _context.DeviceApi.CreateImageView(_context.DeviceHandle, ref imageViewCreateInfo,
+            IntPtr.Zero, out var imageView).ThrowOnError("vkCreateImageView");
+        return imageView;
+    }
+    
+    private void Recreate()
+    {
+        _context.DeviceApi.DeviceWaitIdle(_context.DeviceHandle);
+        _swapchain = CreateSwapchain(_context, _surface, out var extent, this);
+        _swapchainExtent = extent;
+        CreateSwapchainImages();
+    }
+    
+    public bool EnsureSwapchainAvailable()
+    {
+        if (Size != _surface.Size)
+        {
+            Recreate();
+            return true;
+        }
+        return false;
+    }
+
+    public VulkanCommandBuffer StartPresentation()
+    {
+        _nextImage = 0;
+        while (true)
+        {
+            var acquireResult = _context.DeviceApi.AcquireNextImageKHR(
+                _context.DeviceHandle,
+                _swapchain,
+                ulong.MaxValue,
+                _semaphorePair.ImageAvailableSemaphore.Handle,
+                default, out _nextImage);
+            if (acquireResult is VkResult.VK_ERROR_OUT_OF_DATE_KHR or VkResult.VK_SUBOPTIMAL_KHR)
+                Recreate();
+            else
+            {
+                acquireResult.ThrowOnError("vkAcquireNextImageKHR");
+                break;
+            }
+        }
+
+        var commandBuffer = CommandBufferPool.CreateCommandBuffer();
+        commandBuffer.BeginRecording();
+        VulkanMemoryHelper.TransitionLayout(_context, commandBuffer,
+            _swapchainImages[_nextImage], VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED,
+            VkAccessFlags.VK_ACCESS_NONE, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+            VkAccessFlags.VK_ACCESS_TRANSFER_WRITE_BIT, 1);
+        return commandBuffer;
+    }
+
+    internal unsafe void BlitImageToCurrentImage(VulkanCommandBuffer commandBuffer, VulkanImage image)
+    {
+        VulkanMemoryHelper.TransitionLayout(_context, commandBuffer,
+            image.Handle, image.CurrentLayout, VkAccessFlags.VK_ACCESS_NONE,
+            VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+            VkAccessFlags.VK_ACCESS_TRANSFER_READ_BIT,
+            image.MipLevels);
+
+        var srcBlitRegion = new VkImageBlit
+        {
+            srcOffsets2 =
+            {
+                x = image.Size.Width,
+                y = image.Size.Height,
+                z = 1
+            },
+            dstOffsets2 =
+            {
+                x = Size.Width,
+                y = Size.Height,
+                z = 1
+            },
+            srcSubresource =
+            {
+                aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT,
+                layerCount = 1
+            },
+            dstSubresource =
+            {
+                aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT,
+                layerCount = 1
+            }
+        };
+        
+        _context.DeviceApi.CmdBlitImage(commandBuffer.Handle, image.Handle,
+            VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+            _swapchainImages[_nextImage],
+            VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+            1, &srcBlitRegion, VkFilter.VK_FILTER_LINEAR);
+
+        VulkanMemoryHelper.TransitionLayout(_context, commandBuffer,
+            image.Handle, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+            VkAccessFlags.VK_ACCESS_TRANSFER_READ_BIT,
+            image.CurrentLayout, VkAccessFlags.VK_ACCESS_NONE, image.MipLevels);
+    }
+
+    internal unsafe void EndPresentation(VulkanCommandBuffer commandBuffer)
+    {
+        VulkanMemoryHelper.TransitionLayout(_context, commandBuffer,
+            _swapchainImages[_nextImage],
+            VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+            VkAccessFlags.VK_ACCESS_NONE,
+            VkImageLayout.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+            VkAccessFlags.VK_ACCESS_NONE,
+            1);
+        commandBuffer.Submit(new[] { _semaphorePair.ImageAvailableSemaphore },
+            new[] { VkPipelineStageFlags.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT },
+            new[] { _semaphorePair.RenderFinishedSemaphore });
+        
+        var semaphore = _semaphorePair.RenderFinishedSemaphore.Handle;
+        var swapchain = _swapchain;
+        var nextImage = _nextImage;
+
+        VkResult result;
+        var presentInfo = new VkPresentInfoKHR
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+            waitSemaphoreCount = 1,
+            pWaitSemaphores = &semaphore,
+            swapchainCount = 1,
+            pSwapchains = &swapchain,
+            pImageIndices = &nextImage,
+            pResults = &result
+        };
+        
+        _context.DeviceApi.vkQueuePresentKHR(_context.MainQueueHandle, ref presentInfo)
+            .ThrowOnError("vkQueuePresentKHR");
+        result.ThrowOnError("vkQueuePresentKHR");
+    }
+    
+    public void Dispose()
+    {
+        _context.DeviceApi.DeviceWaitIdle(_context.DeviceHandle);
+        _semaphorePair?.Dispose();
+        DestroyCurrentImageViews();
+        DestroySwapchain();
+        CommandBufferPool?.Dispose();
+        CommandBufferPool = null!;
+    }
+
+}

+ 40 - 0
src/Avalonia.Vulkan/Interop/VulkanFence.cs

@@ -0,0 +1,40 @@
+using System;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+internal struct VulkanFence : IDisposable
+{
+    private readonly IVulkanPlatformGraphicsContext _context;
+    private VkFence _handle;
+
+    public VulkanFence(IVulkanPlatformGraphicsContext context, VkFenceCreateFlags flags)
+    {
+        _context = context;
+        var fenceCreateInfo = new VkFenceCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+            flags = flags
+        };
+        
+        _context.DeviceApi.CreateFence(_context.DeviceHandle, ref fenceCreateInfo, IntPtr.Zero, out _handle)
+            .ThrowOnError("vkCreateFence");
+    }
+
+    public VkFence Handle => _handle;
+    
+    public void Dispose()
+    {
+        _context.DeviceApi.DestroyFence(_context.DeviceHandle, _handle, IntPtr.Zero);
+        _handle = default;
+    }
+
+    public bool IsSignaled => _context.DeviceApi.GetFenceStatus(_context.DeviceHandle, _handle) == VkResult.VK_SUCCESS;
+    
+    public unsafe void Wait(ulong timeout = ulong.MaxValue)
+    {
+        VkFence fence = _handle;
+        _context.DeviceApi.WaitForFences(_context.DeviceHandle, 1, &fence, 1, timeout).ThrowOnError("vkWaitForFences");
+    }
+}

+ 197 - 0
src/Avalonia.Vulkan/Interop/VulkanImage.cs

@@ -0,0 +1,197 @@
+using System;
+using System.Diagnostics;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+internal class VulkanImageBase : IDisposable
+{
+    private IVulkanPlatformGraphicsContext _context;
+
+    private VkAccessFlags _currentAccessFlags;
+    public VkImageUsageFlags UsageFlags { get; }
+    private VkImageView _imageView;
+    private VkDeviceMemory _imageMemory;
+    private VkImage _handle;
+    private VulkanCommandBufferPool _commandBufferPool;
+    internal VkImage Handle => _handle;
+    internal VkFormat Format { get; }
+    internal VkImageAspectFlags AspectFlags { get; private set; }
+    public uint MipLevels { get; private set; }
+    public PixelSize Size { get; }
+    public ulong MemorySize { get; private set; }
+    public VkImageLayout CurrentLayout { get; protected set; }
+    public VkDeviceMemory MemoryHandle => _imageMemory;
+
+    public VkImageTiling Tiling => VkImageTiling.VK_IMAGE_TILING_OPTIMAL;
+
+    public VulkanImageInfo ImageInfo => new()
+    {
+        Handle = Handle.Handle,
+        PixelSize = Size,
+        Format = (uint)Format,
+        MemoryHandle = MemoryHandle.Handle,
+        MemorySize = MemorySize,
+        ViewHandle = _imageView.Handle,
+        UsageFlags = (uint)UsageFlags,
+        Layout = (uint)CurrentLayout,
+        Tiling = (uint)Tiling,
+        LevelCount = MipLevels,
+        SampleCount = 1,
+        IsProtected = false
+    };
+
+    public struct MemoryImportInfo
+    {
+        public IntPtr Next;
+        public ulong MemorySize;
+        public ulong MemoryOffset;
+    }
+    
+    public VulkanImageBase(IVulkanPlatformGraphicsContext context,
+        VulkanCommandBufferPool commandBufferPool,
+        VkFormat format, PixelSize size, uint mipLevels = 0)
+    {
+        Format = format;
+        Size = size;
+        MipLevels = mipLevels;
+        _context = context;
+        _commandBufferPool = commandBufferPool;
+        UsageFlags = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
+                           | VkImageUsageFlags.VK_IMAGE_USAGE_TRANSFER_DST_BIT
+                           | VkImageUsageFlags.VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+                           | VkImageUsageFlags.VK_IMAGE_USAGE_SAMPLED_BIT;
+    }
+
+    protected virtual VkDeviceMemory CreateMemory(VkImage image, ulong size, uint memoryTypeBits)
+    {
+        var memoryAllocateInfo = new VkMemoryAllocateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+            allocationSize = size,
+            memoryTypeIndex = (uint)VulkanMemoryHelper.FindSuitableMemoryTypeIndex(_context,
+                memoryTypeBits,
+                VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
+        };
+
+        _context.DeviceApi.AllocateMemory(_context.DeviceHandle, ref memoryAllocateInfo, IntPtr.Zero,
+            out var imageMemory).ThrowOnError("vkAllocateMemory");
+        return imageMemory;
+    }
+    
+    public unsafe void Initialize(void* pNext)
+    {
+        if (Handle.Handle != 0)
+            return;
+        MipLevels = MipLevels != 0 ? MipLevels : (uint)Math.Floor(Math.Log(Math.Max(Size.Width, Size.Height), 2));
+        var createInfo = new VkImageCreateInfo
+        {
+            pNext = pNext,
+            sType = VkStructureType.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+            imageType = VkImageType.VK_IMAGE_TYPE_2D,
+            format = Format,
+            extent = new VkExtent3D
+            {
+                depth = 1,
+                width = (uint)Size.Width,
+                height = (uint)Size.Height
+            },
+            mipLevels = MipLevels,
+            arrayLayers = 1,
+            samples = VkSampleCountFlags.VK_SAMPLE_COUNT_1_BIT,
+            tiling = Tiling,
+            usage = UsageFlags,
+            sharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE,
+            initialLayout = VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED,
+            flags = VkImageCreateFlags.VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
+        };
+        
+        _context.DeviceApi.CreateImage(_context.DeviceHandle, ref createInfo, IntPtr.Zero, out _handle)
+            .ThrowOnError("vkCreateImage");
+
+        _context.DeviceApi.GetImageMemoryRequirements(_context.DeviceHandle, _handle, out var memoryRequirements);
+        try
+        {
+            _imageMemory = CreateMemory(_handle, memoryRequirements.size, memoryRequirements.memoryTypeBits);
+        }
+        catch
+        {
+            _context.DeviceApi.DestroyImage(_context.DeviceHandle, _handle, IntPtr.Zero);
+            throw;
+        }
+
+        _context.DeviceApi.BindImageMemory(_context.DeviceHandle, _handle, _imageMemory, 0)
+            .ThrowOnError("vkBindImageMemory");
+
+        MemorySize = memoryRequirements.size;
+        AspectFlags = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT;
+
+        var imageViewCreateInfo = new VkImageViewCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            components = new(),
+            subresourceRange = new()
+            {
+                aspectMask = AspectFlags,
+                levelCount = MipLevels,
+                layerCount = 1
+            },
+            format = Format,
+            image = _handle,
+            viewType = VkImageViewType.VK_IMAGE_VIEW_TYPE_2D
+        };
+        _context.DeviceApi.CreateImageView(_context.DeviceHandle, ref imageViewCreateInfo,
+            IntPtr.Zero, out _imageView).ThrowOnError("vkCreateImageView");
+        CurrentLayout = VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED;
+    }
+
+    internal void TransitionLayout(VkImageLayout destinationLayout, VkAccessFlags destinationAccessFlags)
+    {
+        var commandBuffer = _commandBufferPool!.CreateCommandBuffer();
+        commandBuffer.BeginRecording();
+        VulkanMemoryHelper.TransitionLayout(_context, commandBuffer, Handle,
+            CurrentLayout, _currentAccessFlags, destinationLayout, destinationAccessFlags,
+            MipLevels);
+        commandBuffer.EndRecording();
+        commandBuffer.Submit();
+        CurrentLayout = destinationLayout;
+        _currentAccessFlags = destinationAccessFlags;
+    }
+    
+    public void TransitionLayout(uint destinationLayout, uint destinationAccessFlags)
+    {
+        TransitionLayout((VkImageLayout)destinationLayout, (VkAccessFlags)destinationAccessFlags);
+    }
+
+    public void Dispose()
+    {
+        var api = _context.DeviceApi;
+        var d = _context.DeviceHandle;
+        if (_imageView.Handle != 0)
+        {
+            api.DestroyImageView(d, _imageView, IntPtr.Zero);
+            _imageView = default;
+        }
+        if (_handle.Handle != 0)
+        {
+            api.DestroyImage(d, _handle, IntPtr.Zero);
+            _handle = default;
+        }
+        if (_imageMemory.Handle != 0)
+        {
+            api.FreeMemory(d, _imageMemory, IntPtr.Zero);
+            _imageMemory = default;
+        }
+    }
+}
+
+unsafe class VulkanImage : VulkanImageBase
+{
+    public VulkanImage(IVulkanPlatformGraphicsContext context, VulkanCommandBufferPool commandBufferPool,
+        VkFormat format, PixelSize size, uint mipLevels = 0) : base(context, commandBufferPool, format, size, mipLevels)
+    {
+        Initialize(null);
+        TransitionLayout(VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VkAccessFlags.VK_ACCESS_NONE_KHR);
+    }
+}

+ 179 - 0
src/Avalonia.Vulkan/Interop/VulkanInstance.cs

@@ -0,0 +1,179 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Avalonia.Reactive;
+using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+internal class VulkanInstance : IVulkanInstance
+{
+    private readonly VkGetInstanceProcAddressDelegate _getProcAddress;
+    private readonly VulkanInstanceApi _api;
+
+    public VulkanInstance(VkInstance handle, VkGetInstanceProcAddressDelegate getProcAddress, string[] enabledExtensions)
+    {
+        Handle = handle;
+        _getProcAddress = getProcAddress;
+        _api = new VulkanInstanceApi(this);
+        EnabledExtensions = enabledExtensions;
+    }
+
+    internal static unsafe IVulkanInstance Create(
+        VulkanInstanceCreationOptions options,
+        VulkanPlatformSpecificOptions platformOptions)
+    {
+        var getProcAddress = options.CustomGetProcAddressDelegate ??
+                             platformOptions.GetProcAddressDelegate ??
+                             throw new ArgumentException("No VkGetInstanceProcAddr provided");
+        
+        
+        using var name = new Utf8Buffer(options.ApplicationName ?? "AvaloniaUI");
+        using var engineName = new Utf8Buffer("AvaloniaUI");
+
+        var gapi = new UnmanagedInterop.VulkanGlobalApi(getProcAddress);
+
+        var supportedExtensions = GetSupportedExtensions(gapi);
+        var appInfo = new VkApplicationInfo()
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_APPLICATION_INFO,
+            apiVersion = VulkanHelpers.MakeVersion(options.VulkanVersion),
+            applicationVersion = VulkanHelpers.MakeVersion(1, 0, 0),
+            engineVersion = VulkanHelpers.MakeVersion(1, 0, 0),
+            pApplicationName = name,
+            pEngineName = engineName,
+        };
+
+        var enabledExtensions = new HashSet<string>(options.InstanceExtensions
+            .Concat(platformOptions.RequiredInstanceExtensions)
+            .Append("VK_KHR_surface"));
+        
+        var enabledLayers = options.EnabledLayers.ToList();
+
+        void AddExtensionsIfSupported(params string[] names)
+        {
+            if(names.All(n=>supportedExtensions.Contains(n)))
+                foreach (var n in names)
+                    enabledExtensions.Add(n);
+        }
+        
+        if (options.UseDebug)
+        {
+            AddExtensionsIfSupported("VK_EXT_debug_utils");
+            if (IsLayerAvailable(gapi, "VK_LAYER_KHRONOS_validation"))
+                enabledLayers.Add("VK_LAYER_KHRONOS_validation");
+        }
+
+        AddExtensionsIfSupported(VulkanExternalObjectsFeature.RequiredInstanceExtensions);
+        
+        using var enabledExtensionBuffers = new Utf8BufferArray(
+            enabledExtensions
+                .Where(x => !string.IsNullOrWhiteSpace(x))
+                .Distinct());
+        
+        using var enabledLayersBuffers = new Utf8BufferArray(enabledLayers
+            .Where(x => !string.IsNullOrWhiteSpace(x))
+            .Distinct());
+
+        
+        var createInfo = new VkInstanceCreateInfo()
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+            pApplicationInfo = &appInfo,
+            ppEnabledLayerNames = enabledLayersBuffers,
+            enabledLayerCount = enabledLayersBuffers.UCount,
+            ppEnabledExtensionNames = enabledExtensionBuffers,
+            enabledExtensionCount = enabledExtensionBuffers.UCount
+        };
+
+        gapi.vkCreateInstance(ref createInfo, IntPtr.Zero, out var pInstance)
+            .ThrowOnError(nameof(gapi.vkCreateInstance));
+        
+        var instance = new VulkanInstance(pInstance, getProcAddress, enabledExtensions.ToArray());
+        var instanceApi = new VulkanInstanceApi(instance);
+
+        if (options.UseDebug)
+        {
+            var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
+            {
+                sType = VkStructureType.VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
+                messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
+                    |VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
+                    |VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
+                    |VkDebugUtilsMessageSeverityFlagsEXT.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
+                messageType = VkDebugUtilsMessageTypeFlagsEXT.VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
+                    |VkDebugUtilsMessageTypeFlagsEXT.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
+                    |VkDebugUtilsMessageTypeFlagsEXT.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
+                pfnUserCallback = VulkanDebugLogger.CallbackPtr
+            };
+
+            instanceApi.CreateDebugUtilsMessengerEXT(pInstance, ref debugCreateInfo, IntPtr.Zero, out var messenger);
+        }
+        
+        return instance;
+    }
+
+    private static unsafe bool IsLayerAvailable(VulkanGlobalApi api, string layerName)
+    {
+        uint layerPropertiesCount = 0;
+
+        api.EnumerateInstanceLayerProperties(ref layerPropertiesCount, null)
+            .ThrowOnError("vkEnumerateInstanceLayerProperties");
+
+        var layerProperties = new VkLayerProperties[layerPropertiesCount];
+
+        fixed (VkLayerProperties* pLayerProperties = layerProperties)
+        {
+            api.EnumerateInstanceLayerProperties(ref layerPropertiesCount, pLayerProperties)
+                .ThrowOnError("vkEnumerateInstanceLayerProperties");
+
+            for (var i = 0; i < layerPropertiesCount; i++)
+            {
+                var currentLayerName = Marshal.PtrToStringAnsi((IntPtr)pLayerProperties[i].layerName);
+                if (currentLayerName == layerName) return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static unsafe HashSet<string> GetSupportedExtensions(VulkanGlobalApi api)
+    {
+        var supportedExtensions = new HashSet<string>();
+        uint supportedExtensionCount = 0;
+        api.vkEnumerateInstanceExtensionProperties(IntPtr.Zero, &supportedExtensionCount, null);
+        if (supportedExtensionCount > 0)
+        {
+            var ptr = (VkExtensionProperties*)Marshal.AllocHGlobal(Unsafe.SizeOf<VkExtensionProperties>() *
+                                                                   (int)supportedExtensionCount);
+            try
+            {
+                api.vkEnumerateInstanceExtensionProperties(IntPtr.Zero, &supportedExtensionCount, ptr)
+                    .ThrowOnError("vkEnumerateInstanceExtensionProperties");
+                for (var c = 0; c < supportedExtensionCount; c++)
+                    supportedExtensions.Add(Marshal.PtrToStringAnsi((IntPtr)ptr[c].extensionName) ?? "");
+            }
+            finally
+            {
+                Marshal.FreeHGlobal((IntPtr)ptr);
+            }
+        }
+
+        return supportedExtensions;
+    }
+
+    public VkInstance Handle { get; }
+    IntPtr IVulkanInstance.Handle => Handle.Handle;
+    
+    public IntPtr GetInstanceProcAddress(IntPtr instance, string name) => _getProcAddress(instance, name);
+    public IntPtr GetDeviceProcAddress(IntPtr device, string name)
+    {
+        using var buf = new Utf8Buffer(name);
+        return _api.GetDeviceProcAddr(new(device), buf);
+    }
+
+    public IEnumerable<string> EnabledExtensions { get; }
+}

+ 69 - 0
src/Avalonia.Vulkan/Interop/VulkanKhrSurface.cs

@@ -0,0 +1,69 @@
+using System;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan.Interop;
+
+
+internal class VulkanKhrSurface : IDisposable
+{
+    private readonly IVulkanPlatformGraphicsContext _context;
+    private readonly IVulkanKhrSurfacePlatformSurface _surfaceInfo;
+    private VkSurfaceKHR _handle;
+    public VkSurfaceKHR Handle => _handle;
+
+    public VulkanKhrSurface(IVulkanPlatformGraphicsContext context, IVulkanKhrSurfacePlatformSurface surfaceInfo)
+    {
+        _context = context;
+        _surfaceInfo = surfaceInfo;
+        _handle = new VkSurfaceKHR(surfaceInfo.CreateSurface(context));
+    }
+    
+    internal bool CanSurfacePresent()
+    {
+        _context.InstanceApi.GetPhysicalDeviceSurfaceSupportKHR(_context.PhysicalDeviceHandle,
+            _context.GraphicsQueueFamilyIndex, _handle, out var isSupported)
+            .ThrowOnError("vkGetPhysicalDeviceSurfaceSupportKHR");
+        return isSupported != 0;
+    }
+
+    internal unsafe VkSurfaceFormatKHR GetSurfaceFormat()
+    {
+        uint surfaceFormatsCount = 0;
+        _context.InstanceApi.GetPhysicalDeviceSurfaceFormatsKHR(_context.PhysicalDeviceHandle,
+            _handle, ref surfaceFormatsCount, null)
+            .ThrowOnError("vkGetPhysicalDeviceSurfaceFormatsKHR");
+
+        if (surfaceFormatsCount == 0)
+            throw new VulkanException("vkGetPhysicalDeviceSurfaceFormatsKHR returned 0 formats");
+
+        var surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)surfaceFormatsCount];
+        _context.InstanceApi.GetPhysicalDeviceSurfaceFormatsKHR(_context.PhysicalDeviceHandle,
+                _handle, ref surfaceFormatsCount, surfaceFormats)
+            .ThrowOnError("vkGetPhysicalDeviceSurfaceFormatsKHR");
+        
+        
+        if (surfaceFormatsCount == 1 && surfaceFormats[0].format == VkFormat.VK_FORMAT_UNDEFINED)
+            return new VkSurfaceFormatKHR
+            {
+                format = VkFormat.VK_FORMAT_B8G8R8A8_UNORM,
+                colorSpace = VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
+            };
+        for (var c = 0; c < surfaceFormatsCount; c++)
+        {
+            if (surfaceFormats[c].format == VkFormat.VK_FORMAT_B8G8R8A8_UNORM
+                && surfaceFormats[c].colorSpace == VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
+                return surfaceFormats[c];
+        }
+
+        return surfaceFormats[0];
+    }
+
+    public PixelSize Size => _surfaceInfo.Size;
+
+    public void Dispose()
+    {
+        if (_handle.Handle != 0)
+            _context.InstanceApi.DestroySurfaceKHR(_context.InstanceHandle, _handle, IntPtr.Zero);
+        _handle = default;
+    }
+}

+ 67 - 0
src/Avalonia.Vulkan/Interop/VulkanMemoryHelper.cs

@@ -0,0 +1,67 @@
+using System;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan.Interop;
+
+internal static class VulkanMemoryHelper
+{
+    internal static int FindSuitableMemoryTypeIndex(IVulkanPlatformGraphicsContext context, uint memoryTypeBits,
+        VkMemoryPropertyFlags flags)
+    {
+        context.InstanceApi.GetPhysicalDeviceMemoryProperties(context.PhysicalDeviceHandle,
+            out var properties);
+        for (var i = 0; i < properties.memoryTypeCount; i++)
+        {
+            var type = properties.memoryTypes[i];
+
+            if ((memoryTypeBits & (1 << i)) != 0 && type.propertyFlags.HasAllFlags(flags)) 
+                return i;
+        }
+
+        return -1;
+    }
+
+
+
+    internal static unsafe void TransitionLayout(IVulkanPlatformGraphicsContext context,
+        VulkanCommandBuffer commandBuffer,
+        VkImage image,
+        VkImageLayout sourceLayout,
+        VkAccessFlags sourceAccessMask,
+        VkImageLayout destinationLayout,
+        VkAccessFlags destinationAccessMask,
+        uint mipLevels)
+    {
+        var subresourceRange = new VkImageSubresourceRange
+        {
+            aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT,
+            levelCount = mipLevels,
+            layerCount = 1
+        };
+
+        var barrier = new VkImageMemoryBarrier
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+            srcAccessMask = sourceAccessMask,
+            dstAccessMask = destinationAccessMask,
+            oldLayout = sourceLayout,
+            newLayout = destinationLayout,
+            srcQueueFamilyIndex = VulkanHelpers.QueueFamilyIgnored,
+            dstQueueFamilyIndex = VulkanHelpers.QueueFamilyIgnored,
+            image = image,
+            subresourceRange = subresourceRange
+        };
+
+        context.DeviceApi.CmdPipelineBarrier(
+            commandBuffer.Handle,
+            VkPipelineStageFlags.VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+            VkPipelineStageFlags.VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+            0,
+            0,
+            IntPtr.Zero,
+            0,
+            IntPtr.Zero,
+            1,
+            &barrier);
+    }
+}

+ 58 - 0
src/Avalonia.Vulkan/Interop/VulkanSemaphore.cs

@@ -0,0 +1,58 @@
+using System;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+class VulkanSemaphore : IDisposable
+{
+    private readonly IVulkanPlatformGraphicsContext _context;
+
+    private VkSemaphore _handle;
+    public VkSemaphore Handle => _handle;
+
+    public VulkanSemaphore(IVulkanPlatformGraphicsContext context)
+    {
+        _context = context;
+        var info = new VkSemaphoreCreateInfo
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO
+        };
+        _context.DeviceApi.CreateSemaphore(context.DeviceHandle, ref info, IntPtr.Zero, out _handle)
+            .ThrowOnError("vkCreateSemaphore");
+    }
+
+    public VulkanSemaphore(IVulkanPlatformGraphicsContext context, VkSemaphore handle)
+    {
+        _context = context;
+        _handle = handle;
+    }
+
+    public void Dispose()
+    {
+        if (_handle.Handle != 0)
+        {
+            _context.DeviceApi.DestroySemaphore(_context.DeviceHandle, _handle, IntPtr.Zero);
+            _handle = default;
+        }
+    }
+}
+
+internal class VulkanSemaphorePair : IDisposable
+{
+
+    public unsafe VulkanSemaphorePair(IVulkanPlatformGraphicsContext context)
+    {   
+        ImageAvailableSemaphore = new VulkanSemaphore(context);
+        RenderFinishedSemaphore = new VulkanSemaphore(context);
+    }
+
+    internal VulkanSemaphore ImageAvailableSemaphore { get; }
+    internal VulkanSemaphore RenderFinishedSemaphore { get; }
+
+    public void Dispose()
+    {
+        ImageAvailableSemaphore.Dispose();
+        RenderFinishedSemaphore.Dispose();
+    }
+}

+ 46 - 0
src/Avalonia.Vulkan/UnmanagedInterop/Utf8BufferArray.cs

@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
+
+namespace Avalonia.Vulkan.Interop;
+
+internal unsafe class Utf8BufferArray : IDisposable
+{
+    private readonly List<Utf8Buffer> _buffers;
+    private byte** _bufferArray;
+
+    public Utf8BufferArray(IEnumerable<string> strings)
+    {
+        _buffers = strings.Select(x => new Utf8Buffer(x)).ToList();
+        _bufferArray = (byte**)Marshal.AllocHGlobal(_buffers.Count * IntPtr.Size);
+        for (var c = 0; c < _buffers.Count; c++)
+            _bufferArray[c] = _buffers[c];
+    }
+
+    public static unsafe implicit operator byte**(Utf8BufferArray a) => a._bufferArray;
+
+    public int Count => _buffers.Count;
+    public uint UCount => (uint)Count;
+
+    public void Dispose() => Dispose(true);
+    void Dispose(bool disposing)
+    {
+        if (_bufferArray != null)
+            Marshal.FreeHGlobal(new IntPtr(_bufferArray));
+        _bufferArray = null;
+        if (disposing)
+        {
+            foreach (var b in _buffers)
+                b.Dispose();
+            _buffers.Clear();
+            GC.SuppressFinalize(this);
+        }
+    }
+
+    ~Utf8BufferArray()
+    {
+        Dispose(false);
+    }
+}

+ 154 - 0
src/Avalonia.Vulkan/UnmanagedInterop/VulkanDeviceApi.cs

@@ -0,0 +1,154 @@
+using System;
+using Avalonia.SourceGenerator;
+using Avalonia.Vulkan.Interop;
+using uint32_t = System.UInt32;
+using uint64_t = System.UInt64;
+using VkBool32 = System.UInt32;
+using VkDeviceSize = System.UInt64;
+
+namespace Avalonia.Vulkan.UnmanagedInterop;
+
+
+internal unsafe partial class VulkanDeviceApi
+{
+    public VulkanDeviceApi(IVulkanDevice device)
+    {
+        Initialize(name =>
+        {
+            var addr = device.Instance.GetDeviceProcAddress(device.Handle, name);
+            if (addr != IntPtr.Zero)
+                return addr;
+            return device.Instance.GetInstanceProcAddress(device.Instance.Handle, name);
+        });
+    }
+
+    [GetProcAddress("vkCreateFence")]
+    public partial VkResult CreateFence(VkDevice device,
+        ref VkFenceCreateInfo pCreateInfo,
+        IntPtr pAllocator,
+        out VkFence pFence);
+
+    [GetProcAddress("vkDestroyFence")]
+    public partial void DestroyFence(VkDevice device, VkFence fence, IntPtr pAllocator);
+
+    [GetProcAddress("vkCreateCommandPool")]
+    public partial VkResult CreateCommandPool(VkDevice device, ref VkCommandPoolCreateInfo pCreateInfo,
+        IntPtr pAllocator, out VkCommandPool pCommandPool);
+
+    [GetProcAddress("vkDestroyCommandPool")]
+    public partial void DestroyCommandPool(VkDevice device, VkCommandPool pool, IntPtr pAllocator);
+
+    [GetProcAddress("vkAllocateCommandBuffers")]
+    public partial VkResult AllocateCommandBuffers(VkDevice device,
+        ref VkCommandBufferAllocateInfo pAllocateInfo, VkCommandBuffer* pCommandBuffers);
+
+    [GetProcAddress("vkFreeCommandBuffers")]
+    public partial void FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
+        VkCommandBuffer* pCommandBuffers);
+
+    [GetProcAddress("vkWaitForFences")]
+    public partial VkResult WaitForFences(VkDevice device, uint32_t fenceCount, VkFence* pFences, VkBool32 waitAll,
+        uint64_t timeout);
+
+    [GetProcAddress("vkGetFenceStatus")]
+    public partial VkResult GetFenceStatus(VkDevice device, VkFence fence);
+    
+    [GetProcAddress("vkBeginCommandBuffer")]
+    public partial VkResult BeginCommandBuffer(VkCommandBuffer commandBuffer, ref VkCommandBufferBeginInfo pBeginInfo);
+
+    [GetProcAddress("vkEndCommandBuffer")]
+    public partial VkResult EndCommandBuffer(VkCommandBuffer commandBuffer);
+
+    [GetProcAddress("vkCreateSemaphore")]
+    public partial VkResult CreateSemaphore(VkDevice device, ref VkSemaphoreCreateInfo pCreateInfo,
+        IntPtr pAllocator, out VkSemaphore pSemaphore);
+
+    [GetProcAddress("vkDestroySemaphore")]
+    public partial void DestroySemaphore(VkDevice device, VkSemaphore semaphore, IntPtr pAllocator);
+
+    [GetProcAddress("vkResetFences")]
+    public partial VkResult ResetFences(VkDevice device, uint32_t fenceCount, VkFence* pFences);
+
+    [GetProcAddress("vkQueueSubmit")]
+    public partial VkResult QueueSubmit(VkQueue queue, uint32_t submitCount, VkSubmitInfo* pSubmits,
+        VkFence fence);
+
+    [GetProcAddress("vkCreateImage")]
+    public partial VkResult CreateImage(VkDevice device, ref VkImageCreateInfo pCreateInfo, IntPtr pAllocator,
+        out VkImage pImage);
+    
+    [GetProcAddress("vkDestroyImage")]
+    public partial void DestroyImage(VkDevice device, VkImage image, IntPtr pAllocator);
+
+    [GetProcAddress("vkGetImageMemoryRequirements")]
+    public partial void GetImageMemoryRequirements(VkDevice device, VkImage image,
+        out VkMemoryRequirements pMemoryRequirements);
+
+    [GetProcAddress("vkAllocateMemory")]
+    public partial VkResult AllocateMemory(VkDevice device, ref VkMemoryAllocateInfo pAllocateInfo, IntPtr pAllocator,
+        out VkDeviceMemory pMemory);
+    
+    [GetProcAddress("vkFreeMemory")]
+    public partial void FreeMemory(VkDevice device, VkDeviceMemory memory, IntPtr pAllocator);
+
+    [GetProcAddress("vkBindImageMemory")]
+    public partial VkResult BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory,
+        VkDeviceSize memoryOffset);
+
+    [GetProcAddress("vkCreateImageView")]
+    public partial VkResult CreateImageView(VkDevice device, ref VkImageViewCreateInfo pCreateInfo, IntPtr pAllocator,
+        out VkImageView pView);
+    
+    [GetProcAddress("vkDestroyImageView")]
+    public partial void DestroyImageView(VkDevice device, VkImageView imageView, IntPtr pAllocator);
+    
+
+    [GetProcAddress("vkCmdPipelineBarrier")]
+    public partial void CmdPipelineBarrier(VkCommandBuffer commandBuffer,
+        VkPipelineStageFlags srcStageMask,
+        VkPipelineStageFlags dstStageMask,
+        VkDependencyFlags dependencyFlags,
+        uint32_t memoryBarrierCount,
+        IntPtr pMemoryBarriers,
+        uint32_t bufferMemoryBarrierCount,
+        IntPtr pBufferMemoryBarriers,
+        uint32_t imageMemoryBarrierCount,
+        VkImageMemoryBarrier* pImageMemoryBarriers);
+    
+    [GetProcAddress("vkCreateSwapchainKHR")]
+    public partial VkResult CreateSwapchainKHR(VkDevice device, ref VkSwapchainCreateInfoKHR pCreateInfo,
+        IntPtr pAllocator, out VkSwapchainKHR pSwapchain);
+    
+    [GetProcAddress("vkDestroySwapchainKHR")]
+    public partial void DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, IntPtr pAllocator);
+
+    [GetProcAddress("vkGetSwapchainImagesKHR")]
+    public partial VkResult GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, ref uint32_t pSwapchainImageCount,
+        VkImage* pSwapchainImages);
+
+    [GetProcAddress("vkDeviceWaitIdle")]
+    public partial VkResult DeviceWaitIdle(VkDevice device);
+
+    [GetProcAddress("vkQueueWaitIdle")]
+    public partial VkResult QueueWaitIdle(VkQueue queue);
+
+    [GetProcAddress("vkAcquireNextImageKHR")]
+    public partial VkResult AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
+        VkSemaphore semaphore, VkFence fence, out uint32_t pImageIndex);
+
+    [GetProcAddress("vkCmdBlitImage")]
+    public partial void CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, VkImageBlit* pRegions, VkFilter filter);
+
+    [GetProcAddress("vkQueuePresentKHR")]
+    public partial VkResult vkQueuePresentKHR(VkQueue queue, ref VkPresentInfoKHR pPresentInfo);
+
+    [GetProcAddress("vkImportSemaphoreFdKHR", true)]
+    public partial VkResult ImportSemaphoreFdKHR(VkDevice device, VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo);
+
+    [GetProcAddress("vkImportSemaphoreWin32HandleKHR", true)]
+    public partial VkResult ImportSemaphoreWin32HandleKHR(VkDevice device,
+        VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
+    
+    
+}

+ 2190 - 0
src/Avalonia.Vulkan/UnmanagedInterop/VulkanEnums.cs

@@ -0,0 +1,2190 @@
+using System;
+
+namespace Avalonia.Vulkan.UnmanagedInterop
+{
+    internal enum VkResult
+    {
+        VK_SUCCESS = 0,
+        VK_NOT_READY = 1,
+        VK_TIMEOUT = 2,
+        VK_EVENT_SET = 3,
+        VK_EVENT_RESET = 4,
+        VK_INCOMPLETE = 5,
+        VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+        VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+        VK_ERROR_INITIALIZATION_FAILED = -3,
+        VK_ERROR_DEVICE_LOST = -4,
+        VK_ERROR_MEMORY_MAP_FAILED = -5,
+        VK_ERROR_LAYER_NOT_PRESENT = -6,
+        VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+        VK_ERROR_FEATURE_NOT_PRESENT = -8,
+        VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+        VK_ERROR_TOO_MANY_OBJECTS = -10,
+        VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+        VK_ERROR_FRAGMENTED_POOL = -12,
+        VK_ERROR_UNKNOWN = -13,
+        VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000,
+        VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003,
+        VK_ERROR_FRAGMENTATION = -1000161000,
+        VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000,
+        VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+        VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+        VK_SUBOPTIMAL_KHR = 1000001003,
+        VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+        VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
+        VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
+        VK_ERROR_INVALID_SHADER_NV = -1000012000,
+        VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000,
+        VK_ERROR_NOT_PERMITTED_EXT = -1000174001,
+        VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000,
+        VK_THREAD_IDLE_KHR = 1000268000,
+        VK_THREAD_DONE_KHR = 1000268001,
+        VK_OPERATION_DEFERRED_KHR = 1000268002,
+        VK_OPERATION_NOT_DEFERRED_KHR = 1000268003,
+        VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000,
+        VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
+        VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
+        VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION,
+        VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+        VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+        VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT,
+        VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+    }
+
+    internal enum VkStructureType
+    {
+        VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
+        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
+        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
+        VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
+        VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
+        VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
+        VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
+        VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
+        VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
+        VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
+        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
+        VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
+        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
+        VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
+        VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
+        VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
+        VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
+        VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
+        VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
+        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
+        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
+        VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
+        VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
+        VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
+        VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
+        VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
+        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
+        VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
+        VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
+        VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
+        VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
+        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
+        VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
+        VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
+        VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
+        VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000,
+        VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000,
+        VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000,
+        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000,
+        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001,
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006,
+        VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013,
+        VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001,
+        VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000,
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001,
+        VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002,
+        VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003,
+        VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001,
+        VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002,
+        VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004,
+        VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006,
+        VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000,
+        VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001,
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002,
+        VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003,
+        VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000,
+        VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002,
+        VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003,
+        VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000,
+        VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001,
+        VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002,
+        VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004,
+        VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000,
+        VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002,
+        VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004,
+        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000,
+        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001,
+        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000,
+        VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001,
+        VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000,
+        VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000,
+        VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52,
+        VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000,
+        VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000,
+        VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001,
+        VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002,
+        VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003,
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004,
+        VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005,
+        VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000,
+        VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000,
+        VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000,
+        VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000,
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001,
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002,
+        VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000,
+        VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001,
+        VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001,
+        VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002,
+        VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003,
+        VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004,
+        VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000,
+        VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001,
+        VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002,
+        VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003,
+        VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004,
+        VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
+        VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
+        VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008,
+        VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009,
+        VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012,
+        VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000,
+        VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001,
+        VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000,
+        VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
+        VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
+        VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
+        VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
+        VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
+        VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
+        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000,
+        VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
+        VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001,
+        VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002,
+        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
+        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
+        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001,
+        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002,
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000,
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001,
+        VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
+        VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000,
+        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
+        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
+        VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
+        VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
+        VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
+        VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000,
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001,
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000,
+        VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001,
+        VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002,
+        VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003,
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000,
+        VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001,
+        VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002,
+        VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000,
+        VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000,
+        VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001,
+        VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002,
+        VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003,
+        VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000,
+        VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000,
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
+        VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
+        VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
+        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000,
+        VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000,
+        VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000,
+        VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001,
+        VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002,
+        VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003,
+        VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000,
+        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000,
+        VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000,
+        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000,
+        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001,
+        VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
+        VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
+        VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
+        VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
+        VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002,
+        VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000,
+        VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001,
+        VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002,
+        VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003,
+        VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004,
+        VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005,
+        VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
+        VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
+        VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+        VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
+        VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
+        VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
+        VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
+        VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
+        VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
+        VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
+        VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000,
+        VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001,
+        VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002,
+        VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003,
+        VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004,
+        VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000,
+        VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001,
+        VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002,
+        VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003,
+        VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004,
+        VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001,
+        VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003,
+        VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000,
+        VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001,
+        VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003,
+        VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
+        VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
+        VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000,
+        VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009,
+        VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010,
+        VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011,
+        VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001,
+        VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015,
+        VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016,
+        VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013,
+        VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001,
+        VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002,
+        VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003,
+        VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004,
+        VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005,
+        VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
+        VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001,
+        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
+        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
+        VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001,
+        VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003,
+        VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004,
+        VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005,
+        VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006,
+        VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009,
+        VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011,
+        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
+        VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000,
+        VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001,
+        VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
+        VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000,
+        VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000,
+        VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
+        VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
+        VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
+        VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000,
+        VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000,
+        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
+        VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
+        VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000,
+        VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000,
+        VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001,
+        VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002,
+        VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003,
+        VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004,
+        VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
+        VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000,
+        VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001,
+        VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000,
+        VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001,
+        VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000,
+        VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002,
+        VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000,
+        VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000,
+        VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001,
+        VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000,
+        VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000,
+        VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
+        VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000,
+        VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001,
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000,
+        VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000,
+        VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002,
+        VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001,
+        VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000,
+        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000,
+        VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001,
+        VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002,
+        VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003,
+        VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004,
+        VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000,
+        VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001,
+        VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002,
+        VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003,
+        VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004,
+        VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005,
+        VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001,
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000,
+        VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000,
+        VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001,
+        VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001,
+        VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002,
+        VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000,
+        VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001,
+        VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000,
+        VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001,
+        VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001,
+        VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000,
+        VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = 1000337000,
+        VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = 1000337001,
+        VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002,
+        VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003,
+        VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = 1000337004,
+        VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = 1000337005,
+        VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = 1000337006,
+        VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = 1000337007,
+        VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = 1000337008,
+        VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = 1000337009,
+        VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = 1000337010,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000,
+        VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,
+        VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
+        VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
+        VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
+        VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
+        VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
+        VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
+
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR =
+            VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
+
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR =
+            VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO,
+
+        VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR =
+            VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO,
+
+        VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR =
+            VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
+        VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
+        VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
+        VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES,
+        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
+        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
+        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
+        VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
+        VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
+
+        VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
+        VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
+
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,
+        VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,
+        VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
+        VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
+        VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
+        VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
+        VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
+        VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
+        VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
+        VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES,
+
+        VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR,
+        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
+        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
+        VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,
+        VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
+
+        VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR =
+            VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
+        VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
+        VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
+        VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
+        VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
+        VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
+
+        VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR =
+            VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
+
+        VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
+        VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
+        VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
+
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
+
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES,
+
+        VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR =
+            VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES,
+        VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+        VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
+        VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+        VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
+
+        VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL =
+            VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
+
+        VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR =
+            VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
+
+        VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR =
+            VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT,
+        VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+        VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
+        VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+
+        VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,
+
+        VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR =
+            VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,
+
+        VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR =
+            VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,
+
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
+        VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+    }
+
+    enum VkPhysicalDeviceType
+    {
+        VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
+        VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
+        VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
+        VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
+        VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
+    }
+
+    [Flags]
+    internal enum VkQueueFlags
+    {
+        VK_QUEUE_GRAPHICS_BIT = 0x00000001,
+        VK_QUEUE_COMPUTE_BIT = 0x00000002,
+        VK_QUEUE_TRANSFER_BIT = 0x00000004,
+        VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
+
+        // Provided by VK_VERSION_1_1
+        VK_QUEUE_PROTECTED_BIT = 0x00000010,
+
+        // Provided by VK_KHR_video_decode_queue
+        VK_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020,
+
+        // Provided by VK_KHR_video_encode_queue
+        VK_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040,
+
+        // Provided by VK_NV_optical_flow
+        VK_QUEUE_OPTICAL_FLOW_BIT_NV = 0x00000100,
+    }
+
+
+    [Flags]
+    enum VkDeviceQueueCreateFlags
+    {
+        // Provided by VK_VERSION_1_1
+        VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001,
+    }
+
+    enum VkFenceCreateFlags
+    {
+        VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001,
+    }
+
+    enum VkCommandPoolCreateFlags
+    {
+        VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001,
+        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002,
+
+        // Provided by VK_VERSION_1_1
+        VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004,
+    }
+
+    enum VkCommandBufferLevel
+    {
+        VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0,
+        VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1,
+    }
+
+    enum VkCommandBufferUsageFlags
+    {
+        VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001,
+        VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002,
+        VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004,
+    }
+
+    enum VkPipelineStageFlags
+    {
+        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001,
+        VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002,
+        VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004,
+        VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008,
+        VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010,
+        VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020,
+        VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040,
+        VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080,
+        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100,
+        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400,
+        VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800,
+        VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000,
+        VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000,
+        VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
+        VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
+
+        // Provided by VK_VERSION_1_3
+        VK_PIPELINE_STAGE_NONE = 0,
+
+        // Provided by VK_EXT_transform_feedback
+        VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000,
+
+        // Provided by VK_EXT_conditional_rendering
+        VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000,
+
+        // Provided by VK_KHR_acceleration_structure
+        VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000,
+
+        // Provided by VK_KHR_ray_tracing_pipeline
+        VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000,
+
+        // Provided by VK_EXT_fragment_density_map
+        VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000,
+
+        // Provided by VK_KHR_fragment_shading_rate
+        VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000,
+
+        // Provided by VK_NV_device_generated_commands
+        VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000,
+
+        // Provided by VK_EXT_mesh_shader
+        VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT = 0x00080000,
+
+        // Provided by VK_EXT_mesh_shader
+        VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT = 0x00100000,
+
+        // Provided by VK_NV_shading_rate_image
+        VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+
+        // Provided by VK_NV_ray_tracing
+        VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
+
+        // Provided by VK_NV_ray_tracing
+        VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
+
+        // Provided by VK_NV_mesh_shader
+        VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT,
+
+        // Provided by VK_NV_mesh_shader
+        VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
+
+        // Provided by VK_KHR_synchronization2
+        VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE,
+    }
+
+    enum VkFormat
+    {
+        VK_FORMAT_UNDEFINED = 0,
+        VK_FORMAT_R4G4_UNORM_PACK8 = 1,
+        VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
+        VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
+        VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
+        VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
+        VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
+        VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
+        VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
+        VK_FORMAT_R8_UNORM = 9,
+        VK_FORMAT_R8_SNORM = 10,
+        VK_FORMAT_R8_USCALED = 11,
+        VK_FORMAT_R8_SSCALED = 12,
+        VK_FORMAT_R8_UINT = 13,
+        VK_FORMAT_R8_SINT = 14,
+        VK_FORMAT_R8_SRGB = 15,
+        VK_FORMAT_R8G8_UNORM = 16,
+        VK_FORMAT_R8G8_SNORM = 17,
+        VK_FORMAT_R8G8_USCALED = 18,
+        VK_FORMAT_R8G8_SSCALED = 19,
+        VK_FORMAT_R8G8_UINT = 20,
+        VK_FORMAT_R8G8_SINT = 21,
+        VK_FORMAT_R8G8_SRGB = 22,
+        VK_FORMAT_R8G8B8_UNORM = 23,
+        VK_FORMAT_R8G8B8_SNORM = 24,
+        VK_FORMAT_R8G8B8_USCALED = 25,
+        VK_FORMAT_R8G8B8_SSCALED = 26,
+        VK_FORMAT_R8G8B8_UINT = 27,
+        VK_FORMAT_R8G8B8_SINT = 28,
+        VK_FORMAT_R8G8B8_SRGB = 29,
+        VK_FORMAT_B8G8R8_UNORM = 30,
+        VK_FORMAT_B8G8R8_SNORM = 31,
+        VK_FORMAT_B8G8R8_USCALED = 32,
+        VK_FORMAT_B8G8R8_SSCALED = 33,
+        VK_FORMAT_B8G8R8_UINT = 34,
+        VK_FORMAT_B8G8R8_SINT = 35,
+        VK_FORMAT_B8G8R8_SRGB = 36,
+        VK_FORMAT_R8G8B8A8_UNORM = 37,
+        VK_FORMAT_R8G8B8A8_SNORM = 38,
+        VK_FORMAT_R8G8B8A8_USCALED = 39,
+        VK_FORMAT_R8G8B8A8_SSCALED = 40,
+        VK_FORMAT_R8G8B8A8_UINT = 41,
+        VK_FORMAT_R8G8B8A8_SINT = 42,
+        VK_FORMAT_R8G8B8A8_SRGB = 43,
+        VK_FORMAT_B8G8R8A8_UNORM = 44,
+        VK_FORMAT_B8G8R8A8_SNORM = 45,
+        VK_FORMAT_B8G8R8A8_USCALED = 46,
+        VK_FORMAT_B8G8R8A8_SSCALED = 47,
+        VK_FORMAT_B8G8R8A8_UINT = 48,
+        VK_FORMAT_B8G8R8A8_SINT = 49,
+        VK_FORMAT_B8G8R8A8_SRGB = 50,
+        VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
+        VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
+        VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
+        VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
+        VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
+        VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
+        VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
+        VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
+        VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
+        VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
+        VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
+        VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
+        VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
+        VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
+        VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
+        VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
+        VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
+        VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
+        VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
+        VK_FORMAT_R16_UNORM = 70,
+        VK_FORMAT_R16_SNORM = 71,
+        VK_FORMAT_R16_USCALED = 72,
+        VK_FORMAT_R16_SSCALED = 73,
+        VK_FORMAT_R16_UINT = 74,
+        VK_FORMAT_R16_SINT = 75,
+        VK_FORMAT_R16_SFLOAT = 76,
+        VK_FORMAT_R16G16_UNORM = 77,
+        VK_FORMAT_R16G16_SNORM = 78,
+        VK_FORMAT_R16G16_USCALED = 79,
+        VK_FORMAT_R16G16_SSCALED = 80,
+        VK_FORMAT_R16G16_UINT = 81,
+        VK_FORMAT_R16G16_SINT = 82,
+        VK_FORMAT_R16G16_SFLOAT = 83,
+        VK_FORMAT_R16G16B16_UNORM = 84,
+        VK_FORMAT_R16G16B16_SNORM = 85,
+        VK_FORMAT_R16G16B16_USCALED = 86,
+        VK_FORMAT_R16G16B16_SSCALED = 87,
+        VK_FORMAT_R16G16B16_UINT = 88,
+        VK_FORMAT_R16G16B16_SINT = 89,
+        VK_FORMAT_R16G16B16_SFLOAT = 90,
+        VK_FORMAT_R16G16B16A16_UNORM = 91,
+        VK_FORMAT_R16G16B16A16_SNORM = 92,
+        VK_FORMAT_R16G16B16A16_USCALED = 93,
+        VK_FORMAT_R16G16B16A16_SSCALED = 94,
+        VK_FORMAT_R16G16B16A16_UINT = 95,
+        VK_FORMAT_R16G16B16A16_SINT = 96,
+        VK_FORMAT_R16G16B16A16_SFLOAT = 97,
+        VK_FORMAT_R32_UINT = 98,
+        VK_FORMAT_R32_SINT = 99,
+        VK_FORMAT_R32_SFLOAT = 100,
+        VK_FORMAT_R32G32_UINT = 101,
+        VK_FORMAT_R32G32_SINT = 102,
+        VK_FORMAT_R32G32_SFLOAT = 103,
+        VK_FORMAT_R32G32B32_UINT = 104,
+        VK_FORMAT_R32G32B32_SINT = 105,
+        VK_FORMAT_R32G32B32_SFLOAT = 106,
+        VK_FORMAT_R32G32B32A32_UINT = 107,
+        VK_FORMAT_R32G32B32A32_SINT = 108,
+        VK_FORMAT_R32G32B32A32_SFLOAT = 109,
+        VK_FORMAT_R64_UINT = 110,
+        VK_FORMAT_R64_SINT = 111,
+        VK_FORMAT_R64_SFLOAT = 112,
+        VK_FORMAT_R64G64_UINT = 113,
+        VK_FORMAT_R64G64_SINT = 114,
+        VK_FORMAT_R64G64_SFLOAT = 115,
+        VK_FORMAT_R64G64B64_UINT = 116,
+        VK_FORMAT_R64G64B64_SINT = 117,
+        VK_FORMAT_R64G64B64_SFLOAT = 118,
+        VK_FORMAT_R64G64B64A64_UINT = 119,
+        VK_FORMAT_R64G64B64A64_SINT = 120,
+        VK_FORMAT_R64G64B64A64_SFLOAT = 121,
+        VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
+        VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
+        VK_FORMAT_D16_UNORM = 124,
+        VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
+        VK_FORMAT_D32_SFLOAT = 126,
+        VK_FORMAT_S8_UINT = 127,
+        VK_FORMAT_D16_UNORM_S8_UINT = 128,
+        VK_FORMAT_D24_UNORM_S8_UINT = 129,
+        VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
+        VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
+        VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
+        VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
+        VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
+        VK_FORMAT_BC2_UNORM_BLOCK = 135,
+        VK_FORMAT_BC2_SRGB_BLOCK = 136,
+        VK_FORMAT_BC3_UNORM_BLOCK = 137,
+        VK_FORMAT_BC3_SRGB_BLOCK = 138,
+        VK_FORMAT_BC4_UNORM_BLOCK = 139,
+        VK_FORMAT_BC4_SNORM_BLOCK = 140,
+        VK_FORMAT_BC5_UNORM_BLOCK = 141,
+        VK_FORMAT_BC5_SNORM_BLOCK = 142,
+        VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
+        VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
+        VK_FORMAT_BC7_UNORM_BLOCK = 145,
+        VK_FORMAT_BC7_SRGB_BLOCK = 146,
+        VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
+        VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
+        VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
+        VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
+        VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
+        VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
+        VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
+        VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
+        VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
+        VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
+        VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
+        VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
+        VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
+        VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
+        VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
+        VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
+        VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
+        VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
+        VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
+        VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
+        VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
+        VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
+        VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
+        VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
+        VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
+        VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
+        VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
+        VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
+        VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
+        VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
+        VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
+        VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
+        VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
+        VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
+        VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
+        VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
+        VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
+        VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032,
+
+        // Provided by VK_VERSION_1_1
+        VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012,
+
+        // Provided by VK_VERSION_1_3
+        VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
+
+        // Provided by VK_IMG_format_pvrtc
+        VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
+
+        // Provided by VK_NV_optical_flow
+        VK_FORMAT_R16G16_S10_5_NV = 1000464000,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK,
+
+        // Provided by VK_EXT_texture_compression_astc_hdr
+        VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_R10X6_UNORM_PACK16_KHR = VK_FORMAT_R10X6_UNORM_PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_R12X4_UNORM_PACK16_KHR = VK_FORMAT_R12X4_UNORM_PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G16B16G16R16_422_UNORM_KHR = VK_FORMAT_G16B16G16R16_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_B16G16R16G16_422_UNORM_KHR = VK_FORMAT_B16G16R16G16_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
+
+        // Provided by VK_EXT_ycbcr_2plane_444_formats
+        VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
+
+        // Provided by VK_EXT_ycbcr_2plane_444_formats
+        VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
+
+        // Provided by VK_EXT_ycbcr_2plane_444_formats
+        VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16,
+
+        // Provided by VK_EXT_ycbcr_2plane_444_formats
+        VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM,
+
+        // Provided by VK_EXT_4444_formats
+        VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16,
+
+        // Provided by VK_EXT_4444_formats
+        VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16,
+    }
+
+    enum VkColorSpaceKHR
+    {
+        VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104003,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014,
+
+        // Provided by VK_AMD_display_native_hdr
+        VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000,
+        VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+
+        // Provided by VK_EXT_swapchain_colorspace
+        VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT,
+    }
+
+    [Flags]
+    enum VkMemoryPropertyFlags
+    {
+        VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001,
+        VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002,
+        VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004,
+        VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008,
+        VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010,
+
+        // Provided by VK_VERSION_1_1
+        VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020,
+
+        // Provided by VK_AMD_device_coherent_memory
+        VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040,
+
+        // Provided by VK_AMD_device_coherent_memory
+        VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080,
+
+        // Provided by VK_NV_external_memory_rdma
+        VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100,
+    }
+
+    [Flags]
+    enum VkMemoryHeapFlags
+    {
+        VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001,
+
+        // Provided by VK_VERSION_1_1
+        VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002,
+
+        // Provided by VK_KHR_device_group_creation
+        VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT,
+    }
+
+    enum VkImageLayout
+    {
+        VK_IMAGE_LAYOUT_UNDEFINED = 0,
+        VK_IMAGE_LAYOUT_GENERAL = 1,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3,
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4,
+        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5,
+        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6,
+        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7,
+        VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,
+
+        // Provided by VK_VERSION_1_2
+        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000,
+
+        // Provided by VK_VERSION_1_2
+        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001,
+
+        // Provided by VK_VERSION_1_2
+        VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002,
+
+        // Provided by VK_VERSION_1_2
+        VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003,
+
+        // Provided by VK_VERSION_1_3
+        VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000,
+
+        // Provided by VK_VERSION_1_3
+        VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001,
+
+        // Provided by VK_KHR_swapchain
+        VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
+
+        // Provided by VK_KHR_video_decode_queue
+        VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000,
+
+        // Provided by VK_KHR_video_decode_queue
+        VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001,
+
+        // Provided by VK_KHR_video_decode_queue
+        VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002,
+
+        // Provided by VK_KHR_shared_presentable_image
+        VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
+
+        // Provided by VK_EXT_fragment_density_map
+        VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000,
+
+        // Provided by VK_KHR_fragment_shading_rate
+        VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003,
+
+        // Provided by VK_KHR_video_encode_queue
+        VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000,
+
+        // Provided by VK_KHR_video_encode_queue
+        VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001,
+
+        // Provided by VK_KHR_video_encode_queue
+        VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002,
+
+        // Provided by VK_EXT_attachment_feedback_loop_layout
+        VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000,
+
+        // Provided by VK_KHR_maintenance2
+        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR =
+            VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
+
+        // Provided by VK_KHR_maintenance2
+        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR =
+            VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
+
+        // Provided by VK_NV_shading_rate_image
+        VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR,
+
+        // Provided by VK_KHR_separate_depth_stencil_layouts
+        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
+
+        // Provided by VK_KHR_separate_depth_stencil_layouts
+        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
+
+        // Provided by VK_KHR_separate_depth_stencil_layouts
+        VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
+
+        // Provided by VK_KHR_separate_depth_stencil_layouts
+        VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
+
+        // Provided by VK_KHR_synchronization2
+        VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
+
+        // Provided by VK_KHR_synchronization2
+        VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
+    }
+
+    [Flags]
+    enum VkAccessFlags
+    {
+        VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001,
+        VK_ACCESS_INDEX_READ_BIT = 0x00000002,
+        VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004,
+        VK_ACCESS_UNIFORM_READ_BIT = 0x00000008,
+        VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010,
+        VK_ACCESS_SHADER_READ_BIT = 0x00000020,
+        VK_ACCESS_SHADER_WRITE_BIT = 0x00000040,
+        VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100,
+        VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200,
+        VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400,
+        VK_ACCESS_TRANSFER_READ_BIT = 0x00000800,
+        VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000,
+        VK_ACCESS_HOST_READ_BIT = 0x00002000,
+        VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
+        VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
+        VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
+
+        // Provided by VK_VERSION_1_3
+        VK_ACCESS_NONE = 0,
+
+        // Provided by VK_EXT_transform_feedback
+        VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000,
+
+        // Provided by VK_EXT_transform_feedback
+        VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000,
+
+        // Provided by VK_EXT_transform_feedback
+        VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000,
+
+        // Provided by VK_EXT_conditional_rendering
+        VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000,
+
+        // Provided by VK_EXT_blend_operation_advanced
+        VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
+
+        // Provided by VK_KHR_acceleration_structure
+        VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000,
+
+        // Provided by VK_KHR_acceleration_structure
+        VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000,
+
+        // Provided by VK_EXT_fragment_density_map
+        VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000,
+
+        // Provided by VK_KHR_fragment_shading_rate
+        VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000,
+
+        // Provided by VK_NV_device_generated_commands
+        VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000,
+
+        // Provided by VK_NV_device_generated_commands
+        VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000,
+
+        // Provided by VK_NV_shading_rate_image
+        VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR,
+
+        // Provided by VK_NV_ray_tracing
+        VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
+
+        // Provided by VK_NV_ray_tracing
+        VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
+
+        // Provided by VK_KHR_synchronization2
+        VK_ACCESS_NONE_KHR = VK_ACCESS_NONE,
+    }
+
+    [Flags]
+    enum VkImageUsageFlags
+    {
+        VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001,
+        VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002,
+        VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004,
+        VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008,
+        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010,
+        VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
+        VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
+        VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
+
+        // Provided by VK_EXT_fragment_density_map
+        VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200,
+
+        // Provided by VK_KHR_fragment_shading_rate
+        VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100,
+
+        // Provided by VK_EXT_attachment_feedback_loop_layout
+        VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x00080000,
+
+        // Provided by VK_HUAWEI_invocation_mask
+        VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000,
+
+        // Provided by VK_QCOM_image_processing
+        VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000,
+
+        // Provided by VK_QCOM_image_processing
+        VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000,
+
+        // Provided by VK_NV_shading_rate_image
+        VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+    }
+
+    enum VkImageAspectFlags
+    {
+        VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001,
+        VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002,
+        VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004,
+        VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040,
+
+        // Provided by VK_VERSION_1_3
+        VK_IMAGE_ASPECT_NONE = 0,
+
+        // Provided by VK_EXT_image_drm_format_modifier
+        VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080,
+
+        // Provided by VK_EXT_image_drm_format_modifier
+        VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100,
+
+        // Provided by VK_EXT_image_drm_format_modifier
+        VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200,
+
+        // Provided by VK_EXT_image_drm_format_modifier
+        VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT,
+
+        // Provided by VK_KHR_maintenance4
+        VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE,
+    }
+
+    [Flags]
+    enum VkImageCreateFlags
+    {
+        VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+        VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+        VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+        VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
+        VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800,
+
+        // Provided by VK_VERSION_1_1
+        VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200,
+
+        // Provided by VK_NV_corner_sampled_image
+        VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000,
+
+        // Provided by VK_EXT_sample_locations
+        VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000,
+
+        // Provided by VK_EXT_fragment_density_map
+        VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000,
+
+        // Provided by VK_EXT_descriptor_buffer
+        VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00010000,
+
+        // Provided by VK_EXT_multisampled_render_to_single_sampled
+        VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000,
+
+        // Provided by VK_EXT_image_2d_view_of_3d
+        VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000,
+
+        // Provided by VK_QCOM_fragment_density_map_offset
+        VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000,
+
+        // Provided by VK_KHR_bind_memory2 with VK_KHR_device_group
+        VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT,
+
+        // Provided by VK_KHR_maintenance1
+        VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT,
+
+        // Provided by VK_KHR_maintenance2
+        VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,
+
+        // Provided by VK_KHR_maintenance2
+        VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_IMAGE_CREATE_DISJOINT_BIT_KHR = VK_IMAGE_CREATE_DISJOINT_BIT,
+
+        // Provided by VK_KHR_bind_memory2
+        VK_IMAGE_CREATE_ALIAS_BIT_KHR = VK_IMAGE_CREATE_ALIAS_BIT,
+    }
+
+    enum VkImageType
+    {
+        VK_IMAGE_TYPE_1D = 0,
+        VK_IMAGE_TYPE_2D = 1,
+        VK_IMAGE_TYPE_3D = 2,
+    }
+
+    [Flags]
+    enum VkSampleCountFlags {
+        VK_SAMPLE_COUNT_1_BIT = 0x00000001,
+        VK_SAMPLE_COUNT_2_BIT = 0x00000002,
+        VK_SAMPLE_COUNT_4_BIT = 0x00000004,
+        VK_SAMPLE_COUNT_8_BIT = 0x00000008,
+        VK_SAMPLE_COUNT_16_BIT = 0x00000010,
+        VK_SAMPLE_COUNT_32_BIT = 0x00000020,
+        VK_SAMPLE_COUNT_64_BIT = 0x00000040,
+    }
+
+    enum VkImageTiling
+    {
+        VK_IMAGE_TILING_OPTIMAL = 0,
+        VK_IMAGE_TILING_LINEAR = 1,
+
+        // Provided by VK_EXT_image_drm_format_modifier
+        VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000,
+    }
+
+    enum VkSharingMode
+    {
+        VK_SHARING_MODE_EXCLUSIVE = 0,
+        VK_SHARING_MODE_CONCURRENT = 1,
+    }
+
+    enum VkImageViewCreateFlags
+    {
+        // Provided by VK_EXT_fragment_density_map
+        VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001,
+
+        // Provided by VK_EXT_descriptor_buffer
+        VK_IMAGE_VIEW_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000004,
+
+        // Provided by VK_EXT_fragment_density_map2
+        VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT = 0x00000002,
+    }
+
+    enum VkImageViewType
+    {
+        VK_IMAGE_VIEW_TYPE_1D = 0,
+        VK_IMAGE_VIEW_TYPE_2D = 1,
+        VK_IMAGE_VIEW_TYPE_3D = 2,
+        VK_IMAGE_VIEW_TYPE_CUBE = 3,
+        VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,
+        VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,
+        VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6,
+    }
+
+    enum VkComponentSwizzle
+    {
+        VK_COMPONENT_SWIZZLE_IDENTITY = 0,
+        VK_COMPONENT_SWIZZLE_ZERO = 1,
+        VK_COMPONENT_SWIZZLE_ONE = 2,
+        VK_COMPONENT_SWIZZLE_R = 3,
+        VK_COMPONENT_SWIZZLE_G = 4,
+        VK_COMPONENT_SWIZZLE_B = 5,
+        VK_COMPONENT_SWIZZLE_A = 6,
+    }
+
+    enum VkDependencyFlags
+    {
+        VK_DEPENDENCY_BY_REGION_BIT = 0x00000001,
+
+        // Provided by VK_VERSION_1_1
+        VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004,
+
+        // Provided by VK_VERSION_1_1
+        VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002,
+
+        // Provided by VK_EXT_attachment_feedback_loop_layout
+        VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008,
+
+        // Provided by VK_KHR_multiview
+        VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT,
+
+        // Provided by VK_KHR_device_group
+        VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT,
+    }
+
+    enum VkSurfaceTransformFlagsKHR
+    {
+        VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001,
+        VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002,
+        VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004,
+        VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008,
+        VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010,
+        VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020,
+        VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040,
+        VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080,
+        VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
+    }
+
+    enum VkCompositeAlphaFlagsKHR
+    {
+        VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
+        VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002,
+        VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004,
+        VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008,
+    }
+
+    enum VkPresentModeKHR
+    {
+        VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+        VK_PRESENT_MODE_MAILBOX_KHR = 1,
+        VK_PRESENT_MODE_FIFO_KHR = 2,
+        VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3,
+
+        // Provided by VK_KHR_shared_presentable_image
+        VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000,
+
+        // Provided by VK_KHR_shared_presentable_image
+        VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001,
+    }
+
+    enum VkSwapchainCreateFlagsKHR
+    {
+        // Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_swapchain
+        VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001,
+
+        // Provided by VK_VERSION_1_1 with VK_KHR_swapchain
+        VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002,
+
+        // Provided by VK_KHR_swapchain_mutable_format
+        VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004,
+
+        // Provided by VK_EXT_swapchain_maintenance1
+        VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT = 0x00000008,
+    }
+    
+    enum VkFilter {
+        VK_FILTER_NEAREST = 0,
+        VK_FILTER_LINEAR = 1,
+        // Provided by VK_EXT_filter_cubic
+        VK_FILTER_CUBIC_EXT = 1000015000,
+        // Provided by VK_IMG_filter_cubic
+        VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT,
+    }
+
+    [Flags]
+    enum VkDebugUtilsMessageSeverityFlagsEXT
+    {
+        VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001,
+        VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010,
+        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100,
+        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000,
+    }
+    
+    [Flags]
+    enum VkDebugUtilsMessageTypeFlagsEXT {
+        VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001,
+        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002,
+        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004,
+        // Provided by VK_EXT_device_address_binding_report
+        VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT = 0x00000008,
+    }
+
+    enum VkObjectType
+    {
+        VK_OBJECT_TYPE_UNKNOWN = 0,
+        VK_OBJECT_TYPE_INSTANCE = 1,
+        VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
+        VK_OBJECT_TYPE_DEVICE = 3,
+        VK_OBJECT_TYPE_QUEUE = 4,
+        VK_OBJECT_TYPE_SEMAPHORE = 5,
+        VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
+        VK_OBJECT_TYPE_FENCE = 7,
+        VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
+        VK_OBJECT_TYPE_BUFFER = 9,
+        VK_OBJECT_TYPE_IMAGE = 10,
+        VK_OBJECT_TYPE_EVENT = 11,
+        VK_OBJECT_TYPE_QUERY_POOL = 12,
+        VK_OBJECT_TYPE_BUFFER_VIEW = 13,
+        VK_OBJECT_TYPE_IMAGE_VIEW = 14,
+        VK_OBJECT_TYPE_SHADER_MODULE = 15,
+        VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
+        VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
+        VK_OBJECT_TYPE_RENDER_PASS = 18,
+        VK_OBJECT_TYPE_PIPELINE = 19,
+        VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
+        VK_OBJECT_TYPE_SAMPLER = 21,
+        VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
+        VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
+        VK_OBJECT_TYPE_FRAMEBUFFER = 24,
+        VK_OBJECT_TYPE_COMMAND_POOL = 25,
+
+        // Provided by VK_VERSION_1_1
+        VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000,
+
+        // Provided by VK_VERSION_1_1
+        VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000,
+
+        // Provided by VK_VERSION_1_3
+        VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000,
+
+        // Provided by VK_KHR_surface
+        VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+
+        // Provided by VK_KHR_swapchain
+        VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
+
+        // Provided by VK_KHR_display
+        VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
+
+        // Provided by VK_KHR_display
+        VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
+
+        // Provided by VK_EXT_debug_report
+        VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
+
+        // Provided by VK_NVX_binary_import
+        VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000,
+
+        // Provided by VK_NVX_binary_import
+        VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001,
+
+        // Provided by VK_EXT_debug_utils
+        VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
+
+        // Provided by VK_KHR_acceleration_structure
+        VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
+
+        // Provided by VK_EXT_validation_cache
+        VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
+
+        // Provided by VK_NV_ray_tracing
+        VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
+
+        // Provided by VK_INTEL_performance_query
+        VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000,
+
+        // Provided by VK_KHR_deferred_host_operations
+        VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000,
+
+        // Provided by VK_NV_device_generated_commands
+        VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000,
+
+        // Provided by VK_FUCHSIA_buffer_collection
+        VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000,
+
+        // Provided by VK_EXT_opacity_micromap
+        VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000,
+
+        // Provided by VK_NV_optical_flow
+        VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV = 1000464000,
+
+        // Provided by VK_KHR_descriptor_update_template
+        VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
+
+        // Provided by VK_KHR_sampler_ycbcr_conversion
+        VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
+
+        // Provided by VK_EXT_private_data
+        VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT,
+    }
+
+    internal enum VkSemaphoreImportFlags
+    {
+        VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 0x00000001,
+        // Provided by VK_KHR_external_semaphore
+        VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
+    }
+
+    internal enum VkExternalSemaphoreHandleTypeFlags
+    {
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001,
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002,
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004,
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008,
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010,
+
+        // Provided by VK_FUCHSIA_external_semaphore
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA = 0x00000080,
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT,
+
+        // Provided by VK_KHR_external_semaphore_capabilities
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
+
+        // Provided by VK_KHR_external_semaphore_capabilities
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+
+        // Provided by VK_KHR_external_semaphore_capabilities
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR =
+            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+
+        // Provided by VK_KHR_external_semaphore_capabilities
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT,
+
+        // Provided by VK_KHR_external_semaphore_capabilities
+        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
+    }
+
+    enum VkExternalMemoryHandleTypeFlagBits
+    {
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001,
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002,
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004,
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 0x00000008,
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 0x00000010,
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020,
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040,
+
+        // Provided by VK_EXT_external_memory_dma_buf
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT = 0x00000200,
+
+        // Provided by VK_ANDROID_external_memory_android_hardware_buffer
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID = 0x00000400,
+
+        // Provided by VK_EXT_external_memory_host
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080,
+
+        // Provided by VK_EXT_external_memory_host
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100,
+
+        // Provided by VK_FUCHSIA_external_memory
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800,
+
+        // Provided by VK_NV_external_memory_rdma
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000,
+
+        // Provided by VK_QNX_external_memory_screen_buffer
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX = 0x00004000,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT,
+
+        // Provided by VK_KHR_external_memory_capabilities
+        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT,
+    }
+}

+ 29 - 0
src/Avalonia.Vulkan/UnmanagedInterop/VulkanGlobalApi.cs

@@ -0,0 +1,29 @@
+using System;
+using Avalonia.SourceGenerator;
+using Avalonia.Vulkan.Interop;
+
+namespace Avalonia.Vulkan.UnmanagedInterop;
+
+internal unsafe partial class VulkanGlobalApi
+{
+    private readonly VkGetInstanceProcAddressDelegate _vkGetProcAddress;
+
+    public VulkanGlobalApi(VkGetInstanceProcAddressDelegate vkGetProcAddress)
+    {
+        _vkGetProcAddress = vkGetProcAddress;
+        Initialize(name => vkGetProcAddress(IntPtr.Zero, name));
+    }
+
+    public IntPtr GetProcAddress(VkInstance instance, string name) => _vkGetProcAddress(instance.Handle, name);
+
+
+    [GetProcAddress("vkEnumerateInstanceLayerProperties")]
+    public partial VkResult EnumerateInstanceLayerProperties(ref uint pPropertyCount, VkLayerProperties* pProperties);
+
+    [GetProcAddress("vkCreateInstance")]
+    public partial VkResult vkCreateInstance(ref VkInstanceCreateInfo pCreateInfo, IntPtr pAllocator, out VkInstance pInstance);
+
+    [GetProcAddress("vkEnumerateInstanceExtensionProperties")]
+    public partial VkResult vkEnumerateInstanceExtensionProperties(IntPtr pLayerName, uint* pPropertyCount,
+        VkExtensionProperties* pProperties);
+}

+ 82 - 0
src/Avalonia.Vulkan/UnmanagedInterop/VulkanInstanceApi.cs

@@ -0,0 +1,82 @@
+using System;
+using Avalonia.SourceGenerator;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+using uint32_t = System.UInt32;
+using VkBool32 = System.UInt32;
+namespace Avalonia.Vulkan;
+
+internal unsafe partial class VulkanInstanceApi
+{
+    public IVulkanInstance Instance { get; }
+
+    public VulkanInstanceApi(IVulkanInstance instance)
+    {
+        Instance = instance;
+        Initialize(name => instance.GetInstanceProcAddress(instance.Handle, name));
+    }
+
+    [GetProcAddress("vkCreateDebugUtilsMessengerEXT", true)]
+    public partial VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
+        ref VkDebugUtilsMessengerCreateInfoEXT pCreateInfo, IntPtr pAllocator, out VkDebugUtilsMessengerEXT pMessenger);
+
+    [GetProcAddress("vkEnumeratePhysicalDevices")]
+    public partial VkResult EnumeratePhysicalDevices(VkInstance instance, ref uint32_t pPhysicalDeviceCount,
+        VkPhysicalDevice* pPhysicalDevices);
+
+    [GetProcAddress("vkGetPhysicalDeviceProperties")]
+    public partial void GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
+        out VkPhysicalDeviceProperties pProperties);
+
+    [GetProcAddress("vkEnumerateDeviceExtensionProperties")]
+    public partial VkResult EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, byte* pLayerName,
+        ref uint32_t pPropertyCount, VkExtensionProperties* pProperties);
+
+    [GetProcAddress("vkGetPhysicalDeviceSurfaceSupportKHR")]
+    public partial VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
+        uint32_t queueFamilyIndex,
+        VkSurfaceKHR surface, out VkBool32 pSupported);
+
+
+    [GetProcAddress("vkGetPhysicalDeviceQueueFamilyProperties")]
+    public partial void GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+        ref uint32_t pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties);
+
+    [GetProcAddress("vkCreateDevice")]
+    public partial VkResult CreateDevice(VkPhysicalDevice physicalDevice, ref VkDeviceCreateInfo pCreateInfo,
+        IntPtr pAllocator, out VkDevice pDevice);
+
+    [GetProcAddress("vkGetDeviceQueue")]
+    public partial void GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
+        out VkQueue pQueue);
+
+    [GetProcAddress("vkGetDeviceProcAddr")]
+    public partial IntPtr GetDeviceProcAddr(VkDevice device, IntPtr pName);
+
+    [GetProcAddress("vkDestroySurfaceKHR")]
+    public partial void DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, IntPtr pAllocator);
+
+    [GetProcAddress("vkGetPhysicalDeviceSurfaceFormatsKHR")]
+    public partial VkResult GetPhysicalDeviceSurfaceFormatsKHR(
+        VkPhysicalDevice physicalDevice,
+        VkSurfaceKHR surface,
+        ref uint32_t pSurfaceFormatCount,
+        VkSurfaceFormatKHR* pSurfaceFormats);
+
+    [GetProcAddress("vkGetPhysicalDeviceMemoryProperties")]
+    public partial void GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
+        out VkPhysicalDeviceMemoryProperties pMemoryProperties);
+
+    [GetProcAddress("vkGetPhysicalDeviceSurfaceCapabilitiesKHR")]
+    public partial VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+        out VkSurfaceCapabilitiesKHR pSurfaceCapabilities);
+
+    [GetProcAddress("vkGetPhysicalDeviceSurfacePresentModesKHR")]
+    public partial VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+        ref uint32_t pPresentModeCount, VkPresentModeKHR* pPresentModes);
+    
+    [GetProcAddress("vkGetPhysicalDeviceProperties2", true)]
+    public partial void GetPhysicalDeviceProperties2(
+        VkPhysicalDevice                            physicalDevice,
+        VkPhysicalDeviceProperties2*                pProperties);
+}

+ 767 - 0
src/Avalonia.Vulkan/UnmanagedInterop/VulkanStructs.cs

@@ -0,0 +1,767 @@
+// ReSharper disable IdentifierTypo
+
+// ReSharper disable InconsistentNaming
+// ReSharper disable NotAccessedField.Global
+#pragma warning disable CS0649
+#pragma warning disable CS0169
+#pragma warning disable CA1823
+using System;
+using uint32_t = System.UInt32;
+using VkSampleCountFlags = System.UInt32;
+using int32_t = System.Int32;
+using VkBool32 = System.UInt32;
+using uint8_t = System.Byte;
+using size_t = System.IntPtr;
+using VkDeviceSize = System.UInt64;
+// ReSharper disable RedundantUnsafeContext
+
+namespace Avalonia.Vulkan.UnmanagedInterop
+{
+    struct VkInstance
+    {
+        public IntPtr Handle;
+        public VkInstance(IntPtr handle)
+        {
+            Handle = handle;
+        }
+    }
+
+    struct VkPhysicalDevice
+    {
+        public IntPtr Handle;
+        public VkPhysicalDevice(IntPtr handle)
+        {
+            Handle = handle;
+        }
+    }
+
+    struct VkDevice
+    {
+        public IntPtr Handle;
+
+        public VkDevice(IntPtr handle)
+        {
+            Handle = handle;
+        }
+    }
+
+    struct VkSwapchainKHR
+    {
+        public ulong Handle;
+    }
+
+    struct VkSemaphore
+    {
+        public ulong Handle;
+    }
+
+    struct VkFence
+    {
+        public ulong Handle;
+    }
+
+    struct VkImage
+    {
+        public ulong Handle;
+    }
+    
+    struct VkImageView
+    {
+        public ulong Handle;
+    }
+    
+    struct VkDeviceMemory
+    {
+        public ulong Handle;
+    }
+
+    struct VkQueue
+    {
+        public IntPtr Handle;
+        public VkQueue(IntPtr handle)
+        {
+            Handle = handle;
+        }
+    }
+
+    struct VkCommandPool
+    {
+        public ulong Handle;
+    }
+    
+    struct VkCommandBuffer
+    {
+        public IntPtr Handle;
+    }
+
+    struct VkSurfaceKHR
+    {
+        public ulong Handle;
+
+        public VkSurfaceKHR(ulong handle)
+        {
+            Handle = handle;
+        }
+    }
+    
+    struct VkDebugUtilsMessengerEXT
+    {
+        public IntPtr Handle;
+    }
+
+    unsafe struct VkLayerProperties
+    {
+        public fixed byte layerName[256];
+        public uint32_t specVersion;
+        public uint32_t implementationVersion;
+        public fixed byte description[256];
+    }
+
+    unsafe struct VkDebugUtilsLabelEXT
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public IntPtr pLabelName;
+        public fixed float color[4];
+    }
+
+    struct VkDebugUtilsObjectNameInfoEXT
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public VkObjectType objectType;
+        public ulong objectHandle;
+        public IntPtr pObjectName;
+    }
+
+    unsafe struct VkDebugUtilsMessengerCallbackDataEXT
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public uint flags;
+        public IntPtr pMessageIdName;
+        public int32_t messageIdNumber;
+        public IntPtr pMessage;
+        public uint32_t queueLabelCount;
+        public VkDebugUtilsLabelEXT* pQueueLabels;
+        public uint32_t cmdBufLabelCount;
+        public VkDebugUtilsLabelEXT* pCmdBufLabels;
+        public uint32_t objectCount;
+        public VkDebugUtilsObjectNameInfoEXT* pObjects;
+    }
+
+    unsafe delegate VkBool32 VkDebugUtilsMessengerCallbackEXTDelegate(
+        VkDebugUtilsMessageSeverityFlagsEXT messageSeverity,
+        VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+        VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+        void* pUserData);
+
+    struct VkDebugUtilsMessengerCreateInfoEXT
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public uint flags;
+        public VkDebugUtilsMessageSeverityFlagsEXT messageSeverity;
+        public VkDebugUtilsMessageTypeFlagsEXT messageType;
+        public IntPtr pfnUserCallback;
+        public IntPtr pUserData;
+    }
+
+    unsafe struct VkInstanceCreateInfo
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public int flags;
+        public VkApplicationInfo* pApplicationInfo;
+        public uint32_t enabledLayerCount;
+        public byte** ppEnabledLayerNames;
+        public uint32_t enabledExtensionCount;
+        public byte** ppEnabledExtensionNames;
+    }
+
+    unsafe struct VkApplicationInfo
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public byte* pApplicationName;
+        public uint32_t applicationVersion;
+        public byte* pEngineName;
+        public uint32_t engineVersion;
+        public uint32_t apiVersion;
+    }
+
+    unsafe struct VkPhysicalDeviceSparseProperties
+    {
+        public VkBool32 residencyStandard2DBlockShape;
+        public VkBool32 residencyStandard2DMultisampleBlockShape;
+        public VkBool32 residencyStandard3DBlockShape;
+        public VkBool32 residencyAlignedMipSize;
+        public VkBool32 residencyNonResidentStrict;
+    }
+
+    unsafe struct VkPhysicalDeviceProperties
+    {
+        public uint32_t apiVersion;
+        public uint32_t driverVersion;
+        public uint32_t vendorID;
+        public uint32_t deviceID;
+        public VkPhysicalDeviceType deviceType;
+        public fixed byte deviceName[256];
+        public fixed uint8_t pipelineCacheUUID[16];
+        public VkPhysicalDeviceLimits limits;
+        public VkPhysicalDeviceSparseProperties sparseProperties;
+    }
+    
+    unsafe struct VkPhysicalDeviceProperties2 {
+        public VkStructureType               sType;
+        public void*                         pNext;
+        public VkPhysicalDeviceProperties    properties;
+    }
+    
+    unsafe struct VkPhysicalDeviceIDProperties {
+        public VkStructureType    sType;
+        public void*              pNext;
+        public fixed uint8_t            deviceUUID[16];
+        public fixed uint8_t            driverUUID[16];
+        public fixed uint8_t            deviceLUID[8];
+        public uint32_t           deviceNodeMask;
+        public VkBool32           deviceLUIDValid;
+    } 
+    
+    unsafe struct VkPhysicalDeviceLimits
+    {
+        public uint32_t maxImageDimension1D;
+        public uint32_t maxImageDimension2D;
+        public uint32_t maxImageDimension3D;
+        public uint32_t maxImageDimensionCube;
+        public uint32_t maxImageArrayLayers;
+        public uint32_t maxTexelBufferElements;
+        public uint32_t maxUniformBufferRange;
+        public uint32_t maxStorageBufferRange;
+        public uint32_t maxPushConstantsSize;
+        public uint32_t maxMemoryAllocationCount;
+        public uint32_t maxSamplerAllocationCount;
+        public VkDeviceSize bufferImageGranularity;
+        public VkDeviceSize sparseAddressSpaceSize;
+        public uint32_t maxBoundDescriptorSets;
+        public uint32_t maxPerStageDescriptorSamplers;
+        public uint32_t maxPerStageDescriptorUniformBuffers;
+        public uint32_t maxPerStageDescriptorStorageBuffers;
+        public uint32_t maxPerStageDescriptorSampledImages;
+        public uint32_t maxPerStageDescriptorStorageImages;
+        public uint32_t maxPerStageDescriptorInputAttachments;
+        public uint32_t maxPerStageResources;
+        public uint32_t maxDescriptorSetSamplers;
+        public uint32_t maxDescriptorSetUniformBuffers;
+        public uint32_t maxDescriptorSetUniformBuffersDynamic;
+        public uint32_t maxDescriptorSetStorageBuffers;
+        public uint32_t maxDescriptorSetStorageBuffersDynamic;
+        public uint32_t maxDescriptorSetSampledImages;
+        public uint32_t maxDescriptorSetStorageImages;
+        public uint32_t maxDescriptorSetInputAttachments;
+        public uint32_t maxVertexInputAttributes;
+        public uint32_t maxVertexInputBindings;
+        public uint32_t maxVertexInputAttributeOffset;
+        public uint32_t maxVertexInputBindingStride;
+        public uint32_t maxVertexOutputComponents;
+        public uint32_t maxTessellationGenerationLevel;
+        public uint32_t maxTessellationPatchSize;
+        public uint32_t maxTessellationControlPerVertexInputComponents;
+        public uint32_t maxTessellationControlPerVertexOutputComponents;
+        public uint32_t maxTessellationControlPerPatchOutputComponents;
+        public uint32_t maxTessellationControlTotalOutputComponents;
+        public uint32_t maxTessellationEvaluationInputComponents;
+        public uint32_t maxTessellationEvaluationOutputComponents;
+        public uint32_t maxGeometryShaderInvocations;
+        public uint32_t maxGeometryInputComponents;
+        public uint32_t maxGeometryOutputComponents;
+        public uint32_t maxGeometryOutputVertices;
+        public uint32_t maxGeometryTotalOutputComponents;
+        public uint32_t maxFragmentInputComponents;
+        public uint32_t maxFragmentOutputAttachments;
+        public uint32_t maxFragmentDualSrcAttachments;
+        public uint32_t maxFragmentCombinedOutputResources;
+        public uint32_t maxComputeSharedMemorySize;
+        public fixed uint32_t maxComputeWorkGroupCount[3];
+        public uint32_t maxComputeWorkGroupInvocations;
+        public fixed uint32_t maxComputeWorkGroupSize[3];
+        public uint32_t subPixelPrecisionBits;
+        public uint32_t subTexelPrecisionBits;
+        public uint32_t mipmapPrecisionBits;
+        public uint32_t maxDrawIndexedIndexValue;
+        public uint32_t maxDrawIndirectCount;
+        public float maxSamplerLodBias;
+        public float maxSamplerAnisotropy;
+        public uint32_t maxViewports;
+        public fixed uint32_t maxViewportDimensions[2];
+        public fixed float viewportBoundsRange[2];
+        public uint32_t viewportSubPixelBits;
+        public size_t minMemoryMapAlignment;
+        public VkDeviceSize minTexelBufferOffsetAlignment;
+        public VkDeviceSize minUniformBufferOffsetAlignment;
+        public VkDeviceSize minStorageBufferOffsetAlignment;
+        public int32_t minTexelOffset;
+        public uint32_t maxTexelOffset;
+        public int32_t minTexelGatherOffset;
+        public uint32_t maxTexelGatherOffset;
+        public float minInterpolationOffset;
+        public float maxInterpolationOffset;
+        public uint32_t subPixelInterpolationOffsetBits;
+        public uint32_t maxFramebufferWidth;
+        public uint32_t maxFramebufferHeight;
+        public uint32_t maxFramebufferLayers;
+        public VkSampleCountFlags framebufferColorSampleCounts;
+        public VkSampleCountFlags framebufferDepthSampleCounts;
+        public VkSampleCountFlags framebufferStencilSampleCounts;
+        public VkSampleCountFlags framebufferNoAttachmentsSampleCounts;
+        public uint32_t maxColorAttachments;
+        public VkSampleCountFlags sampledImageColorSampleCounts;
+        public VkSampleCountFlags sampledImageIntegerSampleCounts;
+        public VkSampleCountFlags sampledImageDepthSampleCounts;
+        public VkSampleCountFlags sampledImageStencilSampleCounts;
+        public VkSampleCountFlags storageImageSampleCounts;
+        public uint32_t maxSampleMaskWords;
+        public VkBool32 timestampComputeAndGraphics;
+        public float timestampPeriod;
+        public uint32_t maxClipDistances;
+        public uint32_t maxCullDistances;
+        public uint32_t maxCombinedClipAndCullDistances;
+        public uint32_t discreteQueuePriorities;
+        public fixed float pointSizeRange[2];
+        public fixed float lineWidthRange[2];
+        public float pointSizeGranularity;
+        public float lineWidthGranularity;
+        public VkBool32 strictLines;
+        public VkBool32 standardSampleLocations;
+        public VkDeviceSize optimalBufferCopyOffsetAlignment;
+        public VkDeviceSize optimalBufferCopyRowPitchAlignment;
+        public VkDeviceSize nonCoherentAtomSize;
+    }
+
+    internal unsafe struct VkExtensionProperties
+    {
+        public fixed byte extensionName[256];
+        public uint32_t specVersion;
+    }
+
+    struct VkQueueFamilyProperties
+    {
+        public VkQueueFlags queueFlags;
+        public uint32_t queueCount;
+        public uint32_t timestampValidBits;
+        public VkExtent3D minImageTransferGranularity;
+    }
+
+    struct VkExtent2D
+    {
+        public uint32_t width;
+        public uint32_t height;
+    }
+
+    struct VkExtent3D
+    {
+        public uint32_t width;
+        public uint32_t height;
+        public uint32_t depth;
+    }
+
+    unsafe struct VkDeviceQueueCreateInfo
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public VkDeviceQueueCreateFlags flags;
+        public uint32_t queueFamilyIndex;
+        public uint32_t queueCount;
+        public float* pQueuePriorities;
+    }
+
+    unsafe struct VkDeviceCreateInfo
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public uint flags;
+        public uint32_t queueCreateInfoCount;
+        public VkDeviceQueueCreateInfo* pQueueCreateInfos;
+        public uint32_t enabledLayerCount;
+        public byte** ppEnabledLayerNames;
+        public uint32_t enabledExtensionCount;
+        public byte** ppEnabledExtensionNames;
+        public IntPtr pEnabledFeatures;
+    }
+
+    struct VkFenceCreateInfo
+    {
+        public VkStructureType sType;
+        IntPtr pNext;
+        public VkFenceCreateFlags flags;
+    }
+
+    struct VkCommandPoolCreateInfo
+    {
+        public VkStructureType sType;
+        IntPtr pNext;
+        public VkCommandPoolCreateFlags flags;
+        public uint32_t queueFamilyIndex;
+    }
+    
+    struct VkCommandBufferAllocateInfo
+    {
+        public VkStructureType sType;
+        IntPtr pNext;
+        public VkCommandPool commandPool;
+        public VkCommandBufferLevel level;
+        public uint32_t commandBufferCount;
+    }
+
+
+
+    struct VkCommandBufferBeginInfo
+    {
+        public VkStructureType sType;
+        IntPtr pNext;
+        public VkCommandBufferUsageFlags flags;
+        IntPtr pInheritanceInfo;
+    }
+
+    struct VkSemaphoreCreateInfo
+    {
+        public VkStructureType sType;
+        IntPtr pNext;
+        uint flags;
+    }
+
+    unsafe struct VkSubmitInfo
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public uint32_t waitSemaphoreCount;
+        public VkSemaphore* pWaitSemaphores;
+        public VkPipelineStageFlags* pWaitDstStageMask;
+        public uint32_t commandBufferCount;
+        public VkCommandBuffer* pCommandBuffers;
+        public uint32_t signalSemaphoreCount;
+        public VkSemaphore* pSignalSemaphores;
+    }
+
+
+    struct VkSurfaceFormatKHR
+    {
+        public VkFormat format;
+        public VkColorSpaceKHR colorSpace;
+    }
+
+
+
+    struct VkMemoryType
+    {
+        public VkMemoryPropertyFlags propertyFlags;
+        public uint32_t heapIndex;
+    }
+
+    struct VkMemoryHeap
+    {
+        public VkDeviceSize size;
+        public VkMemoryHeapFlags flags;
+    }
+
+    unsafe struct VkPhysicalDeviceMemoryProperties
+    {
+        public uint32_t memoryTypeCount;
+        public VkMemoryTypesBuffer memoryTypes;
+        public uint32_t memoryHeapCount;
+        public VkMemoryHeapsBuffer memoryHeaps;
+
+        public struct VkMemoryTypesBuffer
+        {
+            public VkMemoryType Element0;
+            public VkMemoryType Element1;
+            public VkMemoryType Element2;
+            public VkMemoryType Element3;
+            public VkMemoryType Element4;
+            public VkMemoryType Element5;
+            public VkMemoryType Element6;
+            public VkMemoryType Element7;
+            public VkMemoryType Element8;
+            public VkMemoryType Element9;
+            public VkMemoryType Element10;
+            public VkMemoryType Element11;
+            public VkMemoryType Element12;
+            public VkMemoryType Element13;
+            public VkMemoryType Element14;
+            public VkMemoryType Element15;
+            public VkMemoryType Element16;
+            public VkMemoryType Element17;
+            public VkMemoryType Element18;
+            public VkMemoryType Element19;
+            public VkMemoryType Element20;
+            public VkMemoryType Element21;
+            public VkMemoryType Element22;
+            public VkMemoryType Element23;
+            public VkMemoryType Element24;
+            public VkMemoryType Element25;
+            public VkMemoryType Element26;
+            public VkMemoryType Element27;
+            public VkMemoryType Element28;
+            public VkMemoryType Element29;
+            public VkMemoryType Element30;
+            public VkMemoryType Element31;
+
+            public ref VkMemoryType this[int index]
+            {
+                get
+                {
+                    if (index > 31 || index < 0)
+                    {
+                        throw new ArgumentOutOfRangeException(nameof(index));
+                    }
+
+                    fixed (VkMemoryType* ptr = &Element0)
+                    {
+                        return ref ptr[index];
+                    }
+                }
+            }
+        }
+
+        public struct VkMemoryHeapsBuffer
+        {
+            public VkMemoryHeap Element0;
+            public VkMemoryHeap Element1;
+            public VkMemoryHeap Element2;
+            public VkMemoryHeap Element3;
+            public VkMemoryHeap Element4;
+            public VkMemoryHeap Element5;
+            public VkMemoryHeap Element6;
+            public VkMemoryHeap Element7;
+            public VkMemoryHeap Element8;
+            public VkMemoryHeap Element9;
+            public VkMemoryHeap Element10;
+            public VkMemoryHeap Element11;
+            public VkMemoryHeap Element12;
+            public VkMemoryHeap Element13;
+            public VkMemoryHeap Element14;
+            public VkMemoryHeap Element15;
+
+            public ref VkMemoryHeap this[int index]
+            {
+                get
+                {
+                    if (index > 15 || index < 0)
+                    {
+                        throw new ArgumentOutOfRangeException(nameof(index));
+                    }
+
+                    fixed (VkMemoryHeap* ptr = &Element0)
+                    {
+                        return ref ptr[index];
+                    }
+                }
+            }
+
+
+        }
+    }
+
+    unsafe struct VkImageCreateInfo
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkImageCreateFlags flags;
+        public VkImageType imageType;
+        public VkFormat format;
+        public VkExtent3D extent;
+        public uint32_t mipLevels;
+        public uint32_t arrayLayers;
+        public VkSampleCountFlags samples;
+        public VkImageTiling tiling;
+        public VkImageUsageFlags usage;
+        public VkSharingMode sharingMode;
+        public uint32_t queueFamilyIndexCount;
+        public uint32_t* pQueueFamilyIndices;
+        public VkImageLayout initialLayout;
+    }
+
+    struct VkMemoryRequirements
+    {
+        public VkDeviceSize size;
+        public VkDeviceSize alignment;
+        public uint32_t memoryTypeBits;
+    }
+
+    struct VkMemoryAllocateInfo
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public VkDeviceSize allocationSize;
+        public uint32_t memoryTypeIndex;
+    }
+
+    struct VkComponentMapping
+    {
+        public VkComponentSwizzle r;
+        public VkComponentSwizzle g;
+        public VkComponentSwizzle b;
+        public VkComponentSwizzle a;
+    }
+
+    struct VkImageSubresourceRange
+    {
+        public VkImageAspectFlags aspectMask;
+        public uint32_t baseMipLevel;
+        public uint32_t levelCount;
+        public uint32_t baseArrayLayer;
+        public uint32_t layerCount;
+    }
+
+    struct VkImageViewCreateInfo
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public VkImageViewCreateFlags flags;
+        public VkImage image;
+        public VkImageViewType viewType;
+        public VkFormat format;
+        public VkComponentMapping components;
+        public VkImageSubresourceRange subresourceRange;
+    }
+
+    struct VkImageMemoryBarrier
+    {
+        public VkStructureType sType;
+        IntPtr pNext;
+        public VkAccessFlags srcAccessMask;
+        public VkAccessFlags dstAccessMask;
+        public VkImageLayout oldLayout;
+        public VkImageLayout newLayout;
+        public uint32_t srcQueueFamilyIndex;
+        public uint32_t dstQueueFamilyIndex;
+        public VkImage image;
+        public VkImageSubresourceRange subresourceRange;
+    }
+
+    struct VkSurfaceCapabilitiesKHR
+    {
+        public uint32_t minImageCount;
+        public uint32_t maxImageCount;
+        public VkExtent2D currentExtent;
+        public VkExtent2D minImageExtent;
+        public VkExtent2D maxImageExtent;
+        public uint32_t maxImageArrayLayers;
+        public VkSurfaceTransformFlagsKHR supportedTransforms;
+        public VkSurfaceTransformFlagsKHR currentTransform;
+        public VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
+        public VkImageUsageFlags supportedUsageFlags;
+    }
+
+    unsafe struct VkSwapchainCreateInfoKHR
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public VkSwapchainCreateFlagsKHR flags;
+        public VkSurfaceKHR surface;
+        public uint32_t minImageCount;
+        public VkFormat imageFormat;
+        public VkColorSpaceKHR imageColorSpace;
+        public VkExtent2D imageExtent;
+        public uint32_t imageArrayLayers;
+        public VkImageUsageFlags imageUsage;
+        public VkSharingMode imageSharingMode;
+        public uint32_t queueFamilyIndexCount;
+        public uint32_t* pQueueFamilyIndices;
+        public VkSurfaceTransformFlagsKHR preTransform;
+        public VkCompositeAlphaFlagsKHR compositeAlpha;
+        public VkPresentModeKHR presentMode;
+        public VkBool32 clipped;
+        public VkSwapchainKHR oldSwapchain;
+    }
+
+    struct VkOffset3D
+    {
+        public int32_t x;
+        public int32_t y;
+        public int32_t z;
+    }
+
+    struct VkImageSubresourceLayers
+    {
+        public VkImageAspectFlags aspectMask;
+        public uint32_t mipLevel;
+        public uint32_t baseArrayLayer;
+        public uint32_t layerCount;
+    }
+
+    struct VkImageBlit
+    {
+        public VkImageSubresourceLayers srcSubresource;
+        public VkOffset3D srcOffsets1;
+        public VkOffset3D srcOffsets2;
+        public VkImageSubresourceLayers dstSubresource;
+        public VkOffset3D dstOffsets1;
+        public VkOffset3D dstOffsets2;
+    }
+
+    unsafe struct VkPresentInfoKHR
+    {
+        public VkStructureType sType;
+        public IntPtr pNext;
+        public uint32_t waitSemaphoreCount;
+        public VkSemaphore* pWaitSemaphores;
+        public uint32_t swapchainCount;
+        public VkSwapchainKHR* pSwapchains;
+        public uint32_t* pImageIndices;
+        public VkResult* pResults;
+    }
+
+    unsafe struct VkImportSemaphoreFdInfoKHR
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkSemaphore semaphore;
+        public VkSemaphoreImportFlags flags;
+        public VkExternalSemaphoreHandleTypeFlags handleType;
+        public int fd;
+    }
+
+    unsafe struct VkImportSemaphoreWin32HandleInfoKHR
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkSemaphore semaphore;
+        public VkSemaphoreImportFlags flags;
+        public VkExternalSemaphoreHandleTypeFlags handleType;
+        public IntPtr handle;
+        public IntPtr name;
+    }
+
+    unsafe struct VkImportMemoryFdInfoKHR
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkExternalMemoryHandleTypeFlagBits handleType;
+        public int fd;
+    }
+
+    unsafe struct VkImportMemoryWin32HandleInfoKHR
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkExternalMemoryHandleTypeFlagBits handleType;
+        public IntPtr handle;
+        public IntPtr name;
+    }
+
+    unsafe struct VkMemoryDedicatedAllocateInfo
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkImage image;
+        public IntPtr buffer;
+    }
+
+    unsafe struct VkExternalMemoryImageCreateInfo
+    {
+        public VkStructureType sType;
+        public void* pNext;
+        public VkExternalMemoryHandleTypeFlagBits handleTypes;
+    }
+}

+ 19 - 0
src/Avalonia.Vulkan/VulkanBindings.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Avalonia.Vulkan.Interop;
+
+namespace Avalonia.Vulkan;
+
+
+static class VulkanHelpers
+{
+    public static uint MakeVersion(Version v) => MakeVersion(v.Major, v.Minor, v.Build);
+
+    public static uint MakeVersion(int major, int minor, int patch)
+    {
+        return (uint)((major << 22) | (minor << 12) | patch);
+    }
+    
+    public const uint QueueFamilyIgnored = 4294967295;
+}

+ 73 - 0
src/Avalonia.Vulkan/VulkanContext.cs

@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+internal class VulkanContext : IVulkanPlatformGraphicsContext
+{
+    private readonly IVulkanKhrSurfacePlatformSurfaceFactory? _surfaceFactory;
+    private readonly VulkanExternalObjectsFeature? _externalObjectsFeature;
+    public IVulkanDevice Device { get; }
+    public IVulkanInstance Instance => Device.Instance;
+    
+    public VulkanContext(IVulkanDevice device, Dictionary<Type, object> platformFeatures)
+    {
+        Device = device;
+        using (device.Lock())
+        {
+            InstanceApi = new VulkanInstanceApi(device.Instance);
+            DeviceApi = new VulkanDeviceApi(device);
+            if (platformFeatures.TryGetValue(typeof(IVulkanKhrSurfacePlatformSurfaceFactory), out var factory))
+                _surfaceFactory = (IVulkanKhrSurfacePlatformSurfaceFactory)factory;
+        }
+
+        if (
+            VulkanExternalObjectsFeature.RequiredInstanceExtensions.All(ext => Instance.EnabledExtensions.Contains(ext))
+            && VulkanExternalObjectsFeature.RequiredDeviceExtensions.All(ext => Device.EnabledExtensions.Contains(ext)))
+        {
+            _externalObjectsFeature = new VulkanExternalObjectsFeature(this);
+        }
+    }
+    
+    public void Dispose()
+    {
+        
+    }
+
+    public object? TryGetFeature(Type featureType)
+    {
+        if (featureType == typeof(IVulkanContextExternalObjectsFeature))
+            return _externalObjectsFeature;
+        return null;
+    }
+
+    public bool IsLost => Device.IsLost;
+    public IDisposable EnsureCurrent() => Device.Lock();
+
+    public VkDevice DeviceHandle => new (Device.Handle);
+    public VkPhysicalDevice PhysicalDeviceHandle => new (Device.PhysicalDeviceHandle);
+    public VkInstance InstanceHandle => new(Instance.Handle);
+    public VkQueue MainQueueHandle => new(Device.MainQueueHandle);
+    public uint GraphicsQueueFamilyIndex => Device.GraphicsQueueFamilyIndex;
+
+    public VulkanInstanceApi InstanceApi { get; }
+    public VulkanDeviceApi DeviceApi { get; }
+    public IVulkanRenderTarget CreateRenderTarget(IEnumerable<object> surfaces)
+    {
+        foreach (var surf in surfaces)
+        {
+            IVulkanKhrSurfacePlatformSurface khrSurface;
+            if (surf is IVulkanKhrSurfacePlatformSurface khr)
+                khrSurface = khr;
+            else if (_surfaceFactory?.CanRenderToSurface(this, surf) == true)
+                khrSurface = _surfaceFactory.CreateSurface(this, surf);
+            else 
+                continue;
+            return new VulkanKhrRenderTarget(khrSurface, this);
+        }
+
+        throw new VulkanException("Unable to find a suitable platform surface");
+    }
+}

+ 34 - 0
src/Avalonia.Vulkan/VulkanException.cs

@@ -0,0 +1,34 @@
+using System;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+public class VulkanException : Exception
+{
+    public VulkanException(string message) : base(message)
+    {
+        
+    }
+
+    public VulkanException(string funcName, int res) : this(funcName, (VkResult)res)
+    {
+        
+    }
+    
+    internal VulkanException(string funcName, VkResult res) : base($"{funcName} returned {res}")
+    {
+
+    }
+
+    public static void ThrowOnError(string funcName, int res) => ((VkResult)res).ThrowOnError(funcName);
+}
+
+internal static class VulkanExceptionExtensions
+{
+    public static void ThrowOnError(this VkResult res, string funcName)
+    {
+        if (res != VkResult.VK_SUCCESS)
+            throw new VulkanException(funcName, res);
+    }
+}

+ 311 - 0
src/Avalonia.Vulkan/VulkanExternalObjectsFeature.cs

@@ -0,0 +1,311 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Avalonia.Platform;
+using Avalonia.Rendering.Composition;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+internal unsafe class VulkanExternalObjectsFeature : IVulkanContextExternalObjectsFeature
+{
+    public static string[] RequiredInstanceExtensions = {
+        "VK_KHR_get_physical_device_properties2",
+        "VK_KHR_external_memory_capabilities",
+        "VK_KHR_external_semaphore_capabilities"
+    };
+
+    
+    private static string[] s_requiredCommonDeviceExtensions =
+    {
+        "VK_KHR_external_memory",
+        "VK_KHR_external_semaphore",
+        "VK_KHR_dedicated_allocation",
+    };
+
+    private static string[] s_requiredLinuxDeviceExtensions =
+        s_requiredCommonDeviceExtensions.Concat(new[]
+        {
+            "VK_KHR_external_semaphore_fd",
+            "VK_KHR_external_memory_fd"
+        }).ToArray();
+
+    private static string[] s_requiredWin32DeviceExtensions = s_requiredCommonDeviceExtensions.Concat(new[]
+    {
+        "VK_KHR_external_semaphore_win32",
+        "VK_KHR_external_memory_win32"
+    }).ToArray();
+
+    public static string[] RequiredDeviceExtensions = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+        ? s_requiredWin32DeviceExtensions
+        : s_requiredLinuxDeviceExtensions;
+    
+    private readonly VulkanContext _context;
+    private readonly VulkanCommandBufferPool _pool;
+
+    public VulkanExternalObjectsFeature(VulkanContext context)
+    {
+        _context = context;
+        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+        {
+            //TODO: keyed muted
+            SupportedImageHandleTypes = new[]
+            {
+                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueNtHandle,
+                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueKmtHandle,
+            };
+            SupportedSemaphoreTypes = new[]
+            {
+                KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueNtHandle,
+                KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueKmtHandle
+            };
+        }
+        else
+        {
+            SupportedImageHandleTypes = new[]
+            {
+                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor
+            };
+            SupportedSemaphoreTypes = new[]
+            {
+                KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor
+            };
+        }
+
+        var physicalDeviceIDProperties = new VkPhysicalDeviceIDProperties()
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES
+        };
+        
+        var physicalDeviceProperties2 = new VkPhysicalDeviceProperties2()
+        {
+            sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
+            pNext = &physicalDeviceIDProperties
+        };
+        _context.InstanceApi.GetPhysicalDeviceProperties2(_context.PhysicalDeviceHandle, &physicalDeviceProperties2);
+
+        var luid = new Span<byte>(physicalDeviceIDProperties.deviceLUID, 8).ToArray();
+        if (luid.Any(b => b != 0))
+            DeviceLuid = luid;
+        var uuid = new Span<byte>(physicalDeviceIDProperties.deviceUUID, 16).ToArray();
+        if (uuid.Any(b => b != 0))
+            DeviceUuid = uuid;
+        _pool = new VulkanCommandBufferPool(_context);
+    }
+    
+    public IReadOnlyList<string> SupportedImageHandleTypes { get; }
+    public IReadOnlyList<string> SupportedSemaphoreTypes { get; }
+    public byte[]? DeviceUuid { get; }
+    public byte[]? DeviceLuid { get; }
+    
+    
+    public CompositionGpuImportedImageSynchronizationCapabilities GetSynchronizationCapabilities(string imageHandleType)
+    {
+        if (!SupportedImageHandleTypes.Contains(imageHandleType))
+            throw new ArgumentException();
+        //TODO: keyed muted
+        return CompositionGpuImportedImageSynchronizationCapabilities.Semaphores;
+    }
+
+    public IVulkanExternalImage ImportImage(IPlatformHandle handle, PlatformGraphicsExternalImageProperties properties)
+    {
+        _pool.FreeFinishedCommandBuffers();
+        if (!SupportedImageHandleTypes.Contains(handle.HandleDescriptor))
+            throw new NotSupportedException();
+        
+
+        return new ImportedImage(_context, _pool, handle, properties);
+    }
+
+    public IVulkanExternalSemaphore ImportSemaphore(IPlatformHandle handle)
+    {
+        if (!SupportedSemaphoreTypes.Contains(handle.HandleDescriptor))
+            throw new NotSupportedException();
+
+        var typeBit = handle.HandleDescriptor switch
+        {
+            KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor =>
+                VkExternalSemaphoreHandleTypeFlags.VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
+            KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueKmtHandle =>
+                VkExternalSemaphoreHandleTypeFlags.VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+            KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueNtHandle =>
+                VkExternalSemaphoreHandleTypeFlags.VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+            _ => throw new NotSupportedException()
+        };
+
+        var semaphore = new VulkanSemaphore(_context);
+        if (handle.HandleDescriptor ==
+            KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor)
+        {
+            var info = new VkImportSemaphoreFdInfoKHR
+            {
+                sType = VkStructureType.VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
+                fd = handle.Handle.ToInt32(),
+                handleType = typeBit,
+                semaphore = semaphore.Handle
+            };
+            var addr = _context.Instance.GetDeviceProcAddress(_context.Device.Handle, "vkImportSemaphoreFdKHR");
+            if (addr == IntPtr.Zero)
+                addr = _context.Instance.GetInstanceProcAddress(_context.Instance.Handle, "vkImportSemaphoreFdKHR");
+            _context.DeviceApi.ImportSemaphoreFdKHR(_context.DeviceHandle, &info)
+                .ThrowOnError("vkImportSemaphoreFdKHR");
+            return new ImportedSemaphore(_context, _pool, semaphore);
+        }
+        else
+        {
+            var info = new VkImportSemaphoreWin32HandleInfoKHR()
+            {
+                sType = VkStructureType.VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
+                handle = handle.Handle,
+                handleType = typeBit,
+                semaphore = semaphore.Handle
+            };
+            _context.DeviceApi.ImportSemaphoreWin32HandleKHR(_context.DeviceHandle, &info)
+                .ThrowOnError("vkImportSemaphoreWin32HandleKHR");
+            return new ImportedSemaphore(_context, _pool, semaphore);
+        }
+    }
+
+    class ImportedSemaphore : IVulkanExternalSemaphore
+    {
+        private readonly VulkanContext _context;
+        private readonly VulkanCommandBufferPool _pool;
+        private VulkanSemaphore? _sem;
+        private VulkanSemaphore Sem => _sem ?? throw new ObjectDisposedException(nameof(ImportedSemaphore));
+
+        public ImportedSemaphore(VulkanContext context, VulkanCommandBufferPool pool, VulkanSemaphore sem)
+        {
+            _context = context;
+            _pool = pool;
+            _sem = sem;
+        }
+        
+        public void Dispose()
+        {
+            _sem?.Dispose();
+            _sem = null;
+        }
+
+        public ulong Handle => Sem.Handle.Handle;
+
+        void SubmitSemaphore(VulkanSemaphore? wait, VulkanSemaphore? signal)
+        {
+            var buf = _pool.CreateCommandBuffer();
+            buf.BeginRecording();
+            _context.DeviceApi.CmdPipelineBarrier(
+                buf.Handle,
+                VkPipelineStageFlags.VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                VkPipelineStageFlags.VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                0,
+                0,
+                IntPtr.Zero,
+                0,
+                IntPtr.Zero,
+                0,
+                null);
+            
+            buf.EndRecording();
+            buf.Submit(wait != null ? new[] { wait }.AsSpan() : default,
+                new[] { VkPipelineStageFlags.VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT },
+                signal != null ? new[] { signal }.AsSpan() : default);
+        }
+        public void SubmitWaitSemaphore()
+        {
+            SubmitSemaphore(_sem, null);
+        }
+
+        public void SubmitSignalSemaphore()
+        {
+            SubmitSemaphore(null, _sem);
+        }
+    }
+
+    class ImportedImage : VulkanImageBase, IVulkanExternalImage
+    {
+        private readonly IVulkanPlatformGraphicsContext _context;
+        private readonly IPlatformHandle _importHandle;
+        private readonly PlatformGraphicsExternalImageProperties _properties;
+        private readonly VkExternalMemoryHandleTypeFlagBits _typeBit;
+        public VulkanImageInfo Info => ImageInfo;
+
+        public ImportedImage(IVulkanPlatformGraphicsContext context, VulkanCommandBufferPool commandBufferPool,
+            IPlatformHandle importHandle,
+            PlatformGraphicsExternalImageProperties properties) : base(context, commandBufferPool,
+            properties.Format switch
+            {
+                PlatformGraphicsExternalImageFormat.B8G8R8A8UNorm => VkFormat.VK_FORMAT_B8G8R8A8_UNORM,
+                PlatformGraphicsExternalImageFormat.R8G8B8A8UNorm => VkFormat.VK_FORMAT_R8G8B8A8_UNORM,
+                _ => throw new ArgumentException($"Format {properties.Format} is not supported")
+            }, new PixelSize(properties.Width, properties.Height), 1)
+        {
+            _context = context;
+            _importHandle = importHandle;
+            _properties = properties;
+            _typeBit = importHandle.HandleDescriptor switch
+            {
+                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor =>
+                    VkExternalMemoryHandleTypeFlagBits.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
+                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueKmtHandle =>
+                    VkExternalMemoryHandleTypeFlagBits.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaqueNtHandle =>
+                    VkExternalMemoryHandleTypeFlagBits.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+                _ => throw new NotSupportedException()
+            };
+            var externalAlloc = new VkExternalMemoryImageCreateInfo
+            {
+                handleTypes = _typeBit,
+                sType = VkStructureType.VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO
+            };
+            Initialize(&externalAlloc);
+            TransitionLayout(VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VkAccessFlags.VK_ACCESS_TRANSFER_READ_BIT);
+            this.CurrentLayout = VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+        }
+
+        protected override VkDeviceMemory CreateMemory(VkImage image, ulong size, uint memoryTypeBits)
+        {
+            var handle = _importHandle;
+
+            if (_properties.MemoryOffset != 0 || _properties.MemorySize != size)
+                throw new Exception("Invalid memory size");
+            
+            var dedicated = new VkMemoryDedicatedAllocateInfo()
+            {
+                image = image,
+                sType = VkStructureType.VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+            };
+            
+            var isPosixHandle = handle.HandleDescriptor ==
+                                KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor;
+            var win32Info = new VkImportMemoryWin32HandleInfoKHR
+            {
+                sType = VkStructureType.VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
+                handle = handle.Handle,
+                handleType = _typeBit,
+                pNext = &dedicated
+            };
+            var posixInfo = new VkImportMemoryFdInfoKHR()
+            {
+                sType = VkStructureType.VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
+                handleType = _typeBit,
+                fd = isPosixHandle ? handle.Handle.ToInt32() : 0,
+                pNext = &dedicated
+            };
+        
+            var memoryAllocateInfo = new VkMemoryAllocateInfo
+            {
+                pNext =  new IntPtr(isPosixHandle ? &posixInfo : &win32Info),
+                sType = VkStructureType.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+                allocationSize = size,
+                memoryTypeIndex = (uint)VulkanMemoryHelper.FindSuitableMemoryTypeIndex(_context,
+                    memoryTypeBits,
+                    VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
+            };
+
+            _context.DeviceApi.AllocateMemory(_context.DeviceHandle, ref memoryAllocateInfo, IntPtr.Zero,
+                out var imageMemory).ThrowOnError("vkAllocateMemory");
+            return imageMemory;
+        }
+    }
+}

+ 19 - 0
src/Avalonia.Vulkan/VulkanImageInfo.cs

@@ -0,0 +1,19 @@
+using System;
+
+namespace Avalonia.Vulkan;
+
+public struct VulkanImageInfo
+{
+    public uint Format { get; set; }
+    public PixelSize PixelSize { get; set; }
+    public ulong Handle { get; set; }
+    public uint Layout { get; set; }
+    public uint Tiling { get; set; }
+    public uint UsageFlags { get; set; }
+    public uint LevelCount { get; set; }
+    public uint SampleCount { get; set; }
+    public ulong MemoryHandle { get; set; }
+    public ulong ViewHandle { get; set; }
+    public ulong MemorySize { get; set; }
+    public bool IsProtected { get; set; }
+}

+ 107 - 0
src/Avalonia.Vulkan/VulkanKhrSurfaceRenderTarget.cs

@@ -0,0 +1,107 @@
+using System;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Vulkan;
+
+
+internal class VulkanKhrRenderTarget : IVulkanRenderTarget
+{
+    private VulkanKhrSurface _khrSurface;
+    private readonly IVulkanPlatformGraphicsContext _context;
+    private VulkanDisplay _display;
+    private VulkanImage? _image;
+    private readonly IVulkanKhrSurfacePlatformSurface _platformSurface;
+    public VkFormat Format { get; }
+    public bool IsRgba { get; }
+
+    public VulkanKhrRenderTarget(IVulkanKhrSurfacePlatformSurface surface, IVulkanPlatformGraphicsContext context)
+    {
+        _platformSurface = surface;
+        _khrSurface = new(context, surface);
+        _display = VulkanDisplay.CreateDisplay(context, _khrSurface);
+        _context = context;
+        IsRgba = _display.SurfaceFormat.format >= VkFormat.VK_FORMAT_R8G8B8A8_UNORM &&
+                 _display.SurfaceFormat.format <= VkFormat.VK_FORMAT_R8G8B8A8_SRGB;
+
+        // Skia seems to only create surfaces from images with unorm format
+        Format = IsRgba ? VkFormat.VK_FORMAT_R8G8B8A8_UNORM : VkFormat.VK_FORMAT_B8G8R8A8_UNORM;
+    }
+
+    private void CreateImage()
+    {
+        _image = new VulkanImage(_context, _display.CommandBufferPool, Format, _display.Size);
+    }
+
+    private void DestroyImage()
+    {
+        _context.DeviceApi.DeviceWaitIdle(_context.DeviceHandle);
+        _image?.Dispose();
+        _image = null;
+    }
+
+    public void Dispose()
+    {
+        _context.DeviceApi.DeviceWaitIdle(_context.DeviceHandle);
+        DestroyImage();
+        _display?.Dispose();
+        _display = null!;
+        _khrSurface?.Dispose();
+        _khrSurface = null!;
+    }
+
+
+    public IVulkanRenderSession BeginDraw()
+    {
+        var l = _context.EnsureCurrent();
+        _display.CommandBufferPool.FreeUsedCommandBuffers();
+        if (_display.EnsureSwapchainAvailable() || _image == null)
+        {
+            DestroyImage();
+            CreateImage();
+        }
+        else
+            _image.TransitionLayout(VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                VkAccessFlags.VK_ACCESS_NONE);
+
+        return new RenderingSession(_display, _image!, IsRgba, _platformSurface.Scaling, l);
+    }
+
+    public class RenderingSession : IVulkanRenderSession
+    {
+        private readonly VulkanImage _image;
+        private readonly IDisposable _dispose;
+
+        public RenderingSession(VulkanDisplay display, VulkanImage image, bool isRgba, double scaling,
+            IDisposable dispose)
+        {
+            _image = image;
+            _dispose = dispose;
+            Display = display;
+            IsRgba = isRgba;
+            Scaling = scaling;
+        }
+
+        public VulkanDisplay Display { get; }
+        public PixelSize Size => _image.Size;
+        public double Scaling { get; }
+        public bool IsYFlipped => true;
+        public VulkanImageInfo ImageInfo => _image.ImageInfo;
+
+        public bool IsRgba { get; }
+
+        public void Dispose()
+        {
+            try
+            {
+                var commandBuffer = Display.StartPresentation();
+                Display.BlitImageToCurrentImage(commandBuffer, _image);
+                Display.EndPresentation(commandBuffer);
+            }
+            finally
+            {
+                _dispose.Dispose();
+            }
+        }
+    }
+}

+ 73 - 0
src/Avalonia.Vulkan/VulkanOptions.cs

@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+
+namespace Avalonia.Vulkan;
+
+public class VulkanOptions
+{
+    public VulkanInstanceCreationOptions VulkanInstanceCreationOptions { get; set; } = new();
+    public VulkanDeviceCreationOptions VulkanDeviceCreationOptions { get; set; } = new();
+    public IVulkanDevice? CustomSharedDevice { get; set; }
+}
+public class VulkanInstanceCreationOptions
+{
+    public VkGetInstanceProcAddressDelegate? CustomGetProcAddressDelegate { get; set; }
+    
+    /// <summary>
+    /// Sets the application name of the vulkan instance
+    /// </summary>
+    public string? ApplicationName { get; set; }
+
+    /// <summary>
+    /// Specifies the vulkan api version to use
+    /// </summary>
+    public Version VulkanVersion{ get; set; } =  new Version(1, 1, 0);
+
+    /// <summary>
+    /// Specifies additional extensions to enable if available on the instance
+    /// </summary>
+    public IList<string> InstanceExtensions { get; set; } = new List<string>();
+
+    /// <summary>
+    /// Specifies layers to enable if available on the instance
+    /// </summary>
+    public IList<string> EnabledLayers { get; set; } = new List<string>();
+
+    /// <summary>
+    /// Enables the debug layer
+    /// </summary>
+    public bool UseDebug { get; set; }
+
+    /*
+
+
+    /// <summary>
+    /// Sets the presentation mode the swapchain uses if available.
+    /// </summary>
+    //public PresentMode PresentMode { get; set; } = PresentMode.Mailbox;*/
+}
+
+public class VulkanDeviceCreationOptions
+{
+    /// <summary>
+    /// Specifies extensions to enable if available on the logical device
+    /// </summary>
+    public IList<string> DeviceExtensions { get; set; } = new List<string>();
+    
+    /// <summary>
+    /// Selects the first suitable discrete gpu available
+    /// </summary>
+    public bool PreferDiscreteGpu { get; set; }
+    
+    public bool RequireComputeBit { get; set; }
+}
+
+public class VulkanPlatformSpecificOptions
+{
+    public IList<string> RequiredInstanceExtensions { get; set; } = new List<string>();
+    public VkGetInstanceProcAddressDelegate? GetProcAddressDelegate { get; set; }
+    public Func<IVulkanInstance, ulong>? DeviceCheckSurfaceFactory { get; set; }
+    public Dictionary<Type, object> PlatformFeatures { get; set; } = new();
+}
+
+public delegate IntPtr VkGetInstanceProcAddressDelegate(IntPtr instance, string name);

+ 103 - 0
src/Avalonia.Vulkan/VulkanPlatformGraphics.cs

@@ -0,0 +1,103 @@
+using System;
+using Avalonia.Logging;
+using Avalonia.Platform;
+
+namespace Avalonia.Vulkan;
+
+public class VulkanPlatformGraphics : IPlatformGraphics
+{
+    private readonly IVulkanDeviceFactory _factory;
+    private IVulkanPlatformGraphicsContext? _currentSharedContext;
+    private readonly VulkanPlatformSpecificOptions _platformOptions;
+    public VulkanPlatformGraphics(IVulkanDeviceFactory factory, VulkanPlatformSpecificOptions platformOptions)
+    {
+        _factory = factory;
+        _platformOptions = platformOptions;
+    }
+
+    public IPlatformGraphicsContext CreateContext() =>
+        new VulkanContext(_factory.CreateDevice(_platformOptions), _platformOptions.PlatformFeatures);
+
+    public IPlatformGraphicsContext GetSharedContext()
+    {
+        if (_currentSharedContext?.IsLost == true)
+            _currentSharedContext = null;
+        return _currentSharedContext =
+            new VulkanContext(_factory.GetSharedDevice(_platformOptions), _platformOptions.PlatformFeatures);
+    }
+    
+    public bool UsesSharedContext => _factory.UsesShadedDevice;
+
+    
+    public interface IVulkanDeviceFactory
+    {
+        bool UsesShadedDevice { get; }
+        IVulkanDevice GetSharedDevice(VulkanPlatformSpecificOptions platformOptions);
+        IVulkanDevice CreateDevice(VulkanPlatformSpecificOptions platformOptions);
+    }
+
+    
+    class DefaultDeviceFactory : IVulkanDeviceFactory
+    {
+        private readonly IVulkanInstance _instance;
+        private readonly VulkanDeviceCreationOptions _deviceOptions;
+
+        public DefaultDeviceFactory(IVulkanInstance instance, VulkanDeviceCreationOptions deviceOptions)
+        {
+            _instance = instance;
+            _deviceOptions = deviceOptions;
+        }
+
+        public bool UsesShadedDevice => false;
+        
+        public IVulkanDevice GetSharedDevice(VulkanPlatformSpecificOptions platformOptions) => throw new NotSupportedException();
+
+        public IVulkanDevice CreateDevice(VulkanPlatformSpecificOptions platformOptions)
+        {
+            return Interop.VulkanDevice.Create(_instance, _deviceOptions, platformOptions);
+        }
+    }
+
+    class CustomSharedDeviceFactory : IVulkanDeviceFactory
+    {
+        private readonly IVulkanDevice _device;
+
+        public CustomSharedDeviceFactory(IVulkanDevice device)
+        {
+            _device = device;
+        }
+
+        public bool UsesShadedDevice => true;
+        public IVulkanDevice GetSharedDevice(VulkanPlatformSpecificOptions platformOptions) => _device;
+
+        public IVulkanDevice CreateDevice(VulkanPlatformSpecificOptions platformOptions) =>
+            throw new NotSupportedException();
+    }
+    
+    public static VulkanPlatformGraphics? TryCreate(VulkanOptions options, VulkanPlatformSpecificOptions platformOptions)
+    {
+        if (options.CustomSharedDevice != null)
+            return new(new CustomSharedDeviceFactory(options.CustomSharedDevice), platformOptions);
+
+        IVulkanInstance? instance = null;
+        try
+        {
+            instance = VulkanInstance.Create(options.VulkanInstanceCreationOptions ?? new(),
+                platformOptions);
+
+            var devOpts = options.VulkanDeviceCreationOptions ?? new();
+            Interop.VulkanDevice.Create(instance, devOpts, platformOptions)
+                .Dispose();
+
+            return new VulkanPlatformGraphics(new DefaultDeviceFactory(instance, devOpts), platformOptions);
+        }
+        catch (Exception e)
+        {
+            //instance?.Dispose();
+            Logger.TryGet(LogEventLevel.Error, "Vulkan")?.Log(null, "Unable to initialize Vulkan rendering: {0}", e);
+            return null;
+        }
+    }
+}
+
+

+ 29 - 0
src/Avalonia.X11/Vulkan/VulkanNativeInterop.cs

@@ -0,0 +1,29 @@
+using System;
+using Avalonia.SourceGenerator;
+using Avalonia.Vulkan;
+using Avalonia.Vulkan.Interop;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.X11.Vulkan;
+partial class X11VulkanInterface
+{
+    
+    public X11VulkanInterface(IVulkanInstance instance)
+    {
+        Initialize(name => instance.GetInstanceProcAddress(instance.Handle, name));
+    }
+
+    [GetProcAddress("vkCreateXlibSurfaceKHR")]
+    public partial int vkCreateXlibSurfaceKHR(IntPtr instance, ref VkXlibSurfaceCreateInfoKHR pCreateInfo,
+        IntPtr pAllocator, out ulong pSurface);
+}
+
+struct VkXlibSurfaceCreateInfoKHR
+{
+    public const uint VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000;
+    public uint sType;
+    public IntPtr pNext;
+    public uint flags;
+    public IntPtr dpy;
+    public IntPtr window;
+}

+ 94 - 0
src/Avalonia.X11/Vulkan/VulkanSupport.cs

@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Avalonia.Platform;
+using Avalonia.Vulkan;
+
+namespace Avalonia.X11.Vulkan;
+
+internal class VulkanSupport
+{
+    private static IntPtr s_offscreenWindow;
+
+    [DllImport("libvulkan.so.1")]
+    private static extern IntPtr vkGetInstanceProcAddr(IntPtr instance, string name);
+    
+    public static VulkanPlatformGraphics? TryInitialize(X11Info info, VulkanOptions options)
+    {
+        s_offscreenWindow = XLib.XCreateSimpleWindow(info.DeferredDisplay,
+            XLib.XDefaultRootWindow(info.DeferredDisplay), 0, 0, 1,
+            1, 1, IntPtr.Zero, IntPtr.Zero);
+        XLib.XSync(info.DeferredDisplay, true);
+
+        return VulkanPlatformGraphics.TryCreate(options ?? new(), new VulkanPlatformSpecificOptions
+        {
+            RequiredInstanceExtensions = { "VK_KHR_xlib_surface" },
+            GetProcAddressDelegate = vkGetInstanceProcAddr,
+            DeviceCheckSurfaceFactory = instance => CreateDummySurface(info.DeferredDisplay, instance),
+            PlatformFeatures = new Dictionary<Type, object>
+            {
+                [typeof(IVulkanKhrSurfacePlatformSurfaceFactory)] = new VulkanSurfaceFactory(info.DeferredDisplay)
+            }
+        });
+    }
+
+    internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory
+    {
+        private readonly IntPtr _display;
+
+        public VulkanSurfaceFactory(IntPtr display)
+        {
+            _display = display;
+        }
+        
+        public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) =>
+            surface is INativePlatformHandleSurface handle && handle.HandleDescriptor == "XID";
+
+        public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) => 
+            new XidSurface(_display, (INativePlatformHandleSurface)handle);
+    }
+
+    class XidSurface : IVulkanKhrSurfacePlatformSurface 
+    {
+        private readonly IntPtr _display;
+        private readonly INativePlatformHandleSurface _handle;
+
+        public XidSurface(IntPtr display, INativePlatformHandleSurface handle)
+        {
+            _display = display;
+            _handle = handle;
+        }
+
+        public void Dispose()
+        {
+            // No-op
+        }
+
+        public double Scaling => _handle.Scaling;
+        public PixelSize Size => _handle.Size;
+        public ulong CreateSurface(IVulkanPlatformGraphicsContext context) =>
+            CreateXlibSurface(_display, _handle.Handle, context.Instance);
+    }
+
+    private static ulong CreateDummySurface(IntPtr display, IVulkanInstance instance)
+    {
+        var surf = CreateXlibSurface(display, s_offscreenWindow, instance);
+        XLib.XSync(display, true);
+        return surf;
+    }
+
+    private static ulong CreateXlibSurface(IntPtr display, IntPtr window, IVulkanInstance instance)
+    {
+        var vulkanXlib = new X11VulkanInterface(instance);
+        var createInfo = new VkXlibSurfaceCreateInfoKHR
+        {
+            sType = VkXlibSurfaceCreateInfoKHR.VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
+            dpy = display,
+            window = window
+        };
+        VulkanException.ThrowOnError("vkCreateXlibSurfaceKHR",
+            vulkanXlib.vkCreateXlibSurfaceKHR(instance.Handle, ref createInfo, IntPtr.Zero, out var surface));
+        return surface;
+    }
+}
+

+ 17 - 2
src/Avalonia.X11/X11Platform.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
@@ -15,8 +15,10 @@ using Avalonia.Platform;
 using Avalonia.Rendering;
 using Avalonia.Rendering.Composition;
 using Avalonia.Threading;
+using Avalonia.Vulkan;
 using Avalonia.X11;
 using Avalonia.X11.Glx;
+using Avalonia.X11.Vulkan;
 using Avalonia.X11.Screens;
 using static Avalonia.X11.XLib;
 
@@ -214,6 +216,14 @@ namespace Avalonia.X11
                         return egl;
                     }
                 }
+
+                if (renderingMode == X11RenderingMode.Vulkan)
+                {
+                    var vulkan = VulkanSupport.TryInitialize(info,
+                        AvaloniaLocator.Current.GetService<VulkanOptions>() ?? new());
+                    if (vulkan != null)
+                        return vulkan;
+                }
             }
 
             throw new InvalidOperationException($"{nameof(X11PlatformOptions)}.{nameof(X11PlatformOptions.RenderingMode)} has a value of \"{string.Join(", ", opts.RenderingMode)}\", but no options were applied.");
@@ -241,7 +251,12 @@ namespace Avalonia
         /// <summary>
         /// Enables native Linux EGL rendering.
         /// </summary>
-        Egl = 3
+        Egl = 3,
+        
+        /// <summary>
+        /// Enables Vulkan rendering
+        /// </summary>
+        Vulkan = 4
     }
     
     /// <summary>

+ 124 - 0
src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaExternalObjectsFeature.cs

@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Platform;
+using Avalonia.Rendering.Composition;
+using Avalonia.Vulkan;
+using SkiaSharp;
+
+namespace Avalonia.Skia.Vulkan;
+
+internal class VulkanSkiaExternalObjectsFeature : IExternalObjectsRenderInterfaceContextFeature
+{
+    private readonly VulkanSkiaGpu _gpu;
+    private readonly IVulkanPlatformGraphicsContext _context;
+    private readonly IVulkanContextExternalObjectsFeature _feature;
+
+    public VulkanSkiaExternalObjectsFeature(VulkanSkiaGpu gpu,
+        IVulkanPlatformGraphicsContext context, IVulkanContextExternalObjectsFeature feature)
+    {
+        _gpu = gpu;
+        _context = context;
+        _feature = feature;
+    }
+
+
+    public IPlatformRenderInterfaceImportedImage ImportImage(IPlatformHandle handle,
+        PlatformGraphicsExternalImageProperties properties) =>
+        new Image(_gpu, _feature.ImportImage(handle, properties), properties);
+
+    public IPlatformRenderInterfaceImportedSemaphore ImportSemaphore(IPlatformHandle handle) => new Semaphore(_feature.ImportSemaphore(handle));
+
+    class Semaphore : IPlatformRenderInterfaceImportedSemaphore
+    {
+        private IVulkanExternalSemaphore? _inner;
+
+        public Semaphore(IVulkanExternalSemaphore inner)
+        {
+            _inner = inner;
+        }
+
+        public void Dispose()
+        {
+            _inner?.Dispose();
+            _inner = null;
+        }
+
+        public IVulkanExternalSemaphore Inner =>
+            _inner ?? throw new ObjectDisposedException(nameof(IVulkanExternalSemaphore));
+        
+    }
+    
+    class Image : IPlatformRenderInterfaceImportedImage
+    {
+        private readonly VulkanSkiaGpu _gpu;
+        private IVulkanExternalImage? _inner;
+        private readonly PlatformGraphicsExternalImageProperties _properties;
+
+        public Image(VulkanSkiaGpu gpu, IVulkanExternalImage inner, PlatformGraphicsExternalImageProperties properties)
+        {
+            _gpu = gpu;
+            _inner = inner;
+            _properties = properties;
+        }
+
+        public void Dispose()
+        {
+            _inner?.Dispose();
+            _inner = null;
+        }
+
+        public IBitmapImpl SnapshotWithKeyedMutex(uint acquireIndex, uint releaseIndex) => throw new NotSupportedException();
+
+        public IBitmapImpl SnapshotWithSemaphores(IPlatformRenderInterfaceImportedSemaphore waitForSemaphore,
+            IPlatformRenderInterfaceImportedSemaphore signalSemaphore)
+        {
+            var info = _inner!.Info;
+            
+            _gpu.GrContext.ResetContext();
+            ((Semaphore)waitForSemaphore).Inner.SubmitWaitSemaphore();
+            var imageInfo = new GRVkImageInfo
+            {
+                CurrentQueueFamily = _gpu.Vulkan.Device.GraphicsQueueFamilyIndex,
+                Format = info.Format,
+                Image = (ulong)info.Handle,
+                ImageLayout = info.Layout,
+                ImageTiling = info.Tiling,
+                ImageUsageFlags = info.UsageFlags,
+                LevelCount = info.LevelCount,
+                SampleCount = info.SampleCount,
+                Protected = info.IsProtected,
+                Alloc = new GRVkAlloc
+                {
+                    Memory = (ulong)info.MemoryHandle,
+                    Size = info.MemorySize
+                }
+            };
+            using var renderTarget = new GRBackendRenderTarget(_properties.Width, _properties.Height, 1, imageInfo);
+            using var surface = SKSurface.Create(_gpu.GrContext, renderTarget,
+                _properties.TopLeftOrigin ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft,
+                _properties.Format == PlatformGraphicsExternalImageFormat.R8G8B8A8UNorm
+                    ? SKColorType.Rgba8888
+                    : SKColorType.Bgra8888, SKColorSpace.CreateSrgb());
+            var image = surface.Snapshot();
+            _gpu.GrContext.Flush();
+            //surface.Canvas.Flush();
+            
+            ((Semaphore)signalSemaphore).Inner.SubmitSignalSemaphore();
+            
+            return new ImmutableBitmap(image);
+        }
+
+        public IBitmapImpl SnapshotWithAutomaticSync() => throw new NotSupportedException();
+    }
+
+    public IPlatformRenderInterfaceImportedImage ImportImage(ICompositionImportableSharedGpuContextImage image) => throw new System.NotSupportedException();
+
+    public CompositionGpuImportedImageSynchronizationCapabilities
+        GetSynchronizationCapabilities(string imageHandleType) => _feature.GetSynchronizationCapabilities(imageHandleType);
+
+    public byte[]? DeviceUuid => _feature.DeviceUuid;
+    public byte[]? DeviceLuid => _feature.DeviceLuid;
+    
+    public IReadOnlyList<string> SupportedImageHandleTypes => _feature.SupportedImageHandleTypes;
+    public IReadOnlyList<string> SupportedSemaphoreTypes => _feature.SupportedSemaphoreTypes;
+}

+ 86 - 0
src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs

@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Vulkan;
+using Avalonia.Platform;
+using Avalonia.Rendering;
+using SkiaSharp;
+
+namespace Avalonia.Skia.Vulkan;
+
+internal class VulkanSkiaGpu : ISkiaGpu
+{
+    private readonly VulkanSkiaExternalObjectsFeature? _externalObjects;
+    public IVulkanPlatformGraphicsContext Vulkan { get; private set; }
+    public GRContext GrContext { get; private set; }
+
+    public VulkanSkiaGpu(IVulkanPlatformGraphicsContext vulkan, long? maxResourceBytes)
+    {
+        Vulkan = vulkan;
+        var device = vulkan.Device;
+        using (Vulkan.EnsureCurrent())
+        {
+            IntPtr GetProcAddressWrapper(string name, IntPtr instance, IntPtr device)
+            {
+                if (device != IntPtr.Zero)
+                {
+                    var addr = Vulkan.Instance.GetDeviceProcAddress(device, name);
+                    if (addr != IntPtr.Zero)
+                        return addr;
+                }
+
+                if (instance != IntPtr.Zero)
+                {
+                    var addr = Vulkan.Instance.GetInstanceProcAddress(instance, name);
+                    if (addr != IntPtr.Zero)
+                        return addr;
+                }
+
+                return Vulkan.Instance.GetInstanceProcAddress(IntPtr.Zero, name);
+            }
+
+            var ctx = new GRVkBackendContext
+            {
+                VkInstance = device.Instance.Handle,
+                VkPhysicalDevice = device.PhysicalDeviceHandle,
+                VkDevice = device.Handle,
+                VkQueue = device.MainQueueHandle,
+                GraphicsQueueIndex = device.GraphicsQueueFamilyIndex,
+                GetProcedureAddress = GetProcAddressWrapper
+            };
+
+            GrContext = GRContext.CreateVulkan(ctx) ??
+                         throw new VulkanException("Unable to create GrContext from IVulkanDevice");
+            
+            if (maxResourceBytes.HasValue)
+                GrContext.SetResourceCacheLimit(maxResourceBytes.Value);
+        }
+
+        if (vulkan.TryGetFeature<IVulkanContextExternalObjectsFeature>(out var externalObjects))
+            _externalObjects = new VulkanSkiaExternalObjectsFeature(this, vulkan, externalObjects);
+    }
+    
+    public void Dispose()
+    {
+        Vulkan.Dispose();
+    }
+
+    public object? TryGetFeature(Type featureType)
+    {
+        if (featureType == typeof(IExternalObjectsRenderInterfaceContextFeature))
+            return _externalObjects;
+        return null;
+    }
+
+    public bool IsLost => Vulkan.IsLost;
+    public IDisposable EnsureCurrent() => Vulkan.EnsureCurrent();
+    
+    
+    public ISkiaGpuRenderTarget TryCreateRenderTarget(IEnumerable<object> surfaces)
+    {
+        var target = Vulkan.CreateRenderTarget(surfaces);
+        return new VulkanSkiaRenderTarget(this, target);
+    }
+
+    
+    public ISkiaSurface? TryCreateSurface(PixelSize size, ISkiaGpuRenderSession? session) => null;
+}

+ 105 - 0
src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs

@@ -0,0 +1,105 @@
+using System;
+using Avalonia.Skia.Helpers;
+using Avalonia.Vulkan;
+using SkiaSharp;
+
+namespace Avalonia.Skia.Vulkan;
+
+class VulkanSkiaRenderTarget : ISkiaGpuRenderTarget
+{
+    private readonly VulkanSkiaGpu _gpu;
+    private readonly IVulkanRenderTarget _target;
+
+    public VulkanSkiaRenderTarget(VulkanSkiaGpu gpu, IVulkanRenderTarget target)
+    {
+        _gpu = gpu;
+        _target = target;
+    }
+
+    public void Dispose()
+    {
+        _target.Dispose();
+    }
+
+    public ISkiaGpuRenderSession BeginRenderingSession()
+    {
+        var session = _target.BeginDraw();
+        bool success = false;
+        try
+        {
+            var size = session.Size;
+            var scaling = session.Scaling;
+            if (size.Width <= 0 || size.Height <= 0 || scaling < 0)
+            {
+                session.Dispose();
+                throw new InvalidOperationException(
+                    $"Can't create drawing context for surface with {size} size and {scaling} scaling");
+            }
+            _gpu.GrContext.ResetContext();
+            var sessionImageInfo = session.ImageInfo;
+            var imageInfo = new GRVkImageInfo
+            {
+                CurrentQueueFamily = _gpu.Vulkan.Device.GraphicsQueueFamilyIndex,
+                Format = sessionImageInfo.Format,
+                Image = (ulong)sessionImageInfo.Handle,
+                ImageLayout = sessionImageInfo.Layout,
+                ImageTiling = sessionImageInfo.Tiling,
+                ImageUsageFlags = sessionImageInfo.UsageFlags,
+                LevelCount = sessionImageInfo.LevelCount,
+                SampleCount = sessionImageInfo.SampleCount,
+                Protected = sessionImageInfo.IsProtected,
+                Alloc = new GRVkAlloc
+                {
+                    Memory = (ulong)sessionImageInfo.MemoryHandle,
+                    Size = sessionImageInfo.MemorySize
+                }
+            };
+            using var renderTarget = new GRBackendRenderTarget(size.Width, size.Height, 1, imageInfo);
+            var surface = SKSurface.Create(_gpu.GrContext, renderTarget,
+                session.IsYFlipped ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft,
+                session.IsRgba ? SKColorType.Rgba8888 : SKColorType.Bgra8888, SKColorSpace.CreateSrgb());
+            
+            if (surface == null)
+                throw new InvalidOperationException(
+                    $"Surface can't be created with the provided render target");
+            success = true;
+            return new VulkanSkiaRenderSession(_gpu.GrContext, surface, session);
+        }
+        finally
+        {
+            if(!success)
+                session.Dispose();
+        }
+    }
+   
+    public bool IsCorrupted => false;
+
+
+    internal class VulkanSkiaRenderSession : ISkiaGpuRenderSession
+    {
+        private readonly IVulkanRenderSession _vulkanSession;
+
+        public VulkanSkiaRenderSession(GRContext grContext,
+            SKSurface surface,
+            IVulkanRenderSession vulkanSession)
+        {
+            GrContext = grContext;
+            SkSurface = surface;
+            _vulkanSession = vulkanSession;
+            SurfaceOrigin = vulkanSession.IsYFlipped ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft;
+        }
+
+        public void Dispose()
+        {
+            SkSurface.Canvas.Flush();
+            SkSurface.Dispose();
+            GrContext.Flush();
+            _vulkanSession.Dispose();
+        }
+
+        public GRContext GrContext { get; }
+        public SKSurface SkSurface { get; }
+        public double ScaleFactor => _vulkanSession.Scaling;
+        public GRSurfaceOrigin SurfaceOrigin { get; }
+    }
+}

+ 4 - 0
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@@ -5,6 +5,8 @@ using Avalonia.Media;
 using Avalonia.OpenGL;
 using Avalonia.Platform;
 using Avalonia.Media.Imaging;
+using Avalonia.Skia.Vulkan;
+using Avalonia.Vulkan;
 using SkiaSharp;
 using Avalonia.Media.TextFormatting;
 using Avalonia.Metal;
@@ -36,6 +38,8 @@ namespace Avalonia.Skia
                 return new SkiaContext(new GlSkiaGpu(gl, _maxResourceBytes));
             if (graphicsContext is IMetalDevice metal)
                 return new SkiaContext(new SkiaMetalGpu(metal, _maxResourceBytes));
+            if (graphicsContext is IVulkanPlatformGraphicsContext vulkanContext)
+                return new SkiaContext(new VulkanSkiaGpu(vulkanContext, _maxResourceBytes));
             throw new ArgumentException("Graphics context of type is not supported");
         }
 

+ 27 - 0
src/Windows/Avalonia.Win32/Vulkan/VulkanNativeInterop.cs

@@ -0,0 +1,27 @@
+using System;
+using Avalonia.SourceGenerator;
+using Avalonia.Vulkan;
+using Avalonia.Vulkan.UnmanagedInterop;
+
+namespace Avalonia.Win32.Vulkan;
+partial class Win32VulkanInterface
+{
+    public Win32VulkanInterface(IVulkanInstance instance)
+    {
+        Initialize(name => instance.GetInstanceProcAddress(instance.Handle, name));
+    }
+
+    [GetProcAddress("vkCreateWin32SurfaceKHR")]
+    public partial int vkCreateWin32SurfaceKHR(IntPtr instance, ref VkWin32SurfaceCreateInfoKHR pCreateInfo,
+        IntPtr pAllocator, out ulong pSurface);
+}
+
+struct VkWin32SurfaceCreateInfoKHR
+{
+    public const uint VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000;
+    public uint sType;
+    public IntPtr pNext;
+    public uint flags;
+    public IntPtr hinstance;
+    public IntPtr hwnd;
+}

+ 71 - 0
src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs

@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Avalonia.Platform;
+using Avalonia.Vulkan;
+using Avalonia.Win32.Interop;
+
+namespace Avalonia.Win32.Vulkan;
+
+internal class VulkanSupport
+{
+    [DllImport("vulkan-1.dll")]
+    private static extern IntPtr vkGetInstanceProcAddr(IntPtr instance, string name);
+    
+    public static VulkanPlatformGraphics? TryInitialize(VulkanOptions options) =>
+        VulkanPlatformGraphics.TryCreate(options ?? new(), new VulkanPlatformSpecificOptions
+        {
+            RequiredInstanceExtensions = { "VK_KHR_win32_surface" },
+            GetProcAddressDelegate = vkGetInstanceProcAddr,
+            DeviceCheckSurfaceFactory = instance => CreateHwndSurface(OffscreenParentWindow.Handle, instance),
+            PlatformFeatures = new Dictionary<Type, object>
+            {
+                [typeof(IVulkanKhrSurfacePlatformSurfaceFactory)] = new VulkanSurfaceFactory()
+            }
+        });
+
+    internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory
+    {
+        public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) =>
+            surface is INativePlatformHandleSurface handle && handle.HandleDescriptor == "HWND";
+
+        public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) =>
+            new HwndVulkanSurface((INativePlatformHandleSurface)handle);
+    }
+
+    class HwndVulkanSurface : IVulkanKhrSurfacePlatformSurface 
+    {
+        private readonly INativePlatformHandleSurface _handle;
+
+        public HwndVulkanSurface(INativePlatformHandleSurface handle)
+        {
+            _handle = handle;
+        }
+
+        public void Dispose()
+        {
+            // No-op
+        }
+
+        public double Scaling => _handle.Scaling;
+        public PixelSize Size => _handle.Size;
+        public ulong CreateSurface(IVulkanPlatformGraphicsContext context) =>
+            CreateHwndSurface(_handle.Handle, context.Instance);
+    }
+
+    private static ulong CreateHwndSurface(IntPtr window, IVulkanInstance instance)
+    {
+        var vulkanWin32 = new Win32VulkanInterface(instance);
+        var createInfo = new VkWin32SurfaceCreateInfoKHR()
+        {
+            
+            sType = VkWin32SurfaceCreateInfoKHR.VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
+            hinstance =  UnmanagedMethods.GetModuleHandle(null),
+            hwnd = window
+        };
+        VulkanException.ThrowOnError("vkCreateWin32SurfaceKHR",
+            vulkanWin32.vkCreateWin32SurfaceKHR(instance.Handle, ref createInfo, IntPtr.Zero, out var surface));
+        return surface;
+    }
+}
+

+ 9 - 0
src/Windows/Avalonia.Win32/Win32GlManager.cs

@@ -3,10 +3,12 @@ using System.Diagnostics.Tracing;
 using System.Linq;
 using Avalonia.OpenGL;
 using Avalonia.Platform;
+using Avalonia.Vulkan;
 using Avalonia.Win32.DComposition;
 using Avalonia.Win32.DirectX;
 using Avalonia.Win32.OpenGl;
 using Avalonia.Win32.OpenGl.Angle;
+using Avalonia.Win32.Vulkan;
 using Avalonia.Win32.WinRT.Composition;
 
 namespace Avalonia.Win32;
@@ -62,6 +64,13 @@ static class Win32GlManager
                     return wgl;
                 }
             }
+
+            if (renderingMode == Win32RenderingMode.Vulkan)
+            {
+                var vulkan = VulkanSupport.TryInitialize(AvaloniaLocator.Current.GetService<VulkanOptions>() ?? new());
+                if (vulkan != null)
+                    return vulkan;
+            }
         }
 
         throw new InvalidOperationException($"{nameof(Win32PlatformOptions)}.{nameof(Win32PlatformOptions.RenderingMode)} has a value of \"{string.Join(", ", opts.RenderingMode)}\", but no options were applied.");

+ 5 - 1
src/Windows/Avalonia.Win32/Win32PlatformOptions.cs

@@ -22,7 +22,11 @@ public enum Win32RenderingMode
     /// <summary>
     /// Avalonia would try to use native Widows OpenGL with GPU rendering.
     /// </summary>
-    Wgl = 3
+    Wgl = 3,
+    /// <summary>
+    /// Avalonia would try to use native Widows Vulkan with GPU rendering.
+    /// </summary>
+    Vulkan = 4
 }
 
 /// <summary>

+ 1 - 1
src/Windows/Avalonia.Win32/WindowImpl.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics.CodeAnalysis;