Giter VIP home page Giter VIP logo

vulkan's Introduction

vulkan, the ultimate Python binding for Vulkan API

Table of Contents

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 omitted pNext (because its value is None).
  • The default value for sType parameter is the good value so you could have omitted sType.
  • The default value for enabledLayerCount parameter is the length of ppEnabledLayerNames so you could have omitted enabledLayerCount and enabledExtensionCount.
  • 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 or VkException. The VkError exception handles all the error codes reported by Vulkan's VkResult. The VkException exception handles all the success code reported by Vulkan's VkResult, except the VK_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 definitions
  • vulkan/_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!

linagora

vulkan's People

Contributors

amaank404 avatar anlsh avatar apenngrace avatar berserker66 avatar craftyguy avatar dariost avatar florianrhiem avatar mackst avatar okuma10 avatar p-tillmann avatar realitix avatar thunderk avatar victorvde avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vulkan's Issues

Issue with function _new in vulkan's __init__.py

Hi realitix...

There seem to be an issue in vulkan's __init__.py", line 2204, in function _new

    ret = ffi.new(_type.cname + '*', init)[0]
OverflowError: can't convert negative number to unsigned

My original code which used to work:

    def _createLogicalDevice(self):
        '''Create Logical Device'''

        #1. Create Logical Device Queue Create Info.
        queue_priorities = [1.0]
        queue_family_indices = {self.queue_families_graphics_index,
                                self.queue_families_present_index}
        # Note: queue_family_indices is a set; when it's items value are equal,
        #       set keeps only one of them. 
        logical_device_queues_createInfo = [ VkDeviceQueueCreateInfo(
            queueFamilyIndex = i,
            queueCount = 1,
            pQueuePriorities = queue_priorities)
                        for i in queue_family_indices ]
        logging.info('Created logical_device_queues_createInfo.')

the error is in listcomp
for i in queue_family_indices ]

Can you let me know what is wrong and how I can fix it?

VkResult & vkCreateInstance

from vulkan import *

APP_SHORT_NAME = "LunarG SDK Cube Example"

# Create Instance of Application

# create application info
app_Info = VkApplicationInfo(
    sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, #indicates the type of the structure
    pNext = None,
    pApplicationName = APP_SHORT_NAME,
    applicationVersion = 1,
    pEngineName = APP_SHORT_NAME, 
    engineVersion = 1,
    apiVersion = VK_API_VERSION_1_0)

# create application instance info
inst_Info = VkInstanceCreateInfo(
    sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
    pNext = None,
    flags = 0,
    pApplicationInfo = app_Info,
    enabledLayerCount = 0,
    ppEnabledLayerNames = None,
    enabledExtensionCount = 0,
    ppEnabledExtensionNames = None)

#inst = VkInstance()
#res = VkResult()

# create application instance
instance = vkCreateInstance(
    pCreateInfo = inst_Info,
    pAllocator = None)#,
    #pInstance = inst)

print('vkResult(instance) = ', vkResult(instance))

Error message:

print('VkResult(instance) = ', VkResult(instance))
NameError: name 'VkResult' is not defined

Question 1:
How do I call "VkResult" in your wrapper? VkResult is use to return the state of Vulkan function. I noticed your example.py code, VkResult is not used. How can I report the state of a Vulkan function in vulkan?

Question 2:
In the definition of instance using vkCreateInstance, what do I give to pInstance? My confusion here is instance is created so what is the purpose of pInstance. I tried inst = VkInstance() but got error message NameError: name 'VkInstance' is not defined. At the moment, I commented it out to avoid error.

Name changes to structs and functions that have been promoted from 1.0 to 1.1.

I was reading Spec 1.1.77.0 and learnt about some changes in the naming of some functions and structs for Vulkan 1.0 to Vulkan 1.1. I also read 1.1.70.1 release notes and found the explanation for the naming changes. I believe _vulkan.py in vulkan 1.1.71.2 is missing the following updates. There are still more to update. Apologies I could not get to all. There are like 23 occurrences of the phrase "Promotion to Vulkan 1.1" in 1.1.70.1 spec. I only managed to go through 3 of them.

Some changes needed

VkPhysicalDeviceIDPropertiesKHR = VkPhysicalDeviceIDProperties
VkQueueFamilyProperties2KHR = VkQueueFamilyProperties2
VkPhysicalDeviceGroupPropertiesKHR = VkPhysicalDeviceGroupProperties
vkEnumeratePhysicalDeviceGroupsKHR = vkEnumeratePhysicalDeviceGroups
VkDeviceGroupDeviceCreateInfoKHR = VkDeviceGroupDeviceCreateInfo
VkPhysicalDeviceVariablePointerFeaturesKHR = VkPhysicalDeviceVariablePointerFeatures
VkPhysicalDeviceMultiviewFeaturesKHR = VkPhysicalDeviceMultiviewFeatures
VkPhysicalDeviceMultiviewPropertiesKHR = VkPhysicalDeviceMultiviewProperties
VkPhysicalDevice16BitStorageFeaturesKHR = VkPhysicalDevice16BitStorageFeatures
VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR = VkPhysicalDeviceSamplerYcbcrConversionFeatures
VkPhysicalDeviceMaintenance3Properties missing

VkMemoryDedicatedRequirementsKHR =  VkMemoryDedicatedRequirements
VkMemoryDedicatedAllocateInfoKHR = VkMemoryDedicatedAllocateInfo
VkBindBufferMemoryInfoKHR = VkBindBufferMemoryInfo
VkBindImageMemoryInfoKHR = VkBindImageMemoryInfo
vkBindBufferMemory2KHR = vkBindBufferMemory2
vkBindImageMemory2KHR = vkBindImageMemory2

VkDescriptorUpdateTemplateKHR = VkDescriptorUpdateTemplate
VkDescriptorUpdateTemplateCreateFlags missing
VkDescriptorUpdateTemplateType missing
VkDescriptorUpdateTemplateEntryKHR = VkDescriptorUpdateTemplateEntry
VkDescriptorUpdateTemplateCreateInfoKHR = VkDescriptorUpdateTemplateCreateInfo
vkCreateDescriptorUpdateTemplateKHR = vkCreateDescriptorUpdateTemplate
vkDestroyDescriptorUpdateTemplateKHR = vkDestroyDescriptorUpdateTemplate
vkUpdateDescriptorSetWithTemplateKHR = vkUpdateDescriptorSetWithTemplate

Some API Wrappers are built-to-fail

I will be using vkGetPhysicalDeviceSurfaceSupportKHR as an example in this case as it causes the example code to fail on my machine.

When running the example code mentioned in the docs, I found that my device (a laptop with NV 1660Ti and Intel HD Graphics 630) had 3 available queue families. When running L174 of the example code on the 3rd queue family, the program fails with a key error for the array exception_codes in _vulkan.py. This is due to the wrappers in this file (such as the one mentioned above) all using a very limited list of exceptions that don't properly behave.

In my specific case, my machine returned exception code 228. The only mention I've heard of how this utility should be used is a discrepancy in a 2017 release of vulkan which notes that this utility is meant to be interpreted as True/False (I can only guess they mean VK_TRUE and VK_FALSE but I'm a beginner with reading gatekept knowledge so /shrug). Looking through that article it even seems to me that it may be possible that vkGetPhysicalDeviceSurfaceSupportKHR should be avoided and it argues that vkGetPhysicalDeviceSurfaceCapabilities2KHR should be used instead.

But I digress...

My main takeaway from this is that problems like this will arise very often when offering example code, and the example code in this document along with _vulkan.py may be due for an upgrade.

Let me know if more information is needed.

Supplementary info
Running the debugger on the 3 QueueFamily Objects
QueueFamily 1:
image

QueueFamily 2:
image

QueueFamily 3 (Failed):
image
I don't know why this one returns a result that causes the example code to fail. I just know what call causes it to fail and know that calling an arbitrary location in a short array of exceptions caused it to occur.

A better design for vkMapMemory function

I am looking at vulkan compute example. I think the vkMapMemory function can have better design for better performance.

Usually fill mapped memory data

data = vkMapMemory(device, memory, 0, memorySize, 0)
# fill data
mydata = ffi.new('int[]', [1, 2, 3, 4, 5])
ffi.memmove(data, mydata, memorySize)
vkUnmapMemory(device, memory)

Above is OK. But if you want to fetch the data from GPU buffer

data = vkMapMemory(device, memory, 0, memorySize, 0)

