我已经无计可施了。我一直在关注各种资源(但主要是 wgpu repo 的计算缓冲区示例https://github.com/gfx-rs/wgpu/tree/trunk/examples/hello-compute)以便能够访问缓冲区内容。
我正在使用单个 f32 值(12.0 作为随机数)的向量内容初始化一个缓冲区,我希望该值在复制到另一个缓冲区的内容后打印出来。
(旁注:如果相关的话,我使用的是 M1 Mac)
代码:
let size = std::mem::size_of::<f32>() as wgpu::BufferAddress;
let staging_buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size,
usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
let initial_data = vec![12.0; 1];
let storage_buffer = self.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Storage Buffer"),
contents: bytemuck::cast_slice(&initial_data),
usage: wgpu::BufferUsages::STORAGE
| wgpu::BufferUsages::COPY_DST
| wgpu::BufferUsages::COPY_SRC,
});
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
});
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
self.queue.submit(Some(encoder.finish()));
let buffer_slice = staging_buffer.slice(..);
let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel();
buffer_slice.map_async(wgpu::MapMode::Read, move |v| sender.send(v).unwrap());
self.device.poll(wgpu::Maintain::Wait);
if let Some(Ok(())) = receiver.receive().await {
let data = buffer_slice.get_mapped_range();
let result: Vec<f32> = bytemuck::cast_slice(&data).to_vec();
println!("{:?}", data);
println!("{:?}", result);
drop(data);
staging_buffer.unmap();
} else {
panic!("failed to run compute on gpu!")
}
打印输出示例:
BufferView { slice: BufferSlice { buffer: Buffer { context: Context { type: "Native" }, id: ObjectId { id: Some(4611687899623063559) }, data: Any { .. }, map_context: Mutex { data: MapContext { total_size: 4, initial_range: 0..4, sub_ranges: [0..4] } }, size: 4, usage: MAP_READ | COPY_DST }, offset: 0, size: None }, data: BufferMappedRange { ptr: 0x10ff8c100, size: 4 } }
[0.0]
还有我的cargo.toml,如果有帮助的话
[package]
name = "rust_game"
version = "0.1.0"
edition = "2021"
[dependencies]
cfg-if = "1"
anyhow = "1.0"
bytemuck = { version = "1.12", features = [ "derive" ] }
cgmath = { version = "0.18", features = [ "swizzle" ] }
env_logger = "0.10"
pollster = "0.2"
log = "0.4"
tobj = { version = "3.2", features = ["async"]}
wgpu = { version = "0.15"}
winit = "0.27"
instant = "0.1"
futures-intrusive = "0.5.0"
futures = "0.3.28"
[dependencies.image]
version = "0.24"
default-features = false
features = ["png", "jpeg"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
reqwest = { version = "0.11" }
console_error_panic_hook = "0.1"
console_log = "0.2"
wgpu = { version = "0.17", features = ["webgl"]}
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",
"Location",
]}
[build-dependencies]
anyhow = "1.0"
fs_extra = "1.2"
glob = "0.3"
我完全没有想法,如果有人有任何指示,我将不胜感激