From 5752dd9f923f4e260a51f1f2928b15a0b7ad37c4 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Thu, 24 Sep 2020 16:59:13 +0800 Subject: [PATCH 1/8] Bump CEnum version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d00a422..1a6220a 100644 --- a/Project.toml +++ b/Project.toml @@ -8,7 +8,7 @@ Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Vulkan_Headers_jll = "8d446b21-f3ad-5576-a034-752265b9b6f9" [compat] -CEnum = "~0.2.0" +CEnum = "0.4.0" julia = "1" [extras] From 6510a51c4bc2b36ccae13f5c976ad480f506311b Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Thu, 24 Sep 2020 17:48:23 +0800 Subject: [PATCH 2/8] Minor fix --- src/LibVulkan.jl | 2 +- test/glfw.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LibVulkan.jl b/src/LibVulkan.jl index 13d1748..61f7dd9 100644 --- a/src/LibVulkan.jl +++ b/src/LibVulkan.jl @@ -3,7 +3,7 @@ module LibVulkan import Libdl paths = String[] -const libvulkan = Libdl.find_library(["libvulkan", "vulkan", "vulkan-1", "libvulkan.so.1"], paths) +const libvulkan = Libdl.find_library(["libvulkan", "vulkan", "vulkan-1", "libvulkan.so.1", "libMoltenVK"], paths) @assert libvulkan != "" using CEnum diff --git a/test/glfw.jl b/test/glfw.jl index e10392e..c38f821 100644 --- a/test/glfw.jl +++ b/test/glfw.jl @@ -16,7 +16,7 @@ flags = UInt32(0) pApplicationInfo = Base.unsafe_convert(Ptr{VkApplicationInfo}, appInfoRef) requiredExtensions = GLFW.GetRequiredInstanceExtensions() @static if Sys.isapple() - @assert "VK_MVK_macos_surface" in requiredExtensions + @assert ("VK_MVK_macos_surface" in requiredExtensions) || ("VK_EXT_metal_surface" in requiredExtensions) end enabledExtensionCount = Ref{Cuint}(0) ppEnabledExtensionNames = ccall((:glfwGetRequiredInstanceExtensions, GLFW.libglfw), Ptr{Cstring}, (Ref{Cuint},), enabledExtensionCount) From 84b6263ab4a53822697138e84151ec01cf58d1b9 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Fri, 25 Sep 2020 11:27:11 +0800 Subject: [PATCH 3/8] Change patch version to meet JuliaRegistrator's auto-merging rule --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 1a6220a..f8f22ce 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "VulkanCore" uuid = "16167f82-ea26-5cba-b1de-ed6fd5e30a11" -version = "1.2.12" +version = "1.2.0" [deps] CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82" From d24dd8dee5667e0fd1d7f9d3f2cf4f46f8b564d8 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Wed, 30 Sep 2020 20:20:54 +0800 Subject: [PATCH 4/8] Add missing constants and helper functions --- src/LibVulkan.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/LibVulkan.jl b/src/LibVulkan.jl index 61f7dd9..98dfd30 100644 --- a/src/LibVulkan.jl +++ b/src/LibVulkan.jl @@ -39,6 +39,17 @@ const ANativeWindow = Cvoid # TODO: make opaque for now const HINSTANCE = Ptr{Cvoid} const HWND = Ptr{Cvoid} +# TODO: Clang.jl should support this kinda macros +VK_MAKE_VERSION(major, minor, patch) = ( Cuint(major) << 22 ) | ( Cuint(minor) << 12 ) | patch + +VK_VERSION_MAJOR(version) = Cuint(version) >> 22 +VK_VERSION_MINOR(version) = (Cuint(version) >> 12) & 0x3ff +VK_VERSION_PATCH(version) = Cuint(version) & 0xfff + +const VK_API_VERSION_1_0 = VK_MAKE_VERSION(1, 0, 0) +const VK_API_VERSION_1_1 = VK_MAKE_VERSION(1, 1, 0) +const VK_API_VERSION_1_2 = VK_MAKE_VERSION(1, 2, 0) + include(joinpath(@__DIR__, "..", "gen", "vk_common.jl")) include(joinpath(@__DIR__, "..", "gen", "vk_api.jl")) From 92fcbb857d0b1a48a4b9e444eb33be599b3c7aa7 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Sun, 4 Oct 2020 11:18:22 +0800 Subject: [PATCH 5/8] Add support for custom Vulkan SDK names --- src/LibVulkan.jl | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/LibVulkan.jl b/src/LibVulkan.jl index 98dfd30..69ff169 100644 --- a/src/LibVulkan.jl +++ b/src/LibVulkan.jl @@ -2,9 +2,27 @@ module LibVulkan import Libdl -paths = String[] -const libvulkan = Libdl.find_library(["libvulkan", "vulkan", "vulkan-1", "libvulkan.so.1", "libMoltenVK"], paths) -@assert libvulkan != "" +@static if Sys.iswindows() + const libvulkan = "vulkan-1.dll" +elseif Sys.isapple() + const libvulkan = "libvulkan.dylib" +elseif Sys.islinux() + const libvulkan = "libvulkan.so.1" +else + const libvulkan = "libvulkan" +end + +libvulkan_handle = C_NULL + +function __init__() + libname = get(ENV, "JULIA_VULKAN_SDK_LIBNAME", "") + locations = get(ENV, "JULIA_VULKAN_SDK_SEARCH_PATH", "") + if isempty(libname) + libname = Libdl.find_library(["libvulkan", "vulkan", "vulkan-1", "libvulkan.so.1"], locations) + end + @assert libname != "" "cannot detect Vulkan SDK." + global libvulkan_handle = Libdl.dlopen(libname) +end using CEnum From 88991328c3db0523418e29b68d219300e36633d1 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Sun, 4 Oct 2020 12:00:15 +0800 Subject: [PATCH 6/8] Drop travis and appveyor --- .appveyor.yml | 34 ---------------------------------- .travis.yml | 26 -------------------------- 2 files changed, 60 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .travis.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 767903b..0000000 --- a/.appveyor.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Documentation: https://github.com/JuliaCI/Appveyor.jl -environment: - matrix: - - julia_version: 1.0 - - julia_version: 1.1 - - julia_version: 1.2 - - julia_version: 1.3 - - julia_version: nightly -platform: - - x86 - - x64 -matrix: - allow_failures: - - julia_version: nightly -branches: - only: - - master - - /release-.*/ -notifications: - - provider: Email - on_build_success: false - on_build_failure: false - on_build_status_changed: false -install: - - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) -build_script: - - echo "%JL_BUILD_SCRIPT%" - - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" -test_script: - - echo "%JL_TEST_SCRIPT%" - - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" -on_success: - - echo "%JL_CODECOV_SCRIPT%" - - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dcb762c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Documentation: http://docs.travis-ci.com/user/languages/julia/ -language: julia -os: - - linux -julia: - - 1.0 - - 1.1 - - 1.2 - - 1.3 - - nightly -matrix: - allow_failures: - - julia: nightly - fast_finish: true -notifications: - email: false -dist: trusty -sudo: false -addons: - apt: - packages: - - xorg-dev -before_script: - - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start; fi -after_success: - - julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())' From 27c2ae5aad696723bc7b7b805a282af92d0116a4 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Sun, 4 Oct 2020 12:00:45 +0800 Subject: [PATCH 7/8] Set up Github Actions, tweak tests and misc. bugfixes --- .github/workflows/ci.yml | 109 ++++++++++++++++ README.md | 5 +- src/LibVulkan.jl | 4 +- test/glfw.jl | 74 ++++++----- test/old_tests.jl | 121 ++++++++++++++++++ test/runtests.jl | 122 +----------------- test/vk_utils.jl | 2 - test/vkhelper.jl | 267 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 553 insertions(+), 151 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 test/old_tests.jl delete mode 100644 test/vk_utils.jl create mode 100644 test/vkhelper.jl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..076c85a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,109 @@ +# Based on https://github.com/vsg-dev/VulkanSceneGraph/blob/master/.github/workflows/ci.yml +name: CI +on: + push: + pull_request: +env: + JuliaVersion: 1.5 + VulkanSDKVersion: 1.2.148.1 + JULIA_GITHUB_ACTIONS_CI: ON +jobs: + ubuntu-latest-x64: + runs-on: ubuntu-latest + env: + VULKAN_SDK: $GITHUB_WORKSPACE/../$VulkanSDKVersion/x86_64 + steps: + - uses: actions/checkout@v2 + - name: Cache + id: cache + uses: actions/cache@v2 + with: + path: ${{env.VULKAN_SDK}} + key: VulkanSdk${{env.VulkanSDKVersion}}ExtractedLinux + - name: Download & Extract Vulkan SDK + if: steps.cache.outputs.cache-hit != 'true' + run: | + wget --no-cookies -O ../vulkansdk-linux-x86_64-${{env.VulkanSDKVersion}}.tar.gz https://sdk.lunarg.com/sdk/download/${{env.VulkanSDKVersion}}/linux/vulkansdk-linux-x86_64-${{env.VulkanSDKVersion}}.tar.gz?u= + tar -zxf ../vulkansdk-linux-x86_64-${{env.VulkanSDKVersion}}.tar.gz -C ../ + - name: Install xvfb for GLFW + run: sudo apt-get install xvfb && Xvfb :99 & + - uses: julia-actions/setup-julia@v1 + with: + version: ${{env.JuliaVersion}} + arch: x64 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + env: + DISPLAY: :99 + - uses: julia-actions/julia-uploadcodecov@latest + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + windows-latest-x64: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Set env + run: echo "::set-env name=VULKAN_SDK::C:\VulkanSDK\${{env.VulkanSDKVersion}}" + - name: Cache + id: cache + uses: actions/cache@v2 + with: + path: ${{env.VULKAN_SDK}} + key: VulkanSdk${{env.VulkanSDKVersion}}WindowsExtracted2 + - name: Download & Install Vulkan SDK + if: steps.cache.outputs.cache-hit != 'true' + run: | + Invoke-WebRequest -Uri https://sdk.lunarg.com/sdk/download/${{env.VulkanSDKVersion}}/windows/VulkanSDK-${{env.VulkanSDKVersion}}-Installer.exe?u= -OutFile ../vulkan-sdk-${{env.VulkanSDKVersion}}.exe + $installer = Start-Process -FilePath ../vulkan-sdk-${{env.VulkanSDKVersion}}.exe -Wait -PassThru -ArgumentList @("/S"); + $installer.WaitForExit(); + Invoke-WebRequest -Uri https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-runtime.exe -OutFile ../vulkan-runtime.exe + $installer = Start-Process -FilePath ../vulkan-runtime.exe -Wait -PassThru -ArgumentList @("/S"); + $installer.WaitForExit(); + - uses: julia-actions/setup-julia@v1 + with: + version: ${{env.JuliaVersion}} + arch: x64 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + env: + DISPLAY: :99 + - uses: julia-actions/julia-uploadcodecov@latest + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + macos-latest-x64: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Set env + run: | + VULKAN_SDK=$GITHUB_WORKSPACE/../vulkansdk-macos-${{env.VulkanSDKVersion}}/macOS + echo ::set-env name=VULKAN_SDK::$VULKAN_SDK + echo ::set-env name=JULIA_VULKAN_SDK_SEARCH_PATH::$VULKAN_SDK/bin + echo ::set-env name=VK_LAYER_PATH::$VULKAN_SDK/share/vulkan/explicit_layer.d + echo ::set-env name=VK_ICD_FILENAMES::$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json + - name: Cache + id: cache + uses: actions/cache@v2 + with: + path: ${{env.VULKAN_SDK}} + key: VulkanSdk${{env.VulkanSDKVersion}}ExtractedMacos + - name: Download & Extract Vulkan SDK + if: steps.cache.outputs.cache-hit != 'true' + run: | + wget --no-cookies -O ../vulkansdk-macos-${{env.VulkanSDKVersion}}.dmg https://sdk.lunarg.com/sdk/download/${{env.VulkanSDKVersion}}/mac/vulkansdk-macos-${{env.VulkanSDKVersion}}.dmg?u= + hdiutil attach ../vulkansdk-macos-${{env.VulkanSDKVersion}}.dmg + cp -r /Volumes/vulkansdk-macos-${{env.VulkanSDKVersion}} ../ + hdiutil detach /Volumes/vulkansdk-macos-${{env.VulkanSDKVersion}} + - uses: julia-actions/setup-julia@v1 + with: + version: ${{env.JuliaVersion}} + arch: x64 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + env: + DISPLAY: :99 + - uses: julia-actions/julia-uploadcodecov@latest + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index 5f13756..8121b34 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # VulkanCore -[![Build Status](https://travis-ci.org/JuliaGPU/VulkanCore.jl.svg?branch=master)](https://travis-ci.org/JuliaGPU/VulkanCore.jl) +![CI](https://github.com/JuliaGPU/VulkanCore.jl/workflows/CI/badge.svg) +![TagBot](https://github.com/JuliaGPU/VulkanCore.jl/workflows/TagBot/badge.svg) 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 @@ -22,7 +23,7 @@ If these are present, just run `pkg> add VulkanCore` in Julia. - [Vulkan Specification](https://www.khronos.org/registry/vulkan/#apispecs) ## Usage -The Vulkan wrapper is generated using [Clang.jl](https://github.com/JuliaInterop/Clang.jl) +The Vulkan wrapper is generated using [Clang.jl](https://github.com/JuliaInterop/Clang.jl) with the [generator file](gen/generator.jl). The API aims to replicate the Vulkan C-API and is thus very bare bones and hands-on. diff --git a/src/LibVulkan.jl b/src/LibVulkan.jl index 69ff169..cc501f0 100644 --- a/src/LibVulkan.jl +++ b/src/LibVulkan.jl @@ -16,7 +16,7 @@ libvulkan_handle = C_NULL function __init__() libname = get(ENV, "JULIA_VULKAN_SDK_LIBNAME", "") - locations = get(ENV, "JULIA_VULKAN_SDK_SEARCH_PATH", "") + locations = [get(ENV, "JULIA_VULKAN_SDK_SEARCH_PATH", "")] if isempty(libname) libname = Libdl.find_library(["libvulkan", "vulkan", "vulkan-1", "libvulkan.so.1"], locations) end @@ -71,6 +71,8 @@ const VK_API_VERSION_1_2 = VK_MAKE_VERSION(1, 2, 0) include(joinpath(@__DIR__, "..", "gen", "vk_common.jl")) include(joinpath(@__DIR__, "..", "gen", "vk_api.jl")) +const VK_HEADER_VERSION_COMPLETE = VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) + # export everything foreach(names(@__MODULE__, all=true)) do s if startswith(string(s), "VK_") || startswith(string(s), "Vk") || startswith(string(s), "vk") diff --git a/test/glfw.jl b/test/glfw.jl index c38f821..b384394 100644 --- a/test/glfw.jl +++ b/test/glfw.jl @@ -1,34 +1,48 @@ +using GLFW +using VulkanCore +using VulkanCore.LibVulkan + +@assert GLFW.VulkanSupported() + +include("vkhelper.jl") + const WIDTH = 800 const HEIGHT = 600 -# fill application info -sType = VK_STRUCTURE_TYPE_APPLICATION_INFO -pApplicationName = pointer(b"Vulkan Instance") -applicationVersion = convert_vk_back(UInt32, v"1.1") -pEngineName = pointer(b"Test") -engineVersion = convert_vk_back(UInt32, v"1.1") -apiVersion = convert_vk_back(UInt32, v"1.1") -appInfoRef = VkApplicationInfo(sType, C_NULL, pApplicationName, applicationVersion, pEngineName, engineVersion, apiVersion) |> Ref - -# fill create info -sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO -flags = UInt32(0) -pApplicationInfo = Base.unsafe_convert(Ptr{VkApplicationInfo}, appInfoRef) -requiredExtensions = GLFW.GetRequiredInstanceExtensions() -@static if Sys.isapple() - @assert ("VK_MVK_macos_surface" in requiredExtensions) || ("VK_EXT_metal_surface" in requiredExtensions) +## init GLFW window +GLFW.WindowHint(GLFW.CLIENT_API, GLFW.NO_API) # not to create an OpenGL context +GLFW.WindowHint(GLFW.RESIZABLE, 0) +window = GLFW.CreateWindow(WIDTH, HEIGHT, "Vulkan") + +## init Vulkan +## creating instance +appInfoRef = VkApplicationInfo( + "Application Name: Create Instance", + v"1.0.0", + "No Engine Name", + v"1.0.0", + VK_API_VERSION_1_2, +) |> Ref + +extensions = GLFW.GetRequiredInstanceExtensions() +@test check_extensions(extensions) + +layers = get(ENV, "JULIA_GITHUB_ACTIONS_CI", "OFF") == "ON" ? String[] : ["VK_LAYER_KHRONOS_validation"] +@test check_layers(layers) + +createInfoRef = VkInstanceCreateInfo(appInfoRef, layers, extensions) |> Ref + +instanceRef = Ref(VkInstance(C_NULL)) +result = GC.@preserve appInfoRef layers extensions vkCreateInstance(createInfoRef, C_NULL, instanceRef) + +@static if get(ENV, "JULIA_GITHUB_ACTIONS_CI", "OFF") == "ON" + @test_broken result == VK_SUCCESS +else + @test result == VK_SUCCESS +end + +## cleaning up +if result == VK_SUCCESS + vkDestroyInstance(instanceRef[], C_NULL) end -enabledExtensionCount = Ref{Cuint}(0) -ppEnabledExtensionNames = ccall((:glfwGetRequiredInstanceExtensions, GLFW.libglfw), Ptr{Cstring}, (Ref{Cuint},), enabledExtensionCount) -enabledExtensionCount = enabledExtensionCount[] -enabledLayerCount = Cuint(0) -ppEnabledLayerNames = C_NULL -createInfoRef = VkInstanceCreateInfo(sType, C_NULL, flags, pApplicationInfo, enabledLayerCount, ppEnabledLayerNames, enabledExtensionCount, ppEnabledExtensionNames) |> Ref - -# create instance -instanceRef = Ref{VkInstance}(C_NULL) -result = vkCreateInstance(createInfoRef, C_NULL, instanceRef) -result != VK_SUCCESS && error("failed to create instance!") -instance = instanceRef[] -@show instance -vkDestroyInstance(instance, C_NULL) +GLFW.DestroyWindow(window) \ No newline at end of file diff --git a/test/old_tests.jl b/test/old_tests.jl new file mode 100644 index 0000000..f9a7baa --- /dev/null +++ b/test/old_tests.jl @@ -0,0 +1,121 @@ +using VulkanCore +using VulkanCore.LibVulkan +using Test +using GLFW + +const api = VulkanCore.vk + +convert_vk_back(::Type{UInt32}, version::VersionNumber) = (version.major << 22) + (version.minor << 12) + version.patch +convert_vk(::Type{VersionNumber}, version::UInt32) = VersionNumber(UInt32(version) >> 22, (UInt32(version) >> 12) & 0x3ff, UInt32(version) & 0xfff) + +err = VkResult(0) +count = Ref{Cuint}(0) +# Scan layers +err = api.vkEnumerateInstanceLayerProperties(count, C_NULL) +@assert err == api.VK_SUCCESS +global_layer_properties = Vector{api.VkLayerProperties}(undef, count[]) +err = api.vkEnumerateInstanceLayerProperties(count, global_layer_properties) +@assert err == api.VK_SUCCESS + +function Base.show(io::IO, lp::api.VkLayerProperties) + println(io, "Layer Properties: ") + println(io, " Layer Name: ", String(filter(x->x!=0, UInt8[lp.layerName...]))) + println(io, " Spec Version: ", convert_vk(VersionNumber, lp.specVersion)) + println(io, " Implementation Version: ", convert_vk(VersionNumber, lp.implementationVersion)) + println(io, " description: ", String(filter(x->x!=0, UInt8[lp.description...]))) +end +for elem in global_layer_properties + println(elem) +end + +appname = b"vulkaninfo" + +app_info = Ref(VkApplicationInfo(VK_STRUCTURE_TYPE_APPLICATION_INFO, + C_NULL, + pointer(appname), + 1, + pointer(appname), + 1, + convert_vk_back(UInt32, v"1.1"))) + +inst_info = Ref(VkInstanceCreateInfo(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + C_NULL, + UInt32(0), + Base.unsafe_convert(Ptr{VkApplicationInfo}, app_info), + 0, + C_NULL, + 0, + C_NULL)) + +instance = Ref{VkInstance}(C_NULL) + +err = vkCreateInstance(inst_info, C_NULL, instance) +@test err == VK_SUCCESS +println(instance) + +gpu_count = Ref{Cuint}(0) +err = vkEnumeratePhysicalDevices(instance[], gpu_count, C_NULL) +@test err == VK_SUCCESS +devices = Array{VkPhysicalDevice}(undef, gpu_count[]) + +err = vkEnumeratePhysicalDevices(instance[], gpu_count, devices) +@test err == VK_SUCCESS + +deviceprops = Ref{VkPhysicalDeviceProperties}() +vkGetPhysicalDeviceProperties(devices[], deviceprops) + + +function Base.show(io::IO, pdsp::VkPhysicalDeviceSparseProperties) + println(io, "Physical device Sparse Properties: ") + for name in fieldnames(typeof(pdsp)) + println(io, " ", name, " ", getfield(pdsp, name) == 1) + end +end +function Base.show(io::IO, pdp::VkPhysicalDeviceProperties) + println(io, "Physical Device Properties: ") + println(io, " API Version: ", convert_vk(VersionNumber, pdp.apiVersion)) + println(io, " Driver Version: ", convert_vk(VersionNumber, pdp.driverVersion)) + + println(io, " Vendor ID ", pdp.vendorID) + println(io, " Device ID: ", pdp.deviceID) + println(io, " Device Type: ", pdp.deviceType) + println(io, " Device Name: ", String(filter(x->x!=0, UInt8[pdp.deviceName...]))) + println(io, " Pipeline Cache UUID: ", String(collect(pdp.pipelineCacheUUID))) + println(io, " Limits: ", pdp.limits) + println(io, " Sparse Properties: \n ", pdp.sparseProperties) +end + +limitshow(x::Cuint) = Int(x) +limitshow(x::NTuple) = "<"*join(map(limitshow, x), " ")*">" +limitshow(x) = x + +function Base.show(io::IO, pdl::VkPhysicalDeviceLimits) + println(io, "Physical Device Limits: ") + for name in fieldnames(typeof(pdl)) + println(io, " ", name, " ", limitshow(getfield(pdl, name))) + end +end + +println(deviceprops[]) + +queue_count = Ref{Cuint}(0) +vkGetPhysicalDeviceQueueFamilyProperties(devices[], queue_count, C_NULL) +queueprops = Array{VkQueueFamilyProperties}(undef, queue_count[]) +println(queue_count[]) +vkGetPhysicalDeviceQueueFamilyProperties(devices[], queue_count, queueprops) +println(queueprops) + +memprops = Ref{VkPhysicalDeviceMemoryProperties}() +vkGetPhysicalDeviceMemoryProperties(devices[], memprops) + +println(memprops[]) +devicefeatures = Ref{VkPhysicalDeviceFeatures}() +vkGetPhysicalDeviceFeatures(devices[], devicefeatures) + +function Base.show(io::IO, df::VkPhysicalDeviceFeatures) + println(io, "Physical device features: ") + for name in fieldnames(typeof(df)) + println(io, " ", name, ": ", getfield(df, name) != 1 ? "un" : "", "supported") + end +end +println(devicefeatures[]) diff --git a/test/runtests.jl b/test/runtests.jl index 6e263a2..83cc269 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,122 +3,12 @@ using VulkanCore.LibVulkan using Test using GLFW -const api = vk - -include("vk_utils.jl") - -err = api.VkResult(0) -count = Ref{Cuint}(0) -# Scan layers -err = api.vkEnumerateInstanceLayerProperties(count, C_NULL) -@assert err == api.VK_SUCCESS -global_layer_properties = Vector{api.VkLayerProperties}(undef, count[]) -err = api.vkEnumerateInstanceLayerProperties(count, global_layer_properties) -@assert err == api.VK_SUCCESS - -function Base.show(io::IO, lp::api.VkLayerProperties) - println(io, "Layer Properties: ") - println(io, " Layer Name: ", String(filter(x->x!=0, UInt8[lp.layerName...]))) - println(io, " Spec Version: ", convert_vk(VersionNumber, lp.specVersion)) - println(io, " Implementation Version: ", convert_vk(VersionNumber, lp.implementationVersion)) - println(io, " description: ", String(filter(x->x!=0, UInt8[lp.description...]))) -end -for elem in global_layer_properties - println(elem) -end - -appname = b"vulkaninfo" - -app_info = Ref(VkApplicationInfo(VK_STRUCTURE_TYPE_APPLICATION_INFO, - C_NULL, - pointer(appname), - 1, - pointer(appname), - 1, - convert_vk_back(UInt32, v"1.1"))) - -inst_info = Ref(VkInstanceCreateInfo(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - C_NULL, - UInt32(0), - Base.unsafe_convert(Ptr{VkApplicationInfo}, app_info), - 0, - C_NULL, - 0, - C_NULL)) - -instance = Ref{VkInstance}(C_NULL) - -err = vkCreateInstance(inst_info, C_NULL, instance) -@test err == VK_SUCCESS -println(instance) - -gpu_count = Ref{Cuint}(0) -err = vkEnumeratePhysicalDevices(instance[], gpu_count, C_NULL) -@test err == VK_SUCCESS -devices = Array{VkPhysicalDevice}(undef, gpu_count[]) - -err = vkEnumeratePhysicalDevices(instance[], gpu_count, devices) -@test err == VK_SUCCESS - -deviceprops = Ref{VkPhysicalDeviceProperties}() -vkGetPhysicalDeviceProperties(devices[], deviceprops) - - -function Base.show(io::IO, pdsp::VkPhysicalDeviceSparseProperties) - println(io, "Physical device Sparse Properties: ") - for name in fieldnames(typeof(pdsp)) - println(io, " ", name, " ", getfield(pdsp, name) == 1) +@testset "GLFW" begin + if GLFW.VulkanSupported() + include("glfw.jl") end end -function Base.show(io::IO, pdp::VkPhysicalDeviceProperties) - println(io, "Physical Device Properties: ") - println(io, " API Version: ", convert_vk(VersionNumber, pdp.apiVersion)) - println(io, " Driver Version: ", convert_vk(VersionNumber, pdp.driverVersion)) - println(io, " Vendor ID ", pdp.vendorID) - println(io, " Device ID: ", pdp.deviceID) - println(io, " Device Type: ", pdp.deviceType) - println(io, " Device Name: ", String(filter(x->x!=0, UInt8[pdp.deviceName...]))) - println(io, " Pipeline Cache UUID: ", String(collect(pdp.pipelineCacheUUID))) - println(io, " Limits: ", pdp.limits) - println(io, " Sparse Properties: \n ", pdp.sparseProperties) -end - -limitshow(x::Cuint) = Int(x) -limitshow(x::NTuple) = "<"*join(map(limitshow, x), " ")*">" -limitshow(x) = x - -function Base.show(io::IO, pdl::VkPhysicalDeviceLimits) - println(io, "Physical Device Limits: ") - for name in fieldnames(typeof(pdl)) - println(io, " ", name, " ", limitshow(getfield(pdl, name))) - end -end - -println(deviceprops[]) - -queue_count = Ref{Cuint}(0) -vkGetPhysicalDeviceQueueFamilyProperties(devices[], queue_count, C_NULL) -queueprops = Array{VkQueueFamilyProperties}(undef, queue_count[]) -println(queue_count[]) -vkGetPhysicalDeviceQueueFamilyProperties(devices[], queue_count, queueprops) -println(queueprops) - -memprops = Ref{VkPhysicalDeviceMemoryProperties}() -vkGetPhysicalDeviceMemoryProperties(devices[], memprops) - -println(memprops[]) -devicefeatures = Ref{VkPhysicalDeviceFeatures}() -vkGetPhysicalDeviceFeatures(devices[], devicefeatures) - -function Base.show(io::IO, df::VkPhysicalDeviceFeatures) - println(io, "Physical device features: ") - for name in fieldnames(typeof(df)) - println(io, " ", name, ": ", getfield(df, name) != 1 ? "un" : "", "supported") - end -end -println(devicefeatures[]) - -@static if GLFW.VulkanSupported() - include("glfw.jl") -end +@static if get(ENV, "JULIA_GITHUB_ACTIONS_CI", "OFF") == "OFF" + include("old_tests.jl") +end \ No newline at end of file diff --git a/test/vk_utils.jl b/test/vk_utils.jl deleted file mode 100644 index b070735..0000000 --- a/test/vk_utils.jl +++ /dev/null @@ -1,2 +0,0 @@ -convert_vk_back(::Type{UInt32}, version::VersionNumber) = (version.major << 22) + (version.minor << 12) + version.patch -convert_vk(::Type{VersionNumber}, version::UInt32) = VersionNumber(UInt32(version) >> 22, (UInt32(version) >> 12) & 0x3ff, UInt32(version) & 0xfff) diff --git a/test/vkhelper.jl b/test/vkhelper.jl new file mode 100644 index 0000000..c14e0f2 --- /dev/null +++ b/test/vkhelper.jl @@ -0,0 +1,267 @@ +using VulkanCore +using VulkanCore.LibVulkan + +# utils +""" + unsafe_strings2pp(names) -> Ptr{String} +Dump a pointer that is of type `Ptr{String}` from a Julia `String` array. +""" +unsafe_strings2pp(names::Vector{String}) = Base.unsafe_convert(Ptr{Cstring}, Base.cconvert(Ptr{Cstring}, names)) + +""" + to_string(x::NTuple{N,UInt8}) -> String +Convert a `NTuple{N,UInt8}` to `String` dropping all of the `\0`s. +""" +to_string(x::NTuple{N,UInt8}) where {N} = rstrip(String(collect(x)), '\0') + +""" + int2version(::Type{VersionNumber}, ver::Integer) -> VersionNumber +Convert a Vulkan version integer to a `major.minor.patch` `VersionNumber`. +""" +int2version(v::Integer) = VersionNumber(VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), VK_VERSION_PATCH(v)) + +# extension & layer checking +struct ExtensionProperties + name::String + version::VersionNumber +end +ExtensionProperties(extension::VkExtensionProperties) = + ExtensionProperties(to_string(extension.extensionName), int2version(extension.specVersion)) + +struct LayerProperties + name::String + spec_ver::VersionNumber + impl_ver::VersionNumber + description::String +end +LayerProperties(layer::VkLayerProperties) = LayerProperties( + to_string(layer.layerName), + int2version(layer.specVersion), + int2version(layer.implementationVersion), + to_string(layer.description), +) + +""" + get_supported_extensions() -> Vector{String} +Return a vector of supported extensions. +""" +function get_supported_extensions() + count_ref = Ref{Cuint}(0) + vkEnumerateInstanceExtensionProperties(C_NULL, count_ref, C_NULL) + count = count_ref[] + extensions = Vector{VkExtensionProperties}(undef, count) + vkEnumerateInstanceExtensionProperties(C_NULL, count_ref, extensions) + return [ExtensionProperties(ext) for ext in extensions] +end + +""" + check_extensions(required_extensions::Vector{<:AbstractString}) -> Bool +Return `true` when all of the `required_extensions` are supported. +""" +function check_extensions(required_extensions::Vector{<:AbstractString}) + supported = get_supported_extensions() + @info "available extensions:" + for x in supported + @info " $(x.name): $(x.version)" + end + names = [x.name for x in supported] + if all(x->x in names, required_extensions) + return true + else + @error "not all required extensions are supported." + @error "required extensions:" + for extension in required_extensions + @error " $extension" + end + return false + end +end + +""" + get_supported_layers() -> Vector{String} +Return a vector of supported layers. +""" +function get_supported_layers() + count_ref = Ref{Cuint}(0) + vkEnumerateInstanceLayerProperties(count_ref, C_NULL) + count = count_ref[] + layers = Vector{VkLayerProperties}(undef, count) + vkEnumerateInstanceLayerProperties(count_ref, layers) + return [LayerProperties(layer) for layer in layers] +end + +""" + check_layers(required_layers::Vector{<:AbstractString}) -> Bool +Return `true` when all of the `required_layers` are supported. +""" +function check_layers(required_layers::Vector{<:AbstractString}) + supported = get_supported_layers() + @info "available layers:" + for x in supported + @info " $(x.name): $(x.description)($(x.spec_ver)) -- implementation version: $(x.impl_ver)" + end + names = [layer.name for layer in supported] + if all(x->x in names, required_layers) + return true + else + @error "not all required layers are supported." + @error "required layers:" + for layer in required_layers + @error " $layer" + end + return false + end +end + +# instance +function LibVulkan.VkApplicationInfo(app_name::AbstractString, app_ver::VersionNumber, engine_name::AbstractString, engine_ver::VersionNumber, api_ver::Integer) + sType = VK_STRUCTURE_TYPE_APPLICATION_INFO + pNext = C_NULL # reserved for extension-specific structure + pApplicationName = pointer(app_name) + vkApplicationVersion = VK_MAKE_VERSION(app_ver.major, app_ver.minor, app_ver.patch) + pEngineName = pointer(engine_name) + vkEngineVersion = VK_MAKE_VERSION(engine_ver.major, engine_ver.minor, engine_ver.patch) + return VkApplicationInfo(sType, pNext, pApplicationName, vkApplicationVersion, pEngineName, vkEngineVersion, Cuint(api_ver)) +end + +function LibVulkan.VkInstanceCreateInfo(app_info_ref::Ref{VkApplicationInfo}, layers::Vector{String}, extensions::Vector{String}) + sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO + pNext = C_NULL # reserved for extension-specific structure + flags = UInt32(0) # reserved for future use + ppEnabledLayerNames = isempty(layers) ? C_NULL : unsafe_strings2pp(layers) + ppEnabledExtensionNames = isempty(extensions) ? C_NULL : unsafe_strings2pp(extensions) + pApplicationInfo = Base.unsafe_convert(Ptr{VkApplicationInfo}, app_info_ref) + return VkInstanceCreateInfo(sType, pNext, flags, pApplicationInfo, length(layers), ppEnabledLayerNames, length(extensions), ppEnabledExtensionNames) +end + +function LibVulkan.VkInstanceCreateInfo(app_info_ref::Ref{VkApplicationInfo}, debug_info_ref::Ref{VkDebugUtilsMessengerCreateInfoEXT}, layers::Vector{String}, extensions::Vector{String}) + sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO + pNext = Base.unsafe_convert(Ptr{Cvoid}, debug_info_ref) + flags = UInt32(0) # reserved for future use + ppEnabledLayerNames = isempty(layers) ? C_NULL : unsafe_strings2pp(layers) + ppEnabledExtensionNames = isempty(extensions) ? C_NULL : unsafe_strings2pp(extensions) + pApplicationInfo = Base.unsafe_convert(Ptr{VkApplicationInfo}, app_info_ref) + return VkInstanceCreateInfo(sType, pNext, flags, pApplicationInfo, length(layers), ppEnabledLayerNames, length(extensions), ppEnabledExtensionNames) +end + + +# debug +function debug_callback(severity::VkDebugUtilsMessageSeverityFlagBitsEXT, type::VkDebugUtilsMessageTypeFlagsEXT, pCallbackData::Ptr{VkDebugUtilsMessengerCallbackDataEXT}, pUserData::Ptr{Cvoid})::VkBool32 + data = unsafe_load(pCallbackData) + if severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT + @debug "validation layer: $(Base.unsafe_string(data.pMessage))" + elseif severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT + @info "validation layer: $(Base.unsafe_string(data.pMessage))" + elseif severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + @warn "validation layer: $(Base.unsafe_string(data.pMessage))" + elseif severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + @error "validation layer: $(Base.unsafe_string(data.pMessage))" + end + return VK_FALSE +end + +function LibVulkan.VkDebugUtilsMessengerCreateInfoEXT(messageSeverity, messageType, pfnUserCallback, pUserData) + sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT + pNext = C_NULL # reserved for extension-specific structure + flags = UInt32(0) # reserved for future use + return VkDebugUtilsMessengerCreateInfoEXT(sType, pNext, flags, messageSeverity, messageType, pfnUserCallback, pUserData) +end + +function LibVulkan.VkDebugUtilsMessengerCreateInfoEXT(pfnUserCallback, pUserData) + messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT + return VkDebugUtilsMessengerCreateInfoEXT(messageSeverity, messageType, pfnUserCallback, pUserData) +end + +function CreateDebugUtilsMessengerEXT(instance::VkInstance, pCreateInfo::Ref{VkDebugUtilsMessengerCreateInfoEXT}, pAllocator, pDebugMessenger::Ref{VkDebugUtilsMessengerEXT}) + fp = vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT") + if fp != C_NULL + ccall(fp, VkResult, (VkInstance, Ptr{VkDebugUtilsMessengerCreateInfoEXT}, Ptr{VkAllocationCallbacks}, Ptr{VkDebugUtilsMessengerEXT}), instance, pCreateInfo, pAllocator, pDebugMessenger) + else + return VK_ERROR_EXTENSION_NOT_PRESENT + end +end + +function DestroyDebugUtilsMessengerEXT(instance::VkInstance, debugMessenger::VkDebugUtilsMessengerEXT, pAllocator) + fp = vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT") + if fp != C_NULL + ccall(fp, VkResult, (VkInstance, VkDebugUtilsMessengerEXT, Ptr{VkAllocationCallbacks}), instance, debugMessenger, pAllocator) + end +end + +## device and queue family +""" + get_devices(instance::VkInstance) -> Vector{VkPhysicalDevice} +Return a vector of devices. +""" +function get_devices(instance::VkInstance) + count_ref = Ref{Cuint}(0) + vkEnumeratePhysicalDevices(instance, count_ref, C_NULL) + count = count_ref[] + if count == 0 + @error "failed to find GPUs with Vulkan support!" + end + devices = Vector{VkPhysicalDevice}(undef, count) + vkEnumeratePhysicalDevices(instance, count_ref, devices) + return devices +end + +mutable struct QueueFamilyIndices + graphicsFamily::Union{Nothing,Cuint} +end +QueueFamilyIndices() = QueueFamilyIndices(nothing) +is_complete(x::QueueFamilyIndices) = x.graphicsFamily != nothing + +""" + get_queue_family_properties(device::VkPhysicalDevice) -> Vector{VkQueueFamilyProperties} +Return a vector of `VkQueueFamilyProperties`. +""" +function get_queue_family_properties(device::VkPhysicalDevice) + count_ref = Ref{Cuint}(0) + vkGetPhysicalDeviceQueueFamilyProperties(device, count_ref, C_NULL) + properties = Vector{VkQueueFamilyProperties}(undef, count_ref[]) + vkGetPhysicalDeviceQueueFamilyProperties(device, count_ref, properties) + return properties +end + +""" + find_queue_families(device::VkPhysicalDevice) -> QueueFamilyIndices +Return a `QueueFamilyIndices` for the input device. +""" +function find_queue_families(device::VkPhysicalDevice) + indices = QueueFamilyIndices() + families = get_queue_family_properties(device) + for (i,family) in enumerate(families) + if Bool(family.queueFlags & VK_QUEUE_GRAPHICS_BIT) + indices.graphicsFamily = i + end + is_complete(indices) && break + end + return indices +end + +function LibVulkan.VkDeviceQueueCreateInfo(queue_idxs::QueueFamilyIndices, queue_count::Integer, priority::Ref{Cfloat}) + sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO + pNext = C_NULL # reserved for extension-specific structure + flags = UInt32(0) # reserved for future use + queueFamilyIndex = queue_idxs.graphicsFamily + pQueuePriorities = Base.unsafe_convert(Ptr{Cfloat}, priority) + return VkDeviceQueueCreateInfo(sType, pNext, flags, queueFamilyIndex, queue_count, pQueuePriorities) +end + +function LibVulkan.VkDeviceCreateInfo(queue_count::Integer, queue_info::Ref{VkDeviceQueueCreateInfo}, features::Ref{VkPhysicalDeviceFeatures}) + sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO + pNext = C_NULL # reserved for extension-specific structure + flags = UInt32(0) # reserved for future use + queueCreateInfoCount = queue_count + pQueueCreateInfos = Base.unsafe_convert(Ptr{VkDeviceQueueCreateInfo}, queueCreateInfoRef) + pEnabledFeatures = Base.unsafe_convert(Ptr{VkPhysicalDeviceFeatures}, deviceFeaturesRef) + return VkDeviceCreateInfo(sType, pNext, flags, queueCreateInfoCount, pQueueCreateInfos, 0, C_NULL, 0, C_NULL, pEnabledFeatures) +end + +LibVulkan.VkPhysicalDeviceFeatures() = VkPhysicalDeviceFeatures(fill(VK_FALSE,55)...) \ No newline at end of file From 966c3eaf080cf40dcaafc1189c6ef02e56cf2197 Mon Sep 17 00:00:00 2001 From: Gnimuc Date: Sun, 4 Oct 2020 18:59:00 +0800 Subject: [PATCH 8/8] Remove the cache action and fix lib path on macOS --- .github/workflows/ci.yml | 27 +++------------------------ src/LibVulkan.jl | 1 + 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 076c85a..d7be71c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,14 +14,7 @@ jobs: VULKAN_SDK: $GITHUB_WORKSPACE/../$VulkanSDKVersion/x86_64 steps: - uses: actions/checkout@v2 - - name: Cache - id: cache - uses: actions/cache@v2 - with: - path: ${{env.VULKAN_SDK}} - key: VulkanSdk${{env.VulkanSDKVersion}}ExtractedLinux - name: Download & Extract Vulkan SDK - if: steps.cache.outputs.cache-hit != 'true' run: | wget --no-cookies -O ../vulkansdk-linux-x86_64-${{env.VulkanSDKVersion}}.tar.gz https://sdk.lunarg.com/sdk/download/${{env.VulkanSDKVersion}}/linux/vulkansdk-linux-x86_64-${{env.VulkanSDKVersion}}.tar.gz?u= tar -zxf ../vulkansdk-linux-x86_64-${{env.VulkanSDKVersion}}.tar.gz -C ../ @@ -43,16 +36,9 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 - - name: Set env + - name: Set Environment variables run: echo "::set-env name=VULKAN_SDK::C:\VulkanSDK\${{env.VulkanSDKVersion}}" - - name: Cache - id: cache - uses: actions/cache@v2 - with: - path: ${{env.VULKAN_SDK}} - key: VulkanSdk${{env.VulkanSDKVersion}}WindowsExtracted2 - name: Download & Install Vulkan SDK - if: steps.cache.outputs.cache-hit != 'true' run: | Invoke-WebRequest -Uri https://sdk.lunarg.com/sdk/download/${{env.VulkanSDKVersion}}/windows/VulkanSDK-${{env.VulkanSDKVersion}}-Installer.exe?u= -OutFile ../vulkan-sdk-${{env.VulkanSDKVersion}}.exe $installer = Start-Process -FilePath ../vulkan-sdk-${{env.VulkanSDKVersion}}.exe -Wait -PassThru -ArgumentList @("/S"); @@ -76,21 +62,14 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 - - name: Set env + - name: Set Environment variables run: | VULKAN_SDK=$GITHUB_WORKSPACE/../vulkansdk-macos-${{env.VulkanSDKVersion}}/macOS echo ::set-env name=VULKAN_SDK::$VULKAN_SDK - echo ::set-env name=JULIA_VULKAN_SDK_SEARCH_PATH::$VULKAN_SDK/bin + echo ::set-env name=JULIA_VULKAN_SDK_SEARCH_PATH::$VULKAN_SDK/lib echo ::set-env name=VK_LAYER_PATH::$VULKAN_SDK/share/vulkan/explicit_layer.d echo ::set-env name=VK_ICD_FILENAMES::$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json - - name: Cache - id: cache - uses: actions/cache@v2 - with: - path: ${{env.VULKAN_SDK}} - key: VulkanSdk${{env.VulkanSDKVersion}}ExtractedMacos - name: Download & Extract Vulkan SDK - if: steps.cache.outputs.cache-hit != 'true' run: | wget --no-cookies -O ../vulkansdk-macos-${{env.VulkanSDKVersion}}.dmg https://sdk.lunarg.com/sdk/download/${{env.VulkanSDKVersion}}/mac/vulkansdk-macos-${{env.VulkanSDKVersion}}.dmg?u= hdiutil attach ../vulkansdk-macos-${{env.VulkanSDKVersion}}.dmg diff --git a/src/LibVulkan.jl b/src/LibVulkan.jl index cc501f0..5cfd8da 100644 --- a/src/LibVulkan.jl +++ b/src/LibVulkan.jl @@ -22,6 +22,7 @@ function __init__() end @assert libname != "" "cannot detect Vulkan SDK." global libvulkan_handle = Libdl.dlopen(libname) + @assert libvulkan_handle != C_NULL "cannot dlopen libvulkan." end using CEnum