WGPU中write_buffer无法写入缓冲区,输出始终为零的问题求助
问题根源及修正方案
核心错误点
- 缓冲区映射状态冲突:创建缓冲区时设置
mapped_at_creation: true,会让缓冲区立刻处于CPU映射锁定状态——WGPU中缓冲区的CPU映射与GPU访问是互斥的,此时GPU无法执行queue.write_buffer写入操作。 - 未等待GPU异步操作完成:
queue.write_buffer和queue.submit都是异步执行的,提交后不会立刻完成,直接读取会拿到初始的全0数据。 - 读取前未重新映射缓冲区:如果之前解除了缓冲区的CPU映射,要读取GPU写入的数据,必须重新发起映射请求并等待映射完成。
修正后的完整代码
use wgpu; use pollster; fn main() { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::all(), dx12_shader_compiler: Default::default(), }); let adapter = pollster::block_on(instance.request_adapter(&Default::default())).unwrap(); let (device, queue) = pollster::block_on(adapter.request_device(&Default::default(), None)).unwrap(); // 创建缓冲区时关闭初始映射,让GPU可访问 let array_buffer = device.create_buffer(&wgpu::BufferDescriptor { label: Some("gpu_test"), size: 4, usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, mapped_at_creation: false, }); // 向GPU缓冲区写入数据 queue.write_buffer(&array_buffer, 0, &[1, 2, 3, 4]); // 等待GPU所有提交的工作执行完成 pollster::block_on(queue.on_submitted_work_done()).unwrap(); // 重新将缓冲区映射到CPU,等待映射完成 let buffer_slice = array_buffer.slice(..); pollster::block_on(buffer_slice.map_async(wgpu::MapMode::Read)).unwrap(); // 读取并打印数据 let slice = buffer_slice.get_mapped_range(); println!("{:?}", slice.get(0..4)); // 清理映射资源 drop(slice); array_buffer.unmap(); }
关键修正说明
- 创建缓冲区时将
mapped_at_creation改为false,释放GPU访问权限。 - 用
pollster::block_on(queue.on_submitted_work_done())等待GPU写入操作完成,确保读取到最新数据。 - 读取前调用
map_async发起CPU映射请求,并等待映射完成,这是读取GPU写入数据的必要步骤。
内容的提问来源于stack exchange,提问作者Laycookie
相关产品推荐
相关产品推荐

