diff --git a/.github/workflows/generated-bindings-ci.yml b/.github/workflows/generated-bindings-ci.yml index d7e090a..6942821 100644 --- a/.github/workflows/generated-bindings-ci.yml +++ b/.github/workflows/generated-bindings-ci.yml @@ -234,7 +234,7 @@ jobs: module_root="$RUNNER_TEMP/vmodules/antono2/vulkan" mkdir -p "$module_root/c" "$module_root/ergonomic" cp vulkan.v vulkan_video.v loader.v v.mod VERSION REGISTRY_COMMIT VOLK_COMMIT "$module_root/" - cp c/loader_bridge.h c/volk.c.v c/volk_impl.h "$module_root/c/" + cp c/loader_bridge.h c/volk.c.v c/volk_impl.h c/vulkan_core_prelude.h "$module_root/c/" cp -R c/vendor "$module_root/c/" cp ergonomic/*.v "$module_root/ergonomic/" echo "VMODULES=$RUNNER_TEMP/vmodules" >> "$GITHUB_ENV" @@ -282,6 +282,7 @@ jobs: v "${v_flags[@]}" run generator/test fi v "${v_flags[@]}" -o "$RUNNER_TEMP/bundled-header-smoke" ci/bundled_header_smoke + v "${v_flags[@]}" run ci/header_order_smoke v "${v_flags[@]}" test ergonomic python3 scripts/check_docs.py v "${v_flags[@]}" -o "$RUNNER_TEMP/vulkan-first-use" examples/getting_started @@ -299,6 +300,12 @@ jobs: v -cc tcc test ergonomic VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \ v -cc tcc run examples/ergonomic_lifecycle + - name: Exercise current V3 device discovery and lifecycle + if: runner.os == 'Linux' && matrix.v-channel == 'master' + shell: bash + run: | + VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \ + v -new-compiler -cc gcc run examples/ergonomic_lifecycle - name: Check out presentation example dependency if: runner.os == 'Linux' && matrix.v-channel == 'stable' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 diff --git a/c/volk.c.v b/c/volk.c.v index 6475fad..47a9fe7 100644 --- a/c/volk.c.v +++ b/c/volk.c.v @@ -5,4 +5,6 @@ module c #flag -I@VMODROOT/c/vendor/include #flag -I@VMODROOT/c/vendor/volk #flag linux -Wl,-Bsymbolic +// Establish the pinned core before GLFW or another consumer includes Vulkan. +#preinclude "@VMODROOT/c/vulkan_core_prelude.h" #include "@VMODROOT/c/volk_impl.h" diff --git a/c/vulkan_core_prelude.h b/c/vulkan_core_prelude.h new file mode 100644 index 0000000..267038c --- /dev/null +++ b/c/vulkan_core_prelude.h @@ -0,0 +1,8 @@ +#pragma once + +// Consumers such as GLFW must see the pinned core without function prototypes. +// Keep the Volk implementation and its CRT headers in the normal include phase. +#ifndef VK_NO_PROTOTYPES +#define VK_NO_PROTOTYPES +#endif +#include "vendor/include/vulkan/vulkan_core.h" diff --git a/ci/header_order_smoke/consumer.h b/ci/header_order_smoke/consumer.h new file mode 100644 index 0000000..fd5f46a --- /dev/null +++ b/ci/header_order_smoke/consumer.h @@ -0,0 +1,6 @@ +#ifndef VK_HEADER_VERSION +#error "Pinned Vulkan headers must precede consumer includes" +#endif +static uint32_t v_vulkan_consumer_header_version(void) { + return VK_HEADER_VERSION; +} diff --git a/ci/header_order_smoke/consumer/consumer.c.v b/ci/header_order_smoke/consumer/consumer.c.v new file mode 100644 index 0000000..e516cec --- /dev/null +++ b/ci/header_order_smoke/consumer/consumer.c.v @@ -0,0 +1,9 @@ +module consumer + +#include "@VMODROOT/ci/header_order_smoke/consumer.h" + +fn C.v_vulkan_consumer_header_version() u32 + +pub fn header_version() u32 { + return C.v_vulkan_consumer_header_version() +} diff --git a/ci/header_order_smoke/main.c.v b/ci/header_order_smoke/main.c.v new file mode 100644 index 0000000..2aa96cc --- /dev/null +++ b/ci/header_order_smoke/main.c.v @@ -0,0 +1,8 @@ +module main + +import ci.header_order_smoke.consumer +import antono2.vulkan as vk + +fn main() { + assert consumer.header_version() == u32(vk.header_version) +} diff --git a/ergonomic/discovery.v b/ergonomic/discovery.v index a5fdee2..bf71057 100644 --- a/ergonomic/discovery.v +++ b/ergonomic/discovery.v @@ -24,7 +24,7 @@ fn extension_infos(properties []vk.ExtensionProperties) []ExtensionInfo { mut result := []ExtensionInfo{cap: properties.len} for property in properties { result << ExtensionInfo{ - name: unsafe { cstring_to_vstring(&property.extensionName[0]) }.clone() + name: unsafe { cstring_to_vstring(&property.extensionName[0]) }.clone() spec_version: property.specVersion } } @@ -35,9 +35,9 @@ fn layer_infos(properties []vk.LayerProperties) []LayerInfo { mut result := []LayerInfo{cap: properties.len} for property in properties { result << LayerInfo{ - name: unsafe { cstring_to_vstring(&property.layerName[0]) }.clone() - description: unsafe { cstring_to_vstring(&property.description[0]) }.clone() - spec_version: property.specVersion + name: unsafe { cstring_to_vstring(&property.layerName[0]) }.clone() + description: unsafe { cstring_to_vstring(&property.description[0]) }.clone() + spec_version: property.specVersion implementation_version: property.implementationVersion } } @@ -50,7 +50,7 @@ pub fn instance_extensions() ![]ExtensionInfo { require_success(vk.initialize_loader(), 'volkInitialize')! for { mut count := u32(0) - mut no_properties := unsafe { nil } + mut no_properties := unsafe { &vk.ExtensionProperties(nil) } require_success(vk.enumerate_instance_extension_properties(unsafe { nil }, &count, mut no_properties), 'vkEnumerateInstanceExtensionProperties(count)')! if count == 0 { return []ExtensionInfo{} @@ -72,7 +72,7 @@ pub fn instance_layers() ![]LayerInfo { require_success(vk.initialize_loader(), 'volkInitialize')! for { mut count := u32(0) - mut no_properties := unsafe { nil } + mut no_properties := unsafe { &vk.LayerProperties(nil) } require_success(vk.enumerate_instance_layer_properties(&count, mut no_properties), 'vkEnumerateInstanceLayerProperties(count)')! if count == 0 { return []LayerInfo{} @@ -92,7 +92,7 @@ pub fn instance_layers() ![]LayerInfo { pub fn (device PhysicalDevice) extensions() ![]ExtensionInfo { for { mut count := u32(0) - mut no_properties := unsafe { nil } + mut no_properties := unsafe { &vk.ExtensionProperties(nil) } require_success(vk.enumerate_device_extension_properties(device.handle, unsafe { nil }, &count, mut no_properties), 'vkEnumerateDeviceExtensionProperties(count)')! if count == 0 { return []ExtensionInfo{} diff --git a/ergonomic/ergonomic.v b/ergonomic/ergonomic.v index a3f7acc..95207fa 100644 --- a/ergonomic/ergonomic.v +++ b/ergonomic/ergonomic.v @@ -161,7 +161,7 @@ pub fn select_queue_family(families []QueueFamily, required_flags vk.QueueFlags) // family properties. pub fn (device PhysicalDevice) queue_families() []QueueFamily { mut count := u32(0) - mut no_properties := unsafe { nil } + mut no_properties := unsafe { &vk.QueueFamilyProperties(nil) } vk.get_physical_device_queue_family_properties(device.handle, &count, mut no_properties) if count == 0 { return []QueueFamily{} diff --git a/ergonomic/presentation.v b/ergonomic/presentation.v index a7c3e5c..4d4dce8 100644 --- a/ergonomic/presentation.v +++ b/ergonomic/presentation.v @@ -31,7 +31,7 @@ pub fn (device PhysicalDevice) surface_formats(surface vk.SurfaceKHR) ![]vk.Surf } for { mut count := u32(0) - mut no_formats := unsafe { nil } + mut no_formats := unsafe { &vk.SurfaceFormatKHR(nil) } result := vk.get_physical_device_surface_formats_khr(device.handle, surface, &count, mut no_formats) if result == .incomplete { continue @@ -82,8 +82,8 @@ pub fn (device PhysicalDevice) surface_present_modes(surface vk.SurfaceKHR) ![]v // to configure or recreate a swapchain. pub fn (device PhysicalDevice) surface_support(surface vk.SurfaceKHR) !SurfaceSupport { return SurfaceSupport{ - capabilities: device.surface_capabilities(surface)! - formats: device.surface_formats(surface)! + capabilities: device.surface_capabilities(surface)! + formats: device.surface_formats(surface)! present_modes: device.surface_present_modes(surface)! } } @@ -135,7 +135,7 @@ pub fn select_surface_extent(capabilities vk.SurfaceCapabilitiesKHR, return capabilities.currentExtent } return vk.Extent2D{ - width: clamp_u32(requested.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width) + width: clamp_u32(requested.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width) height: clamp_u32(requested.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height) } }