如何在Rust中异步等待wgpu命令缓冲区完成?
在Rust中异步等待wgpu命令缓冲区完成的方法
wgpu 原生并未提供直接的异步版本 device.poll() 方法,但可以基于现有API封装出支持 .await 的异步等待逻辑,满足你想要的使用形式。
实现方式一:异步循环检查提交索引
借助Tokio或async-std这类异步运行时,在异步任务中循环调用 device.poll() 并检查提交索引,期间短暂休眠避免CPU占用过高:
use std::time::Duration; use wgpu::Device; async fn wait_for_submission(device: &Device, target_idx: u64) { loop { // 触发GPU工作推进 device.poll(wgpu::Maintain::WaitForSubmissionIndex(target_idx)); // 检查是否已达到目标提交索引 if device.get_submission_index() >= target_idx { break; } // 短暂休眠,让出CPU给其他任务 tokio::time::sleep(Duration::from_millis(1)).await; } } // 使用示例 // let submission_idx = queue.submit(&[command_buffer]); // wait_for_submission(&device, submission_idx).await;
实现方式二:结合回调与异步通道
利用 Queue::on_submitted_work_done() 回调,搭配异步通道(如tokio的oneshot)实现工作完成时的异步通知,同时结合 poll 确保GPU工作被正确推进:
use wgpu::{Device, Queue}; use tokio::sync::oneshot; async fn wait_for_submission_oneshot(queue: &Queue, target_idx: u64) -> Result<(), oneshot::error::RecvError> { let (sender, receiver) = oneshot::channel(); // 注册工作完成回调 queue.on_submitted_work_done(move || { let _ = sender.send(()); }); // 循环检查并推进GPU工作 loop { queue.device().poll(wgpu::Maintain::WaitForSubmissionIndex(target_idx)); if queue.device().get_submission_index() >= target_idx { break; } tokio::time::sleep(Duration::from_millis(1)).await; } // 等待回调通知 receiver.await }
两种方式都能实现类似 device.poll(...).await 的异步等待效果,你可以根据项目使用的异步运行时和复杂度需求选择合适的方案。
内容的提问来源于stack exchange,提问作者Nick The Hacker
相关产品推荐
相关产品推荐

