Code Monkey home page Code Monkey logo

vulkan.jl's Introduction

Vulkan

tests

Vulkan.jl is a lightweight wrapper around the Vulkan graphics and compute library. It exposes abstractions over the underlying C interface, primarily geared towards developers looking for a more natural way to work with Vulkan with minimal overhead.

It builds upon the core API provided by VulkanCore.jl. Because Vulkan is originally a C specification, interfacing with it requires some knowledge before correctly being used from Julia. This package acts as an abstraction layer, so that you don't need to know how to properly call a C library, while still retaining full functionality. The wrapper is generated directly from the Vulkan Specification.

This is a very similar approach to that taken by VulkanHpp, except that the target language is Julia and not C++.

If you have questions, want to brainstorm ideas or simply want to share cool things you do with Vulkan don't hesitate to create a thread in our Zulip channel.

Status

This package is a work in progress and has not reached its 1.0 version yet. As such, documentation may not be complete and functionality may change without warning. If it happens, make sure to check out the changelog. At this stage, you should not use this library in production; however, you are encouraged to push its boundaries through non-critical projects. If you find limitations, bugs or want to suggest potential improvements, do not hesitate to submit issues or pull requests. The goal is definitely to be production-ready as soon as possible.

In particular, because the library relies on automatic code generation, there may be portions of the Vulkan API that are not wrapped correctly. While you should not have trouble in most cases, there are always edge cases which were not accounted for during generation. Please open an issue whenever you encounter such a case, so that we can reliably fix those wrapping issues for future use.

Testing

Currently, continuous integration runs only on Ubuntu 32/64 bits, for lack of a functional CI setup with Vulkan for MacOS and Windows. Because public CI services lack proper driver support, the CPU Vulkan implementation Lavapipe is used. If you are not on Linux, we cannot guarantee that this library will work for you, although so far nothing is platform-dependent. If that is the case, we recommend that you test this package with your own setup.

vulkan.jl's People

Contributors

claforte avatar dependabot[bot] avatar exaexa avatar fatteneder avatar github-actions[bot] avatar gnimuc avatar juliatagbot avatar ranocha avatar seelengrab avatar serenity4 avatar simondanisch avatar timholy 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

vulkan.jl's Issues

Disallow equality comparison between flags of different type

Similar to how bitwise or, and and xor is disallowed between different flags, equality checks should also be disallowed between flags of different type. This is to make it harder to accidentally compare flags of different type and make it fail early.

Initial discussion in #11.

Better design for (logging) flags

Follow up discussion for #11, how should comparisons of the form

(A | B) >= A

be handled for bitmasks? The context this came up in was logging severity.

Also worth thinking about - should type flags work more like an enum that shouldn't be possible to combine with |? Does that make sense in the context of Vulkan? I.e, should the fact that bitmasks/flags are implemented as a UInt32 be purely an implementation detail?

[question] Recommended compiler from GLSL to SPIR-V

Hello,

first off, many thanks for writing this wrapper, it works so nicely. With completion and inline documentation, coding vulkan in REPL is just way happier experience than in other languages. This issue is more of a question and perhaps a request for documentation, and I understand that this is not a core concern for Vulkan wrapper libraries, but I gues it'd better be answered for the sake of library usefulness :]

Question: what is the easiest way to compile shaders to spir-v, say from a triple-quoted string literal with glsl directly to Vector{Uint32}?

Currently I'm just running the glslangValidator binary manually, but that's neither very safe, convenient, nor portable. If there is a good "reasonably portable" approach to call glslang or shaderc from julia? If there exists a recommendable way, mind if I send a PR that adds it to (say) a FAQ in the documentation? (Perhaps together with some of my other discoveries, mostly unwrap, and the Very Useful™ minimal compute example :] )

Thanks!

Cleanup

Hello,

I am new to Julia and it is not very clear to me how resources such as instances and logical devices should be destroyed with Vulkan.jl. Should we call, say, destroy_device(), or maybe finalize()?

Reading the generated code, it looks like resources are automatically associated with a destructor, but it is not entirely clear to me what the purpose of that is.

Thank you.

Usage with RenderDoc

I was looking into how I could debug a Vulkan.jl app using RenderDoc.

So far I did not manage to get it to work. But here is what I have tried:

Following the quickstart section, I provided as an executable path a path to juliaup/bin/julia, and use something like --project=<path-to-project-dir> -e "using VulkanTutorial; main()" as command line arguments.
This is enough to launch the app from within RenderDoc, however, the advertised in-app overlay is not visible, and upon trying to capture (using F12) nothing happens.

Following their FAQ I did some more configuring and debugging:

  • RenderDoc assumes Vulkan 1.3, so make sure to set this when calling Vulkan.ApplicationInfo(). Fixing did not help.
  • I enabled the VK_EXT_tooling_info extension, which in turn provides the get_physical_device_tool_properties_ext function which should return a list of enabled tools. The FAQ says that RenderDoc should appear there, but for me it doesn't.
  • The same FAQ also says librender.so should be loaded when the app is launched from RenderDoc, but Libdl.dllist() does not list it in my tests.
  • I think RenderDoc also does some configuration using environment variables. So I verified that passing them from RenderDoc to Julia works (the launcher panel in RenderDoc has a field to set environment variables). I also saw that RenderDoc does indeed set some vars up, but nothing too interesting there either.

Atm I suspect the problem to be related to Julia not being linked to Vulkan directly, but instead we load i through Vulkan.jl. Unfortunately, the docs on internals of RenderDoc skip the part of how RenderDoc hooks itself up with the driver and application.

@serenity4 Do you have any ideas on how we could get this working?

The author of RenderDoc mentions in various places that he is happy to help, so I might also open an issue with RenderDoc and ask for details on the injection.
But for that I need to craft a MWE Vulkan.jl app first.

Precompilation fails on 0.1.2

Error log
Vulkan [9f14b124-c50e-4008-a7d4-969b3a6cd68a]

ERROR: LoadError: LoadError: UndefVarError: VkAccelerationStructureVersionKHR not defined
Stacktrace:
  [1] top-level scope
    @ ~\.julia\packages\Vulkan\Ek6Ym\generated\vulkan_wrapper.jl:718
  [2] include(mod::Module, _path::String)
    @ Base .\Base.jl:386
  [3] include(x::String)
    @ Vulkan ~\.julia\packages\Vulkan\Ek6Ym\src\Vulkan.jl:1
  [4] top-level scope
    @ ~\.julia\packages\Vulkan\Ek6Ym\src\Vulkan.jl:37
  [5] include
    @ .\Base.jl:386 [inlined]
  [6] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concre
deps::Vector{Pair{Base.PkgId, UInt64}}, source::Nothing)
    @ Base .\loading.jl:1213
  [7] top-level scope
    @ none:1
  [8] eval
    @ .\boot.jl:360 [inlined]
  [9] eval(x::Expr)
    @ Base.MainInclude .\client.jl:446
 [10] top-level scope
    @ none:1
in expression starting at ~\.julia\packages\Vulkan\Ek6Ym\generated\vulkan_wrapper.jl:718
in expression starting at ~\.julia\packages\Vulkan\Ek6Ym\src\Vulkan.jl:1

