Vulkan

An explicit, low-level cross-vendor API for graphics and compute. Compute shaders are written in GLSL (or HLSL), compiled ahead of time to SPIR-V, and run on every modern GPU from NVIDIA, AMD, Intel and — via MoltenVK — Apple. Verbose, but it gives you total control and portability, which is why most new engines target it.

KhronosC/C++ · GLSL → SPIR-Vcross-vendoropen standardlow-level

Official docs ↗ ← All libraries

Install

# Install the LunarG Vulkan SDK (glslc, validation layers, headers)
# Linux (Ubuntu):
wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan.list https://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list
sudo apt-get update && sudo apt-get install -y vulkan-sdk
vulkaninfo | head    # verify a device is visible

Hello, GPU

double.comp — a Vulkan compute shader (GLSL, compiled to SPIR-V)

// double.comp — GLSL compute shader
#version 450
layout(local_size_x = 64) in;
layout(std430, binding = 0) buffer Data { float v[]; };

void main() {
    uint i = gl_GlobalInvocationID.x;
    v[i] = v[i] * 2.0;
}

/* Host (C/C++ with the Vulkan API, abbreviated):
   vkCreateInstance / pick a VkPhysicalDevice / vkCreateDevice (a compute queue)
   load double.spv -> vkCreateShaderModule
   VkDescriptorSetLayout (one storage buffer) -> VkPipelineLayout
   vkCreateComputePipelines(..., stage = double.spv, "main")
   vkCreateBuffer + vkAllocateMemory (HOST_VISIBLE) -> upload the array
   vkUpdateDescriptorSets -> bind the buffer at binding 0
   vkCmdBindPipeline / vkCmdBindDescriptorSets
   vkCmdDispatch(n / 64, 1, 1) -> vkQueueSubmit -> vkQueueWaitIdle
   map the memory back: the array is now doubled                              */

Run it:

glslc double.comp -o double.spv   # then dispatch it from the host program above

Learn more