# amusing int array data
# you need to loop through the array to get the data
mydata = [ffi.addressof(data, i)[0] for i in range(int(memorySize/4))]

vkUnmapMemory(device, memory)

array.array work with cffi example

import array
import cffi

ffi = cffi.FFI()

a = array.array('I', [1, 2, 3, 4, 5])
pa = ffi.cast('uint32_t *', a.buffer_info()[0])
print(pa, pa[0])
pa[0] = 7
print(a)
print(pa, pa[0])

a[0] = 10
print(a)
print(pa, pa[0])
print(ffi.addressof(pa, 1), ffi.addressof(pa, 1)[0])

<cdata 'uint32_t *' 0x000002A454682420> 1
array('I', [7, 2, 3, 4, 5])
<cdata 'uint32_t *' 0x000002A454682420> 7
array('I', [10, 2, 3, 4, 5])
<cdata 'uint32_t *' 0x000002A454682420> 10
<cdata 'uint32_t *' 0x000002A454682424> 2

So how about we can do something like this with vkMapMemory

bufferLength = 16384
bufferSize = 4 * bufferLength
memorySize = bufferSize * 2
msize = int(memorySize / 4)

# data array
da = array.array('I', [0] * msize)
# pointer of the array
pda = ffi.cast('uint32_t *', da.buffer_info()[0])
# pointer of the array pointer
ppda = ffi.cast('void**', pda)
vkMapMemory(device, memory, 0, memorySize, 0, ppda)
# fill data
for i in range(len(da)):
    da[i] = random.randint(1, 100000)

vkUnmapMemory(device, memory)

##################################################
# do compute stuff
##################################################

# fetch data

vkMapMemory(device, memory, 0, memorySize, 0, ppda)
# no for loop
print(da)

vkUnmapMemory(device, memory)

example program fails with various validation errors

Thank you for creating the Python Vulkan Bindings.

I am just now trying to become more familiar with Vulkan on Python. For some reason I am having an issue running the example.

I installed SDL2 and PYSDL2 on my computer and placed the binary in my venv's site-packages directory, prepending the following line above import sdl2:

os.environ["PYSDL2_DLL_PATH"] = "C:\\Users\\TGubs\\Code\\Python\\vulkan_py_playground\\venv\\Lib\\site-packages"

I then tried running the example using the latest SDL2.dll I could find and the most recent Windows build of Vulkan. Here are my results:

(venv) PS C:\Users\TGubs\Code\Python\vulkan_py_playground> python vulkan/example/example_sdl2.py
availables extensions: ['VK_KHR_device_group_creation', 'VK_KHR_external_fence_capabilities', 'VK_KHR_external_memory_capabilities', 'VK_KHR_external_semaphore_capabilities', 'VK_KHR_get_physical_device_properties2', 'VK_KHR_get_surface_capabilities2', 'VK_KHR_surface', 'VK_KHR_surface_protected_capabilities', 'VK_KHR_win32_surface', 'VK_EXT_debug_report', 'VK_EXT_debug_utils', 'VK_EXT_swapchain_colorspace', 'VK_NV_external_memory_capabilities']

availables layers: ['VK_LAYER_NV_optimus', 'VK_LAYER_NV_nsight', 'VK_LAYER_VALVE_steam_overlay', 'VK_LAYER_VALVE_steam_fossilize', 'VK_LAYER_LUNARG_api_dump', 'VK_LAYER_LUNARG_assistant_layer', 'VK_LAYER_LUNARG_core_validation', 'VK_LAYER_LUNARG_device_simulation', 'VK_LAYER_KHRONOS_validation', 'VK_LAYER_LUNARG_monitor', 'VK_LAYER_LUNARG_object_tracker', 'VK_LAYER_LUNARG_screenshot', 'VK_LAYER_LUNARG_standard_validation', 'VK_LAYER_LUNARG_parameter_validation', 'VK_LAYER_GOOGLE_threading', 'VK_LAYER_GOOGLE_unique_objects', 'VK_LAYER_LUNARG_vktrace']

Create windows surface
availables devices: ['GeForce GTX 1080 Ti']
selected device: GeForce GTX 1080 Ti

3 available queue family
DEBUG: Validation  [ VUID-vkGetPhysicalDeviceSurfaceSupportKHR-surface-parameter ] Object: 0x7d4bd4000000002 (Type = 26) | Invalid VkSurfaceKHR Object 0x7d4bd4000000002. The Vulkan spec states: surface must be a valid VkSurfaceKHR handle (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkGetPhysicalDeviceSurfaceSupportKHR-surface-parameter)
DEBUG: Validation  [ UNASSIGNED-Threading-Info ] Object: 0x7d4bd4000000002 (Type = 0) | Couldn't find VkNonDispatchableHandle Object 0x7d4bd4000000002. This should not happen and may indicate a bug in the application.

I am on Windows10, Python 3.7-32. Wondering if there is something wrong with my configuration.

Thanks in advance!

VkPipeline array type incorrect (compute example fails)

(First - thanks for the cool package!).

Running the compute example fails with the trace below. I tried various fixes like ffi.new("VkPipeline*") etc but didn't find a way to fix it. I get the same behavior on linux and mac installations using either the pip package or installation from source.

It looks like this is related to #56.

$python example_mandelbrot_compute.py 
Traceback (most recent call last):
  File "example_mandelbrot_compute.py", line 562, in <module>
    app.run()
  File "example_mandelbrot_compute.py", line 134, in run
    self.createCommandBuffer()
  File "example_mandelbrot_compute.py", line 517, in createCommandBuffer
    vkCmdBindPipeline(self.__commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, self.__pipeline)
  File "/usr/local/lib/python2.7/dist-packages/vulkan-1.1.99.1-py2.7.egg/vulkan/_vulkan.py", line 6340, in vkCmdBindPipeline
    result = _callApi(lib.vkCmdBindPipeline, commandBuffer,pipelineBindPoint,pipeline)
  File "/usr/local/lib/python2.7/dist-packages/vulkan-1.1.99.1-py2.7.egg/vulkan/_vulkan.py", line 4962, in _callApi
    return fn(*fn_args)
TypeError: initializer for ctype 'struct VkPipeline_T *' must be a pointer to same type, not cdata 'struct VkPipeline_T *[1]'
Exception TypeError: "'NoneType' object is not callable" in <bound method ComputeApplication.__del__ of <__main__.ComputeApplication object at 0x7fa3387d3810>> ignored

Cython/C bindings

In a nutshell, something similar to the numpy <-> cython bridge, which allows you to "cimport" numpy, giving you typed and direct access to numpy.

In this module, this would mean there is a cython api, through which you work directly with the C structures and types (therefore no conversion between C and python - which is, and probably will always be, the slowest part of this module).

I don't know enough about cython to even know how feasible it is to achieve this, or how much work it is.

I can just say, that in my project I am using cython (gil-less) threads to use multiple CPU cores to then feed data into vulkan, the bottleneck in my case is the conversion from cython/c to python back to c structures.

I know that it is possible to bind to vulkan directly from cython, but then you don't get this modules error checking.

unable to install

Both pip and manual install gives me this error.

`WARNING: The wheel package is not available.
WARNING: The wheel package is not available.
ERROR: Command errored out with exit status 1:
command: 'D:\Nikola\Python\Projects\10RealWorldApps\venv\Scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Okuma_10\AppData\Local\Temp\pip-wheel-tekhmmz1\pycparser\setup.py'"'"'; file='"'"'C:\Users\Okuma_10\AppD
ata\Local\Temp\pip-wheel-tekhmmz1\pycparser\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\Okuma_10\AppData\Lo
cal\Temp\pip-wheel-fasnoyy2'
cwd: C:\Users\Okuma_10\AppData\Local\Temp\pip-wheel-tekhmmz1\pycparser
Complete output (6 lines):
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: setup.py --help [cmd1 cmd2 ...]
or: setup.py --help-commands
or: setup.py cmd --help

error: invalid command 'bdist_wheel'

ERROR: Failed building wheel for pycparser
ERROR: Failed to build one or more wheels
Traceback (most recent call last):
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\setuptools\installer.py", line 128, in fetch_build_egg
subprocess.check_call(cmd)
File "C:\Users\Okuma_10\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 347, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['D:\Nikola\Python\Projects\10RealWorldApps\venv\Scripts\python.exe', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', 'C:\Users\Okuma_10\AppData\Local\Temp\tmpeus9tyww', '--quiet', 'pycparser
']' returned non-zero exit status 1.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "setup.py", line 28, in
cffi_modules=["vulkan/vulkan_build.py:ffi"]
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\setuptools_init_.py", line 144, in setup
install_setup_requires(attrs)
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\setuptools_init
.py", line 139, in install_setup_requires
dist.fetch_build_eggs(dist.setup_requires)
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\setuptools\dist.py", line 721, in fetch_build_eggs
replace_conflicting=True,
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\pkg_resources_init
.py", line 782, in resolve
replace_conflicting=replace_conflicting
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\pkg_resources_init_.py", line 1065, in best_match
return self.obtain(req, installer)
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\pkg_resources_init_.py", line 1077, in obtain
return installer(requirement)
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\setuptools\dist.py", line 777, in fetch_build_egg
return fetch_build_egg(self, req)
File "D:\Nikola\Python\Projects\10RealWorldApps\venv\lib\site-packages\setuptools\installer.py", line 130, in fetch_build_egg
raise DistutilsError(str(e))
distutils.errors.DistutilsError: Command '['D:\Nikola\Python\Projects\10RealWorldApps\venv\Scripts\python.exe', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', 'C:\Users\Okuma_10\AppData\Local\Temp\tmpeus9tyww', '--quiet', 'pycpars
er']' returned non-zero exit status 1.
`

