Code Monkey home page Code Monkey logo

vulkancore.jl's Introduction

VulkanCore

CI TagBot

VulkanCore wraps Vulkan and exposes the library calls necessary to work with Vulkan. It is targeted for developers wanting to directly work with Vulkan in Julia.

If you are looking for a high-level idiomatic Julia API you might wish to take a look at Vulkan.jl.

Installation

You are required to have a Vulkan capable device and the appropriate drivers.

If these are present, run:

pkg> add VulkanCore

References

Usage

The Vulkan wrapper is generated using Clang.jl with the generator file.

The API aims to replicate the Vulkan C-API and is thus very bare bones and hands-on.

using VulkanCore.LibVulkan

count = Ref{Cuint}(0)

# Scan layers
err = vkEnumerateInstanceLayerProperties(count, C_NULL)
@assert err == VK_SUCCESS

global_layer_properties = Vector{VkLayerProperties}(undef, count[])
err = vkEnumerateInstanceLayerProperties(count, global_layer_properties)
@assert err == VK_SUCCESS

Contributing

You are welcome to submit pull-request for improvements, but since this is primarily a wrapper you might focus your attention on the high-level API at Vulkan.jl.

Thanks

This package is inspired by the work done on CUDArt.jl and OpenCL.jl.

A big thank you also to all core Julia developers, who made this possible in the first place.

vulkancore.jl's People

Contributors

gnimuc avatar vchuravy avatar simondanisch avatar serenity4 avatar holocronweaver avatar staticfloat avatar ranocha avatar juliatagbot avatar tkelman avatar dependabot[bot] avatar femtocleaner[bot] avatar

Stargazers

Barzin avatar Jordan Castro avatar  avatar TheDark avatar  avatar  avatar Leonardo Mariscal avatar tyoc213 avatar Serge Volkov avatar Ryosuke Horiuchi avatar ReactSmarter avatar Diego Valcarce avatar Balen avatar  avatar Jeanne-Kamikaze avatar Joshua Higginbotham avatar Christian Laforte avatar Bert Chan avatar Cuda Chen avatar sprhawk avatar watosar avatar Kernel Soe avatar Nick Ochiel avatar  avatar james gilles avatar Ionizing avatar Dennis Ogiermann avatar David Lin avatar Bermi Ferrer avatar Inoki avatar Jeff Kingyens avatar  avatar Andrew Prentice avatar  avatar Kenneth Steimel avatar Chang Gao avatar Kusti Skytén avatar  avatar Claudia Doppioslash avatar STYLIANOS IORDANIS avatar Chance Snow avatar Wilbur Chen avatar  avatar Dmitrii Kuznetsov avatar Dez avatar  avatar Kamil Ziemian avatar Wojciech Miłkowski avatar David Wicks avatar  avatar Tianqi Chen avatar Lawrence Dark avatar  avatar Yue Zhuo avatar Joshua Brewster (Bubba Skrimp) avatar Andrew McKay avatar M. Edward (Ed) Borasky avatar Compl Yue avatar Benoît Legat avatar xiuliren avatar Gábor Mező avatar PeterLiou avatar  avatar Mario Link avatar Stephen Oates avatar David Dohan avatar Rasmus Scholer avatar schlady avatar Waldir Pimenta avatar Cyrille Rossant avatar  avatar Eric Jang avatar Randy Zwitch avatar Kenta Sato avatar Lee James O'Riordan avatar

Watchers

Takeshi Watanabe avatar ERKIN KANLIOGLU avatar Daniel Peirano avatar Yichao Yu avatar James Cloos avatar  avatar Tim Holy avatar Manuel avatar  avatar  avatar

vulkancore.jl's Issues

Using Ref{T} instead of Ptr{T}

Just a question. Wouldn't it be possible to use Ref{T} instead of Ptr{T} in VulkanCore.jl/gen/api/vk_common_1.0.0.jl? Is there any specific reason you are using Ptr instead? Because as far as I understand, Refs and Ptrs behave the same when used as parameters to c functions, but Refs protect their values from Julias GC.

Drop prefix vk