Stacktrace:
 [1] pkgerror(msg::String)
   @ Pkg.Types C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\Types.jl:55
 [2] precompile(ctx::Pkg.Types.Context; internal_call::Bool, strict::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ Pkg.API C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:1244
 [3] precompile
   @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:920 [inlined]
 [4] #precompile#196
   @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:918 [inlined]
 [5] precompile()
   @ Pkg.API C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:918
 [6] top-level scope
   @ REPL[5]:1

Short version:

UndefVarError: VkAccelerationStructureVersionKHR not defined at Vulkan\Ek6Ym\generated\vulkan_wrapper.jl:718. Is this from VulkanCore? Would this need a new version/update the dependency as well?

Tests assume code is in a git repository

Running the tests seems to assume the package is in a git directory. If I do ]dev Vulkan, I don't get this error message, so I'm guessing those working on Vulkan.jl just haven't spotted that it doesn't work in a standard (non-dev) install of the package...

I haven't looked into what the test is trying to do, but it seems that it should be working within Julia's packaging / artefact framework to do it, right? Downloading the whole development history as a git repository takes somewhat more time (especially if your internet connection is pants like mine) and space than just the version in use, so it'd be nice to do without that (and wouldn't it be nice if Julia supported using shallow repos - which would at least reduce the cost...)

I'm not sure if this is a bug in "Documenter", or a bug in how Vulkan.jl uses "Documenter", or a conscious decision for reasons outside my ken, but as something of a neophyte in the world of Julia, I'm hoping somebody who actually works on Vulkan.jl is able to determine that!

Note, this error log was generated using 1.9.0-rc3, but I get essentially the same using 1.8.5, so I don't think it's to do with the version of Julia I'm using.

JULIA_DEBUG=Documenter julia--project=.
] add Vulkan
(...)
] test Vulkan
(...)
┌ Warning: Unable to determine HTML(edit_link = ...) from remote HEAD branch, defaulting to "master".
│ Calling `git remote` failed with an exception. Set JULIA_DEBUG=Documenter to see the error.
│ Unless this is due to a configuration error, the relevant variable should be set explicitly.
└ @ Documenter.Utilities ~/.julia/packages/Documenter/H5y27/src/Utilities/Utilities.jl:822
┌ Debug: Command: setenv(`/usr/bin/git remote show origin`,[ ***ENV stripped for privacy/brevity*** ]; dir="/home/sammy/.julia/packages/Vulkan/76XsG/test")
│   exception =
│    failed process: Process(setenv(`/usr/bin/git remote show origin`,[ ***ENV stripped for privacy/brevity*** ]; dir="/home/sammy/.julia/packages/Vulkan/76XsG/test"), ProcessExited(128)) [128]
│
│    Stacktrace:
│      [1] pipeline_error
│        @ ./process.jl:565 [inlined]
│      [2] read(cmd::Base.CmdRedirect)
│        @ Base ./process.jl:449
│      [3] read
│        @ ./process.jl:458 [inlined]
│      [4] git_remote_head_branch(varname::String, root::String; remotename::String, fallback::String)
│        @ Documenter.Utilities ~/.julia/packages/Documenter/H5y27/src/Utilities/Utilities.jl:820
│      [5] git_remote_head_branch
│        @ ~/.julia/packages/Documenter/H5y27/src/Utilities/Utilities.jl:794 [inlined]
│      [6] Documenter.Writers.HTMLWriter.HTML()
│        @ Documenter.Writers.HTMLWriter ~/.julia/packages/Documenter/H5y27/src/Writers/HTMLWriter.jl:419
│      [7] (::Documenter.var"#all_doctests#32"{Bool, Vector{Regex}, Vector{Module}})()
│        @ Documenter ~/.julia/packages/Documenter/H5y27/src/Documenter.jl:942
│      [8] macro expansion
│        @ ~/opt/julia-1.9.0-rc3/share/julia/stdlib/v1.9/Test/src/Test.jl:478 [inlined]
│      [9] macro expansion
│        @ ~/.julia/packages/Documenter/H5y27/src/Documenter.jl:963 [inlined]
│     [10] macro expansion
│        @ ~/opt/julia-1.9.0-rc3/share/julia/stdlib/v1.9/Test/src/Test.jl:1498 [inlined]
│     [11] doctest(source::String, modules::Vector{Module}; fix::Bool, testset::String, doctestfilters::Vector{Regex})
│        @ Documenter ~/.julia/packages/Documenter/H5y27/src/Documenter.jl:963
│     [12] doctest
│        @ ~/.julia/packages/Documenter/H5y27/src/Documenter.jl:927 [inlined]
│     [13] doctest(package::Module; manual::Bool, testset::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
│        @ Documenter ~/.julia/packages/Documenter/H5y27/src/Documenter.jl:898
│     [14] doctest(package::Module)
│        @ Documenter ~/.julia/packages/Documenter/H5y27/src/Documenter.jl:884
│     [15] top-level scope
│        @ ~/.julia/packages/Vulkan/76XsG/test/base.jl:29
│     [16] include(mod::Module, _path::String)
│        @ Base ./Base.jl:457
│     [17] include(x::String)
│        @ Main.var"##292" ~/.julia/packages/SafeTestsets/A83XK/src/SafeTestsets.jl:23
│     [18] macro expansion
│        @ ~/.julia/packages/Vulkan/76XsG/test/runtests.jl:4 [inlined]
│     [19] macro expansion
│        @ ~/opt/julia-1.9.0-rc3/share/julia/stdlib/v1.9/Test/src/Test.jl:1498 [inlined]
│     [20] top-level scope
│        @ ~/.julia/packages/Vulkan/76XsG/test/runtests.jl:4
│     [21] eval(m::Module, e::Any)
│        @ Core ./boot.jl:370
│     [22] top-level scope
│        @ ~/.julia/packages/SafeTestsets/A83XK/src/SafeTestsets.jl:23
│     [23] include(fname::String)
│        @ Base.MainInclude ./client.jl:478
│     [24] top-level scope
│        @ none:6
│     [25] eval
│        @ ./boot.jl:370 [inlined]
│     [26] exec_options(opts::Base.JLOptions)
│        @ Base ./client.jl:280
│     [27] _start()
│        @ Base ./client.jl:522
│   stderr = "fatal: not a git repository (or any of the parent directories): .git\n"
└ @ Documenter.Utilities ~/.julia/packages/Documenter/H5y27/src/Utilities/Utilities.jl:827
(...)

As it happens, I'm probably not going to be able to use Vulkan.jl because my weenie GPU apparently only has support for vulkan 1.2, (perhaps that's a limitation of the underlying drivers and might change in future...) but I thought you might appreciate the feedback anyway :-)

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!

`VkPresentModeKHR` has no high level equivalent `PresentModeKHR`

I think this enum would have to be added in VulkanCore and this package would need a new set of generated functions, as the wrapper for get_physical_device_surface_present_modes_khr right now returns ::Vektor{VkPresentModeKHR} instead of the documented ::Vektor{PresentModeKHR}. Not sure how those all get generated though.

