メインコンテンツへスキップ

wgpuでバッファに書き込みをした際にvalidation errorが出る原因と解決方法

··934 文字·2 分·
CG プログラミング wgpu
著者
Admin
目次

状況
#

wgpu error: Validation Error

Caused by:
    In Queue::write_buffer
    Copy of 0..400 would end up overrunning the bounds of the Destination buffer of size 0

のようなエラーメッセージが🔗wgpu::Queue::write_buffer関数を呼んだ際に出る。

原因 & 解決方法
#

エラーメッセージはバッファの最大サイズを超えた書き込みをしようとしていることを検出して警告してくれている。

wgpu拡張の(wgpu::util::DeviceExt, wgpu::util) 🔗wgpu::Device::create_buffer_init関数でバッファを作成すると、作成する際に渡したデータの大きさでバッファの最大サイズが設定される。

一度作成したバッファの最大サイズは実行時に変更できないようだ。

サンプルコードなどでもcreate_buffer_initは多用されているが、実際のアプリケーションでは、バッファの書き込みサイズがチマチマ変わることも多いので、最大サイズを自分で設定できる🔗wgpu::Device::create_buffer関数を利用する必要がある。

具体的にcreate_bufferで作成したバッファにどうやってデータをセットするかだが、create_buffer_init関数の実装がシンプルなので見てマネをするか、wgpu::Queue::write_bufferで書き込めば良い。

create_buffer_init内の書き込み処理。

  buffer.slice(..).get_mapped_range_mut()[..unpadded_size as usize]
                .copy_from_slice(descriptor.contents);
            buffer.unmap();

Queue::write_bufferのようにsubmitでまとめて後で書き込むのではなく同期的にGPUバッファをマッピングしてそこにデータを書き込んでいる。

バッファの最大サイズはwgpu::COPY_BUFFER_ALIGNMENTの倍数にしておく必要がある。
バックエンド問わずcreate_buffer_init内で勝手にalignしてくれているので例えDirectXやOpenGLを利用していても統一しておいたほうが良いはず。

参考までに該当コードのBeforeAfterを載せておく。

// Before
let cube_instance_buffer =
    wgpu_device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
        label: Some("cube instance buffer"),
        contents: bytemuck::cast_slice(&cube_instances),// バッファの内容を渡して初期化
        usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
});

// After
let cube_instance_buffer = wgpu_device.create_buffer(&wgpu::BufferDescriptor {
    label: Some("cube instance buffer"),
    size: (pit_size_xyz.0 * pit_size_xyz.1 * pit_size_xyz.2) as u64
        * std::mem::size_of::<CubeWGPUInstance>() as u64,// バッファの最大サイズのみ指定して後でwgpu::Queue::write_bufferで内容を書き込んだり更新する。
    usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
    mapped_at_creation: false,
});

Related

wgpuを利用した自作ゲームで頂点が視界に入らないのでRenderDocでデバッグする
··1197 文字·3 分
プログラミング wgpu RenderDoc CG ゲームプログラミング
近況、進捗、就活、仕事のやめどき、今後の計画
··2301 文字·5 分
日記 学習 プログラミング 数学 wgpu 仕事 CG 数学 退職
TriangleStripでキューブ(直方体)を描く
··1170 文字·3 分
プログラミング 学習 CG
頂点モードについてかんたんに解説。