« All posts

GoCL: A Zero-Overhead C++20 Vulkan Proxy Layer

GoCL is an open-source C++20 Vulkan proxy that rewrites SPIR-V on the fly based on GPU capabilities, lazy-loads heavy backends, and adds zero measurable runtime overhead.

GoCL is a Vulkan proxy (vulkan_proxy.so / vulkan-1.dll) paired with a static library (GoCL_core.a) that intercepts Vulkan calls and adapts them to a GPU's real capabilities before they reach the driver. At its core sits a capability oracle: at device creation time every relevant physical device feature is queried once and stored in a plain DeviceCapabilities struct, so every subsystem reads branch-predictable data instead of doing virtual dispatch or runtime checks on the hot path.

The proxy patches a dispatch table at vkCreateDevice time to hook Vulkan entry points, and on Linux it links with -Wl,-z,now so all dynamic symbols resolve eagerly at load time — Callgrind confirms zero lazy-binding overhead inside the render loop. Unsupported shader features such as FP16 ops or oversized descriptor sets are detected and the SPIR-V binary is rewritten in memory with no external compiler or LLVM dependency, widening FP16 to FP32 and splitting large descriptor bindings.

The heavyweight Basis Universal transcoder used for ASTC→ETC2 conversion lives in a separate gocl_transcoder.so and is only dlopen'd when an ASTC texture actually appears, keeping the proxy's baseline footprint minimal since its static initializers never fire otherwise. All the extra work happens once, at pipeline creation or texture load, leaving the render loop untouched — Callgrind instruction counts on a GTX 960M across 75+ Sascha Willems Vulkan examples show the proxy running about 3.8% fewer total instructions than native (3.806B vs 3.955B), with FPS and frame times matching within noise.

The project is dual-licensed under Apache-2.0 or MIT and is tested in CI against Mesa Lavapipe, making it a notable case study for engineers who want runtime GPU adaptability without paying a real performance tax.