Auto-fill sType

The sType has a default value. In the C/C++ version of vulkan, there is no such thing as a default structure value, so it has to be filled in manually. Since this wrapper uses keyword arguments anyway, it should be reasonable to make the default sType the default value for the sType kwarg, instead of None. Should, for some reason an overwrite or explicit sType be wished, this would still be possible as a keyword argument's default can easily be overwritten.

No module named 'vulkan._vulkancache'

love the fact it's pretty much standalone, but there's an issue upon extraction.
image
I'm using x86 Windows Anaconda on Wine (Linux) for testing
CWD is Z:\home\tcll\Downloads\vulkan-1.1.71.2\

How would one create a Vertex Buffer (vulkan memory management)?

Hello, I'm trying to extend the vulkan example using this tutorial and the VULK engine as a guide. It was all and good until I've hit a memcpy. I tryied to gain some insight looking at vulk/vulkanobject.py, line 787, but I can't make heads of tail of it. This is the specific block of code that contains the memcpy:

void* data;
vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
memcpy(data, vertices.data(), (size_t) bufferInfo.size);
vkUnmapMemory(device, vertexBufferMemory);

How does one manage memory with vulkan?

Thank you :)

Debug Callback does not work.

Or at least it doesn't for me.

If we take the Vulkan Tutorial:
https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Validation_layers#page_Message_callback

Then not removing the debug callback before destroying the instance should yield a debug output.

So we change the almost last line in the vulkan example to
#vkDestroyDebugReportCallbackEXT(instance, callback, None)
So that we intentionally trip this debug message.

What I found is, that no debug message appears.

I've started investigating this as I noticed the debug callback function never executes in my own project, which makes debugging harder than it should be.

Should it matter, this is win10 64bit on amd graphics, with as of now recent drivers.

extensions functions call bugs

vkGetPhysicalDeviceFeatures2 call is missing sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2

def _wrap_vkGetPhysicalDeviceFeatures2(fn):
    def vkGetPhysicalDeviceFeatures2(physicalDevice
            ,):

        pFeatures = ffi.new('VkPhysicalDeviceFeatures2*')
        #pFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2

        result = _callApi(fn, physicalDevice,pFeatures)

        return pFeatures[0]

Here is another C\C++ usage code which not able to do

    VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptorIndexing = { };
    descriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;

    VkPhysicalDeviceFeatures2 features2 = { };
    features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;

    auto found = std::find(_deviceExtensions.begin(), _deviceExtensions.end(), VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
    if (found != _deviceExtensions.end())
        features2.pNext = &descriptorIndexing;

    vkGetPhysicalDeviceFeatures2( _physicalDevice, &features2 );

vkGetPhysicalDeviceProperties2 is the same not able to assign other structs to pNext

def _wrap_vkGetPhysicalDeviceProperties2(fn):
    def vkGetPhysicalDeviceProperties2(physicalDevice
            ,pNext=ffi.NULL):

        pProperties = ffi.new('VkPhysicalDeviceProperties2*')
        #pProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2
        #if pNext != ffi.NULL:
            #pProperties.pNext = ffi.addressof(pNext)

        result = _callApi(fn, physicalDevice,pProperties)

        return pProperties[0]

    return vkGetPhysicalDeviceProperties2

Example of usage

# VkPhysicalDeviceRayTracingPropertiesNV should be able to pass to VkPhysicalDeviceProperties2.pNext
self._rayTracingProperties = VkPhysicalDeviceRayTracingPropertiesNV(
            maxRecursionDepth=0,
            shaderGroupHandleSize=0
        )
props = vkGetPhysicalDeviceProperties2KHR(self._physicalDevice, self._rayTracingProperties)

I'm working on the VKRay examples and found out above issues. There could be more bugs. Right now I change the code(comment out on above) to pass those bugs.

"Invalid SurfaceKHR object" when running example

When trying to run the example, it crashes and I have to forcefully close it. I tried pulling and installing the library from the most recent master branch, but this didn't fix the issue.

availables extensions: ['VK_KHR_surface', 'VK_KHR_win32_surface', 'VK_EXT_debug_report', 'VK_NV_external_memory_capabilities', 'VK_KHR_get_physical_device_properties2', 'VK_KHX_device_group_creation', 'VK_EXT_display_surface_counter']

availables layers: ['VK_LAYER_LUNARG_api_dump', 'VK_LAYER_LUNARG_core_validation', 'VK_LAYER_LUNARG_monitor', 'VK_LAYER_LUNARG_object_tracker', 'VK_LAYER_LUNARG_parameter_validation', 'VK_LAYER_LUNARG_screenshot', 'VK_LAYER_LUNARG_standard_validation', 'VK_LAYER_GOOGLE_threading', 'VK_LAYER_GOOGLE_unique_objects', 'VK_LAYER_LUNARG_vktrace', 'VK_LAYER_NV_optimus', 'VK_LAYER_VALVE_steam_overlay', 'VK_LAYER_RENDERDOC_Capture']

Create windows surface
availables devices: ['GeForce GTX 960M']
selected device: GeForce GTX 960M

2 available queue family
DEBUG: ObjectTracker Invalid SurfaceKHR Object 0x3ffaba800000001. The spec valid usage text states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetPhysicalDeviceSurfaceSupportKHR-surface-parameter)

example_sdl2.py has unstable FPS because it lacks completion fence/semaphores

This is probably related to Bug #55

In my instance, vkAcquireNextImageKHR burns through a handful of buffers at max speed, and then settles down to 60Hz (1 buffer every 16.6666666 ms). I suspect that this would put a 10-15 frame latency in things I do if this were an active application rather than an example.

I'm on Windows 10, a Microsoft Surface Pro, with Intel UHD Graphics 620 via the external Surface dock to an LG 32UD99-W monitor via mini-Displayport and Vulkan SDK 1.1.114.0

The synchronization primitives used in the example don't seem to be sufficient to get stable and repeatable results on hardware.

I also did a grubby port to glfw to see if there was an SDL issue, GLFW exhibits the same behavior.

Thanks.

main.py.zip

example.py: queueFamilyIndices appears undefined (line 283) and typo in line 281

In examply.py line, it writes
281 imageSharingMode = VK_SHARING_MODE_CONCURREN
283 pQueueFamilyIndices = queueFamilyIndices

Issues:

  1. There is a typo in 281, letter 'T" is missing: it should be VK_SHARING_MODE_CONCURRENT
  2. The term queueFamilyIndices appears to be undefined. I believe queueFamilyIndices = {queue_family_graphic_index, queue_family_present_index} should either appear in line 279 or 183.

Why can't create xcb surface?

@realitix I noticed an issue with creating a xcb surface. My function to create such a surface is given below. However, vkGetInstanceProcAddr gives a ProcedureNotFoundError.

