LLVK 1.2.182-rc2

This is a prerelease version of LLVK.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package LLVK --version 1.2.182-rc2
NuGet\Install-Package LLVK -Version 1.2.182-rc2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LLVK" Version="1.2.182-rc2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add LLVK --version 1.2.182-rc2
#r "nuget: LLVK, 1.2.182-rc2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install LLVK as a Cake Addin
#addin nuget:?package=LLVK&version=1.2.182-rc2&prerelease

// Install LLVK as a Cake Tool
#tool nuget:?package=LLVK&version=1.2.182-rc2&prerelease

LLVK

Low-Level Vulkan Bindings (LLVK) is a set of auto-generated .NET 6+ bindings for Vulkan.

LLVK aims to be a very thin wrapper over the Vulkan C API, designed to minimize the overhead around preparing and using Vulkan types and calls. It also aims to add as little cruft as possible, making translating Vulkan C code to LLVK code easy (within the limitations of C#).

The majority of the library is code generated from the official Vulkan XML spec.

Design

To this end, the following design features are central to the codebase:

  • No Marshaling - Every API type is an unmanaged struct with a byte-perfect memory layout match to the corresponding C types.
    • Unit testing for each type to ensure that this is valid
  • Unmanaged Function Pointers - All API functions are implemented as delegate* unmanaged<...>, no DllImport in sight.
  • Device Functions - Device-level functions are loaded with vkGetDeviceProcAddr for the best performance.
  • Native Types - Use of nint and nuint where applicable, and raw pointers instead of IntPtr.

There is also a small set of hand-crafted types that provide additional utilities for working with the API and unmanaged code in general.

Generator

The generator app is designed to panic if anything even slightly out of the ordinary is encountered which is not accounted for explicitly in the generator. This is to ensure that nothing that appears in new API versions is missed just because it is not explicitly handled. It is expected that each API update will require a few additions and changes to make the generator happy. It is documented in the code how to make these changes as needed.

Using the Library

The two main library components are the LLVK namespace, which contains all of the hand-crafted support types, and the LLVK.Vulkan class which contains all of the generated Vulkan API code.

The intended use for the Vulkan class is to statically import it and its child classes to make Vulkan types and methods available in the current scope. The instance and device functions must also be loaded once the objects are created:

// Include LLVK utilities
using LLVK;
// Imports core Vulkan API types/functions into the current scope
using static LLVK.Vulkan;
// Imports vendor specific types/functions into the current scope
using static LLVK.Vulkan.KHR; // + other vendors

... // Global functions only

vkCreateInstance(&createInfo, null, &instance)
VulkanLoader.LoadInstanceFunctions(instance);

... // Global + Instance level functions only

vkCreateDevice(physicalDevice, &createInfo, null, &device);
VulkanLoader.LoadDeviceFunctions(device);

... // All functions are available

A few usage notes:

  • Naming:
    • Bitmask enums have FlagBits replaced with Flags (e.g. VkImageUsageFlagBitsVkImageUsageFlags).
    • Enum values are normalized to PascalCase, have their common prefix removed, and have _BIT removed if present (e.g. VK_IMAGE_USAGE_TRANSFER_SRC_BITVkImageUsageFlags.TransferSrc).
    • Structs, handles, and functions all have the same name as their spec types.
  • Loading Instance and Device Functions:
    • After creating an instance or device, LLVK.VulkanLoader.Load{Instance/Device}Functions(VkInstance/VkDevice) must be called to load the functions.
    • LLVK.VulkanLoader.IsFunctionLoaded(string) can be used to check if an API function was successfully loaded.
  • Utilities:
    • Extensions and layers can easily be queried with InstanceExtensionSet, InstanceLayerSet, and DeviceExtensionSet.
    • UTF-8 strings and lists of strings can be created and manipulated with NativeStringUtf8 and NativeStringListUtf8.
    • VulkanStructureChain<...> can create and operate on linked chains of supported Vulkan structs.
    • All handle types have implicit boolean casts for nullity.
  • All disabled/provisional/beta extensions and features are not generated.

There are also some important factors to keep in mind due to the pecularities of C#:

  • It is important that the SType and PNext fields be initialized correctly in all types that have them, which is done automatically by calling the no-args constructor for the types. Un-initialized API types will not have the correct value for SType.
  • The library assumes a 64-bit little-endian target, and likely wont work on big-endian or 32-bit targets (which is not much of an issue as the overlap between platforms that support both Vulkan and .NET is almost entirely 64-bit LE).
Versions

The versioning of the LLVK library is identical to the version of the Vulkan specification that the code was generated against. A fourth version component indicates which version of the generator was used, making the final version <vk_major>.<vk_minor>.<vk_revision>.<gen_version>. The value of <gen_version> is always the major version of the generator project.

The generator version will only be bumped within a specific versioned release to fix a critical issue with that release. Otherwise, the generator version should always remain at zero for each release. This means that any one generator version value is not necessarily the same generator source between different releases.

Building

The solution has two build configurations:

  • Generator|Any CPU - Builds only the generator application.
  • Library|Any CPU - Builds all projects. Still requires 64-bit at runtime, despite targeting "Any CPU".
Updating Bindings

If you are updating the library for a specific version of the headers, you will need to use the following steps:

  1. Download the tagged vk.xml from GitHub.
  2. Build the Generator project (with the Generator|Any CPU config), and run it with:
    • -i <vk.xml>, pointing to the downloaded XML specification to generate from.
    • -l <LLVK.csproj>, pointing to the csproj file for the LLVK library.
    • -t <LLVK.Tests.csproj>, pointing to the csproj file for the LLVK.Tests library.
    • -s <X.X.X>, where <X.X.X> is the SDK version of the downloaded headers.
    • Optionally -v as well to help diagnose build issues.
  3. Fix all of the errors that crop up during the header parsing stage, which may include (but are not limited to):
    • Supporting new platforms or beta specifications as they appear.
    • Adding new generated or manual types and tests.
    • Changing SpecParser.cs to handle new use cases.
    • Changing SpecGenerator.vs or any of the generation templates.
  4. Update the versions in LLVK.csproj and LLVK.Generator.csproj to match the SDK version.
  5. Run build.{sh|bat} in LLVK.Tests/Native to build the native testing code, and correct any build/generation issues.
  6. Build the library (with the Library|Any CPU config), and run the unit tests and make changes until all are passing.

Credits

Both the LLVK generator application and library are licensed under the MIT license. See the LICENSE file at the root of this repository for more information.

Any third party tools are used under their original licenses, which can be found in the acknowledgement links above.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.182-rc4 72 2/17/2024
1.2.182-rc3 65 2/8/2024
1.2.182-rc2 122 12/28/2023
1.2.182-rc 127 11/7/2023