All variables starting with vk or VK_ that are already in package vk should be renamed.
vk.SUCCESS instead of vk.VK_SUCCESS and vk.createImage instead of vk.vkCreateImage etc.

Standardize the use of the C wrapper

Would there be an interest in exposing a safe way to use the generated API? It requires previous experience with C wrappers to actually use the library with a minimum of crashes and do something meaningful with it. In the end, there are several ways to deal with this, but it requires a lot of time and efforts to first figure it out and then write the code (because the API is huge). Personally I struggled a lot with finding efficient ways of making sure pointers stay valid.

I've taken a programmatic approach with this wrapper, we may reuse the generating code and tweak it if necessary. Currently it generates the following:

  1. Mutable structs around Vulkan handles (e.g. VkInstance, which is just a Ptr{Cvoid}) to allow finalizers to be registered.
  2. Basic reference counting to ensure finalizers don't destroy a handle while it is the parent of a non-finalized object (since finalizer execution order is undefined).
  3. New structs which guarantee that, if the corresponding API struct has pointer fields, these stay valid while the struct is alive (by putting strings/arrays/refs inside a dummy Vector{Any} and bundle it inside the struct).
  4. Friendly ("julian") structs for those that are only returned and never requested by the API, with a conversion from their API counterparts. Basically, VkBool32 is replaced by Bool, NTuple{N, UInt8} by String, UInt32 by VersionNumber (if the field actually represents a version number).
  5. Wrapper around API calls, including error checking. Some functions have implicit return values (which take the form of a pointer argument whose memory is mutated by the API), so the wrapper function generates a corresponding Ref, calls the API, dereference it. Other functions require being called twice: once for filling the length of an array to be filled by the API, and once with the initialized array of the right size. Certain functions/structs may have optional arguments but this is not captured inside VulkanCore. The generated functions/constructors expose keyword arguments when this is the case. Vulkan constructors (vkCreate...) are wrapped differently in that they automatically register a finalizer to the wrapped object with the parent handle (if applicable) and allocator used to create it (as required by the specification).

I'd like your opinion on whether these features would be interesting for VulkanCore, only a subset of it, or none. I don't really have an opinion myself, although I think that having a new VulkanWrapper.jl (or similar) package would only bring confusion when there already are VulkanCore.jl and Vulkan.jl. Another possibility is to choose to have Vulkan.jl be lower-level, just wrapping the Vulkan API with the above without introducing abstractions and leaving that to other packages. It could be a better approach actually, because high-level graphics libraries often tend to be huge and not composable. It also lines up more with what one might expect, that is a way to use Vulkan as a backend, not a user-level library.

ByteString not defined Problem

ByteString not defined Problem when using VulkanCore

WARNING: deprecated syntax "Base.(:&)".
Use "Base.:&" instead.
ERROR: LoadError: LoadError: UndefVarError: ByteString not defined
Stacktrace:
[1] include_from_node1(::String) at .\loading.jl:576
[2] include(::String) at .\sysimg.jl:14
[3] include_from_node1(::String) at .\loading.jl:576
[4] include(::String) at .\sysimg.jl:14
[5] anonymous at .<missing>:2
while loading C:\Users\Max.julia\v0.6\VulkanCore\src\api.jl, in expression starting on line 10
while loading C:\Users\Max.julia\v0.6\VulkanCore\src\VulkanCore.jl, in expression starting on line
6
ERROR: Failed to precompile VulkanCore to C:\Users\Max.julia\lib\v0.6\VulkanCore.ji.
Stacktrace:
[1] compilecache(::String) at .\loading.jl:710
[2] _require(::Symbol) at .\loading.jl:497
[3] require(::Symbol) at .\loading.jl:405
[4] eval(::Module, ::Any) at .\boot.jl:235
[5] eval(::Any) at .\boot.jl:234
[6] macro expansion at C:\Users\Max.julia\v0.6\Atom\src\repl.jl:118 [inlined]
[7] anonymous at .<missing>:?

Incorrect union types

The unions are currently not generated correctly. I believe this will be fixed by JuliaInterop/Clang.jl#278 (do you confirm @Gnimuc?), though I thought it would be nice to track it somewhere.

For example, the XML specification for the VkClearColorValue type lists:

<type category="union" name="VkClearColorValue" comment="// Union allowing specification of floating point, integer, or unsigned integer color data. Actual value selected is based on image/attachment being cleared.">
    <member><type>float</type>                  <name>float32</name>[4]</member>
    <member><type>int32_t</type>                <name>int32</name>[4]</member>
    <member><type>uint32_t</type>               <name>uint32</name>[4]</member>
</type>

and, in Julia, we only have the float part of the union correct:

struct VkClearColorValue
    float32::NTuple{4, Cfloat}
end

Windows compat issue

For now, Clang.jl doesn't support cross-compilation, so one should manually tweak the generated script for different host platforms.

diff

It's very likely that in the future Clang.jl can do the tweaking automatically for users via CompilationDatabase + Artifacts.

Semantic versioning

As I understand it, VulkanCore uses a particular convention for versions, where the major and minor numbers are identical to the wrapped Vulkan version, and the patch number being the "version" of the wrapper itself.

The problem is that it is not in line with the semantic versioning of other packages. Therefore it may lead to issues like JuliaGPU/Vulkan.jl#16 because releases are assumed to never be breaking unless the major version of Vulkan changes (which does not happen often!). However, we may have breaking changes in how we wrap things, or even the specification itself may yield breaking changes (version 1.2.162 did).

Furthermore, since we now have the headers as an Artifact (Vulkan_Headers_jll) whose version is that of the Vulkan specification, I see little need in tracking the version also here and even less so as our package version.

Therefore I propose to respect semantic versioning from now on for future releases.

Add API methods for calling into function pointers

When we transitioned to the new Clang generator, I didn't notice that we lost the definitions for API functions that take a function pointer and ccall into it, like we had here.

Would it be possible to add these definitions to the generator? Originally we just parsed the API file after the generator was run to add them, but I am wondering if there is a more natural way to do it.

"using VulkanCore" crashes in Julia 0.6.0

How to reproduce:

  1. Install Julia 0.6.0 on Linux from upstream binary. I'm on Arch Linux.
  2. Start Julia. Pkg.add("VulkanCore") works but using VulkanCore crashes:
julia> Pkg.update()
INFO: Updating METADATA...
INFO: Computing changes...
INFO: No packages to install, update or remove

julia> Pkg.add("VulkanCore")
INFO: Cloning cache of VulkanCore from https://github.com/JuliaGPU/VulkanCore.jl.git
INFO: Installing VulkanCore v1.0.0
INFO: Package database updated

julia> using VulkanCore
INFO: Precompiling module VulkanCore.

WARNING: deprecated syntax "typealias Window UInt32" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:18.
Use "const Window = UInt32" instead.

WARNING: deprecated syntax "typealias VisualID UInt32" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:19.
Use "const VisualID = UInt32" instead.

WARNING: deprecated syntax "typealias Display Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:21.
Use "const Display = Void" instead.

WARNING: deprecated syntax "typealias xcb_connection_t Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:23.
Use "const xcb_connection_t = Void" instead.

WARNING: deprecated syntax "typealias xcb_window_t UInt32" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:24.
Use "const xcb_window_t = UInt32" instead.

WARNING: deprecated syntax "typealias xcb_visualid_t UInt32" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:25.
Use "const xcb_visualid_t = UInt32" instead.

WARNING: deprecated syntax "typealias wl_display Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:27.
Use "const wl_display = Void" instead.

WARNING: deprecated syntax "typealias wl_surface Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:28.
Use "const wl_surface = Void" instead.

WARNING: deprecated syntax "typealias MirConnection Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:30.
Use "const MirConnection = Void" instead.

WARNING: deprecated syntax "typealias MirSurface Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:31.
Use "const MirSurface = Void" instead.

WARNING: deprecated syntax "typealias ANativeWindow Void" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:33.
Use "const ANativeWindow = Void" instead.

WARNING: deprecated syntax "typealias HINSTANCE Ptr{Void}" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:35.
Use "const HINSTANCE = Ptr{Void}" instead.

WARNING: deprecated syntax "typealias HWND Ptr{Void}" at /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl:36.
Use "const HWND = Ptr{Void}" instead.

WARNING: deprecated syntax "abstract Cenum{T}" at /home/znmeb/.julia/v0.6/VulkanCore/src/CEnum.jl:4.
Use "abstract type Cenum{T} end" instead.

WARNING: deprecated syntax "bitstype 32 $typename<:CEnum.Cenum{UInt32}" at /home/znmeb/.julia/v0.6/VulkanCore/src/CEnum.jl:88.
Use "primitive type $typename<:CEnum.Cenum{UInt32} 32 end" instead.

WARNING: deprecated syntax "Base.(:|)".
Use "Base.:|" instead.

WARNING: deprecated syntax "Base.(:&)".
Use "Base.:&" instead.
ERROR: LoadError: LoadError: UndefVarError: ByteString not defined
Stacktrace:
 [1] include_from_node1(::String) at ./loading.jl:569
 [2] include(::String) at ./sysimg.jl:14
 [3] include_from_node1(::String) at ./loading.jl:569
 [4] include(::String) at ./sysimg.jl:14
 [5] anonymous at ./<missing>:2
while loading /home/znmeb/.julia/v0.6/VulkanCore/src/api.jl, in expression starting on line 10
while loading /home/znmeb/.julia/v0.6/VulkanCore/src/VulkanCore.jl, in expression starting on line 6
ERROR: Failed to precompile VulkanCore to /home/znmeb/.julia/lib/v0.6/VulkanCore.ji.
Stacktrace:
 [1] compilecache(::String) at ./loading.jl:703
 [2] _require(::Symbol) at ./loading.jl:490
 [3] require(::Symbol) at ./loading.jl:398

julia> 

I haven't tried this on older versions of Julia or other versions of Linux.

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

CEnum: Bitwise ORing support?

Since bit masking is ubiquitously used in Vulkan, I think it would be nice to support bitwise |:

julia> vk.VK_DEBUG_REPORT_ERROR_BIT_EXT | vk.VK_DEBUG_REPORT_WARNING_BIT_EXT
ERROR: UndefVarError: enum_argument_error not defined
Stacktrace:
 [1] convert(::Type{VulkanCore.api.VkDebugReportFlagBitsEXT}, ::Int64) at C:\Users\Gnimuc\.julia\v0.
6\VulkanCore\src\CEnum.jl:91
 [2] |(::VulkanCore.api.VkDebugReportFlagBitsEXT, ::VulkanCore.api.VkDebugReportFlagBitsEXT) at C:\U
sers\Gnimuc\.julia\v0.6\VulkanCore\src\CEnum.jl:4

An esay workaround is simply to write Cuint(vk.VK_DEBUG_REPORT_ERROR_BIT_EXT) | Cuint(vk.VK_DEBUG_REPORT_WARNING_BIT_EXT), but it seems CEnum do support bitwise &:

julia> vk.VK_DEBUG_REPORT_ERROR_BIT_EXT & vk.VK_DEBUG_REPORT_ERROR_BIT_EXT
VK_DEBUG_REPORT_ERROR_BIT_EXT(8)

Is this just a bug?

oh, I see:

is_member($typename, x) || Base.enum_argument_error($(Expr(:quote, name)), x)
Base.bitcast($typename, convert(Int32, x))
end
CEnum.enum_names(::Type{$typename}) = tuple($(map(x-> Expr(:quote, first(x)), name_values)...))

It seems this is intended, if so, I'm wondering what's the purpose of:

Base.(:|)(a::T, b::T) where {T<:Cenum} = T(Int(a) | Int(b))

Scope of this package?

The package name somehow implies this package is only for Vulkan Core API. Should we also mantain KHR extensions or all published extensions in this package? Maybe it's a good idea to maintain everything in one place and rename the package to Vulkan.jl? Following the naming convention of the JuliaGL org, Vulkan.jl can be renamed to VKAbstraction.jl accordingly.

Make CEnum an independent package?

So other c wrappers can use it without adding VulkanCore as a dependency or copy-pasting the file CEnum.jl and the corresponding license.

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.