blade: enforce alignment in the belt
This commit is contained in:
parent
c5ff46e14f
commit
d6bbcf503b
3 changed files with 16 additions and 9 deletions
|
@ -58,6 +58,7 @@ impl BladeAtlas {
|
||||||
upload_belt: BladeBelt::new(BladeBeltDescriptor {
|
upload_belt: BladeBelt::new(BladeBeltDescriptor {
|
||||||
memory: gpu::Memory::Upload,
|
memory: gpu::Memory::Upload,
|
||||||
min_chunk_size: 0x10000,
|
min_chunk_size: 0x10000,
|
||||||
|
alignment: 4,
|
||||||
}),
|
}),
|
||||||
monochrome_textures: Default::default(),
|
monochrome_textures: Default::default(),
|
||||||
polychrome_textures: Default::default(),
|
polychrome_textures: Default::default(),
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct ReusableBuffer {
|
||||||
pub struct BladeBeltDescriptor {
|
pub struct BladeBeltDescriptor {
|
||||||
pub memory: gpu::Memory,
|
pub memory: gpu::Memory,
|
||||||
pub min_chunk_size: u64,
|
pub min_chunk_size: u64,
|
||||||
|
pub alignment: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A belt of buffers, used by the BladeAtlas to cheaply
|
/// A belt of buffers, used by the BladeAtlas to cheaply
|
||||||
|
@ -21,6 +22,7 @@ pub struct BladeBelt {
|
||||||
|
|
||||||
impl BladeBelt {
|
impl BladeBelt {
|
||||||
pub fn new(desc: BladeBeltDescriptor) -> Self {
|
pub fn new(desc: BladeBeltDescriptor) -> Self {
|
||||||
|
assert_ne!(desc.alignment, 0);
|
||||||
Self {
|
Self {
|
||||||
desc,
|
desc,
|
||||||
buffers: Vec::new(),
|
buffers: Vec::new(),
|
||||||
|
@ -39,9 +41,10 @@ impl BladeBelt {
|
||||||
|
|
||||||
pub fn alloc(&mut self, size: u64, gpu: &gpu::Context) -> gpu::BufferPiece {
|
pub fn alloc(&mut self, size: u64, gpu: &gpu::Context) -> gpu::BufferPiece {
|
||||||
for &mut (ref rb, ref mut offset) in self.active.iter_mut() {
|
for &mut (ref rb, ref mut offset) in self.active.iter_mut() {
|
||||||
if *offset + size <= rb.size {
|
let aligned = offset.next_multiple_of(self.desc.alignment);
|
||||||
let piece = rb.raw.at(*offset);
|
if aligned + size <= rb.size {
|
||||||
*offset += size;
|
let piece = rb.raw.at(aligned);
|
||||||
|
*offset = aligned + size;
|
||||||
return piece;
|
return piece;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,13 +78,15 @@ impl BladeBelt {
|
||||||
//Note: assuming T: bytemuck::Zeroable
|
//Note: assuming T: bytemuck::Zeroable
|
||||||
pub fn alloc_data<T>(&mut self, data: &[T], gpu: &gpu::Context) -> gpu::BufferPiece {
|
pub fn alloc_data<T>(&mut self, data: &[T], gpu: &gpu::Context) -> gpu::BufferPiece {
|
||||||
assert!(!data.is_empty());
|
assert!(!data.is_empty());
|
||||||
let alignment = mem::align_of::<T>() as u64;
|
let type_alignment = mem::align_of::<T>() as u64;
|
||||||
|
assert_eq!(
|
||||||
|
self.desc.alignment % type_alignment,
|
||||||
|
0,
|
||||||
|
"Type alignment {} is too big",
|
||||||
|
type_alignment
|
||||||
|
);
|
||||||
let total_bytes = data.len() * mem::size_of::<T>();
|
let total_bytes = data.len() * mem::size_of::<T>();
|
||||||
let mut bp = self.alloc(alignment + (total_bytes - 1) as u64, gpu);
|
let bp = self.alloc(total_bytes as u64, gpu);
|
||||||
let rem = bp.offset % alignment;
|
|
||||||
if rem != 0 {
|
|
||||||
bp.offset += alignment - rem;
|
|
||||||
}
|
|
||||||
unsafe {
|
unsafe {
|
||||||
std::ptr::copy_nonoverlapping(data.as_ptr() as *const u8, bp.data(), total_bytes);
|
std::ptr::copy_nonoverlapping(data.as_ptr() as *const u8, bp.data(), total_bytes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,6 +251,7 @@ impl BladeRenderer {
|
||||||
let instance_belt = BladeBelt::new(BladeBeltDescriptor {
|
let instance_belt = BladeBelt::new(BladeBeltDescriptor {
|
||||||
memory: gpu::Memory::Shared,
|
memory: gpu::Memory::Shared,
|
||||||
min_chunk_size: 0x1000,
|
min_chunk_size: 0x1000,
|
||||||
|
alignment: 0x100, // required by DX12
|
||||||
});
|
});
|
||||||
let atlas = Arc::new(BladeAtlas::new(&gpu));
|
let atlas = Arc::new(BladeAtlas::new(&gpu));
|
||||||
let atlas_sampler = gpu.create_sampler(gpu::SamplerDesc {
|
let atlas_sampler = gpu.create_sampler(gpu::SamplerDesc {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue