Sharing textures between iced (wgpu) and Vulkano

Hi all.

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.

Thanks.

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
    }
}

documentation for the wgpu paint callback: