serafim / vulkan
PHP Vulkan Bindings
Requires
- php: ^8.4
- ext-ffi: *
- ffi/env: ^1.1
- ffi/location: ^1.1
Requires (Dev)
- ffi/preprocessor: ^1.0
- friendsofphp/php-cs-fixer: ^3.95
- nette/php-generator: ^4.2
- phpat/phpat: ^0.12.5
- phpstan/phpstan: ^2.3
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^12.0|^13.0
- symfony/console: ^7.4|^8.0
- symfony/http-client: ^7.4|^8.0
- symfony/process: ^7.4|^8.0
Suggests
- ffi/preprocessor: Required to compile the Vulkan headers at runtime with PreprocessorHeadersLoader
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-30 22:48:09 UTC
README
PHP Vulkan Bindings
PHP bindings of the Vulkan API on top of ext-ffi for Linux (Xlib, XCB,
Wayland), Windows and macOS (MoltenVK).
Requirements
- PHP ^8.4
- ext-ffi
- GPU and drivers supporting Vulkan API
Installation
composer require serafim/vulkan
Usage
Creates an instance and prints the names of the GPUs.
use Serafim\Vulkan\Struct\VkApplicationInfo; use Serafim\Vulkan\Struct\VkInstanceCreateInfo; use Serafim\Vulkan\Vulkan; $vk = Vulkan::load(); $instance = $vk->vkCreateInstance(new VkInstanceCreateInfo( applicationInfo: new VkApplicationInfo( applicationName: 'Example', ), )); foreach ($vk->vkEnumeratePhysicalDevices($instance) as $device) { $properties = $vk->vkGetPhysicalDeviceProperties($device); echo $properties->deviceName . "\n"; }
Instance version and extensions
The highest API version and the instance extensions the installed Vulkan supports. Needs no instance. Lists of unknown length are lazy collections.
echo $vk->vkEnumerateInstanceVersion() . "\n"; foreach ($vk->vkEnumerateInstanceExtensionProperties() as $extension) { echo $extension->extensionName . "\n"; }
API version
The Vulkan version the application targets. All the macros of Vulkan
(VK_MAKE_API_VERSION and others) are available as vk_* functions.
use function Serafim\Vulkan\vk_make_api_version; $info = new VkApplicationInfo( applicationName: 'Example', apiVersion: vk_make_api_version(0, 1, 3, 0), );
Queue families
Every queue belongs to a family with its own capabilities. Finds the families that support graphics, flags are checked with a bit mask.
use Serafim\Vulkan\Enum\VkQueueFlagBits; foreach ($vk->vkGetPhysicalDeviceQueueFamilyProperties($device) as $index => $family) { if ($family->queueFlags & VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT) { echo "Graphics queue family: $index ($family->queueCount queues)\n"; } }
Chained structures
Properties are split across extension structures linked by pNext. List the
classes you need and read each back by class.
use Serafim\Vulkan\Struct\VkPhysicalDeviceVulkan13Properties; $properties = $vk->vkGetPhysicalDeviceProperties2($device, [ VkPhysicalDeviceVulkan13Properties::class, ]); $vulkan13 = $properties->chain[VkPhysicalDeviceVulkan13Properties::class]; echo $vulkan13->driverName . "\n"; // Vulkan 1.2 echo $vulkan13->deviceUUID . "\n"; // Vulkan 1.1 echo $vulkan13->maxSubgroupSize . "\n";
Logical device and queue
Opens a logical device on a GPU and gets its queue. There is no destroy: an
object is destroyed with its PHP handle, children first.
use Serafim\Vulkan\Struct\VkDeviceCreateInfo; use Serafim\Vulkan\Struct\VkDeviceQueueCreateInfo; $logical = $vk->vkCreateDevice($device, new VkDeviceCreateInfo( queueCreateInfos: [ new VkDeviceQueueCreateInfo( queueFamilyIndex: 0, queuePriorities: [1.0], ), ], )); $queue = $vk->vkGetDeviceQueue($logical, 0, 0); $vk->vkQueueWaitIdle($queue);
Enabling features
Structures that extend the one a command takes are given in its chain list.
The structure of a Vulkan version holds the features of all the older ones.
use Serafim\Vulkan\Struct\VkPhysicalDeviceVulkan13Features; $logical = $vk->vkCreateDevice($device, new VkDeviceCreateInfo( queueCreateInfos: [new VkDeviceQueueCreateInfo( queueFamilyIndex: 0, queuePriorities: [1.0], )], chain: [new VkPhysicalDeviceVulkan13Features( dynamicRendering: true, bufferDeviceAddress: true, // Vulkan 1.2 multiview: true, // Vulkan 1.1 )], ));
Errors
A failed command throws CommandFailedException, its code is the VkResult
value.
use Serafim\Vulkan\Enum\VkResult; use Serafim\Vulkan\Exception\CommandFailedException; try { $vk->vkCreateInstance(new VkInstanceCreateInfo( enabledLayerNames: ['missing'], )); } catch (CommandFailedException $e) { $result = VkResult::from($e->getCode()); echo $result->name; }
More in ./examples/*.php