You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
}

关键修正说明

  1. 创建缓冲区时将mapped_at_creation改为false,释放GPU访问权限。
  2. 用pollster::block_on(queue.on_submitted_work_done())等待GPU写入操作完成,确保读取到最新数据。
  3. 读取前调用map_async发起CPU映射请求,并等待映射完成,这是读取GPU写入数据的必要步骤。

内容的提问来源于stack exchange,提问作者Laycookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:53:26