I can create a xlib surface. Also, previously I had tested the same code to make a xcb surface a year ago and that worked. Can you point me the cause of the issue as I can't figure it out? I have checked for the presence of vkCreateXcbSurfaceKHR in _vulkan.py and vulkan.cdef.h and found it mentioned there. The libx11 packages on my system are shown below too. So what gives?

    def setSurface(self):

        info = self.window.info.info
        
        def create_surface(name, surface_createInfo):
            f = vkGetInstanceProcAddr(self.instance, name)
            return f(self.instance, surface_createInfo, None)
        
        def _surface_xlib():
            surface_createInfo = VkXlibSurfaceCreateInfoKHR(
                sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
                flags = 0,
                dpy    = info.x11.display,
                window = info.x11.window)
            return create_surface('vkCreateXlibSurfaceKHR', surface_createInfo)

        def _surface_xcb():
            surface_createInfo = VkXcbSurfaceCreateInfoKHR(
                sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
                flags = 0,
                connection = info.x11.display,
                window     = info.x11.window)
            return create_surface('vkCreateXcbSurfaceKHR', surface_createInfo)

        surface_mapping = { 'VK_KHR_xlib_surface': _surface_xlib,
                            'VK_KHR_xcb_surface': _surface_xcb,
                            }

        err = '- fail to create Vulkan Surface: '
        try:
            self.surface = surface_mapping[self.window.vulkan_surface_ext]()
        except VkError:
            logging.error(err)
            self.cleanup()

  File "~/Vulkan/MyProject/triangle_example/triangle11.py", line 160, in surface_xlib
    vkCreateXlibSurfaceKHR = vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR")
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 6856, in vkGetInstanceProcAddr
    raise ProcedureNotFoundError()
vulkan._vulkan.ProcedureNotFoundError
$ dpkg -l | grep libx11
ii  libx11-6:amd64                              2:1.6.3-1ubuntu2                                 amd64        X11 client-side library
ii  libx11-data                                 2:1.6.3-1ubuntu2                                 all          X11 client-side library
ii  libx11-dev:amd64                            2:1.6.3-1ubuntu2                                 amd64        X11 client-side library (development headers)
ii  libx11-doc                                  2:1.6.3-1ubuntu2                                 all          X11 client-side library (development documentation)
ii  libx11-protocol-perl                        0.56-7                                           all          Perl module for the X Window System Protocol, version 11
ii  libx11-xcb-dev:amd64                        2:1.6.3-1ubuntu2                                 amd64        Xlib/XCB interface library (development headers)
ii  libx11-xcb1:amd64                           2:1.6.3-1ubuntu2                                 amd64        Xlib/XCB interface library

Queue enumeration code incorrect in example

The code as it was defined will get different values for queue_family_graphic_index and queue_family_present_index. Which I think is not valid.

To get the example to work I had to replace that code with this (based on pyVulcan example code)

support_presents = [-1] * len(queue_families)

for i, queue_family in enumerate(queue_families):
    support_presents[i] = vkGetPhysicalDeviceSurfaceSupportKHR(
        physicalDevice=physical_device,
        queueFamilyIndex=i,
        surface=surface)
    if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT):
        queue_family_graphic_index = i
    if queue_family.queueCount > 0 and support_presents[i]:
        queue_family_graphic_index = i
        queue_family_present_index = i
        break

if queue_family_present_index==-1:
    for i, v in enumerate(support_presents):
        if v == VK_TRUE:
            queue_family_present_index = i

Reducing Vulkan API call overhead

hi realitix,

Just read this blog few days ago.

Reducing Vulkan API call overhead

That's very similar this extension binding from cffi doing. The difference is that article was loading all API with vkGetInstanceProcAddr and vkGetDeviceProcAddr. In this extension only extension api were loading with those two function.
So I'm very curious will it fast if you doing like the article way?
I did a very simple test. Duplicate the installed vulkan to vk and make some change to the _vulkan.py in vk.

def vkCreateInstance(pCreateInfo
        ,pAllocator
        ,):

    pName = 'vkCreateInstance'
    fn = _callApi(lib.vkGetInstanceProcAddr, ffi.NULL, pName)
    fn = ffi.cast('PFN_' + pName, fn)
    pInstance = ffi.new('VkInstance*')

    result = _callApi(fn, pCreateInfo,pAllocator,pInstance)
    if result != VK_SUCCESS:
        raise exception_codes[result]

    return pInstance[0]



def vkDestroyInstance(instance
        ,pAllocator
        ,):
    pName = 'vkDestroyInstance'
    fn = _callApi(lib.vkGetInstanceProcAddr, instance, pName)
    fn = ffi.cast('PFN_' + pName, fn)
    result = _callApi(fn, instance,pAllocator)

and run a simple test

import timeit

test2 = '''
appInfo = vk.VkApplicationInfo(
            sType=vk.VK_STRUCTURE_TYPE_APPLICATION_INFO,
            pApplicationName='Hello Triangle',
            applicationVersion=vk.VK_MAKE_VERSION(1, 0, 0),
            pEngineName='No Engine',
            engineVersion=vk.VK_MAKE_VERSION(1, 0, 0),
            apiVersion=vk.VK_MAKE_VERSION(1, 0, 3)
)

createInfo = vk.VkInstanceCreateInfo(
                sType=vk.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
                pApplicationInfo=appInfo,
                enabledExtensionCount=0,
                enabledLayerCount=0
)

instance = vk.vkCreateInstance(createInfo, None)

vk.vkDestroyInstance(instance, None)
'''

print(timeit.timeit(test2, setup='import vulkan as vk', number=1000))
print(timeit.timeit(test2, setup='import vk', number=1000))

# 9.073086824310769
# 8.990983812290121

That seems a bit fast.

Count arguments of vulkan structures are not necessary

extracted from a discussion from here: #34 (comment)

calling len() on the passed arguments to a vulkan function can be handled by this module internally, making passing a Count optional.

Original post follows:

Hm. By the same token though, should it not also work this way the other way around then?
You know, for consistency.
So in this example:

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

enabledLayerCount and enabledExtensionCount should then be automatic - or optional?

vkQueuePresentKHR returned None

Hi realitix,
Is the function vkQueuePresentKHR suppose to return None or VkResult? I was expecting the latter.

I am attempting the resizeable window tutorial of Vulkan Tutorial. I noticed that vkQueuePresentKHR returns None.

        result = self.fnp['vkQueuePresentKHR'](self.present_queue, presentInfo)
        print('result = ',result)
 
        if result == VK_ERROR_OUT_OF_DATE_KHR or result == VK_SUBOPTIMAL_KHR:
            logging.error("Needs to recreate swapchain.!")
            self._recreateSwapChain()
        elif result != VK_SUCCESS:
            logging.error("Failed to present swapchain image!")

        vkQueueWaitIdle(self.present_queue)

Output:

result =  None
2017-10-18 16:21:19,156 vulkanbase_v3_recreateSwapChain._drawFrame                     +1625 : ERROR    Failed to present swapchain image!

Support for MoltenVK (MacOs)?

Does this currently support MoltenVK? I've added the components to my path and can run vulkaninfo but cannot get the example to run.

