From 311ec03d5408a71ea282ec4fc07308aec8284747 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 26 Jun 2025 17:03:48 -0400 Subject: [PATCH] Write vulkan api interop example --- Cargo.lock | 3 + examples/features/Cargo.toml | 3 + examples/features/src/api_interop/mod.rs | 2 + examples/features/src/api_interop/vulkan.rs | 89 +++++++++++++++++++++ examples/features/src/lib.rs | 1 + 5 files changed, 98 insertions(+) create mode 100644 examples/features/src/api_interop/mod.rs create mode 100644 examples/features/src/api_interop/vulkan.rs diff --git a/Cargo.lock b/Cargo.lock index bca74e27938..3798fb484d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4964,6 +4964,7 @@ dependencies = [ name = "wgpu-examples" version = "25.0.0" dependencies = [ + "ash", "bytemuck", "cfg-if", "console_error_panic_hook", @@ -4973,6 +4974,7 @@ dependencies = [ "fern", "flume", "glam", + "glow", "ktx2", "log", "nanorand 0.8.0", @@ -4988,6 +4990,7 @@ dependencies = [ "wgpu", "wgpu-test", "wgpu-types", + "windows 0.58.0", "winit 0.29.15", ] diff --git a/examples/features/Cargo.toml b/examples/features/Cargo.toml index b11ba7fc8a7..0fcf082296c 100644 --- a/examples/features/Cargo.toml +++ b/examples/features/Cargo.toml @@ -49,6 +49,9 @@ wgpu-types = { workspace = true, features = [ "trace", # TODO(#5974): this should be a dep on wgpu/trace and not wgpu-types at all ] } winit.workspace = true +windows.workspace = true +ash.workspace = true +glow.workspace = true [dev-dependencies] wgpu-test.workspace = true diff --git a/examples/features/src/api_interop/mod.rs b/examples/features/src/api_interop/mod.rs new file mode 100644 index 00000000000..19063b024c8 --- /dev/null +++ b/examples/features/src/api_interop/mod.rs @@ -0,0 +1,2 @@ +// Various examples of interop with Vulkan +mod vulkan; diff --git a/examples/features/src/api_interop/vulkan.rs b/examples/features/src/api_interop/vulkan.rs new file mode 100644 index 00000000000..6a361acc28b --- /dev/null +++ b/examples/features/src/api_interop/vulkan.rs @@ -0,0 +1,89 @@ +#![allow(unused_variables, dead_code)] + +type VkApi = wgpu::hal::vulkan::Api; + +fn custom_instance_extensions() { + // Storage for our custom vulkan extension. Actually fill this out in real code. + let mut debug_report_create_info = ash::vk::DebugReportCallbackCreateInfoEXT::default(); + + // Create a Vulkan wgpu-hal instance with custom extensions. + let wgpu_hal_instance = unsafe { + wgpu::hal::vulkan::Instance::init_with_callback( + &wgpu::hal::InstanceDescriptor { + name: "Vulkan Test", + flags: wgpu::InstanceFlags::debugging(), + memory_budget_thresholds: wgpu::MemoryBudgetThresholds::default(), + backend_options: wgpu::BackendOptions::default(), + }, + // This callback allows you to add custom extensions and their feature flags without + // wgpu's knowledge. Do not remove or disable any feature, wgpu will get mad. + Some(Box::new(|args| { + // Add a debug report extension. + args.extensions.push(ash::ext::debug_report::NAME); + // Extend the create info with the debug report create info. + *args.create_info = args.create_info.push_next(&mut debug_report_create_info); + // We also have access to the entry if we need it. + let _ = args.entry; + })), + ) + .unwrap() + }; + + // Create a wgpu instance from the hal instance. + let wgpu_instance = unsafe { wgpu::Instance::from_hal::(wgpu_hal_instance) }; +} + +fn custom_device_extensions(adapter: &wgpu::Adapter) { + unsafe { + // Storage for our custom device extensions. Actually fill this out in real code. + let mut buffer_device_address_create_info = + ash::vk::PhysicalDeviceBufferDeviceAddressFeatures::default(); + + // Open an "OpenDevice" with the adapter, adding some extensions. + let hal_device: wgpu::hal::OpenDevice = adapter + .as_hal::() + .unwrap() + .open_with_callback( + wgpu::Features::empty(), + &wgpu::MemoryHints::Performance, + Some(Box::new(|args| { + // Add the buffer device address extension. + args.extensions.push(ash::khr::buffer_device_address::NAME); + // Extend the create info with the buffer device address create info. + *args.create_info = args + .create_info + .push_next(&mut buffer_device_address_create_info); + // We also have access to the queue create infos if we need them. + let _ = args.queue_create_infos; + })), + ) + .unwrap(); + + // Create a wgpu device from the hal device. + let (device, queue) = adapter + .create_device_from_hal(hal_device, &wgpu::DeviceDescriptor::default()) + .unwrap(); + } +} + +fn as_hal() { + unsafe { + let instance: wgpu::Instance = unimplemented!(); + let adapter: wgpu::Adapter = unimplemented!(); + let device: wgpu::Device = unimplemented!(); + let queue: wgpu::Queue = unimplemented!(); + let buffer: wgpu::Buffer = unimplemented!(); + let texture: wgpu::Texture = unimplemented!(); + let view: wgpu::TextureView = unimplemented!(); + let sampler: wgpu::Sampler = unimplemented!(); + let shader_module: wgpu::ShaderModule = unimplemented!(); + let pipeline_layout: wgpu::PipelineLayout = unimplemented!(); + let render_pipeline: wgpu::RenderPipeline = unimplemented!(); + let compute_pipeline: wgpu::ComputePipeline = unimplemented!(); + let command_encoder: wgpu::CommandEncoder = unimplemented!(); + + // Instance + let hal_instance = instance.as_hal::().unwrap(); + hal_instance.shared_instance(); + } +} diff --git a/examples/features/src/lib.rs b/examples/features/src/lib.rs index 479f1d12e9a..0a3fe2e98b3 100644 --- a/examples/features/src/lib.rs +++ b/examples/features/src/lib.rs @@ -4,6 +4,7 @@ pub mod framework; pub mod utils; +pub mod api_interop; pub mod big_compute_buffers; pub mod boids; pub mod bunnymark;