use super::{
GpuAffinePoint, GpuConfig, GpuContext, GpuDistinguishedPoint, GpuKangaroo, KangarooPipeline,
};
use anyhow::Result;
use wgpu::{BindGroup, Buffer, BufferUsages};
pub struct GpuBuffers {
#[allow(dead_code)]
config_buffer: Buffer,
#[allow(dead_code)]
jump_points_buffer: Buffer,
#[allow(dead_code)]
jump_distances_buffer: Buffer,
pub kangaroos_buffer: Buffer,
pub dp_buffer: Buffer,
pub dp_count_buffer: Buffer,
pub staging_buffer: Buffer,
pub bind_group: BindGroup,
}
impl GpuBuffers {
pub fn new(
ctx: &GpuContext,
pipeline: &KangarooPipeline,
config: &GpuConfig,
jump_points: &[GpuAffinePoint],
jump_distances: &[[u32; 8]],
num_kangaroos: u32,
max_dps: u32,
) -> Result<Self> {
let config_buffer = ctx.create_buffer_init(
"Config Buffer",
BufferUsages::UNIFORM | BufferUsages::COPY_DST,
&[*config]
);
let jump_points_buffer = ctx.create_buffer_init(
"Jump Points Buffer",
BufferUsages::STORAGE,
jump_points
);
let jump_distances_buffer = ctx.create_buffer_init(
"Jump Distances Buffer",
BufferUsages::STORAGE,
jump_distances
);
let kangaroos_buffer = ctx.create_buffer::<GpuKangaroo>(
"Kangaroos Buffer",
BufferUsages::STORAGE | BufferUsages::COPY_DST | BufferUsages::COPY_SRC,
num_kangaroos as u64
);
let dp_buffer = ctx.create_buffer::<GpuDistinguishedPoint>(
"DP Buffer",
BufferUsages::STORAGE | BufferUsages::COPY_SRC,
max_dps as u64
);
let dp_count_buffer = ctx.create_buffer_init(
"DP Count Buffer",
BufferUsages::STORAGE | BufferUsages::COPY_SRC | BufferUsages::COPY_DST,
&[0u32]
);
let kangaroos_size = (num_kangaroos as usize) * std::mem::size_of::<GpuKangaroo>();
let dp_size = (max_dps as usize) * std::mem::size_of::<GpuDistinguishedPoint>();
let staging_size = std::cmp::max(kangaroos_size, dp_size) as u64 + 4;
let staging_buffer = ctx.create_buffer::<u8>(
"Staging Buffer",
BufferUsages::MAP_READ | BufferUsages::COPY_DST,
staging_size
);
let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Kangaroo Bind Group"),
layout: &pipeline.bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: config_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 1,
resource: jump_points_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 2,
resource: jump_distances_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 3,
resource: kangaroos_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 4,
resource: dp_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 5,
resource: dp_count_buffer.as_entire_binding(),
},
],
});
Ok(Self {
config_buffer,
jump_points_buffer,
jump_distances_buffer,
kangaroos_buffer,
dp_buffer,
dp_count_buffer,
staging_buffer,
bind_group,
})
}
}