I'd be happy to add the necessary code though, provided I can find out where it is.

`WriteDescriptorSet` expects to only handle `image_info`

According to vulkan-tutorial.com, VkWriteDescriptorSet can either refer to buffers, image data or buffer views. The wrapper WriteDescriptorSet defines the field descriptorCount of VkWriteDescriptorSet solely based on the length of image_info, which is required to be passed, even though it may not be used every time the wrapper is called.

I could trace this down to this line in vulkan_wrapper.jl containing pointer_length(image_info):

vks = VkWriteDescriptorSet(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, unsafe_convert(Ptr{Cvoid}, next), dst_set, dst_binding, dst_array_element, pointer_length(image_info), descriptor_type, unsafe_convert(Ptr{VkDescriptorImageInfo}, image_info), unsafe_convert(Ptr{VkDescriptorBufferInfo}, buffer_info), unsafe_convert(Ptr{VkBufferView}, texel_buffer_view))

which imo should be max(pointer_length(image_info), pointer_length(buffer_info), pointer_length(texel_buffer_view)).

Another option would be to make these three arguments keywords and check which exists (checking for exclusivity as well) and using that as the basis for the length.

`ERROR_LAYER_NOT_PRESENT` when creating instance

I am attempting to follow the tutorial and am running into a layer not present error:

julia> const application_info = ApplicationInfo(v"0.0.1", v"0.0.1", v"1.3", application_name = "Demo", engine_name = "DemoEngine");

julia> const instance = Instance(
           ["VK_LAYER_KHRONOS_validation"],
           ["VK_EXT_debug_utils"];
           application_info=application_info,
       )
ERROR: ERROR_LAYER_NOT_PRESENT: failed to execute #= /<path>/<to>/.julia/packages/Vulkan/69Z8R/generated/linux.jl:30768 =# @dispatch nothing vkCreateInstance(create_info, allocator, pInstance)
Stacktrace:
 [1] unwrap
   @ ~/.julia/packages/ResultTypes/AUZ9z/src/ResultTypes.jl:67 [inlined]
 [2] Instance(enabled_layer_names::Vector{String}, enabled_extension_names::Vector{String}; allocator::Ptr{Nothing}, next::Ptr{Nothing}, flags::Int64, application_info::ApplicationInfo)
   @ Vulkan ~/.julia/packages/Vulkan/69Z8R/generated/linux.jl:47624
 [3] top-level scope
   @ REPL[16]:1

The layer appears to exist

julia> for layer in something(Vulkan.enumerate_instance_layer_properties().result)
       println(layer.layer_name)
       end
VK_LAYER_VALVE_steam_overlay_32
VK_LAYER_VALVE_steam_fossilize_32
VK_LAYER_VALVE_steam_overlay_64
VK_LAYER_VALVE_steam_fossilize_64
VK_LAYER_MESA_device_select
VK_LAYER_KHRONOS_synchronization2
VK_LAYER_KHRONOS_validation
VK_LAYER_KHRONOS_profiles
VK_LAYER_LUNARG_monitor
VK_LAYER_MESA_overlay
VK_LAYER_LUNARG_screenshot
VK_LAYER_LUNARG_api_dump
VK_LAYER_LUNARG_gfxreconstruct
$ vulkaninfo
==========
VULKANINFO
==========

Vulkan Instance Version: 1.3.231

...

Layers: count = 13
==================
VK_LAYER_KHRONOS_validation (Khronos Validation Layer) Vulkan version 1.3.231, layer version 1:
	Layer Extensions: count = 3
		VK_EXT_debug_report        : extension revision 9
		VK_EXT_debug_utils         : extension revision 1
		VK_EXT_validation_features : extension revision 2

Julia/package version:

julia> versioninfo()
Julia Version 1.6.7
Commit 3b76b25b64 (2022-07-19 15:11 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: 12th Gen Intel(R) Core(TM) i7-12700H
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, goldmont)
(vulkan_test) pkg> st
      Status `~/Code/vulkan_test/Project.toml`
  [9f14b124] Vulkan v0.4.1

Any help would be greatly appreciated.

Unsatisfiable requirements detected for package Vulkan

Hello. I am running into the following error installing the Vulkan package on a clean Julia install. The VulkanCore package, on the other hand, installs just fine. I am not sure what specifically is causing the version restriction. Could somebody help?

Thank you.

ERROR: Unsatisfiable requirements detected for package Vulkan [9f14b124]:
 Vulkan [9f14b124] log:
 ├─possible versions are: [0.1.0-0.1.3, 0.2.0-0.2.4, 0.3.0] or uninstalled
 ├─restricted to versions * by an explicit requirement, leaving only versions [0.1.0-0.1.3, 0.2.0-0.2.4, 0.3.0]
 └─restricted by julia compatibility requirements to versions: uninstalled — no versions left

Intended Purpose of this Package Going Forward

Hi, while this is currently a WIP I was curious to know whether this Package when complete will serve as a safe wrapper around the Vulkan API, or will it also provide helper functions that will abstract away some of the tasks that are required when making a Vulkan application (like functions for image and buffer creation that automatically allocate and bind memory, other functions for memory management etc.)

And if it's the latter, has the package reached a point where work on such functionality can be started or will it be started at some point in the future.

SwapchainKHR auto-finalized before its time (segfault)

Thank you for the carefully designed wrapper, it's really nice.

I can't seem to preserve my swapchain object throughout the life of my program. Although Base.GC.enable_logging(true) tells me that no GC is being run, very consistently Vulkan.set_preferences!("LOG_REFCOUNT" => "true") shows the refcount of my swapchain going to zero before trying to create framebuffers, and then I get a segfault from the validation layers upon trying to access the ImageView.

I've tried adding a GC.@preserve swapchain nothing at the end of my main function and tried to save the swapchain in a struct for later, but neither keeps the refcount above zero. Currently the only thing that works consistently is manually setting swapchain.destructor = _ -> nothing.

Package versions:

    [052768ef] CUDA v5.2.0                                                                                                                              
    [f7f18e0c] GLFW v3.4.1                                                                                                                              
    [90137ffa] StaticArrays v1.9.1                                                                                                                      
    [9f14b124] Vulkan v0.6.14                                                                                                                           
    [6fd5517d] glslang_jll v11.7.0+0    

I'd try to submit an MWE but Vulkan doesn't seem very amenable to short reproducible scripts. I can try if necessary. Thanks!

Encountering a Segmentation Fault and Exception: EXCEPTION_ACCESS_VIOLATION

Hi, when I run the following code in windows:

using Vulkan, GLFW

width = 1400
height = 800
enable_validation_layers = true
required_queue_families = ["graphics", "presentation"]


GLFW.Init()
GLFW.WindowHint(GLFW.CLIENT_API, GLFW.NO_API)
GLFW.WindowHint(GLFW.RESIZABLE, false)
window = GLFW.CreateWindow(width, height, "Win")


# Vulkan Init
layers = ["VK_LAYER_KHRONOS_validation"]
alllayers = enumerate_instance_layer_properties()
alllayernames = map(i -> i.layer_name, alllayers.result.value)
enable_validation_layers && length(layers) != length(filter(i -> i in alllayernames, layers)) && error("Required Layers not available")

extensions = GLFW.GetRequiredInstanceExtensions()
enable_validation_layers && (extensions = vcat(extensions, Vulkan.VK_EXT_DEBUG_UTILS_EXTENSION_NAME))
allextensions = enumerate_instance_extension_properties()

const application_info = ApplicationInfo(
    v"0.0.1", # application version
    v"0.0.1", # engine version
    v"1.2"; # requested API version
    application_name="Demo",
    engine_name="DemoEngine"
)

const instance = Instance(
    layers,
    extensions;
    application_info
)


# WSI 
surface = GLFW.CreateWindowSurface(instance, window)


# Physical Devices
device_extensions = ["VK_KHR_swapchain"]
function get_family_indices(device::PhysicalDevice)
    outp = Dict{String,Any}("graphics" => nothing, "compute" => nothing, "presentation" => nothing)
    families = get_physical_device_queue_family_properties(device)

    for x in 1:length(families)
        QUEUE_GRAPHICS_BIT in families[x].queue_flags && outp["graphics"] === nothing && (outp["graphics"] = x - 1)
        QUEUE_COMPUTE_BIT in families[x].queue_flags && outp["compute"] === nothing && (outp["compute"] = x - 1)
        unwrap(get_physical_device_surface_support_khr(device, x - 1, surface)) && outp["presentation"] === nothing && (outp["presentation"] = x - 1)
    end
    outp
end

function get_swapchain_support(device::PhysicalDevice)
    outp = Dict()
    outp["capabilities"] = get_physical_device_surface_capabilities_khr(device, surface) |> unwrap
    outp["formats"] = get_physical_device_surface_formats_khr(device, surface) |> unwrap
    outp["modes"] = get_physical_device_surface_present_modes_khr(device, surface) |> unwrap
    outp
end

devices = enumerate_physical_devices(instance) |> unwrap
function check_device(device)
    properties = get_physical_device_properties(device)
    features = get_physical_device_features(device)
    family_indices = get_family_indices(device)
    available_extensions = enumerate_device_extension_properties(device) |> unwrap
    has_extensions = reduce(&, [x in map(i -> i.extension_name, available_extensions) for x in device_extensions])
    has_extensions || return false
    swapchain_support = get_swapchain_support(device)

    properties.device_type == PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
        (features.vks.geometryShader |> Bool) &&
        reduce(&, [family_indices[x] !== nothing for x in required_queue_families]) &&
        length(swapchain_support["modes"]) > 0 &&
        length(swapchain_support["formats"]) > 0
end
suitable_devices = filter(i -> check_device(i), devices)
length(suitable_devices) == 0 && error("No Compatible Device Found")
physical_device = suitable_devices[1]
queue_families = get_family_indices(physical_device)
queue_indices = unique(values(queue_families))


# Logical Devices
queue_create_infos = [DeviceQueueCreateInfo(x, [1.0]) for x in queue_indices]
device_layers = enable_validation_layers ? layers : []
device_features = PhysicalDeviceFeatures()
device = Device(physical_device, queue_create_infos, device_layers, device_extensions, enabled_features=device_features)

queues = Dict()
for (key, value) in queue_families
    queues[key] = get_device_queue(device, value, 0)
end


# Swapchain
swapchain_support = get_swapchain_support(physical_device)
format = swapchain_support["formats"][1]
for j in swapchain_support["formats"]
    j == Vulkan.VK_FORMAT_B8G8R8A8_SRGB && j.colorSpace == Vulkan.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR && (global format = j)
end
mode = Vulkan.VK_PRESENT_MODE_MAILBOX_KHR in swapchain_support["modes"] ? Vulkan.VK_PRESENT_MODE_MAILBOX_KHR : Vulkan.VK_PRESENT_MODE_FIFO_KHR


# Main Loop
while !GLFW.WindowShouldClose(window)
    GLFW.PollEvents()
end

# Cleanup
destroy_device(device)
destroy_surface_khr(instance, surface)
destroy_instance(instance)
GLFW.DestroyWindow(window)
GLFW.Terminate()

It gives the follwoing output:

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x5ef59b4e -- vkGetPhysicalDeviceSurfaceFormatsKHR at C:\Users\waliw\.julia\packages\VulkanCore\iP628\lib\x86_64-w64-mingw32.jl:7981 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\src\prewrap\errors.jl:25 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:55399 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\src\prewrap\errors.jl:39 [inlined]
#_get_physical_device_surface_formats_khr#1459 at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:55398
in expression starting at D:\Programming\Projects\julia\vulkan-tutorial\index.jl:82
vkGetPhysicalDeviceSurfaceFormatsKHR at C:\Users\waliw\.julia\packages\VulkanCore\iP628\lib\x86_64-w64-mingw32.jl:7981 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\src\prewrap\errors.jl:25 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:55399 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\src\prewrap\errors.jl:39 [inlined]
#_get_physical_device_surface_formats_khr#1459 at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:55398
_get_physical_device_surface_formats_khr##kw at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:55397 [inlined]
macro expansion at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\src\prewrap\errors.jl:48 [inlined]
#get_physical_device_surface_formats_khr#1747 at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:64049
get_physical_device_surface_formats_khr at C:\Users\waliw\.julia\packages\Vulkan\bHXH3\generated\windows.jl:64049
unknown function (ip: 000000005ef5a4cf)
get_swapchain_support at D:\Programming\Projects\julia\vulkan-tutorial\index.jl:61
check_device at D:\Programming\Projects\julia\vulkan-tutorial\index.jl:74
#11 at D:\Programming\Projects\julia\vulkan-tutorial\index.jl:82 [inlined]
filter at .\array.jl:2484
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1788 [inlined]
do_call at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:126
eval_value at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:215
eval_stmt_value at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:166 [inlined]
eval_body at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:583
jl_interpret_toplevel_thunk at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:731
jl_toplevel_eval_flex at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:885
jl_toplevel_eval_flex at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:830
jl_toplevel_eval at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:894 [inlined]
jl_toplevel_eval_in at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:944
eval at .\boot.jl:373 [inlined]
include_string at .\loading.jl:1196
_include at .\loading.jl:1253
include at .\Base.jl:418
exec_options at .\client.jl:292
_start at .\client.jl:495
jfptr__start_21275.clone_1 at C:\Users\waliw\scoop\apps\julia\current\lib\julia\sys.dll (unknown line)
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1788 [inlined]
true_main at /cygdrive/c/buildbot/worker/package_win64/build/src\jlapi.c:559
jl_repl_entrypoint at /cygdrive/c/buildbot/worker/package_win64/build/src\jlapi.c:701
mainCRTStartup at /cygdrive/c/buildbot/worker/package_win64/build/cli\loader_exe.c:42
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
Allocations: 9220682 (Pool: 9218356; Big: 2326); GC: 11
VUID-vkDestroyInstance-instance-00629(ERROR / SPEC): msgNum: -1958900200 - Validation Error: [ VUID-vkDestroyInstance-instance-00629 ] Object 0: handle = 0x62b74460, type = VK_OBJECT_TYPE_INSTANCE; Object 1: handle = 0xfd5b260000000001, type = VK_OBJECT_TYPE_SURFACE_KHR; | MessageID = 0x8b3d8e18 | OBJ ERROR : For VkInstance 0x62b74460[], VkSurfaceKHR 0xfd5b260000000001[] has not been destroyed. The Vulkan spec states: All child objects created using instance must have been destroyed prior to destroying instance (https://vulkan.lunarg.com/doc/view/1.3.211.0/windows/1.3-extensions/vkspec.html#VUID-vkDestroyInstance-instance-00629)
    Objects: 2
        [0] 0x62b74460, type: 1, name: NULL
        [1] 0xfd5b260000000001, type: 1000000000, name: NULL

Error when running the same code in Linux:

signal (11): Segmentation fault
in expression starting at /media/data/Programming/Projects/julia/vulkan-tutorial/index.jl:82
vkGetPhysicalDeviceSurfaceFormatsKHR at /home/wali/.julia/packages/VulkanCore/iP628/lib/x86_64-linux-gnu.jl:7961 [inlined]
macro expansion at /home/wali/.julia/packages/Vulkan/bHXH3/src/prewrap/errors.jl:25 [inlined]
macro expansion at /home/wali/.julia/packages/Vulkan/bHXH3/generated/linux.jl:54099 [inlined]
macro expansion at /home/wali/.julia/packages/Vulkan/bHXH3/src/prewrap/errors.jl:39 [inlined]
#_get_physical_device_surface_formats_khr#1433 at /home/wali/.julia/packages/Vulkan/bHXH3/generated/linux.jl:54098
_get_physical_device_surface_formats_khr##kw at /home/wali/.julia/packages/Vulkan/bHXH3/generated/linux.jl:54097 [inlined]
macro expansion at /home/wali/.julia/packages/Vulkan/bHXH3/src/prewrap/errors.jl:48 [inlined]
#get_physical_device_surface_formats_khr#1729 at /home/wali/.julia/packages/Vulkan/bHXH3/generated/linux.jl:62578
get_physical_device_surface_formats_khr at /home/wali/.julia/packages/Vulkan/bHXH3/generated/linux.jl:62578
unknown function (ip: 0x7f6777ce254d)
get_swapchain_support at /media/data/Programming/Projects/julia/vulkan-tutorial/index.jl:61
check_device at /media/data/Programming/Projects/julia/vulkan-tutorial/index.jl:74
#11 at /media/data/Programming/Projects/julia/vulkan-tutorial/index.jl:82 [inlined]
filter at ./array.jl:2484
unknown function (ip: 0x7f67f78bc7bc)
unknown function (ip: 0x7f67f78bc084)
unknown function (ip: 0x7f67f78bced4)
unknown function (ip: 0x7f67f78bdce3)
unknown function (ip: 0x7f67f78da92f)
unknown function (ip: 0x7f67f78db556)
jl_toplevel_eval_in at /usr/bin/../lib/julia/libjulia-internal.so.1 (unknown line)
unknown function (ip: 0x7f67e05a3747)
unknown function (ip: 0x7f67e06e92d1)
unknown function (ip: 0x7f67e06e8d72)
unknown function (ip: 0x7f67e080f95c)
unknown function (ip: 0x7f67e02ee472)
unknown function (ip: 0x7f67e02ee5c8)
unknown function (ip: 0x7f67f79023b2)
jl_repl_entrypoint at /usr/bin/../lib/julia/libjulia-internal.so.1 (unknown line)
main at julia (unknown line)
unknown function (ip: 0x7f67f7e4d28f)
__libc_start_main at /usr/bin/../lib/libc.so.6 (unknown line)
_start at julia (unknown line)
Allocations: 10119165 (Pool: 10116669; Big: 2496); GC: 11
[1]    3464 segmentation fault (core dumped)  julia index.jl

Julia Version: 1.7
Device: Nvidia GTX 1050 TI

Cannot construct ClearValue for depthStencil

> ClearValue(ClearDepthStencilValue(1, 0))

ERROR: LoadError: MethodError: Cannot `convert` an object of type ClearDepthStencilValue to an object of type NTuple{16, UInt8}
Closest candidates are:
  convert(::Type{T}, ::T) where T<:Tuple at essentials.jl:315
  convert(::Type{T}, ::Tuple{Vararg{Any, N}}) where {N, T<:Tuple} at essentials.jl:316
  convert(::Type{T}, ::CartesianIndex) where T<:Tuple at multidimensional.jl:137
  ...
Stacktrace:
 [1] VulkanCore.LibVulkan.VkClearValue(data::ClearDepthStencilValue)
   @ VulkanCore.LibVulkan ~\.julia\packages\VulkanCore\HsTdu\lib\x86_64-w64-mingw32.jl:3244

Convenience Constructor for PhysicalDeviceVulkan12Features

Hi,

it would be nice to have constructors from a list of symbols for PhysicalDeviceVulkan11Features and PhysicalDeviceVulkan12Features, equivalently to the constructor you wrote for PhysicalDeviceFeatures.
I took your existing code and adapted it slightly for the other two structs:

In src/device.jl

function PhysicalDeviceVulkan11Features(features::AbstractArray; next = C_NULL)
    names = filter(n -> n  (:sType, :pNext), fieldnames(VkPhysicalDeviceVulkan11Features))
    diff = setdiff(collect(features), names)
    if length(diff) > 0
        error("Invalid physical device Vulkan 1.1 features: $(join(diff, ", "))")
    end
    args = map(in(features), names)
    PhysicalDeviceVulkan11Features(args...; next=next)
end

PhysicalDeviceVulkan11Features(features::Symbol...) = PhysicalDeviceVulkan11Features(collect(features))

function PhysicalDeviceVulkan12Features(features::AbstractArray; next = C_NULL)
    names = filter(n -> n  (:sType, :pNext), fieldnames(VkPhysicalDeviceVulkan12Features))
    diff = setdiff(collect(features), names)
    if length(diff) > 0
        error("Invalid physical device Vulkan 1.2 features: $(join(diff, ", "))")
    end
    args = map(in(features), names)
    PhysicalDeviceVulkan12Features(args...; next=next)
end

PhysicalDeviceVulkan12Features(features::Symbol...) = PhysicalDeviceVulkan12Features(collect(features))

Note that I had to add a filter to exclude sTypeand pNext to get the correct argument list.
Beside that, these functions are mostly identical, so you may find it cleaner to generate them somehow with a macro.

Thanks for the great package btw

fails to find vulkan validation layer on 1.8 (linux)

Previously when I had used this package in Julia 1.7 it seemed to be able to find the lib for the validation layer that was installed on my system.

On 1.8 it seems to be failing to link to it:

ERROR: ERROR_LAYER_NOT_PRESENT: failed to execute #= /home/expandingman/.julia/packages/Vulkan/bHXH3/generated/linux.jl:46990 =# @dispatch nothing vkCreateInstance(create_info, allocator, pInstance)
Stacktrace:
 [1] unwrap(r::ResultTypes.Result{Instance, VulkanError})
   @ ResultTypes ~/.julia/packages/ResultTypes/AUZ9z/src/ResultTypes.jl:67
 [2] Instance(enabled_layer_names::Vector{String}, enabled_extension_names::Vector{String}; allocator::Ptr{Nothing}, next::Ptr{Nothing}, flags::Int64, application_info::ApplicationInfo)
   @ Vulkan ~/.julia/packages/Vulkan/bHXH3/generated/linux.jl:66011

I have confirmed that /lib/libVkLayer_khronos_validation.so exists.

I tried figuring out where in the code it tries to link to them to determine why it's failing but so far I haven't found it.

`ShaderModule` requires a lot of manual initialization

E.g. I had to do ShaderModule(device, length(code), reinterpret(UInt32, code)) instead of simply ShaderModule(device, code), as I expected.

I read the compiled shader code (done with glslc, like vulkan-tutorial.com recommends) simply via read("shader.frag"), which returns a byte vector. Could maybe also be simplified to just make ShaderModule(device, ::String) take a path, though that would preclude hard-coded shaders in the same source code and dynamically generated shaders.

Supporting `MemoryRef`?

Hi! With the new Memory PR on 1.11/nightly, it seems there's a new failure mode in the generated code here (or I'm doing something wrong again). The top-level call I'm doing is Vulkan.create_device, like so:

    queueInfo = Vulkan.DeviceQueueCreateInfo(indices.graphicsFamily, queuePriorities)
    deviceinfo = Vulkan.DeviceCreateInfo([queueInfo], [], [])
    deviceFeatures = Vulkan.create_device(app.physicalDevice, deviceinfo) |> unwrap

This is the stacktrace I get:

ERROR: LoadError: MethodError: no method matching pointer_length(::MemoryRef{Float32})

Closest candidates are:
  pointer_length(::Ptr{Nothing})
   @ Vulkan ~/.julia/packages/Vulkan/uRhTL/src/prewrap/pointers.jl:25
  pointer_length(::Tuple{Any, Any})
   @ Vulkan ~/.julia/packages/Vulkan/uRhTL/src/prewrap/pointers.jl:28
  pointer_length(::Base.RefArray)
   @ Vulkan ~/.julia/packages/Vulkan/uRhTL/src/prewrap/pointers.jl:27
  ...

Stacktrace:
  [1] Vulkan._DeviceQueueCreateInfo(queue_family_index::UInt32, queue_priorities::Vector{Float32}; next::Ptr{Nothing}, flags::Vulkan.DeviceQueueCreateFlag)
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:26450
  [2] Vulkan._DeviceQueueCreateInfo(x::Vulkan.DeviceQueueCreateInfo)
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:50115
  [3] convert(T::Type{Vulkan._DeviceQueueCreateInfo}, x::Vulkan.DeviceQueueCreateInfo)
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:56829
  [4] setindex!(A::Memory{Vulkan._DeviceQueueCreateInfo}, x::Vulkan.DeviceQueueCreateInfo, i1::Int64)
    @ Base ./genericmemory.jl:188
  [5] unsafe_copyto!(dest::Memory{Vulkan._DeviceQueueCreateInfo}, doffs::Int64, src::Memory{Vulkan.DeviceQueueCreateInfo}, soffs::Int64, n::Int64)
    @ Base ./genericmemory.jl:103
  [6] unsafe_copyto!(dest::Memory{Vulkan._DeviceQueueCreateInfo}, doffs::Int64, src::Memory{Vulkan.DeviceQueueCreateInfo}, soffs::Int64, n::Int64)
    @ Base ./genericmemory.jl:83 [inlined]
  [7] _copyto_impl!
    @ ./array.jl:308 [inlined]
  [8] copyto!
    @ ./array.jl:294 [inlined]
  [9] copyto!
    @ ./array.jl:319 [inlined]
 [10] copyto_axcheck!
    @ ./abstractarray.jl:1195 [inlined]
 [11] Array
    @ ./array.jl:612 [inlined]
 [12] convert
    @ ./array.jl:604 [inlined]
 [13] convert_nonnull
    @ ~/.julia/packages/Vulkan/uRhTL/src/prewrap/pointers.jl:30 [inlined]
 [14] Vulkan._DeviceCreateInfo(x::Vulkan.DeviceCreateInfo)
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:50117
 [15] convert(T::Type{Vulkan._DeviceCreateInfo}, x::Vulkan.DeviceCreateInfo)
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:56831
 [16] macro expansion
    @ ~/.julia/packages/Vulkan/uRhTL/src/prewrap/errors.jl:48 [inlined]
 [17] create_device(physical_device::Vulkan.PhysicalDevice, create_info::Vulkan.DeviceCreateInfo; allocator::Ptr{Nothing})
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:68603
 [18] create_device(physical_device::Vulkan.PhysicalDevice, create_info::Vulkan.DeviceCreateInfo)
    @ Vulkan ~/.julia/packages/Vulkan/uRhTL/generated/linux.jl:68602
 [19] createLogicalDevice!(app::MLTarget.App)
    @ MLTarget ~/Documents/projects/MLTarget.jl/src/MLTarget.jl:145
 [20] initVulkan!(app::MLTarget.App)
    @ MLTarget ~/Documents/projects/MLTarget.jl/src/MLTarget.jl:48
 [21] run!(app::MLTarget.App)
    @ MLTarget ~/Documents/projects/MLTarget.jl/src/MLTarget.jl:209
 [22] main()
    @ MLTarget ~/Documents/projects/MLTarget.jl/src/MLTarget.jl:233
 [23] top-level scope
    @ ~/Documents/projects/MLTarget.jl/run.jl:7
in expression starting at /home/sukera/Documents/projects/MLTarget.jl/run.jl:7

If I'm reading the existing definition for pointer_length right, this assumed that everything worked with RefArray (as it did in the past), though this now gets a MemoryRef, which isn't supported (and doesn't have the link back to the parent array). Not entirely sure how to fix this best.

Do not destroy external handles

As raised in #7, the generated code for get_swapchain_images_khr registers a destructor for the returned images. This is unwanted since the application does not own these images. Furthermore, the registration uses an undefined allocator, which produces an error.

Offending sample (may be others):

function get_swapchain_images_khr(device::Device, swapchain::SwapchainKHR)::Result{Vector{Image}, VulkanError}
    pSwapchainImageCount = Ref{UInt32}()
    @repeat_while_incomplete begin
            @check vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, C_NULL)
            pSwapchainImages = Vector{VkImage}(undef, pSwapchainImageCount[])
            @check vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages)
        end
    Image.(pSwapchainImages, (x->destroy_image(device, x; allocator)), device)
end

Can't bitwise-OR `VK_COLOR_COMPONANT_...` and `UInt32`

Seems like this got missed somehow.

vulkan-tutorial.com uses bitwise or to combine these flags/masks, but when I try to do the same I hit a MethodError:

    colorBlendAttachment = Vulkan.PipelineColorBlendAttachmentState(
        false,
        Vulkan.VK_BLEND_FACTOR_ONE,
        Vulkan.VK_BLEND_FACTOR_ZERO,
        Vulkan.VK_BLEND_OP_ADD,
        Vulkan.VK_BLEND_FACTOR_ONE,
        Vulkan.VK_BLEND_FACTOR_ZERO,
        Vulkan.VK_BLEND_OP_ADD;
        color_write_mask = Vulkan.VK_COLOR_COMPONENT_R_BIT |
            Vulkan.VK_COLOR_COMPONENT_G_BIT |
            Vulkan.VK_COLOR_COMPONENT_B_BIT |
            Vulkan.VK_COLOR_COMPONENT_A_BIT
    )

results in

ERROR: LoadError: MethodError: no method matching |(::UInt32, ::VulkanCore.LibVulkan.VkColorComponentFlagBits)
Closest candidates are:
  |(::Any, ::Any, ::Any, ::Any...) at operators.jl:560
  |(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:332
  |(::Integer, ::T) where T<:Vulkan.BitMask at C:\Users\valentin\.julia\packages\Vulkan\CZsmD\src\prewrap\bitmasks.jl:55
  ...

These seem to return a UInt32 when done once, but chaining them leads to the above error:

julia> Vulkan.VK_COLOR_COMPONENT_G_BIT | Vulkan.VK_COLOR_COMPONENT_B_BIT
0x00000006

julia> ans |> typeof
UInt32

julia> (Vulkan.VK_COLOR_COMPONENT_G_BIT | Vulkan.VK_COLOR_COMPONENT_B_BIT) | Vulkan.VK_COLOR_COMPONENT_A_BIT
ERROR: MethodError: no method matching |(::UInt32, ::VkColorComponentFlagBits)

Presence of garbage data when retrieving physical device memory types

Hi,
I'm getting what seems to be an overflowing buffer reads when trying to enumerate the available physical device memory types.

Reduced to the simplest reproducer I know the problem looks like this:

using Vulkan
println.(get_physical_device_memory_properties(unwrap(enumerate_physical_devices(Instance([],[])))[1]).memory_types);

The command lists a few valid memory types, but these are followed by garbage that looks like random data picked from uninitialized memory, such as:

MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0x00000001)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT), 0x00000000)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT), 0x00000001)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT), 0x00000001)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT), 0x00000002)
MemoryType(MemoryPropertyFlag(), 0x00000004)             #this is the first invalid one, there's only 3 memory hea entries
MemoryType(MemoryPropertyFlag(), 0x00004000)
MemoryType(MemoryPropertyFlag(), 0x0000001f)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT | MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT), 0x0000001f)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT | MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT), 0x00000008)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT | MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT), 0x0000001f)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT | MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT), 0x0000001f)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT), 0x00000001)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT), 0x42a6aaab)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_HOST_CACHED_BIT), 0x00000008)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_HOST_CACHED_BIT), 0x00000002)
MemoryType(MemoryPropertyFlag(), 0x437fe000)
MemoryType(MemoryPropertyFlag(), 0x40ffc000)
MemoryType(MemoryPropertyFlag(), 0x7d9d8d00)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT | MEMORY_PROPERTY_RESERVED_8_BIT_NV), 0x00000001)
MemoryType(MemoryPropertyFlag(), 0xffffff80)
MemoryType(MemoryPropertyFlag(MEMORY_PROPERTY_DEVICE_LOCAL_BIT | MEMORY_PROPERTY_HOST_VISIBLE_BIT | MEMORY_PROPERTY_HOST_COHERENT_BIT | MEMORY_PROPERTY_HOST_CACHED_BIT | MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT | MEMORY_PROPERTY_PROTECTED_BIT | MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD | MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD | MEMORY_PROPERTY_RESERVED_8_BIT_NV), 0x00000002)
MemoryType(MemoryPropertyFlag(), 0x0223f5f0)
MemoryType(MemoryPropertyFlag(), 0x00000000)
MemoryType(MemoryPropertyFlag(), 0x00000002)
MemoryType(MemoryPropertyFlag(), 0x03a16470)

The beginning of the listing checks with the vulkaninfo, the rest seems to be garbage.

I'll try to debug what's wrong and report back. Is there any guess on whether this is a possible "premature GC" issue?

Thanks!
-mk


Relevant vulkaninfo section:

VkPhysicalDeviceMemoryProperties:
=================================
memoryHeaps: count = 3
	memoryHeaps[0]:
		size   = 4294967296 (0x100000000) (4.00 GiB)
		budget = 4099145728 (0xf4540000) (3.82 GiB)
		usage  = 0 (0x00000000) (0.00 B)
		flags: count = 1
			MEMORY_HEAP_DEVICE_LOCAL_BIT
	memoryHeaps[1]:
		size   = 25050470400 (0x5d51fd800) (23.33 GiB)
		budget = 25050470400 (0x5d51fd800) (23.33 GiB)
		usage  = 0 (0x00000000) (0.00 B)
		flags:
			None
	memoryHeaps[2]:
		size   = 257949696 (0x0f600000) (246.00 MiB)
		budget = 254935040 (0x0f320000) (243.12 MiB)
		usage  = 3014656 (0x002e0000) (2.88 MiB)
		flags: count = 1
			MEMORY_HEAP_DEVICE_LOCAL_BIT
memoryTypes: count = 11
	memoryTypes[0]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				None
			IMAGE_TILING_LINEAR:
				color images
				(non-sparse, non-transient)
	memoryTypes[1]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				color images
				(non-sparse)
			IMAGE_TILING_LINEAR:
				None
	memoryTypes[2]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				FORMAT_D16_UNORM
				(non-sparse, non-transient)
			IMAGE_TILING_LINEAR:
				None
	memoryTypes[3]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				FORMAT_X8_D24_UNORM_PACK32
				FORMAT_D24_UNORM_S8_UINT
				(non-sparse, non-transient)
			IMAGE_TILING_LINEAR:
				None
	memoryTypes[4]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				FORMAT_D32_SFLOAT
				(non-sparse, non-transient)
			IMAGE_TILING_LINEAR:
				None
	memoryTypes[5]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				FORMAT_D32_SFLOAT_S8_UINT
				(non-sparse, non-transient)
			IMAGE_TILING_LINEAR:
				None
	memoryTypes[6]:
		heapIndex     = 1
		propertyFlags = 0x0000:
			None
		usable for:
			IMAGE_TILING_OPTIMAL:
				FORMAT_S8_UINT
				(non-sparse, non-transient)
			IMAGE_TILING_LINEAR:
				None
	memoryTypes[7]:
		heapIndex     = 0
		propertyFlags = 0x0001: count = 1
			MEMORY_PROPERTY_DEVICE_LOCAL_BIT
		usable for:
			IMAGE_TILING_OPTIMAL:
				color images
				FORMAT_D16_UNORM
				FORMAT_X8_D24_UNORM_PACK32
				FORMAT_D32_SFLOAT
				FORMAT_S8_UINT
				FORMAT_D24_UNORM_S8_UINT
				FORMAT_D32_SFLOAT_S8_UINT
			IMAGE_TILING_LINEAR:
				color images
				(non-sparse, non-transient)
	memoryTypes[8]:
		heapIndex     = 1
		propertyFlags = 0x0006: count = 2
			MEMORY_PROPERTY_HOST_VISIBLE_BIT
			MEMORY_PROPERTY_HOST_COHERENT_BIT
		usable for:
			IMAGE_TILING_OPTIMAL:
				None
			IMAGE_TILING_LINEAR:
				color images
				(non-sparse, non-transient)
	memoryTypes[9]:
		heapIndex     = 1
		propertyFlags = 0x000e: count = 3
			MEMORY_PROPERTY_HOST_VISIBLE_BIT
			MEMORY_PROPERTY_HOST_COHERENT_BIT
			MEMORY_PROPERTY_HOST_CACHED_BIT
		usable for:
			IMAGE_TILING_OPTIMAL:
				None
			IMAGE_TILING_LINEAR:
				color images
				(non-sparse, non-transient)
	memoryTypes[10]:
		heapIndex     = 2
		propertyFlags = 0x0007: count = 3
			MEMORY_PROPERTY_DEVICE_LOCAL_BIT
			MEMORY_PROPERTY_HOST_VISIBLE_BIT
			MEMORY_PROPERTY_HOST_COHERENT_BIT
		usable for:
			IMAGE_TILING_OPTIMAL:
				None
			IMAGE_TILING_LINEAR:
				color images
				(non-sparse, non-transient)

Add convenience method for comparing `DebugUtilsMessageSeverityFlagEXT`s

Since these are arranged to be comparable via >= (at least the tutorial pretends that's the case), this would be useful and save some unwrapping. E.g. this

Base.isless(a::DebugUtilsMessageSeverityFlagEXT, b::DebugUtilsMessageSeverityFlagEXT) = isless(a.val, b.val)

does the job, unsure where/how this would be added. Just putting it into the namespace somewhere seems to work fine (as a hacky fix while I work through vulkan-tutorial.com, at least).

Surfaces obtained from GLFW have to be converted & destroyed manually

Obtaining a surface from GLFW via GLFW.CreateWindowSurface(instance, window) have to be destroyed manually via a call to destroy_surface_khr. You also seem to have to acquire the correct type manually (via SurfaceKHR(surface, instance, RefCounter(0))) in the first place.

If they're not destroyed, Vulkan (rightfully so) complains about the instance being destroyed in spite of the surface not being destroyed yet.

Not sure where/how this should be added.

create_render_pass causes validation errors, eventual crash

Hi,
Experienced graphics engineer, Julia newbie here.

My code that calls create_render_pass doesn't work and eventually causes a segfault. With the validation layer enabled, I get a ton of messages like:
VUID-VkSubpassDescription-flags-parameter(ERROR / SPEC): msgNum: 1258039040 - Validation Error: [ VUID-VkSubpassDescription-flags-parameter ] Object 0: handle = 0x255c658, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x4afc2700 | vkCreateRenderPass: value of pCreateInfo->pSubpasses[0].flags contains flag bits that are not recognized members of VkSubpassDescriptionFlagBits The Vulkan spec states: flags must be a valid combination of VkSubpassDescriptionFlagBits values (https://vulkan.lunarg.com/doc/view/1.2.170.0/linux/1.2-extensions/vkspec.html#VUID-VkSubpassDescription-flags-parameter)
Objects: 1
[0] 0x255c658, type: 3, name: NULL
VUID-VkSubpassDescription-pipelineBindPoint-parameter(ERROR / SPEC): msgNum: -93556066 - Validation Error: [ VUID-VkSubpassDescription-pipelineBindPoint-parameter ] Object 0: handle = 0x255c658, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xfa6c729e | vkCreateRenderPass: value of pCreateInfo->pSubpasses[0].pipelineBindPoint (32557) does not fall within the begin..end range of the core VkPipelineBindPoint enumeration tokens and is not an extension added token. The Vulkan spec states: pipelineBindPoint must be a valid VkPipelineBindPoint value (https://vulkan.lunarg.com/doc/view/1.2.170.0/linux/1.2-extensions/vkspec.html#VUID-VkSubpassDescription-pipelineBindPoint-parameter)

This leads me to believe that the proper C struct isn't being passed to Vulkan. This is my function: am I doing something wrong?
function createSimpleRenderpass(vDevice::VulkanDevice, colorFormat, depthFormat, colorFinalLayout) colorAttachmentDesc = VK.AttachmentDescription( colorFormat, VK.SAMPLE_COUNT_1_BIT, VK.VK_ATTACHMENT_LOAD_OP_CLEAR, VK.VK_ATTACHMENT_STORE_OP_STORE, VK.VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK.VK_ATTACHMENT_STORE_OP_DONT_CARE, VK.VK_IMAGE_LAYOUT_UNDEFINED, colorFinalLayout) depthAttachmentDesc = VK.AttachmentDescription( depthFormat, VK.SAMPLE_COUNT_1_BIT, VK.VK_ATTACHMENT_LOAD_OP_CLEAR, VK.VK_ATTACHMENT_STORE_OP_STORE, VK.VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK.VK_ATTACHMENT_STORE_OP_DONT_CARE, VK.VK_IMAGE_LAYOUT_UNDEFINED, VK.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) colorReference = VK.AttachmentReference(0, VK.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) depthReference = VK.AttachmentReference(1, VK.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) println("colorReference: $colorReference") println("depthReference: $depthReference") subpassDescription = VK.SubpassDescription( VK.VK_PIPELINE_BIND_POINT_GRAPHICS, [], [colorReference],[], resolve_attachments = [], depth_stencil_attachment = depthReference) println("SubpassDescription: $SubpassDescription") subpassDependencies = [ VK.SubpassDependency( VK.VK_SUBPASS_EXTERNAL, 0, VK.PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, src_access_mask = VK.VK_ACCESS_MEMORY_READ_BIT, dst_access_mask = VK.VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dependency_flags = VK.VK_DEPENDENCY_BY_REGION_BIT), VK.SubpassDependency( 0, VK.VK_SUBPASS_EXTERNAL, VK.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK.PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, src_access_mask = VK.VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dst_access_mask = VK.VK_ACCESS_MEMORY_READ_BIT, dependency_flags = VK.VK_DEPENDENCY_BY_REGION_BIT)] println("subpassDependencies: $subpassDependencies") unwrap(VK.create_render_pass( vDevice.device, VK.RenderPassCreateInfo([colorAttachmentDesc, depthAttachmentDesc], [SubpassDescription], subpassDependencies))) end

Test if bitmask contains bit

Currently, if we have a bitmask and want to know if it includes a certain bit, we have to do one of

mask & val == val
mask | val == mask

A short function for this would be nice, especially with long identifiers as is usually the case with Vulkan.

I was thinking of val in mask via overloading Base.in(val, mask::BitMask). It's short and the bonus is that Base.in(mask) creates an anonymous function for free.

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.