I'm trying to update rend3-hp (my fork of abandoned rend3) to wgpu 30, from wgpu 24. There were many breaking changes. I'm down from 150 compile errors to only 2. But I'm stuck on those.
error[E0308]: mismatched types
--> rend3/src/util/scatter_copy.rs:103:65
|
103 | let mapped_slice: &mut [u32] = bytemuck::cast_slice_mut(&mut mapped_range);
| ------------------------ ^^^^^^^^^^^^^^^^^ expected `&mut [_]`, found `&mut Result<BufferViewMut, ...>`
| |
| arguments to this function are incorrect
|
= note: expected mutable reference `&mut [_]`
found mutable reference `&mut std::result::Result<BufferViewMut, MapRangeError>`
note: function defined here
--> /home/john/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytemuck-1.25.2/src/lib.rs:423:8
|
423 | pub fn cast_slice_mut<
| ^^^^^^^^^^^^^^
This worked with WGPU 24.
Here's the trouble spot:
let mut writer = encase::internal::Writer::new(
&item.data,
bytemuck::cast_slice_mut::<_, u8>(&mut mapped_slice[range_start + 1..range_end]),
0,
)
.unwrap();
item.data.write_into(&mut writer);
The first problem is just that mapped_range is now a Result. That's easy to fix. But after fixing that, we have a type mismatch.
A Writer from encase encapsulates a destination, which is then passed to write_into of the source data. That then calls a function of the Writer. This is kind of backwards, but that's the way it's set up. The Writer mechanism supports repeated writes, but here the code creates a Writer and discards it after one Write, so this is a lot more complex than it needs to be.
What this code is doing is writing directly to a part of the address space mapped as write-only on the CPU and read-only on the GPU. Wgpu recently introduced the trait WriteOnly, which is like MaybeUninit; you can write, but not read. Although WriteOnly means don't even try to read it; you'll get a memory protection fault.
Since WriteOnly was introduced in a high level crate, Wgpu, the bytemuck and encase low level crates don't know about it. But there are WGPU functions that need their parameter to be WriteOnly. There's no way I can add that trait to an existing data item. I can change rend3-hp, but not wgpu, bytemuck, or encase.
The functions in scatter_copy mostly take generic parameters. So we can't do much with them except use the very few available functions of their traits. All the function demands of the data is that it be ShaderSize + WriteInto They're not Pod, for example, which would help with conversion. (Also, bytemuck has its own Pod type. rather than using the one from the Pod crate, just to confuse things.) There was so much generic and trait cleverness in this area that adding WriteOnly broke too much.
All this really does is put the bytes of item.data into the mapped slice. Is there some straightforward way to do that?