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
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