Add uninitialised buffer support to builder

Also uses this support in brickmap
This commit is contained in:
Jarrod Doyle 2023-09-08 16:00:11 +01:00
parent 6706d58016
commit a5ec013001
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
2 changed files with 43 additions and 21 deletions

View File

@ -5,13 +5,17 @@ use super::Context;
#[derive(Debug)] #[derive(Debug)]
pub struct BulkBufferBuilder<'a> { pub struct BulkBufferBuilder<'a> {
descriptors: Vec<wgpu::util::BufferInitDescriptor<'a>>, order: Vec<(bool, usize)>,
init_descriptors: Vec<wgpu::util::BufferInitDescriptor<'a>>,
descriptors: Vec<wgpu::BufferDescriptor<'a>>,
current_usage: wgpu::BufferUsages, current_usage: wgpu::BufferUsages,
} }
impl<'a> BulkBufferBuilder<'a> { impl<'a> BulkBufferBuilder<'a> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
order: vec![],
init_descriptors: vec![],
descriptors: vec![], descriptors: vec![],
current_usage: wgpu::BufferUsages::UNIFORM, current_usage: wgpu::BufferUsages::UNIFORM,
} }
@ -22,26 +26,48 @@ impl<'a> BulkBufferBuilder<'a> {
self self
} }
pub fn with_buffer(mut self, label: &'a str, contents: &'a [u8]) -> Self { pub fn with_buffer(mut self, label: &'a str, size: u64, mapped: bool) -> Self {
let descriptor = wgpu::BufferDescriptor {
label: Some(label),
size,
usage: self.current_usage,
mapped_at_creation: mapped,
};
self.order.push((false, self.descriptors.len()));
self.descriptors.push(descriptor);
self
}
pub fn with_init_buffer(mut self, label: &'a str, contents: &'a [u8]) -> Self {
let descriptor = wgpu::util::BufferInitDescriptor { let descriptor = wgpu::util::BufferInitDescriptor {
label: Some(label), label: Some(label),
contents, contents,
usage: self.current_usage, usage: self.current_usage,
}; };
self.descriptors.push(descriptor); self.order.push((true, self.init_descriptors.len()));
self.init_descriptors.push(descriptor);
self self
} }
pub fn with_bytemuck_buffer<A: NoUninit>(self, label: &'a str, contents: &'a [A]) -> Self { pub fn with_init_buffer_bm<A: NoUninit>(self, label: &'a str, contents: &'a [A]) -> Self {
self.with_buffer(label, bytemuck::cast_slice(contents)) self.with_init_buffer(label, bytemuck::cast_slice(contents))
} }
pub fn build(self, context: &Context) -> Vec<wgpu::Buffer> { pub fn build(self, context: &Context) -> Vec<wgpu::Buffer> {
let device = &context.device;
let mut buffers = vec![]; let mut buffers = vec![];
for descriptor in self.descriptors { for (init, index) in self.order {
buffers.push(context.device.create_buffer_init(&descriptor)); let buffer = if init {
device.create_buffer_init(&(self.init_descriptors[index]))
} else {
device.create_buffer(&(self.descriptors[index]))
};
buffers.push(buffer);
} }
buffers buffers
} }
} }

View File

@ -92,12 +92,6 @@ impl BrickmapManager {
let mut feedback_data = vec![0u32; 4 + 4 * max_requested_brickmaps as usize]; let mut feedback_data = vec![0u32; 4 + 4 * max_requested_brickmaps as usize];
feedback_data[0] = max_requested_brickmaps; feedback_data[0] = max_requested_brickmaps;
let feedback_data_u8 = bytemuck::cast_slice(&feedback_data); let feedback_data_u8 = bytemuck::cast_slice(&feedback_data);
let feedback_result_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Feedback Read"),
size: feedback_data_u8.len() as u64,
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
mapped_at_creation: false,
});
let mut brickgrid_upload_data = vec![0u32; 4 + 4 * max_uploaded_brickmaps as usize]; let mut brickgrid_upload_data = vec![0u32; 4 + 4 * max_uploaded_brickmaps as usize];
brickgrid_upload_data[0] = max_uploaded_brickmaps; brickgrid_upload_data[0] = max_uploaded_brickmaps;
@ -108,19 +102,21 @@ impl BrickmapManager {
let brickmap_staged = Vec::new(); let brickmap_staged = Vec::new();
let mut buffers = gfx::BulkBufferBuilder::new() let mut buffers = gfx::BulkBufferBuilder::new()
.with_bytemuck_buffer("Brick World State", &[state_uniform]) .with_init_buffer_bm("Brick World State", &[state_uniform])
.set_usage(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST) .set_usage(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST)
.with_bytemuck_buffer("Brickgrid", &brickgrid) .with_init_buffer_bm("Brickgrid", &brickgrid)
.with_bytemuck_buffer("Brickmap Cache", &brickmap_cache) .with_init_buffer_bm("Brickmap Cache", &brickmap_cache)
.with_bytemuck_buffer("Shading Table", &shading_table) .with_init_buffer_bm("Shading Table", &shading_table)
.with_bytemuck_buffer("Brickgrid Unpack", &brickgrid_upload_data) .with_init_buffer_bm("Brickgrid Unpack", &brickgrid_upload_data)
.with_bytemuck_buffer("Brickmap Unpack", &brickmap_upload_data) .with_init_buffer_bm("Brickmap Unpack", &brickmap_upload_data)
.set_usage( .set_usage(
wgpu::BufferUsages::STORAGE wgpu::BufferUsages::STORAGE
| wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::COPY_DST
| wgpu::BufferUsages::COPY_SRC, | wgpu::BufferUsages::COPY_SRC,
) )
.with_buffer("Feedback", feedback_data_u8) .with_init_buffer("Feedback", feedback_data_u8)
.set_usage(wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ)
.with_buffer("Feedback Read", feedback_data_u8.len() as u64, false)
.build(context); .build(context);
Self { Self {
@ -129,7 +125,6 @@ impl BrickmapManager {
brickmap_cache_map, brickmap_cache_map,
brickmap_cache_idx: 0, brickmap_cache_idx: 0,
shading_table_allocator, shading_table_allocator,
feedback_result_buffer,
unpack_max_count: max_uploaded_brickmaps as usize, unpack_max_count: max_uploaded_brickmaps as usize,
brickgrid_staged, brickgrid_staged,
brickmap_staged, brickmap_staged,
@ -141,6 +136,7 @@ impl BrickmapManager {
brickgrid_unpack_buffer: buffers.remove(0), brickgrid_unpack_buffer: buffers.remove(0),
brickmap_unpack_buffer: buffers.remove(0), brickmap_unpack_buffer: buffers.remove(0),
feedback_buffer: buffers.remove(0), feedback_buffer: buffers.remove(0),
feedback_result_buffer: buffers.remove(0),
} }
} }