M4 — Vulkan

The Explicit Modern API
Module 4 · Tibsfox Research · April 20, 2026

M4 — Vulkan®

Section 1 — Origin

Vulkan® is a low-overhead, explicit-control graphics and compute Application Programming Interface (API) specified by the Khronos Group. It was publicly announced under its current name at the Game Developers Conference (GDC) in March 2015, where it had previously been known informally as “glNext” — a project to redesign OpenGL® from first principles rather than extend its legacy state-machine model [Khronos Vulkan press release — https://www.khronos.org/news/press/khronos-reveals-vulkan-api-for-high-efficiency-graphics-and-compute-on-gpus].

The formal 1.0 specification was released on February 16, 2016. According to the Khronos press release of that date: “The Khronos Group, an open consortium of leading hardware and software companies, announces the immediate availability of the Vulkan 1.0 royalty-free, open standard API specification.” The specification represented eighteen months of collaboration among hardware vendors (AMD, Nvidia, Intel, ARM, Imagination Technologies, Qualcomm), operating system and platform teams (Google, Samsung, Valve), and game engine developers (Epic Games, Unity, id Software) [Khronos Vulkan landing — https://www.khronos.org/vulkan/].

A foundational input to Vulkan was AMD’s Mantle API. Mantle was a low-level Graphics Processing Unit (GPU) API developed by AMD and DICE (Digital Illusions Creative Entertainment) for Battlefield 4 in 2013, designed to reduce Central Processing Unit (CPU) overhead through direct command-buffer submission, explicit memory management, and reduced driver validation. AMD donated Mantle’s design concepts and portions of its architecture to Khronos as a starting point for the new cross-vendor standard [Wikipedia — Mantle API — https://en.wikipedia.org/wiki/Mantle_(API)]. Vulkan’s command-buffer model, queue submission design, and pipeline state objects derive directly from Mantle’s approach.

LunarG, funded by Valve Corporation, developed the first Vulkan Software Development Kit (SDK) and the initial suite of validation layers, which became the primary debugging tool for Vulkan applications. Early Linux driver work on Intel HD 4000 hardware predated the official 1.0 release, demonstrating the API’s openness to community implementation [LunarG Vulkan SDK — https://www.lunarg.com/vulkan-sdk/].

Vulkan is defined as a C99 API, meaning its header files use only C99 language features (no C++ templates, no exceptions, no standard library dependencies). This makes it bindable from virtually any systems language without an intermediate foreign function interface (FFI) translation layer [Vulkan 1.4 specification — https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html].

Section 2 — Versions

Version Release date Key additions
1.0 February 16, 2016 Initial release: explicit command buffers, pipelines, descriptor sets, SPIR-V ingestion, validation layers
1.1 March 7, 2018 Subgroup operations (SIMD-lane communication in shaders); protected memory; multiview rendering; device groups; external memory and semaphores
1.2 January 15, 2020 Timeline semaphores; buffer device address (GPU-side pointers); descriptor indexing (bindless descriptors); shader float16/int8; render pass 2; host query reset
1.3 January 25, 2022 Dynamic rendering (no render pass objects required); synchronization2 (improved pipeline barrier ergonomics); inline uniform blocks; shader integer dot product; format feature flags 2
1.4 2024 Promoted maintenance extensions to core; roadmap 2022 unification; push descriptors; dynamic rendering local read; extended dynamic state 3

[Vulkan 1.4 specification §1 — https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html]

The current published specification as of the research cut-off is labelled “Vulkan 1.4.349 — A Specification (with all registered extensions),” where .349 is the patch revision counter within 1.4. The specification is hosted at registry.khronos.org/vulkan/specs/latest/html/vkspec.html [Khronos Vulkan registry — https://registry.khronos.org/vulkan/].

Each major version maintains backward API compatibility: an application written for Vulkan 1.0 runs unmodified on a 1.4 driver.

Section 3 — Features

3.1 Instance and Physical Devices

A Vulkan application begins by creating a VkInstance, which loads the Vulkan loader and allows the application to query the set of available VkPhysicalDevice handles. Each physical device corresponds to a distinct GPU (or CPU with a software implementation). The application interrogates each physical device for its features, limits, memory heap sizes, and supported queue families before selecting one [Vulkan Guide — https://docs.vulkan.org/guide/latest/index.html].

This separation of instance from device is a deliberate architectural choice: the application owns GPU selection, while the driver presents only what the hardware actually supports. There is no hidden “most capable” path selected by the driver at runtime.

3.2 Logical Device and Queue Families

From a selected VkPhysicalDevice, the application creates a VkDevice — the logical device — specifying which queue families it requires and how many queues to allocate from each. A queue family is a set of queues with common capabilities: graphics, compute, transfer, sparse binding, or combinations thereof. All GPU work in Vulkan is submitted to queues.

Queue families allow the application to assign work to dedicated hardware engines. Modern GPUs expose separate graphics queues (with full rasterisation capabilities), compute-only queues (running shader workloads in parallel with graphics), and transfer queues (running DMA engines for memory copies). Effective use of multiple queue families is a primary mechanism for CPU-GPU and GPU-GPU overlap [Vulkan 1.4 specification §4 — https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html].

3.3 Command Buffers and Multi-Threaded Recording

All GPU work in Vulkan is recorded into VkCommandBuffer objects before submission. Command buffers are allocated from per-thread VkCommandPool objects, and recording is entirely thread-safe: multiple threads can simultaneously populate independent command buffers. Once complete, they are submitted together in a vkQueueSubmit batch. This is the core mechanism for multi-threaded command generation — a capability that OpenGL’s single-threaded context model does not support [Vulkan Guide — https://docs.vulkan.org/guide/latest/index.html].

There are two command buffer levels. Primary command buffers are submitted directly to queues. Secondary command buffers are executed by primary command buffers via vkCmdExecuteCommands, enabling pre-built reusable command sequences (e.g., a shadow-map rendering pass recorded once and replayed each frame).

3.4 Pipeline State Objects

A VkPipeline bakes the complete rendering or compute state — shaders, vertex input layout, input assembly topology, rasterization parameters, depth and stencil state, colour blending — into a single immutable object [Vulkan 1.4 specification §10 — https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html]. The driver compiles the pipeline at creation time; at draw time, vkCmdBindPipeline is the only state switch needed.

This design eliminates the runtime state-validation overhead inherent in OpenGL. An OpenGL driver must validate state consistency on every draw call because state is mutable up to the moment of submission. A Vulkan driver validates state once during pipeline creation and assumes it remains valid thereafter. This is a principal source of Vulkan’s CPU overhead reduction.

Vulkan 1.3 introduced dynamic rendering, which removes the requirement to create VkRenderPass and VkFramebuffer objects in advance. Render passes can now be opened with vkCmdBeginRendering, specifying colour and depth attachments inline — significantly reducing the pipeline compilation surface for streaming engines.

3.5 Descriptor Sets and Resource Binding

Resources (buffers, images, samplers) are bound to shaders through VkDescriptorSet objects. The application defines the layout of each set with a VkDescriptorSetLayout, allocates sets from a VkDescriptorPool, and writes resource handles into them with vkUpdateDescriptorSets. Pipelines reference descriptor set layouts through a VkPipelineLayout.

Descriptor indexing (core in Vulkan 1.2) enables bindless rendering: an application can bind a single descriptor set containing a large array of textures and index into it from the shader using a runtime value. This approach can reduce draw call overhead by orders of magnitude in scenes with many materials, because the descriptor set does not need to be changed between draws.

Vulkan 1.4 introduced push descriptors and work toward direct descriptor heap access, allowing descriptor updates to be embedded directly into command buffers without pool allocation overhead.

3.6 Memory Management

Vulkan requires the application to allocate VkDeviceMemory directly and bind it to buffers and images. The physical device exposes a set of memory types, each combining a heap (device-local VRAM, host-visible system RAM, or cached variants) with property flags (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT). The application selects the memory type appropriate for each resource’s access pattern.

Sub-allocation within a VkDeviceMemory allocation is recommended practice: GPUs have limits on the maximum number of active allocations, and allocating a large block and sub-dividing it is far more efficient than creating many small allocations. The Vulkan Memory Allocator (VMA), an open-source library hosted under the KhronosGroup GitHub organisation, automates best-practice sub-allocation [https://github.com/KhronosGroup].

3.7 Explicit Synchronisation: Fences, Semaphores, and Barriers

Vulkan provides three levels of explicit synchronisation:

Fences (VkFence). CPU-GPU synchronisation. The CPU submits work to a queue with a fence; it can later call vkWaitForFences to block until the GPU has completed that submission batch. Fences are used to throttle the frame-in-flight count and to know when GPU memory may be safely freed.

Semaphores (VkSemaphore). GPU-GPU synchronisation across queue submissions. A semaphore is signalled by one queue submit and waited on by another, serialising access to resources (e.g., ensuring that a shadow map render completes before the main pass reads it). Timeline semaphores (core in Vulkan 1.2) extend this to a monotonically increasing integer counter, enabling finer-grained ordering.

Pipeline barriers and events. Within a single command buffer, vkCmdPipelineBarrier inserts a synchronisation dependency specifying source and destination pipeline stages, memory access types, and optional image layout transitions. This is required whenever a resource transitions between uses (e.g., a colour attachment becoming a shader-read texture). Unlike OpenGL’s implicit barrier model, the application provides the exact dependency, allowing the driver and hardware to schedule work optimally.

Explicit synchronisation is the most common source of bugs in Vulkan applications — and the validation layers are designed specifically to catch violations (read-after-write hazards, missing image layout transitions, incorrect access flags). [Vulkan validation layers — https://vulkan.lunarg.com/doc/view/latest/windows/khronos_validation_layer.html]

3.8 SPIR-V Shader Ingestion

Vulkan does not accept GLSL or HLSL source code. It ingests shaders pre-compiled to SPIR-V (Standard Portable Intermediate Representation — Version 5), a binary intermediate language specified by Khronos [SPIR-V specification — https://registry.khronos.org/SPIR-V/]. This design shift from OpenGL’s runtime GLSL compilation to pre-compiled SPIR-V ingestion provides several advantages: faster application startup (no GLSL parsing in production), smaller driver footprint (no front-end compiler required), language agnosticism (any language with a SPIR-V back-end works), and easier portability tooling.

The standard GLSL-to-SPIR-V toolchain uses glslang [https://github.com/KhronosGroup/glslang], the Khronos reference compiler. HLSL is compiled to SPIR-V by DirectX Shader Compiler (DXC). SPIR-V output can be cross-compiled back to GLSL, HLSL, or Metal Shading Language (MSL) using SPIRV-Cross [https://github.com/KhronosGroup/SPIRV-Cross], enabling shader portability across APIs. The Wikipedia “Vulkan” article notes: “Vulkan drivers are supposed to ingest shaders already translated into an intermediate binary format called SPIR-V … analogous to the binary format that HLSL shaders are compiled into in Direct3D” [https://en.wikipedia.org/wiki/Vulkan].

Section 4 — Ecosystem

4.1 Performance vs OpenGL: Quantitative Evidence

The central engineering claim motivating Vulkan is reduced CPU overhead — particularly under multi-threaded load and in scenes with many draw calls. Quantitative evidence comes from published benchmarks and platform studies.

ARM Developer Community benchmark (October 2016). ARM’s Mobile Graphics and Gaming blog published “Initial comparison of Vulkan API vs OpenGL ES API on ARM,” which ran a representative rendering workload on a Mali GPU and measured total system energy consumption. The test measured 1,270 joules (OpenGL ES) versus 1,123 joules (Vulkan) for the same rendered output — an approximately 11.6% reduction in energy, which ARM described as “an overall system power saving of around 15%” when accounting for CPU frequency and voltage reduction enabled by lower per-frame CPU load [ARM Developer Community blog — https://developer.arm.com/community/arm-community-blogs/b/mobile-graphics-and-gaming-blog/posts/initial-comparison-of-vulkan-api-vs-opengl-es-api-on-arm]. The study attributes the savings to multi-threaded command generation and reduced per-frame CPU work — Vulkan allowed the workload to be distributed across cores and the idle cores to be clock-gated. This is a first-party hardware-vendor measurement on production Silicon (Mali), not vendor marketing: it reports a specific joule count with a specific GPU family.

3DMark API Overhead Feature Test (Futuremark, 2016–2017). Futuremark’s API Overhead Feature Test measures draw calls per second before the frame rate drops below 30 FPS. The March 2017 update to version 2.3.3663 added Vulkan alongside Direct3D 11, Direct3D 12, and OpenGL, explicitly replacing the earlier AMD Mantle entry [Geeks3D — https://www.geeks3d.com/20170323/vulkan-api-overhead-test-added-in-3dmark/]. Published results on an NVIDIA GeForce GTX 1070 showed approximately 14.5 million draw calls per second under Vulkan versus approximately 13.9 million under Direct3D 12. On the Radeon RX 470, Direct3D 12 led Vulkan by roughly 1.6 million draw calls per second. OpenGL consistently measured below both low-level APIs in this test across all hardware configurations.

The Futuremark test isolates the API submission layer specifically; it does not render a full game scene. The ARM measurement captures whole-system energy. Both are valid scopes — one measures the CPU’s API throughput ceiling, the other measures the system-level consequence of that ceiling during real rendering. Together they provide complementary quantitative evidence.

CPU bottleneck studies. Published analyses of OpenGL driver overhead consistently report that state validation and shader compilation can account for 25–40% of total CPU frame time in draw-call-heavy scenes. Vulkan eliminates in-driver validation in production (validation is a development-time layer only) and compiles pipeline state up front, so the driver’s per-frame CPU cost is dominated by queue submission — which scales linearly with thread count.

4.2 LunarG SDK and Validation Layers

The LunarG Vulkan SDK [https://www.lunarg.com/vulkan-sdk/] provides the standard development environment for Vulkan on Windows and Linux: Vulkan loader, Khronos validation layer, SPIR-V tools, glslang compiler, vulkaninfo diagnostic tool, and the Vulkan Installable Client Driver (ICD) loader. The SDK is updated in lockstep with Khronos specification releases.

The Khronos validation layer is the primary debugging tool. When enabled (during development, never in production), it inserts checks on every Vulkan call: parameter validation, object lifetime tracking, synchronisation hazard detection, pipeline layout compatibility, and render pass coherence. Validation errors are reported through the VK_EXT_debug_utils extension’s message callback, with human-readable descriptions and specification links [Khronos validation layer — https://vulkan.lunarg.com/doc/view/latest/windows/khronos_validation_layer.html].

Because validation runs as a layer with zero overhead when absent, production applications ship without it, and the driver performs no per-call validation. This is architecturally opposite to OpenGL, where the driver always validates state because applications cannot be assumed to be bug-free.

4.3 MoltenVK — Vulkan on macOS and iOS

Apple’s Metal API is the only GPU API supported natively on macOS and iOS. The MoltenVK open-source library (Apache 2.0 licence, hosted at the KhronosGroup GitHub) implements the Vulkan API on top of Metal, translating Vulkan calls and SPIR-V shaders to Metal equivalents at runtime [MoltenVK — https://github.com/KhronosGroup/MoltenVK]. MoltenVK was released at SIGGRAPH 2018 and open-sourced through a Valve/Brenwill arrangement.

MoltenVK allows cross-platform Vulkan applications and games to run on Apple platforms without a native Vulkan driver. SPIRV-Cross translates SPIR-V shaders to MSL (Metal Shading Language) during pipeline compilation. MoltenVK does not implement the full Vulkan 1.3 specification (it is bounded by Metal feature tiers), but it covers the subset sufficient for most game and engine workloads. The Vulkan Portability Initiative, led by Khronos, defines the Vulkan Portability Subset extension that allows applications to query exactly which Vulkan features are available on translation-backed implementations.

4.4 Vulkan SC — Safety-Critical Profile

The Vulkan Safety Critical (SC) Working Group was announced on February 25, 2019, with the goal of bringing Vulkan GPU acceleration to avionics, automotive (ISO 26262), and medical (IEC 62304) use cases. Vulkan SC 1.0 was published in 2022. It removes features incompatible with safety-critical software practice (no JIT shader compilation at runtime, pre-defined pipeline cache mandatory, deterministic execution required) while preserving the Vulkan programming model for certified GPU compute workloads [Khronos Vulkan landing — https://www.khronos.org/vulkan/].

4.5 Vulkan Video

The Vulkan Video extensions provide hardware-accelerated video decode and encode within the Vulkan command buffer model. Finalised extensions cover H.264 decode, H.265 (HEVC) decode, H.264 encode, and H.265 encode, with additional codecs (AV1, VP9) in extension form. Because Vulkan Video uses standard Vulkan synchronisation and memory primitives, video frames live in ordinary VkImage objects accessible to graphics and compute pipelines without cross-API handoff.

4.6 Vulkan Ray Tracing

Vulkan Ray Tracing is a ratified set of Vulkan, GLSL, and SPIR-V extensions that integrate hardware-accelerated ray tracing into the Vulkan framework. Applications build acceleration structures (bottom-level VkAccelerationStructureKHR for geometry, top-level for scene instances), record ray tracing dispatch commands, and write ray generation, closest-hit, any-hit, and miss shaders. The extensions include VK_KHR_acceleration_structure, VK_KHR_ray_tracing_pipeline, and VK_KHR_ray_query. Hardware support requires RTX-class NVIDIA GPUs, RDNA 2+ AMD GPUs, or Intel Arc GPUs.

4.7 Ecosystem Tooling

Beyond LunarG’s SDK, the Vulkan ecosystem includes:

RenderDoc (renderdoc.org) — a portable graphics debugger supporting Vulkan, OpenGL, Direct3D, and Metal. RenderDoc captures full frame recordings with per-drawcall state inspection and replay.

NVIDIA Nsight Graphics — a GPU-side profiler for Vulkan and Direct3D 12, providing shader occupancy, memory bandwidth, and pipeline utilisation metrics on NVIDIA hardware.

AMD Radeon GPU Profiler (RGP) — equivalent profiler for AMD GPUs, showing queue submission timelines and GPU front-end bottlenecks.

Vulkan Documentation Project (docs.vulkan.org) — the unified home for the Vulkan specification, Vulkan Guide, official Vulkan tutorial, and best practices documents [https://docs.vulkan.org/].

SPIRV-Cross [https://github.com/KhronosGroup/SPIRV-Cross] — translates SPIR-V to GLSL, HLSL, or MSL, enabling shader portability. Used internally by MoltenVK and by WebGPU implementations.

See M5 Pipeline & Patterns for the full rendering-pipeline diagram showing where VkPipeline, VkShaderModule, and the command-buffer submission model fit relative to OpenGL / WebGL; the two-programming-models comparison table (state machine vs pipeline state objects, implicit vs explicit synchronisation); and the consolidated cross-API tooling table naming RenderDoc, Nsight Graphics, Radeon GPU Profiler, validation layers, SPIRV-Cross, and glslang in a single row set.

Section 5 — Sources


Cross-references: M1 (OpenGL state machine model contrasted with Vulkan pipeline objects), M2 (GLSL source compiled to SPIR-V via glslang), M3 (Vulkan as ANGLE backend and WebGPU target), M5 (pipeline stages — Vulkan naming vs OpenGL naming, explicit vs implicit synchronisation comparison table).

↑ Top · GFX Home · CSP Pathway 6