Skip to content

Awake Vulkan Backend

Status: stable.

Vulkan implementation of awake:engine:render:contract. awake-vulkan's expect class Renderer implements the contract interface; one actual per platform target (Android, desktop, iOS).

Installation

In-Repo Dependency

implementation(project(":awake:backend:vulkan"))
Pulls in :awake:backend:vulkan:bindings transitively (api(...)). Also depends on :awake:core and :awake:ui:ui-core, and exposes :awake:engine:render:contract as api so downstream code can use Renderer against the shared interface.

Standalone Maven Dependency (vulkan-kmp)

If you only need raw Vulkan API bindings without engine dependencies:

// commonMain
implementation("com.awakekt.awake:vulkan-kmp:<version>")

See bindings/README.md for full setup instructions across Desktop JVM, Android, and iOS.

  • Desktop JVM: Embedded Fat JAR (/natives/<os-arch>/) with VulkanNativeLoader auto-extracting to ~/.awake/natives/ at runtime (zero configuration).
  • Android: vulkan-kmp-android-native AAR with multi-ABI .so (arm64-v8a, x86_64) resolved automatically.
  • iOS: Kotlin/Native cinterop linking with MoltenVK.xcframework.

Module layout

include(":awake:backend:vulkan")                    // this module — hand-authored orchestration
include(":awake:backend:vulkan:bindings")            // Vulkan API surface (mostly generated)
include(":awake:backend:vulkan:bindings:android-native")
include(":awake:backend:vulkan:generator")           // the codegen tool that produces bindings/

vulkan depends on vulkan:bindings via api(...) — orchestration sits above the raw API surface, not mixed into it.

What's hand-authored here (30 files, 11 packages)

application/, commands/, debug/, device/, material/, mesh/, pipeline/, renderer/, swapchain/, texture/, ui/ — real logic: Renderer, RenderPipeline, SwapchainManager, GraphicsDevice, and the UI-framework draw pipelines (UiGlyphRenderPipeline, UiRoundedQuadRenderPipeline, ...).

Renderer (renderer/Renderer.kt + its extension-split siblings RendererDraw3D.kt/ RendererDrawUi.kt/RendererSwapchain*.kt/RendererVertexWriters.kt) is the single per-frame orchestrator — it dispatches both 3D scene draws and UI draws through one swapchain/command-buffer, which is why some of those files import awake:ui:ui-core even though most of this module never does.

What's generated vs hand-authored inside vulkan:bindings (2026-08-18 finding)

The Gradle module boundary (vulkan vs vulkan:bindings) splits orchestration from raw API surface — it does not mark which files inside bindings/ are machine-generated. Verified against vulkan:generator's own source (nothing in it references these filenames): 6 files under vulkan/bindings/.../vulkan/ root are hand-authored, not generated, and carry no marker distinguishing them from the ~126 generated files in models//enums/:

File Lines Purpose
Vulkan.kt 466 Hand-written facade wrapping the generated enums/models/models.info types
Common.kt 51 Hand-tuned Vulkan spec constants (VK_TRUE, VK_WHOLE_SIZE, ...) and type aliases
Annotations.kt 55 Support annotations for the binding layer
Flags.kt 29 Flag-type helpers
VulkanSurface.kt 25 Surface-creation support
Version.kt 19 Vulkan API version constants

Everything else under vulkan:bindings (models/, enums/, models/info/, models/physicaldevice/, ...) is generated by vulkan:generator and will be silently overwritten on the next codegen run — do not hand-edit those files. The 6 above are safe to hand-edit; they are never touched by the generator.

Known gap, not yet fixed: none of the generated files carry a // generated, do not edit header, so this distinction currently lives only in this README and in the fact that vulkan:generator's source doesn't reference the 6 exception filenames — not enforced by tooling. If vulkan:generator starts emitting a header comment on every file it writes, that becomes the real, in-file signal instead of this table.

Extensibility

Renderer's constructor already follows a consistent optional-content-vs-capability pattern (see skyboxRenderPipeline vs lineRenderPipeline) so a consumer can build their own rendering content without forking this module. Full convention + the rule for new features: docs/reference/render-extensibility.md.