starting compaction stuff
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
|
||||
[[vk::binding(0, 0)]]
|
||||
RWStructuredBuffer<uint32_t> count_buffer;
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
RWStructuredBuffer<uint32_t> reduced_buffer;
|
||||
[[vk::binding(1, 1)]]
|
||||
RWStructuredBuffer<uint32_t> sum_buffer;
|
||||
[[vk::binding(2, 1)]]
|
||||
RWStructuredBuffer<uint32_t> compaction_buffer;
|
||||
|
||||
groupshared uint32_t local_data[256 * 2];
|
||||
static uint32_t THREAD_WIDTH = 256;
|
||||
static uint32_t DATA_WIDTH = THREAD_WIDTH * 2;
|
||||
|
||||
[numthreads(256, 1, 1)]
|
||||
[shader("compute")]
|
||||
void block_sum(
|
||||
uint32_t3 workgroup_id: SV_GroupID,
|
||||
uint32_t3 local_thread_id: SV_GroupThreadID,
|
||||
uint32_t3 global_thread_id: SV_DispatchThreadID)
|
||||
{
|
||||
// Perform sum in current block
|
||||
|
||||
// Copy local_datainto LDS with predicate
|
||||
let thread_index = global_thread_id.x;
|
||||
let local_thread_index = local_thread_id.x;
|
||||
let total = count_buffer.getCount();
|
||||
|
||||
if (thread_index * 2 < total)
|
||||
{
|
||||
local_data[local_thread_index * 2] = select(count_buffer[thread_index * 2] != 0, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
local_data[local_thread_index * 2] = 0;
|
||||
}
|
||||
|
||||
if (thread_index * 2 + 1 < total)
|
||||
{
|
||||
local_data[local_thread_index * 2 + 1] = select(count_buffer[thread_index * 2 + 1] != 0, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
local_data[local_thread_index * 2 + 1] = 0;
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
var width : uint32_t = 2;
|
||||
while (width <= DATA_WIDTH)
|
||||
{
|
||||
let dest_index = width * (thread_index + 1) - 1;
|
||||
let get_index = dest_index - (width / 2);
|
||||
// println!("{}, {}", get_index, dest_index);
|
||||
if (dest_index < DATA_WIDTH)
|
||||
{
|
||||
local_data[dest_index] += local_data[get_index];
|
||||
}
|
||||
width *= 2;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
||||
local_data[DATA_WIDTH - 1] = 0;
|
||||
while (width >= 2)
|
||||
{
|
||||
let dest_index = width * (thread_index + 1) - 1;
|
||||
let get_index = dest_index - (width / 2);
|
||||
// println!("{}, {}", get_index, dest_index);
|
||||
if (dest_index < DATA_WIDTH)
|
||||
{
|
||||
let self_data = local_data[dest_index];
|
||||
local_data[dest_index] += local_data[get_index];
|
||||
local_data[get_index] = self_data;
|
||||
}
|
||||
width /= 2;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
||||
// Block now contains running local sum
|
||||
// Dump back to sum buffer
|
||||
sum_buffer[2 * thread_index] = local_data[2 * local_thread_index];
|
||||
sum_buffer[2 * thread_index + 1] = local_data[2 * local_thread_index + 1];
|
||||
|
||||
// Write to reduced buffer
|
||||
reduced_buffer[workgroup_id.x] = local_data[DATA_WIDTH - 1];
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
[shader("compute")]
|
||||
void linear_reduced_sum(
|
||||
uint32_t3 workgroup_id: SV_GroupID,
|
||||
uint32_t3 local_thread_id: SV_GroupThreadID,
|
||||
uint32_t3 global_thread_id: SV_DispatchThreadID)
|
||||
{
|
||||
let size = reduced_buffer.getCount();
|
||||
|
||||
// Perform exclusive sum
|
||||
var running_sum : uint32_t = 0;
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
let value = reduced_buffer[i];
|
||||
reduced_buffer[i] = running_sum;
|
||||
running_sum += value;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(256, 1, 1)]
|
||||
[shader("compute")]
|
||||
void uniform_add(
|
||||
uint32_t3 workgroup_id: SV_GroupID,
|
||||
uint32_t3 local_thread_id: SV_GroupThreadID,
|
||||
uint32_t3 global_thread_id: SV_DispatchThreadID)
|
||||
{
|
||||
let thread_index = global_thread_id.x;
|
||||
let local_thread_index = local_thread_id.x;
|
||||
|
||||
// Gather
|
||||
let reduced_value = reduced_buffer[global_thread_id.x];
|
||||
// Apply
|
||||
sum_buffer[thread_index * 2] += reduced_value;
|
||||
sum_buffer[thread_index * 2 + 1] += reduced_value;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
module example;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Contains useful facilities to render data streamed in from the host
|
||||
|
||||
// Can produce a voxel given
|
||||
// - Its depth
|
||||
// - Its position within the chunk
|
||||
// - The chunks position
|
||||
pub trait ChunkVoxelProducer
|
||||
{
|
||||
fn produce_voxel(
|
||||
&mut self,
|
||||
depth: usize,
|
||||
chunk_position: (usize, usize, usize),
|
||||
voxel_position: (usize, usize, usize),
|
||||
);
|
||||
}
|
||||
+1
-1
@@ -182,7 +182,7 @@ impl State
|
||||
let egui_renderer = EguiRenderer::new(&device, surface_format, &window);
|
||||
|
||||
let mut voxel_cache = VoxelCache::<4>::new(100_000, device.clone(), queue.clone());
|
||||
let cache_interface = CacheProducerInterface::new(1024, &device);
|
||||
let cache_interface = CacheProducerInterface::new(256, &device);
|
||||
|
||||
let terrain_generator = TerrainGenerator::<4>::new(5, "vxls_height.tif", 0.2, "img.jpg");
|
||||
// let terrain_generator = TerrainGenerator::<4>::new(
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod request_buffer;
|
||||
pub mod structure_table;
|
||||
pub mod usage_buffer;
|
||||
pub mod producer_interface;
|
||||
pub mod indirect_buffer;
|
||||
|
||||
pub mod data;
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
use wgpu::{Buffer, BufferUsages, Device, util::DeviceExt};
|
||||
|
||||
pub struct BufferCompactor
|
||||
{
|
||||
size: usize,
|
||||
block_count: usize,
|
||||
reduced_buffer: Buffer,
|
||||
sum_buffer: Buffer,
|
||||
compaction_buffer: Buffer,
|
||||
}
|
||||
|
||||
impl BufferCompactor
|
||||
{
|
||||
const THREAD_COUNT: usize = 256;
|
||||
pub fn new(device: &Device, size: usize) -> Self
|
||||
{
|
||||
let block_count = size.div_ceil(size);
|
||||
let reduced_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("indirect_buffer_reduced"),
|
||||
contents: bytemuck::cast_slice(vec![0; block_count].as_slice()),
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
|
||||
let sum_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("indirect_buffer_sum"),
|
||||
contents: bytemuck::cast_slice(vec![0; size].as_slice()),
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
|
||||
let compaction_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("indirect_buffer_compaction"),
|
||||
contents: bytemuck::cast_slice(vec![0; size].as_slice()),
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
|
||||
BufferCompactor {
|
||||
size,
|
||||
block_count,
|
||||
reduced_buffer,
|
||||
sum_buffer,
|
||||
compaction_buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user