Awesome
<p align="center"> <img src="https://cdn.rawgit.com/realitix/vulkan/182062bc/logo/cvulkan-180x180.png" /> </p>vulkan, the ultimate Python binding for Vulkan API
Table of Contents
- Presentation
- How to install
- How to use
- How to contribute
- Architecture
- Community
- Stay in touch
- History
- Supported By
Presentation
vulkan is a Python extension which supports the Vulkan API. It leverages power of Vulkan with simplicity of Python. It's a complete Vulkan wrapper, it keeps the original Vulkan API and try to limit differences induced by Python.
vulkan is compatible with Python 2 and Python 3.
How to install
Pip
You can install directly vulkan with pip:
pip install vulkan
Manual install
You can install it manually if you want the latest version:
git clone https://github.com/realitix/vulkan
cd vulkan
python setup.py install
How to use
Getting started
To try this wrapper, execute the following commands (on linux):
git clone https://github.com/realitix/vulkan.git
cd vulkan
python setup.py install
pip install -r requirements.txt
python example/example_sdl2.py
Known errors :
OSError: cannot load library 'libvulkan.so'
means you didn't install the Vulkan SDK.
vulkan.VkErrorExtensionNotPresent
means your have installed the Vulkan SDK but your driver doesn't support it.
pip install vulkan
fails on Windows 10: Try pip install --upgrade pip setuptools wheel
before installing vulkan
.
Platform not supported
error: It's probably because your pysdl2 wrapper is using SDL3. To fix it, install pysdl2-dll
in your venv.
API
The vulkan wrapper gives you complete access to the Vulkan API, including extension functions.
Code convention
Similar to Vulkan, structs are prefixed with Vk, enumeration values are prefixed with VK_ and functions are prefixed with vk.
Structs
Vulkan struct creation is achieved in vulkan wrapper using python functions.
For example, if you want to create the Vulkan struct VkInstanceCreateInfo
,
you must initialize it with its keyword parameters. In vulkan wrapper, you will call
the Python function VkInstanceCreateInfo
with named parameters as shown below.
In C++ (Vulkan) we write:
VkInstanceCreateInfo instance_create_info = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
&application_info, // *pApplicationInfo
3, // enabledLayerCount
&layers, // *ppEnabledLayerNames
3, // enabledExtensionCount
&extensions // *ppEnabledExtensionNames
};
Our vulkan wrapper equivalent of the above C++ code is :
import vulkan as vk
instance_create_info = vk.VkInstanceCreateInfo(
sType=vk.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
pNext=None,
flags=0,
pApplicationInfo=application_info,
enabledLayerCount=len(layers),
ppEnabledLayerNames=layers,
enabledExtensionCount=len(extensions),
ppEnabledExtensionNames=extensions,
)
To create the struct, you must remember to pass all parameters at creation time.
This includes the Vulkan layers and extensions denoted by ppEnabledLayerNames
and ppEnabledExtensionNames
, which vulkan wrapper is able to facilitate too.
This struct example demonstrates how vulkan wrapper conveniently converts your Python code into native C types.
Note:
- The default value for all parameters is
None
so you could have omittedpNext
(because its value isNone
). - The default value for
sType
parameter is the good value so you could have omittedsType
. - The default value for
enabledLayerCount
parameter is the length ofppEnabledLayerNames
so you could have omittedenabledLayerCount
andenabledExtensionCount
. - Order of parameters doesn't matter since they are keyword parameters.
- The C++ syntax is more risky because you must pass all parameters in specific order.
Functions
vulkan greatly simplifies the calling of functions. In Vulkan API, you have to explicitly write three kinds of function:
- functions that create nothing
- functions that create one object
- functions that create several objects
In vulkan wrapper, all these troubles goes away.
vulkan will takes care of you and knows when to return None
, an object or a list
.
Here are three examples:
# Create one object
instance = vk.vkCreateInstance(createInfo, None)
# Create a list of object
extensions = vk.vkEnumerateDeviceExtensionProperties(physical_device, None)
# Return None
vk.vkQueuePresentKHR(presentation_queue, present_create)
Vulkan functions usually return a VkResult
, which returns the success and
error codes/states of the function. vulkan is pythonic and converts VkResult
to exception: if the result is not VK_SUCCESS
, an exception is raised.
More elaboration is given in the next section.
Exceptions
-
vulkan has two types of Exceptions, namely
VkError
orVkException
. TheVkError
exception handles all the error codes reported by Vulkan'sVkResult
. TheVkException
exception handles all the success code reported by Vulkan'sVkResult
, except theVK_SUCCESS
success code. -
Exception names are pythonized:
VK_NOT_READY
->VkNotReady
.
Constants
All Vulkan constants are available in vulkan and it even provides some fancy
constants like UINT64_MAX
.
Resources
To understand how to use this wrapper, you have to look for example/exemple_*
files
or refer to Vulk engine.
How to contribute
To contribute, you should first read the Architecture
section.
Any contribution is welcome and I answer quickly.
Architecture
vulkan is a CFFI module generated by a Python script.
When you install this module, you need two files:
vulkan/vulkan.cdef.h
containing CFFI definitionsvulkan/_vulkan.py
containing the actual executed Python script
Theses two files are generated by the generator/generate.py
script.
vulkan/vulkan.cdef.h
is generated with a cpp
command call, it applies pre-processing to the Vulkan C header.
It can't work as is because of pycparser
which cannot parse the output. That's the purpose of fake_libc_include
folder.
vulkan/_vulkan.py
needs more work.
To proceed, the generator computes a model of Vulkan API based on vk.xml
(the file from Kronos describing the API) and then uses a jinja2
template
to write the file.
Here the basic steps:
- Load vk.xml
- Use
xmltodict
to parse the xml document - Generate a good data model from it
- Pass the model to the
vulkan.template.py
file - The template engine generate the final Python file
How to update the package on PyPi (for maintainer only)
- python setup.py sdist bdist_wheel
- twine upload dist/* -u token -p pypi-TOKENID
Community
You can checkout my blog, I speak about vulkan: Blog
History
This module comes from a long journey. I have first created CVulkan. CVulkan is a wrapper created in plain C, plain C is hard to maintain... So I have decided to restart with CFFI which is from far the best way to do it. There was a module pyVulkan that did what I wanted to do. But it was not working and the code was hard to maintain. I asked to the maintainer to let me help him but I got no answer. I forked his project and I rewrote every single part to obtain a good module.
Supported By
vulkan is supported by helpful 3rd parties via code contributions, test devices and so forth. Make our supporters happy and visit their sites!