diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf index 465e579a44..799e920441 100644 --- a/Avalonia.Desktop.slnf +++ b/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", diff --git a/Avalonia.sln b/Avalonia.sln index 88a43802a8..2ebd2550ae 100644 --- a/Avalonia.sln +++ b/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 diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings index 52f687ffab..cc58566622 100644 --- a/Avalonia.sln.DotSettings +++ b/Avalonia.sln.DotSettings @@ -39,4 +39,5 @@ True True True - True + True + True diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props index a9af587a45..43ab0fbab2 100644 --- a/build/CoreLibraries.props +++ b/build/CoreLibraries.props @@ -5,6 +5,7 @@ + diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index b3372ee0f8..036dd13f7a 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/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() { diff --git a/samples/GpuInterop/Program.cs b/samples/GpuInterop/Program.cs index 8d7ccf4866..e07780f80b 100644 --- a/samples/GpuInterop/Program.cs +++ b/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() .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"); } } diff --git a/samples/GpuInterop/VulkanDemo/VulkanContent.cs b/samples/GpuInterop/VulkanDemo/VulkanContent.cs index fe95db00f4..576c34e837 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanContent.cs +++ b/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()); CreateDepthAttachment(size); var api = _context.Api; diff --git a/samples/GpuInterop/VulkanDemo/VulkanContext.cs b/samples/GpuInterop/VulkanDemo/VulkanContext.cs index 0983a373f3..6983a69d86 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanContext.cs +++ b/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(physicalDeviceIDProperties.DeviceLuid, 8)); diff --git a/samples/GpuInterop/VulkanDemo/VulkanImage.cs b/samples/GpuInterop/VulkanDemo/VulkanImage.cs index a385468b26..ea43441243 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanImage.cs +++ b/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 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(); - - 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(); + + 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(_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(); - return new PlatformHandle( - dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write), - KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle); + if (_d3dTexture2D != null) + { + using var dxgi = _d3dTexture2D!.QueryInterface(); + 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, diff --git a/samples/GpuInterop/VulkanDemo/VulkanSemaphorePair.cs b/samples/GpuInterop/VulkanDemo/VulkanSemaphorePair.cs index 279c313a27..163a39dd9e 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanSemaphorePair.cs +++ b/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(_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); } -} \ No newline at end of file +} diff --git a/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs b/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs index cd026b3972..a748ba4bb6 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs +++ b/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!); diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 3c80f1866c..8d691c3586 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -34,6 +34,7 @@ + diff --git a/src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs b/src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs index ce9b38ead2..ac9398c99b 100644 --- a/src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs +++ b/src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs @@ -56,5 +56,8 @@ namespace Avalonia.Platform.Interop ArrayPool.Shared.Return(bytes); } } + + public static implicit operator IntPtr(Utf8Buffer b) => b.handle; + public static unsafe implicit operator byte*(Utf8Buffer b) => (byte*)b.handle; } } diff --git a/src/Avalonia.Base/Platform/PlatformGraphicsExternalMemory.cs b/src/Avalonia.Base/Platform/PlatformGraphicsExternalMemory.cs index 4b47c93eb5..b9be1f7dc9 100644 --- a/src/Avalonia.Base/Platform/PlatformGraphicsExternalMemory.cs +++ b/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 /// public const string VulkanOpaquePosixFileDescriptor = nameof(VulkanOpaquePosixFileDescriptor); + + /// + /// A NT handle that's been exported by Vulkan using VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT or in a compatible way + /// + 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); } /// diff --git a/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj b/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj new file mode 100644 index 0000000000..7ade700b64 --- /dev/null +++ b/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj @@ -0,0 +1,17 @@ + + + + net6.0;netstandard2.0 + true + + + + + + + + + + + + diff --git a/src/Avalonia.Vulkan/IVulkanContextExternalObjectsFeature.cs b/src/Avalonia.Vulkan/IVulkanContextExternalObjectsFeature.cs new file mode 100644 index 0000000000..9d64f3f687 --- /dev/null +++ b/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 SupportedImageHandleTypes { get; } + IReadOnlyList 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; } +} diff --git a/src/Avalonia.Vulkan/IVulkanDevice.cs b/src/Avalonia.Vulkan/IVulkanDevice.cs new file mode 100644 index 0000000000..66dafac990 --- /dev/null +++ b/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 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 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 surfaces); +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/IVulkanPlatformSurface.cs b/src/Avalonia.Vulkan/IVulkanPlatformSurface.cs new file mode 100644 index 0000000000..9d34a4da8e --- /dev/null +++ b/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); +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/IVulkanRenderTarget.cs b/src/Avalonia.Vulkan/IVulkanRenderTarget.cs new file mode 100644 index 0000000000..0088ec8867 --- /dev/null +++ b/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; } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanCommandBuffer.cs b/src/Avalonia.Vulkan/Interop/VulkanCommandBuffer.cs new file mode 100644 index 0000000000..096858fddd --- /dev/null +++ b/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 waitSemaphores, + ReadOnlySpan waitDstStageMask, + ReadOnlySpan 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); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanCommandBufferPool.cs b/src/Avalonia.Vulkan/Interop/VulkanCommandBufferPool.cs new file mode 100644 index 0000000000..02ec0bb6ae --- /dev/null +++ b/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 _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); +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanDebugLogger.cs b/src/Avalonia.Vulkan/Interop/VulkanDebugLogger.cs new file mode 100644 index 0000000000..0d77ce3c88 --- /dev/null +++ b/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; + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanDevice.Create.cs b/src/Avalonia.Vulkan/Interop/VulkanDevice.Create.cs new file mode 100644 index 0000000000..dcc48f8634 --- /dev/null +++ b/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(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 Extensions; + public uint QueueCount; + } + + static List GetDeviceExtensions(VulkanInstanceApi instance, VkPhysicalDevice physicalDevice) + { + uint propertyCount = 0; + instance.EnumerateDeviceExtensionProperties(physicalDevice, null, ref propertyCount, null); + var extensionProps = new VkExtensionProperties[propertyCount]; + var extensions = new List((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; + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanDevice.cs b/src/Avalonia.Vulkan/Interop/VulkanDevice.cs new file mode 100644 index 0000000000..24d02687bc --- /dev/null +++ b/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 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 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; +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanDisplay.cs b/src/Avalonia.Vulkan/Interop/VulkanDisplay.cs new file mode 100644 index 0000000000..cda28ecff7 --- /dev/null +++ b/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(); + private VkImageView[] _swapchainImageViews = Array.Empty(); + 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(); + + } + + 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!; + } + +} diff --git a/src/Avalonia.Vulkan/Interop/VulkanFence.cs b/src/Avalonia.Vulkan/Interop/VulkanFence.cs new file mode 100644 index 0000000000..c1ecde16ee --- /dev/null +++ b/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"); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanImage.cs b/src/Avalonia.Vulkan/Interop/VulkanImage.cs new file mode 100644 index 0000000000..7bc32ffe59 --- /dev/null +++ b/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); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanInstance.cs b/src/Avalonia.Vulkan/Interop/VulkanInstance.cs new file mode 100644 index 0000000000..a4b9c8bbf8 --- /dev/null +++ b/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(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 GetSupportedExtensions(VulkanGlobalApi api) + { + var supportedExtensions = new HashSet(); + uint supportedExtensionCount = 0; + api.vkEnumerateInstanceExtensionProperties(IntPtr.Zero, &supportedExtensionCount, null); + if (supportedExtensionCount > 0) + { + var ptr = (VkExtensionProperties*)Marshal.AllocHGlobal(Unsafe.SizeOf() * + (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 EnabledExtensions { get; } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanKhrSurface.cs b/src/Avalonia.Vulkan/Interop/VulkanKhrSurface.cs new file mode 100644 index 0000000000..2fcaf49247 --- /dev/null +++ b/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; + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanMemoryHelper.cs b/src/Avalonia.Vulkan/Interop/VulkanMemoryHelper.cs new file mode 100644 index 0000000000..acaef7c097 --- /dev/null +++ b/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); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/Interop/VulkanSemaphore.cs b/src/Avalonia.Vulkan/Interop/VulkanSemaphore.cs new file mode 100644 index 0000000000..aa6c032e00 --- /dev/null +++ b/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(); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/UnmanagedInterop/Utf8BufferArray.cs b/src/Avalonia.Vulkan/UnmanagedInterop/Utf8BufferArray.cs new file mode 100644 index 0000000000..0df20275b6 --- /dev/null +++ b/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 _buffers; + private byte** _bufferArray; + + public Utf8BufferArray(IEnumerable 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); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/UnmanagedInterop/VulkanDeviceApi.cs b/src/Avalonia.Vulkan/UnmanagedInterop/VulkanDeviceApi.cs new file mode 100644 index 0000000000..f3f3e5f824 --- /dev/null +++ b/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); + + +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/UnmanagedInterop/VulkanEnums.cs b/src/Avalonia.Vulkan/UnmanagedInterop/VulkanEnums.cs new file mode 100644 index 0000000000..e3530489f4 --- /dev/null +++ b/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, + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/UnmanagedInterop/VulkanGlobalApi.cs b/src/Avalonia.Vulkan/UnmanagedInterop/VulkanGlobalApi.cs new file mode 100644 index 0000000000..089b939aee --- /dev/null +++ b/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); +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/UnmanagedInterop/VulkanInstanceApi.cs b/src/Avalonia.Vulkan/UnmanagedInterop/VulkanInstanceApi.cs new file mode 100644 index 0000000000..fd8c1d40cd --- /dev/null +++ b/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); +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/UnmanagedInterop/VulkanStructs.cs b/src/Avalonia.Vulkan/UnmanagedInterop/VulkanStructs.cs new file mode 100644 index 0000000000..bce6aa06bd --- /dev/null +++ b/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; + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanBindings.cs b/src/Avalonia.Vulkan/VulkanBindings.cs new file mode 100644 index 0000000000..d3a05fa980 --- /dev/null +++ b/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; +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanContext.cs b/src/Avalonia.Vulkan/VulkanContext.cs new file mode 100644 index 0000000000..dab8ec5230 --- /dev/null +++ b/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 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 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"); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanException.cs b/src/Avalonia.Vulkan/VulkanException.cs new file mode 100644 index 0000000000..ac316044d8 --- /dev/null +++ b/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); + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanExternalObjectsFeature.cs b/src/Avalonia.Vulkan/VulkanExternalObjectsFeature.cs new file mode 100644 index 0000000000..d8d9a4cb48 --- /dev/null +++ b/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(physicalDeviceIDProperties.deviceLUID, 8).ToArray(); + if (luid.Any(b => b != 0)) + DeviceLuid = luid; + var uuid = new Span(physicalDeviceIDProperties.deviceUUID, 16).ToArray(); + if (uuid.Any(b => b != 0)) + DeviceUuid = uuid; + _pool = new VulkanCommandBufferPool(_context); + } + + public IReadOnlyList SupportedImageHandleTypes { get; } + public IReadOnlyList 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; + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanImageInfo.cs b/src/Avalonia.Vulkan/VulkanImageInfo.cs new file mode 100644 index 0000000000..5dbbecd572 --- /dev/null +++ b/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; } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanKhrSurfaceRenderTarget.cs b/src/Avalonia.Vulkan/VulkanKhrSurfaceRenderTarget.cs new file mode 100644 index 0000000000..7a83c85eeb --- /dev/null +++ b/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(); + } + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanOptions.cs b/src/Avalonia.Vulkan/VulkanOptions.cs new file mode 100644 index 0000000000..5a82af607b --- /dev/null +++ b/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; } + + /// + /// Sets the application name of the vulkan instance + /// + public string? ApplicationName { get; set; } + + /// + /// Specifies the vulkan api version to use + /// + public Version VulkanVersion{ get; set; } = new Version(1, 1, 0); + + /// + /// Specifies additional extensions to enable if available on the instance + /// + public IList InstanceExtensions { get; set; } = new List(); + + /// + /// Specifies layers to enable if available on the instance + /// + public IList EnabledLayers { get; set; } = new List(); + + /// + /// Enables the debug layer + /// + public bool UseDebug { get; set; } + + /* + + + /// + /// Sets the presentation mode the swapchain uses if available. + /// + //public PresentMode PresentMode { get; set; } = PresentMode.Mailbox;*/ +} + +public class VulkanDeviceCreationOptions +{ + /// + /// Specifies extensions to enable if available on the logical device + /// + public IList DeviceExtensions { get; set; } = new List(); + + /// + /// Selects the first suitable discrete gpu available + /// + public bool PreferDiscreteGpu { get; set; } + + public bool RequireComputeBit { get; set; } +} + +public class VulkanPlatformSpecificOptions +{ + public IList RequiredInstanceExtensions { get; set; } = new List(); + public VkGetInstanceProcAddressDelegate? GetProcAddressDelegate { get; set; } + public Func? DeviceCheckSurfaceFactory { get; set; } + public Dictionary PlatformFeatures { get; set; } = new(); +} + +public delegate IntPtr VkGetInstanceProcAddressDelegate(IntPtr instance, string name); \ No newline at end of file diff --git a/src/Avalonia.Vulkan/VulkanPlatformGraphics.cs b/src/Avalonia.Vulkan/VulkanPlatformGraphics.cs new file mode 100644 index 0000000000..3ae4907404 --- /dev/null +++ b/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; + } + } +} + + diff --git a/src/Avalonia.X11/Vulkan/VulkanNativeInterop.cs b/src/Avalonia.X11/Vulkan/VulkanNativeInterop.cs new file mode 100644 index 0000000000..4bdba6d8cc --- /dev/null +++ b/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; +} \ No newline at end of file diff --git a/src/Avalonia.X11/Vulkan/VulkanSupport.cs b/src/Avalonia.X11/Vulkan/VulkanSupport.cs new file mode 100644 index 0000000000..860e913954 --- /dev/null +++ b/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 + { + [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; + } +} + diff --git a/src/Avalonia.X11/X11Platform.cs b/src/Avalonia.X11/X11Platform.cs index c6856aff2a..7a65ef54c7 100644 --- a/src/Avalonia.X11/X11Platform.cs +++ b/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() ?? 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 /// /// Enables native Linux EGL rendering. /// - Egl = 3 + Egl = 3, + + /// + /// Enables Vulkan rendering + /// + Vulkan = 4 } /// diff --git a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaExternalObjectsFeature.cs b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaExternalObjectsFeature.cs new file mode 100644 index 0000000000..5c5427b8d9 --- /dev/null +++ b/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 SupportedImageHandleTypes => _feature.SupportedImageHandleTypes; + public IReadOnlyList SupportedSemaphoreTypes => _feature.SupportedSemaphoreTypes; +} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs new file mode 100644 index 0000000000..34670a5ca7 --- /dev/null +++ b/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(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 surfaces) + { + var target = Vulkan.CreateRenderTarget(surfaces); + return new VulkanSkiaRenderTarget(this, target); + } + + + public ISkiaSurface? TryCreateSurface(PixelSize size, ISkiaGpuRenderSession? session) => null; +} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs new file mode 100644 index 0000000000..b761d21b4e --- /dev/null +++ b/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; } + } +} diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index e65d9c15e7..05dbd684ef 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/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"); } diff --git a/src/Windows/Avalonia.Win32/Vulkan/VulkanNativeInterop.cs b/src/Windows/Avalonia.Win32/Vulkan/VulkanNativeInterop.cs new file mode 100644 index 0000000000..93b4a8e5c8 --- /dev/null +++ b/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; +} diff --git a/src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs b/src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs new file mode 100644 index 0000000000..ab72fd5898 --- /dev/null +++ b/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 + { + [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; + } +} + diff --git a/src/Windows/Avalonia.Win32/Win32GlManager.cs b/src/Windows/Avalonia.Win32/Win32GlManager.cs index cef200b4d7..16a9d02dad 100644 --- a/src/Windows/Avalonia.Win32/Win32GlManager.cs +++ b/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() ?? 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."); diff --git a/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs b/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs index 4506d7a3e8..b66ea893a3 100644 --- a/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs +++ b/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs @@ -22,7 +22,11 @@ public enum Win32RenderingMode /// /// Avalonia would try to use native Widows OpenGL with GPU rendering. /// - Wgl = 3 + Wgl = 3, + /// + /// Avalonia would try to use native Widows Vulkan with GPU rendering. + /// + Vulkan = 4 } /// diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index fa2223a466..8a09cff07f 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/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;