I'm starting on a Vulkan-compute heavy project and am using Vulkano for my work.
However, I want to be able to display the results of this work in a widget inside a UI, and want to use Iced, as I enjoy using it. Iced's main backend is wgpu, which may use Vulkan under the hood depending on the platform, and I was wondering if there was a way to either share gpu memory between an iced widget and my Vulkano code, or a way to transfer an image to wgpu without going through main memory.
I know I can output the compute results back to main memory and then reupload to iced, but these images may be quite large so might have a lot of overhead.
Alternatively, if anyone knows of a gui crate that would handle this better, I'd be happy to try it out.
iced has a Shader widget which is like a 3D canvas and allows you to draw custom contents. I'm not very familiar with the wgpu api, but if you can import a raw vulkan resource as a wgpu texture, you can use that to draw the image. the widget api is a bit hard to use though.
if you are familiar with immediate mode gui, you can try egui. since it's immediate mode, it's very straightforward to draw custom widgets: you can simply add a paint callback for the ui content. the code for wgpu backend looks like this:
fn main() -> eframe::Result {
// the default option selects wgpu renderer, as long as
// the feature is enabled, which is enabled by default
let native_options = eframe::NativeOptions::default();
eframe::run_native("MyApp", native_options, Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc)))))
}
impl eframe::App for MyEguiApp {
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ui, |ui| {
let rect = ui.max_rect();
ui.painter().add(egui_wgpu::Callback::new_paint_callback(
rect,
MyPaintCallback::new(),
));
});
}
}
impl egui_wgpu::CallbackTrait for MyPaintCallback {
fn pain(
&self,
info: egui::PaintCallbackInfo,
render_pass: &mut wgpu::RenderPass<'static>,
resources: &egui_wgpu::CallbackResources,
) {
// use the render pass to draw
}
}