raise OSError('Cannot find Vulkan SDK version. Please ensure that it is '
OSError: Cannot find Vulkan SDK version. Please ensure that it is installed and that the <sdk_root>/<version>/lib/ folder is in the library path

When I run vulkaninfo from the command line.

===========
VULKAN INFO
===========

Vulkan API Version: 1.0.69



Instance Extensions:
====================
Instance Extensions	count = 3
	VK_KHR_surface                      : extension revision 25
	VK_MVK_macos_surface                : extension revision  2
	VK_EXT_debug_report                 : extension revision  9
Layers: count = 0
=======
Presentable Surfaces:
=====================
None found

Question about _wrap functions

I see that certain functions are only defined with a _wrap prefix, such as vkGetPhysicalDeviceSurfaceSupportKHR. It looks like such functions require a call to vkGetInstanceProcAddr or vkGetDeviceProcAddr in order to get a function pointer.

I'm wondering why certain functions are defined with _wrap and others aren't.

Thanks.

"Random" Value changes.

So, not sure where the problem comes from but basically I tried to move the example to a bit more of an object oriented style and something broke, that the validation layers and other debugs are not catching.

When I run my example version, you end up with results like these:
https://i.imgur.com/vfqQriT.png
https://i.imgur.com/413Ij60.png
https://i.imgur.com/Y6Yx1yR.png

So seemingly random different errors and visual bugs.
Now I've looked at some of the variables, such as the "extent" structure changing the internal variables during initialization and creating invalid images or framebuffer etc. So I believe some pointer is pointing wrong and the wrong data is changed - somewhere. Also, when I run this, almost always at the end do I get
"DEBUG: ObjectTracker Unable to remove SwapchainKHR obj 0x2. Was it created? Has it already been destroyed?"
And python.exe has stopped working. The interesting bit, is that the python crash only occurs when I include the SDL2 stuff, might be related.

So, if someone is up for trying to find the problem, I put it into this dropbox folder:
https://www.dropbox.com/sh/kra2lyi5qefdjwh/AABnGvmNFjs3voatE33w_Y84a?dl=0

vkEnumerateInstanceVersion is not available.

Hi realitix. I think we need the vkEnumerateInstanceVersion function in _vulkan.py for Vulkan versions 1.1.70.0 and upwards.

According to Spec, this function is obtained using

vkGetInstanceProcAddr( instance=Null, pName=vkEnumerateInstanceVersion )

After reading _vulkan.py, I noticed that vkEnumerateInstanceExtensionProperties, vkEnumerateInstanceLayerProperties and vkCreateInstance were explicitly declared python functions. Meaning functions provided by vkGetInstanceProcAddr when instance=Null are to be explicitly declared python functions. Thus _vulkan.py should have vkEnumerateInstanceVersion as an explicitly declared python function.

I did try something like:

vkEnumerateInstanceVersion = vkGetInstanceProcAddr(None, vkEnumerateInstanceVersion)

but got

UnboundLocalError: local variable 'vkEnumerateInstanceVersion' referenced before assignment

Suggestion. Will the following function be appropriate for _vulkan.py?

def vkEnumerateInstanceVersion(pApiVersion):
   ''Supply pApiVersion in str format, e.g. `1.1.77.0` '''

    pApiVersion = pApiVersion.split('.')
    major = int(pApiVersion[0])
    minor = int(pApiVersion[1])
    patch = int(pApiVersion[2])
    pApiVersion = VK_MAKE_VERSION(major, minor, patch)

    result = _callApi(lib.vkEnumerateInstanceVersion, pApiVersion)
    if result != VK_SUCCESS:
        raise exception_codes[result]

    return result

Debug Utils Messenger error

when enabling VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT in VkDebugUtilsMessengerCreateInfoEXT

I get an error to the console. The message still prints but I get this as well:

TypeError: an integer is required
From cffi callback <function _external_vkDebugUtilsMessengerCallbackEXT at 0x000002391337DB88>:
Trying to convert the result back to C:
TypeError: an integer is required

I tried with no printing in the debug function, just a pass and with no message I still get the error.
Removing the flag removes the error.

Why 1 item and not 2 items is returned by vkGetPhysicalDeviceSurfacePresentModesKHR?

Hi realitix,

I noticed that for function vkGetPhysicalDeviceSurfacePresentModesKHR, it only returns the presentModes. I was expecting it to return both presentModes and presentModeCount as defined in Spec. Is is possible to return 2 items instead of one item so it follows Vulkan?

I did noticed in line 4463, you defined pPresentModes = ffi.new('VkPresentModeKHR[]', pPresentModeCount[0]) . Did you make pPresentModes a tuple or generator containing the presentMode and the presentModeCount? Pardon me I don't understand ffi.

At the moment, I am using a loop to expose the presentMode and len to expose presentModeCount.

    self.surface_presentModes = self.fnp['vkGetPhysicalDeviceSurfacePresentModesKHR'](
        physicalDevice=self.physical_device, surface=self.surface)
    print('self.surface_presentModes = ', self.surface_presentModes)
    print('len(self.surface_presentModes) = ', len(self.surface_presentModes))
    for mode in self.surface_presentModes:
        print('- available_surface_present_mode = {}'.format(mode) )

Output:

self.surface_presentModes =  <cdata 'enum VkPresentModeKHR[]' owning 12 bytes>
len(self.surface_presentModes) =  3
- available_surface_present_mode = 2
- available_surface_present_mode = 3
- available_surface_present_mode = 0

Appreciate your explanation.

PFN_vkCreateWin32SurfaceKHR not defined error on windows

I get the following error running the example on Windows. It looks like the function vkCreateWin32SurfaceKHR is defined in the DLL but the type 'PFN_vkCreateWin32SurfaceKHR is not.


Create windows surface
Traceback (most recent call last):
  File "example.py", line 145, in <module>
    surface = surface_mapping[wm_info.subsystem]()
  File "example.py", line 132, in surface_win32
    vkCreateWin32SurfaceKHR = vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR")
  File "E:\Python\Python35\lib\site-packages\vulkan\__init__.py", line 5234, in vkGetInstanceProcAddr
    fn = ffi.cast('PFN_' + pName, fn)
ffi.error: undefined type name
PFN_vkCreateWin32SurfaceKHR

VkWin32SurfaceCreateInfoKHR not defined in Windows Vulkan DLL

The structure VkWin32SurfaceCreateInfoKHR is not defined in the Windows DLL (Nvidia drivers Windows 8.1).

The result is this error in the example code:

Create windows surface
Traceback (most recent call last):
  File "example.py", line 145, in <module>
    surface = surface_mapping[wm_info.subsystem]()
  File "example.py", line 137, in surface_win32
    flags=0)
  File "E:\Python\Python35\lib\site-packages\vulkan-1.0.48-py3.5.egg\vulkan\__init__.py", line 2113, in VkWin32SurfaceCreateInfoKHR
    return _new('VkWin32SurfaceCreateInfoKHR', sType=sType,pNext=pNext,flags=flags,hinstance=hinstance,hwnd=hwnd)
  File "E:\Python\Python35\lib\site-packages\vulkan-1.0.48-py3.5.egg\vulkan\__init__.py", line 1831, in _new
    _type = ffi.typeof(ctype)
ffi.error: undefined type name
VkWin32SurfaceCreateInfoKHR
^

Vulkan Memory Allocator

There is a library for vulkan memory allocation management by GPU-Open
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
I keep seeing it recommended in various documentation and tutorials.
It feels like a nice fit for a python-vulkan module as it gives the option for simpler memory management, something that people using Python generally opted out of.

If possible, including this library or offering an optional extension would be fantastic (that is just my opinion, of course.)

typo in example.py line 132, 133

I believe there is a typo in example.py line 132 & 133.
For Win32 window, it say:

sType=VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
hinstance=get_instance(wm_info.info.win.window),

Instead, I think It should be:

sType=VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
hinstance=get_instance(wm_info.info.win.hinstance),

What is the correct `commandBuffer` parameter for `vkBeginCommandBuffer`?

Hi realitx, I got a Python TypeError at vkBeginCommandBuffer when trying to copy a staging buffer to a vertex buffer.

 allocInfo =  <cdata 'struct VkCommandBufferAllocateInfo' owning 32 bytes>
self.commandBuffer_transfer =  <cdata 'struct VkCommandBuffer_T *[1]' owning 8 bytes>

Traceback (most recent call last):
  File "~/6_staging_buffer/application_v6_staging_buffer.py", line 227, in <module>
    main()
  File "~/6_staging_buffer/application_v6_staging_buffer.py", line 209, in main
    vulkanbase = initVulkan(window, debug=debug, vertices=vertices)
  File "~/6_staging_buffer/application_v6_staging_buffer.py", line 35, in initVulkan
    return vulkanbase.Setup(window, debug, vertices)
  File "~/6_staging_buffer/vulkanbase_v6_staging_buffer.py", line 214, in __init__
    self.createVertexBuffer()  #New
  File "~/6_staging_buffer/vulkanbase_v6_staging_buffer.py", line 1665, in createVertexBuffer
    self.copyBuffer(self.stagingBuffer, self.vertexBuffer, buffersize)
  File "~/6_staging_buffer/vulkanbase_v6_staging_buffer.py", line 1695, in copyBuffer
    vkBeginCommandBuffer(self.commandBuffer_transfer, beginInfo)
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 4572, in vkBeginCommandBuffer
    result = _callApi(lib.vkBeginCommandBuffer, commandBuffer,pBeginInfo)
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 3573, in _callApi
    return fn(*fn_args)
TypeError: initializer for ctype 'struct VkCommandBuffer_T *' must be a pointer to same type, not cdata 'struct VkCommandBuffer_T *[1]'

It seems that the commandBuffer parameter I had passed to vkBeginCommandBuffer is the wrong type. I don't know why this is the case. The 'vkBeginCommandBuffer' occurred in my copyBuffer method is given below.

    def copyBuffer(self, srcBuffer, dstBuffer, size):
        logging.info('')
        logging.info('  -- Copy Buffer to Another Buffer:')
        allocInfo = VkCommandBufferAllocateInfo(
            level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
            commandPool = self.command_pool_transfer,
            #commandPool = self.command_pool,
            commandBufferCount = 1,)
        logging.info('    - set allocInfo.')
        print('allocInfo = ', allocInfo)
        self.commandBuffer_transfer = vkAllocateCommandBuffers(
            self.logical_device, allocInfo)
        logging.info('    - created commandBuffer_transfer.')
        print('self.commandBuffer_transfer = ', self.commandBuffer_transfer)

        beginInfo = VkCommandBufferBeginInfo(
            flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)
        logging.info('    - set CommandBufferBeginInfo.')
        

        vkBeginCommandBuffer(self.commandBuffer_transfer, beginInfo)
        logging.info('    - vkBeginCommandBuffer.')
        copyRegion = [ VkBufferCopy( srcOffset = 0,
                                     dstOffest = 0,
                                     size = size) ]
        logging.info('    - copyRegion.')
        vkCmdCopyBuffer( self.commandBuffer_transfer, srcBuffer, dstBuffer,
                         len(copyRegion), copyRegion )
        logging.info('    - vkCmdCopyBuffer.')
        vkEndCommandBuffer(self.commandBuffer_transfer)
        logging.info('    - vkEndCommandBuffer.')


        submitInfo = VkSubmitInfo(
            commandBufferCount = 1,
            pCommandBuffers = self.commandBuffer_transfer )
        logging.info('    - set submitInfo.')

        vkQueueSubmit( self.transfer_queue, 1, submitInfo, VK_NULL_HANDLE)
        logging.info('    - vkQueueSubmit.')
        vkQueueWaitIdle( self.transfer_queue )

        vkFreeCommandBuffers( self.logical_device, self.commandPool_transfer, 1,
                              self.commandBuffer_transfer )
        logging.info('    - free Transfer vkQueueSubmit.')

Referring to Vulk, I noticed you put self.commandBuffer_transfer into a list. So I made the following changes:

        vkBeginCommandBuffer([self.commandBuffer_transfer], beginInfo)

However, I now get a Python ValueError:

  File "~/6_staging_buffer/vulkanbase_v6_staging_buffer.py", line 1697, in copyBuffer
    vkBeginCommandBuffer([self.commandBuffer_transfer], beginInfo)
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 4572, in vkBeginCommandBuffer
    result = _callApi(lib.vkBeginCommandBuffer, commandBuffer,pBeginInfo)
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 3572, in _callApi
    fn_args = [_auto_handle(i, j) for i, j in zip(args, ffi.typeof(fn).args)]
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 3572, in <listcomp>
    fn_args = [_auto_handle(i, j) for i, j in zip(args, ffi.typeof(fn).args)]
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 3566, in _auto_handle
    ptr, _ = _cast_ptr(x, _type)
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 90, in _cast_ptr3
    return _cast_ptr2(x, _type)
  File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 80, in _cast_ptr2
    ret = ffi.new(_type.item.cname+'[]', x)
ValueError: array item of unknown size: 'struct VkCommandBuffer_T' 

Can you advice me what i am doing wrong and what is the correct way to write this part? Thanks.

Example program freezes my PC when interacting with something

I am on Linux (Distro: POP!_OS 20.04) with official Nvidia Drivers (440.100) on a GTX 1050

If i click on the window or something behind the window or anything then my pc freezes and it takes a few seconds to be able to interact again.

Here is the whole console.

~/.development/vulkan$ python3 example/example_sdl2.py 
availables extensions: ['VK_KHR_device_group_creation', 'VK_KHR_external_fence_capabilities', 'VK_KHR_external_memory_capabilities', 'VK_KHR_external_semaphore_capabilities', 'VK_KHR_get_display_properties2', 'VK_KHR_get_physical_device_properties2', 'VK_KHR_get_surface_capabilities2', 'VK_KHR_surface', 'VK_KHR_surface_protected_capabilities', 'VK_KHR_wayland_surface', 'VK_KHR_xcb_surface', 'VK_KHR_xlib_surface', 'VK_KHR_display', 'VK_EXT_direct_mode_display', 'VK_EXT_acquire_xlib_display', 'VK_EXT_display_surface_counter', 'VK_EXT_debug_report', 'VK_EXT_debug_utils']

availables layers: ['VK_LAYER_VALVE_steam_overlay_32', 'VK_LAYER_VALVE_steam_fossilize_64', 'VK_LAYER_VALVE_steam_fossilize_32', 'VK_LAYER_VALVE_steam_overlay_64', 'VK_LAYER_MESA_overlay', 'VK_LAYER_LUNARG_standard_validation']

Create Xlib surface
availables devices: ['GeForce GTX 1050', 'Intel(R) UHD Graphics 630 (CFL GT2)']
selected device: GeForce GTX 1050

3 available queue family
indice of selected queue families, graphic: 0, presentation: 0

availables device extensions: ['VK_KHR_8bit_storage', 'VK_KHR_16bit_storage', 'VK_KHR_bind_memory2', 'VK_KHR_create_renderpass2', 'VK_KHR_dedicated_allocation', 'VK_KHR_depth_stencil_resolve', 'VK_KHR_descriptor_update_template', 'VK_KHR_device_group', 'VK_KHR_draw_indirect_count', 'VK_KHR_driver_properties', 'VK_KHR_external_fence', 'VK_KHR_external_fence_fd', 'VK_KHR_external_memory', 'VK_KHR_external_memory_fd', 'VK_KHR_external_semaphore', 'VK_KHR_external_semaphore_fd', 'VK_KHR_get_memory_requirements2', 'VK_KHR_image_format_list', 'VK_KHR_imageless_framebuffer', 'VK_KHR_maintenance1', 'VK_KHR_maintenance2', 'VK_KHR_maintenance3', 'VK_KHR_multiview', 'VK_KHR_pipeline_executable_properties', 'VK_KHR_push_descriptor', 'VK_KHR_relaxed_block_layout', 'VK_KHR_sampler_mirror_clamp_to_edge', 'VK_KHR_sampler_ycbcr_conversion', 'VK_KHR_shader_atomic_int64', 'VK_KHR_shader_draw_parameters', 'VK_KHR_shader_float16_int8', 'VK_KHR_shader_float_controls', 'VK_KHR_storage_buffer_storage_class', 'VK_KHR_swapchain', 'VK_KHR_swapchain_mutable_format', 'VK_KHR_timeline_semaphore', 'VK_KHR_uniform_buffer_standard_layout', 'VK_KHR_variable_pointers', 'VK_KHR_vulkan_memory_model', 'VK_EXT_blend_operation_advanced', 'VK_EXT_buffer_device_address', 'VK_EXT_calibrated_timestamps', 'VK_EXT_conditional_rendering', 'VK_EXT_conservative_rasterization', 'VK_EXT_depth_clip_enable', 'VK_EXT_depth_range_unrestricted', 'VK_EXT_descriptor_indexing', 'VK_EXT_discard_rectangles', 'VK_EXT_display_control', 'VK_EXT_fragment_shader_interlock', 'VK_EXT_global_priority', 'VK_EXT_host_query_reset', 'VK_EXT_index_type_uint8', 'VK_EXT_inline_uniform_block', 'VK_EXT_line_rasterization', 'VK_EXT_memory_budget', 'VK_EXT_pci_bus_info', 'VK_EXT_pipeline_creation_feedback', 'VK_EXT_post_depth_coverage', 'VK_EXT_sample_locations', 'VK_EXT_sampler_filter_minmax', 'VK_EXT_scalar_block_layout', 'VK_EXT_separate_stencil_usage', 'VK_EXT_shader_demote_to_helper_invocation', 'VK_EXT_shader_subgroup_ballot', 'VK_EXT_shader_subgroup_vote', 'VK_EXT_shader_viewport_index_layer', 'VK_EXT_subgroup_size_control', 'VK_EXT_texel_buffer_alignment', 'VK_EXT_transform_feedback', 'VK_EXT_vertex_attribute_divisor', 'VK_EXT_ycbcr_image_arrays', 'VK_NV_clip_space_w_scaling', 'VK_NV_dedicated_allocation', 'VK_NV_dedicated_allocation_image_aliasing', 'VK_NV_device_diagnostic_checkpoints', 'VK_NV_fill_rectangle', 'VK_NV_fragment_coverage_to_color', 'VK_NV_framebuffer_mixed_samples', 'VK_NV_coverage_reduction_mode', 'VK_NV_geometry_shader_passthrough', 'VK_NV_sample_mask_override_coverage', 'VK_NV_shader_sm_builtins', 'VK_NV_shader_subgroup_partitioned', 'VK_NV_viewport_array2', 'VK_NV_viewport_swizzle', 'VK_NVX_device_generated_commands', 'VK_NVX_multiview_per_view_attributes']

Logical device and graphic queue successfully created

selected format: 44
3 available swapchain present modes
3 images view created
FPS: 64
FPS: 61
FPS: 61
FPS: 61
FPS: 50
FPS: 2
FPS: 9
FPS: 1
FPS: 4
FPS: 3
FPS: 5
FPS: 1
FPS: 56
FPS: 61
FPS: 60
FPS: 61
FPS: 61
FPS: 61
FPS: 61
FPS: 61
FPS: 61
FPS: 8
FPS: 2
FPS: 4
FPS: 59
FPS: 61
FPS: 61
FPS: 61
FPS: 16
FPS: 62
FPS: 61
FPS: 61
FPS: 32
FPS: 60
^CTraceback (most recent call last):
  File "example/example_sdl2.py", line 693, in <module>
    draw_frame()
  File "example/example_sdl2.py", line 673, in draw_frame
    vkQueueWaitIdle(presentation_queue)
  File "/home/fuyu/.local/lib/python3.8/site-packages/vulkan/_vulkan.py", line 5305, in vkQueueWaitIdle
    result = _callApi(lib.vkQueueWaitIdle, queue)
  File "/home/fuyu/.local/lib/python3.8/site-packages/vulkan/_vulkan.py", line 4962, in _callApi
    return fn(*fn_args)
KeyboardInterrupt

The lag spikes are the freezes

Need VK_RESULT

following the tutorial from vulkan-tutorial.com I'm at the part with the swapchain recreation due to window resizing.
In the tutorial the VK_RESULT from vkAcquireNextImageKHR is tested for VK_ERROR_OUT_OF_DATE_KHR as a trigger for swapchain recreation. But the python Vulkan module returns only the imageIndex.

Maybe in such cases the wrapper could return a tuple, and thus such a function call could look like
result,imageIndex = vkAcquireNextImageKHR()

But anyway, is there any way to setup the swapchain recreation when window size chages?

SDL2 now has vulkan support

So, PySDL2 updated:
https://github.com/marcusva/py-sdl2
News Article:
https://www.pygame.org/news.html

Now uses SDL2 2.0.6, which has vulkan support, as in it can now create a vulkan instance attached to a window "for you".

Should the SDL2 example be updated to use this functionality? Or should the old way be kept to show how this might be done with other frameworks that don't have out of the box support?

It should be noted I haven't tried this yet. So I don't know if this vulkan manages to wrap the sdl2 references correctly and therefore if you even can use the new sdl2 stuff without using cffi in the application.

class _StrWrap unsupported python2

class _StrWrap():
    """Wrap a FFI Cdata object

    This class is a proxy class which auto-convert FFI string to Python
    string. It must be used only on object containing string data.
    Original CFFI string can always be accessed by prefixing the property with
    an underscore.
    """
    def __init__(self, obj):
        self.obj = obj

    def __setattr__(self, key, value):
        if key == 'obj':
            return super().__setattr__(key, value)

        setattr(self.obj, key, value)

    def __getattr__(self, key):
        try:
            attr = getattr(self.obj, key)
        except AttributeError as origin_exc:
            # Remove the first underscore if exists
            if key.startswith('_'):
                try:
                    return getattr(self.obj, key[1:])
                except AttributeError:
                    raise origin_exc
            raise origin_exc

        return _cstr(attr)

This is not supported on python2

    def __setattr__(self, key, value):
        if key == 'obj':
            return super().__setattr__(key, value)

If you run on python2 will get this error.
return super().setattr(key, value)
TypeError: super() takes at least 1 argument (0 given)
Exception TypeError: "'NoneType' object is not callable" in <bound method HelloTriangleApplication.del of <main.HelloTriangleApplication object at 0x000000000306F888>> ignored

vkGetPhysicalDeviceSurfaceFormatsKHR

Hello, i just installed the latest vulkan sdk and the latest python vulkan wrapper and also the latest glfw. I am totally new to the vulkan world, but i am experienced in opengl.
When i first run the example_glfw.py i had a problem with the VkSurfaceKHR, i solved it just by updating my graphics drivers.
But i can get through this error:
Loader Message NULL pointer passed into vkGetPhysicalDeviceSurfaceFormatsKHR for pSurfaceFormatCount!

The problem lies in the __querySwapChainSupport method, in this line:
details.formats = vkGetPhysicalDeviceSurfaceFormatsKHR(device, self.__surface)

My question is, should these examples work with the most recent or latest version of vulkan sdk, python vulkan and glfw? Have you tried it?

Application unresponsive under Linux without vkQueueWaitIdle call

When I run the program under Linux, the window is unresponsive and the whole screen is freezing intermittently.
Adding an extra call to vkQueueWaitIdle( presentation_queue ) at the end of the draw_frame() function solves the issue.
Is that something expected?

How to get the VkResult of vkAcquireNextImageKHR?

Hi realitix, from vulkan I noticed that vkAcquireNextImageKHR returns the index of the next presentable image in the swapchain, which it is suppose to do. However, how do I access the VkResult from this function? As you can see from my code here, the logic that I have written would not work as it needs the VkResult of vkAcquireNextImageKHR.

        image_index = self.fnp['vkAcquireNextImageKHR'](
            self.logical_device, self.swapchain, UINT64_MAX,
            self.semaphore_image_available, VK_NULL_HANDLE )

        if image_index == VK_ERROR_OUT_OF_DATE_KHR:
            self._recreateSwapChain()
            logging.info("VK_ERROR_OUT_OF_DATE_KHR: Need to recreate swapchain image!")
        elif image_index != VK_SUCCESS and image_index != VK_SUBOPTIMAL_KHR:
            logging.error("Failed to acquire swapchain image!")
        print('image_index = ', image_index)

image_index should not be passed to the logic but the VkResult that is supposed to be returned by vkAcquireNextImageKHR.

Suggested condition for VkPipelineInputAssemblyStateCreateInfo

Hi @realitix , according to Vulkan spec on Drawing Commands, primitiveRestartEnable must be VK_FALSE for certain topology.

I like to suggest appending VkPipelineInputAssemblyStateCreateInfo with the below condition. What do you think?

def VkPipelineInputAssemblyStateCreateInfo(#sType=VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,pNext=None,flags=None,topology=None,primitiveRestartEnable=None,):
    disallow_primitiveRestartEnable = (0,1,3,6,8,10) ##new
    if topology in disallow_primitiveRestartEnable: primitiveRestartEnable=VK_FALSE ##new
        
    return _new('VkPipelineInputAssemblyStateCreateInfo', sType=sType,pNext=pNext,flags=flags,topology=topology,primitiveRestartEnable=primitiveRestartEnable)

vkGetPhysicalDeviceSurfaceCapabilitiesKHR gives VkErrorInitializationFailed for xcb surface

Issue:
I obtained the following error in my code for an xcb surface during vulkan command 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR'.

File "~/.local/lib/python3.5/site-packages/vulkan/_vulkan.py", line 5207, in vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    raise exception_codes[result]
vulkan._vulkan.VkErrorInitializationFailed

To investigate the issue, I used your example_sdl2.py script and substituted all definitions pertaining to xlib with xcb. And I got the same error msg.

Changes made to example_sdl2.py:

  1. replaced line 60 with extensions.append('VK_KHR_xcb_surface')
  2. replaced lines 101 to 109 with
def surface_xcb():
    print("Create Xcb surface")
    vkCreateXcbSurfaceKHR = vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR")
    surface_create = VkXcbSurfaceCreateInfoKHR(
            sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
            connection = wm_info.info.x11.display,
            window = wm_info.info.x11.window,
            flags = 0)
    return vkCreateXcbSurfaceKHR(instance, surface_create, None)
  1. replaced line 140 with sdl2.SDL_SYSWM_X11: surface_xcb

The xlib version of example_sdl2.py works well on my system.

Question:
Is VkErrorInitializationFailed due to an issue in vulkan or Vulkan?

Still active?

Do the versions of this repo necessarily track with the LunarG versions? I see that this repo is currently at version 1.1.71.2. LunarG's Vulkan SDK is now at 1.1.85.0 (as of Oct 2018).

By the way, if you are a Mac user, I created a vulkan installer for the homebrew package manager. It can be installed with the command brew cask install apenngrace/vulkan/vulkan-sdk. I have been testing this python wrapper on the Mac and so far so good!

Step by step instructions to use vulkan needed

I have installed setup.py.

Can you provide the step by step instructions (show explicit commands) to running example.py?
This will aid beginners to learn to use of your python wrapper for vulkan. The documentation in README.md is not enough to go by.

I tried the below. Appreciate your guidance

$ cd vulkan-master 
$ sudo python3 setup.py install
running install
Checking .pth file support in /usr/local/lib/python3.5/dist-packages/
/usr/bin/python3 -E -c pass
TEST PASSED: /usr/local/lib/python3.5/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
creating vulkan.egg-info
writing top-level names to vulkan.egg-info/top_level.txt
writing vulkan.egg-info/PKG-INFO
writing dependency_links to vulkan.egg-info/dependency_links.txt
writing requirements to vulkan.egg-info/requires.txt
writing manifest file 'vulkan.egg-info/SOURCES.txt'
reading manifest file 'vulkan.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'vulkan.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/_cffi_build
copying _cffi_build/vulkan_build.py -> build/lib/_cffi_build
copying _cffi_build/__init__.py -> build/lib/_cffi_build
creating build/lib/vulkan
copying vulkan/__init__.py -> build/lib/vulkan
copying vulkan/_vulkan.py -> build/lib/vulkan
generating cffi module 'build/lib/vulkan/_vulkan.py'
already up-to-date
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/vulkan
copying build/lib/vulkan/__init__.py -> build/bdist.linux-x86_64/egg/vulkan
copying build/lib/vulkan/_vulkan.py -> build/bdist.linux-x86_64/egg/vulkan
creating build/bdist.linux-x86_64/egg/_cffi_build
copying build/lib/_cffi_build/vulkan_build.py -> build/bdist.linux-x86_64/egg/_cffi_build
copying build/lib/_cffi_build/__init__.py -> build/bdist.linux-x86_64/egg/_cffi_build
byte-compiling build/bdist.linux-x86_64/egg/vulkan/__init__.py to __init__.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/vulkan/_vulkan.py to _vulkan.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/_cffi_build/vulkan_build.py to vulkan_build.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/_cffi_build/__init__.py to __init__.cpython-35.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying vulkan.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying vulkan.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying vulkan.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying vulkan.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying vulkan.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
_cffi_build.__pycache__.vulkan_build.cpython-35: module references __file__
creating dist
creating 'dist/vulkan-1.3.0-py3.5.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing vulkan-1.3.0-py3.5.egg
creating /usr/local/lib/python3.5/dist-packages/vulkan-1.3.0-py3.5.egg
Extracting vulkan-1.3.0-py3.5.egg to /usr/local/lib/python3.5/dist-packages
Adding vulkan 1.3.0 to easy-install.pth file

Installed /usr/local/lib/python3.5/dist-packages/vulkan-1.3.0-py3.5.egg
Processing dependencies for vulkan==1.3.0
Searching for cffi==1.10.0
Best match: cffi 1.10.0
Adding cffi 1.10.0 to easy-install.pth file

Using /usr/local/lib/python3.5/dist-packages
Searching for pycparser==2.17
Best match: pycparser 2.17
pycparser 2.17 is already the active version in easy-install.pth

Using /usr/local/lib/python3.5/dist-packages
Finished processing dependencies for vulkan==1.3.0

$ cd generator
$ ls
fake_libc_include  generate.py  vk_platform.h  vk.xml  vulkan.h  vulkan.template.py
$ python3 generate.py 
Traceback (most recent call last):
  File "generate.py", line 5, in <module>
    import inflection
ImportError: No module named 'inflection'
$ sudo pip3 install inflection
[sudo] password for sunbear: 
The directory '$HOME/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '$HOME/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting inflection
Installing collected packages: inflection
Successfully installed inflection-0.3.1
$ python3 generate.py 
Traceback (most recent call last):
  File "generate.py", line 7, in <module>
    import xmltodict
ImportError: No module named 'xmltodict'
$ sudo pip3 install xmltodict
The directory '$HOME/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '$HOME/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting xmltodict
  Downloading xmltodict-0.10.2.tar.gz
Installing collected packages: xmltodict
  Running setup.py install for xmltodict ... done
Successfully installed xmltodict-0.10.2
$ python3 generate.py 
$ ls
fake_libc_include  generate.py  vk_platform.h  vk.xml  vulkan.h  vulkan.template.py
$ python3 vulkan.template.py 
  File "vulkan.template.py", line 115
    {% for _, enums in model.enums.items() %}
     ^
SyntaxError: invalid syntax

$ cd ../example/
$ ls
example.py  frag.spv  shader.frag  shader.vert  vert.spv
$ python3 example.py
Traceback (most recent call last):
  File "example.py", line 6, in <module>
    import sdl2
ImportError: No module named 'sdl2'
$ pip3 install sdl2
Collecting sdl2
  Could not find a version that satisfies the requirement sdl2 (from versions: )
No matching distribution found for sdl2
$ pip3 install sdl
Collecting sdl
  Could not find a version that satisfies the requirement sdl (from versions: )
No matching distribution found for sdl

Questions on heapIndex, flags and propertyFlags provided by pMemoryProperties.

I have used the vkGetPhysicalDeviceMemoryProperties to obtain the memory properties of a specific physical device, i.e. GPU, and printed out the returned values.

    def _setPhysicalDevice(self):
        self.physical_device = self.physical_devices[0]
        self.physical_device_memory = vk.vkGetPhysicalDeviceMemoryProperties(
            self.physical_device)
        print('    view physical_devices[0] properties')
        self._printPhysicalDeviceMemoryProperties(self.physical_device_memory)

    @staticmethod
    def _printPhysicalDeviceMemoryProperties(memory):
        print('  Memory:')
        print('  -memoryTypeCount: {}'.format(memory.memoryTypeCount))
        print('  -memoryTypes[VK_MAX_MEMORY_TYPES]:')
        for n, i in enumerate(memory.memoryTypes):
            print('    -{}, propertyFlags: {}, heapIndex: {}'.format(
                n, i.propertyFlags, i.heapIndex))
            if n == memory.memoryTypeCount - 1: break
        print('  -memoryHeapCount: {}'.format(memory.memoryHeapCount))
        print('  -memoryHeaps[VK_MAX_MEMORY_HEAPS]:')
        size = 0
        for n, i in enumerate(memory.memoryHeaps):
            print('    -{}, size: {}, flags: {}'.format(n, i.size, i.flags))
            if i.flags == 1 and i.size:
                size += i.size
            if n == memory.memoryHeapCount - 1: break
        print('GPU memory size = ', size)
      Memory:
      -memoryTypeCount: 11
      -memoryTypes[VK_MAX_MEMORY_TYPES]:
        -0, propertyFlags: 0, heapIndex: 1
        -1, propertyFlags: 0, heapIndex: 1
        -2, propertyFlags: 0, heapIndex: 1
        -3, propertyFlags: 0, heapIndex: 1
        -4, propertyFlags: 0, heapIndex: 1
        -5, propertyFlags: 0, heapIndex: 1
        -6, propertyFlags: 0, heapIndex: 1
        -7, propertyFlags: 1, heapIndex: 0
        -8, propertyFlags: 1, heapIndex: 0
        -9, propertyFlags: 6, heapIndex: 1
        -10, propertyFlags: 14, heapIndex: 1
      -memoryHeapCount: 2
      -memoryHeaps[VK_MAX_MEMORY_HEAPS]:
        -0, size: 6442450944, flags: 1
        -1, size: 25186016256, flags: 0

Based on this output, I can see there are 2 memory heaps.

  • The 1st heap has flags=1 that indicates that it refers to the local device memory and it has 6442450944 bytes. I have checked with the GPU spec, the GPU is suppose to have 6.144GB Standard Memory Config. Despite of the ~298MB differences in memory, I think it is reasonable to conclude that "-0, size: 6442450944, flags: 1" refers to the GPU i am querying.

  • The 2nd heap has a size of ~25.2GB and flags=0. Tomaka believes it refers to the available CPU RAM in my system. I can accept that given that it is less than the actual RAM capacity in my system. However, Vulkan spec did not describe this flag value. Can you tell me where you defined this in vulkan?

  • For the array memoryTypes, I see its first seven elements propertyFlags has a value of 0. However, Vulkan spec did not describe such a bitmask. Also, their heapIndex has a value 1. Are they referring to the 1st element of the array memoryHeaps. If so, should their corresponding propertyFlags=0x00000001?

  • The 8th and 9th elements of memoryTypes has a heapIndex of 0 and a propertyFlags of 1. Is this reasonable?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.