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