Fix batched writes logic in iced_wgpu::buffer
This commit is contained in:
parent
d11e271d26
commit
35af0aa84f
1 changed files with 31 additions and 26 deletions
|
|
@ -1,7 +1,12 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::num::NonZeroU64;
|
||||||
use std::ops::RangeBounds;
|
use std::ops::RangeBounds;
|
||||||
|
|
||||||
pub const MAX_WRITE_SIZE: usize = 1024 * 100;
|
pub const MAX_WRITE_SIZE: usize = 100 * 1024;
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
const MAX_WRITE_SIZE_U64: NonZeroU64 =
|
||||||
|
unsafe { NonZeroU64::new_unchecked(MAX_WRITE_SIZE as u64) };
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Buffer<T> {
|
pub struct Buffer<T> {
|
||||||
|
|
@ -70,40 +75,40 @@ impl<T: bytemuck::Pod> Buffer<T> {
|
||||||
contents: &[T],
|
contents: &[T],
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let bytes: &[u8] = bytemuck::cast_slice(contents);
|
let bytes: &[u8] = bytemuck::cast_slice(contents);
|
||||||
|
let mut bytes_written = 0;
|
||||||
|
|
||||||
if bytes.len() <= MAX_WRITE_SIZE {
|
// Split write into multiple chunks if necessary
|
||||||
|
while bytes_written + MAX_WRITE_SIZE < bytes.len() {
|
||||||
belt.write_buffer(
|
belt.write_buffer(
|
||||||
encoder,
|
encoder,
|
||||||
&self.raw,
|
&self.raw,
|
||||||
offset as u64,
|
(offset + bytes_written) as u64,
|
||||||
(bytes.len() as u64).try_into().expect("Non-empty write"),
|
MAX_WRITE_SIZE_U64,
|
||||||
device,
|
device,
|
||||||
)
|
)
|
||||||
.copy_from_slice(bytes);
|
.copy_from_slice(
|
||||||
} else {
|
&bytes[bytes_written..bytes_written + MAX_WRITE_SIZE],
|
||||||
let mut bytes_written = 0;
|
);
|
||||||
|
|
||||||
let bytes_per_chunk = (bytes.len().min(MAX_WRITE_SIZE) as u64)
|
bytes_written += MAX_WRITE_SIZE;
|
||||||
.try_into()
|
|
||||||
.expect("Non-empty write");
|
|
||||||
|
|
||||||
while bytes_written < bytes.len() {
|
|
||||||
belt.write_buffer(
|
|
||||||
encoder,
|
|
||||||
&self.raw,
|
|
||||||
(offset + bytes_written) as u64,
|
|
||||||
bytes_per_chunk,
|
|
||||||
device,
|
|
||||||
)
|
|
||||||
.copy_from_slice(
|
|
||||||
&bytes[bytes_written
|
|
||||||
..bytes_written + bytes_per_chunk.get() as usize],
|
|
||||||
);
|
|
||||||
|
|
||||||
bytes_written += bytes_per_chunk.get() as usize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There will always be some bytes left, since the previous
|
||||||
|
// loop guarantees `bytes_written < bytes.len()`
|
||||||
|
let bytes_left = ((bytes.len() - bytes_written) as u64)
|
||||||
|
.try_into()
|
||||||
|
.expect("non-empty write");
|
||||||
|
|
||||||
|
// Write them
|
||||||
|
belt.write_buffer(
|
||||||
|
encoder,
|
||||||
|
&self.raw,
|
||||||
|
(offset + bytes_written) as u64,
|
||||||
|
bytes_left,
|
||||||
|
device,
|
||||||
|
)
|
||||||
|
.copy_from_slice(&bytes[bytes_written..]);
|
||||||
|
|
||||||
self.offsets.push(offset as u64);
|
self.offsets.push(offset as u64);
|
||||||
|
|
||||||
bytes.len()
|
bytes.len()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue