feature: add a producer_interface struct to cleanly represent the $ interface
This commit is contained in:
+80
-110
@@ -59,6 +59,8 @@ use crate::voxel_cache::data::CacheResponse;
|
||||
use crate::voxel_cache::data::ColorBytes;
|
||||
use crate::voxel_cache::data::DestinationElement;
|
||||
use crate::voxel_cache::data::LocationPoolElement;
|
||||
use crate::voxel_cache::producer_interface::CacheProducerInterface;
|
||||
use crate::voxel_cache::producer_interface::CacheRequest;
|
||||
|
||||
mod camera;
|
||||
mod egui_renderer;
|
||||
@@ -81,6 +83,7 @@ struct State
|
||||
|
||||
pipeline: RenderPipeline,
|
||||
voxel_cache: Arc<Mutex<VoxelCache<4>>>,
|
||||
cache_interface: Arc<CacheProducerInterface<4>>,
|
||||
terrain_generator: Arc<TerrainGenerator<4>>,
|
||||
chunk_pos_map: Arc<HashMap<u32, (usize, usize, usize)>>,
|
||||
instance_buffer: Buffer,
|
||||
@@ -156,20 +159,21 @@ impl State
|
||||
let egui_renderer = EguiRenderer::new(&device, surface_format, &window);
|
||||
|
||||
let mut voxel_cache = VoxelCache::<4>::new(200_000, device.clone(), queue.clone());
|
||||
let cache_interface = CacheProducerInterface::new(1024, &device);
|
||||
|
||||
//let terrain_generator = TerrainGenerator::<4>::new(5, "vxls_height.tif", 0.2, "img.jpg");
|
||||
let terrain_generator = TerrainGenerator::<4>::new(5, "vxls_height.tif", 0.2, "img.jpg");
|
||||
// let terrain_generator = TerrainGenerator::<4>::new(
|
||||
// 5,
|
||||
// "./pointe_percee/height.tif",
|
||||
// 0.2,
|
||||
// "./pointe_percee/ortho.jpg",
|
||||
// );
|
||||
let terrain_generator = TerrainGenerator::<4>::new(
|
||||
5,
|
||||
"/home/albin/Documents/vxls_maps/lapiz/height.tif",
|
||||
0.2,
|
||||
"/home/albin/Documents/vxls_maps/lapiz/ortho.jpg",
|
||||
);
|
||||
// let terrain_generator = TerrainGenerator::<4>::new(
|
||||
// 5,
|
||||
// "/home/albin/Documents/vxls_maps/lapiz/height.tif",
|
||||
// 0.2,
|
||||
// "/home/albin/Documents/vxls_maps/lapiz/ortho.jpg",
|
||||
// );
|
||||
|
||||
let mut chunk_pos_map = HashMap::new();
|
||||
let chunk_instances = (0..terrain_generator.chunk_width)
|
||||
@@ -280,6 +284,7 @@ impl State
|
||||
usage_vec: Arc::new(Mutex::new(vec![])),
|
||||
pipeline: chunk_pipeline,
|
||||
voxel_cache: Arc::new(Mutex::new(voxel_cache)),
|
||||
cache_interface: cache_interface.into(),
|
||||
insertion_debounce: false,
|
||||
camera: Default::default(),
|
||||
instance_buffer,
|
||||
@@ -380,6 +385,7 @@ impl State
|
||||
// Create texture view.
|
||||
// NOTE: We must handle Timeout because the surface may be unavailable
|
||||
// (e.g., when the window is occluded on macOS).
|
||||
// ~~ Texture view creation ~~
|
||||
let surface_texture = match self.surface.get_current_texture()
|
||||
{
|
||||
wgpu::CurrentSurfaceTexture::Success(texture) => texture,
|
||||
@@ -407,6 +413,16 @@ impl State
|
||||
}
|
||||
};
|
||||
|
||||
let texture_view = surface_texture
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor {
|
||||
// Without add_srgb_suffix() the image we will be working with
|
||||
// might not be "gamma correct".
|
||||
format: Some(self.surface_format.add_srgb_suffix()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// ~~ Ray-marching timestamp query setup ~~
|
||||
let timestamp_query = self.device.create_query_set(&wgpu::QuerySetDescriptor {
|
||||
label: Some("timestamp_query_set"),
|
||||
ty: wgpu::QueryType::Timestamp,
|
||||
@@ -420,18 +436,8 @@ impl State
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let texture_view = surface_texture
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor {
|
||||
// Without add_srgb_suffix() the image we will be working with
|
||||
// might not be "gamma correct".
|
||||
format: Some(self.surface_format.add_srgb_suffix()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// Renders a GREEN screen
|
||||
// ~~ Main render pass ~~
|
||||
let mut encoder = self.device.create_command_encoder(&Default::default());
|
||||
|
||||
{
|
||||
let mut renderpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
@@ -440,7 +446,12 @@ impl State
|
||||
depth_slice: None,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||
r: 0.,
|
||||
g: 2. / 255.,
|
||||
b: 15. / 255.,
|
||||
a: 1.,
|
||||
}),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
@@ -478,24 +489,7 @@ impl State
|
||||
encoder.resolve_query_set(×tamp_query, 0..2, ×tamp_buffer, 0);
|
||||
}
|
||||
|
||||
let requests = self.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("dummy_dumb_dinky_aaaahhh_buffer"),
|
||||
size: 16 * 2000,
|
||||
usage: BufferUsages::STORAGE | BufferUsages::COPY_SRC,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
if !self
|
||||
.camera
|
||||
.pressed_keyset
|
||||
.contains(&winit::keyboard::KeyCode::KeyF)
|
||||
{
|
||||
self.voxel_cache
|
||||
.lock()
|
||||
.cache_post_render(&mut encoder, requests.clone());
|
||||
}
|
||||
|
||||
// If you wanted to call any drawing commands, they would go here.
|
||||
// ~~ EGUI Render pass ~~
|
||||
{
|
||||
self.egui_renderer.begin_frame(&self.window);
|
||||
egui::Window::new("Window ! ").resizable(true).show(
|
||||
@@ -547,7 +541,7 @@ impl State
|
||||
);
|
||||
}
|
||||
|
||||
// Report usage
|
||||
// ~~ Build usage buffer histogram
|
||||
let time_stamp = self.voxel_cache.lock().current_timestamp();
|
||||
let cloned_usage_histogram = self.usage_vec.clone();
|
||||
DownloadBuffer::read_buffer(
|
||||
@@ -567,27 +561,7 @@ impl State
|
||||
},
|
||||
);
|
||||
|
||||
// Submit the command in the queue to execute
|
||||
self.queue.submit([encoder.finish()]);
|
||||
self.window.pre_present_notify();
|
||||
self.queue.present(surface_texture);
|
||||
if !self
|
||||
.camera
|
||||
.pressed_keyset
|
||||
.contains(&winit::keyboard::KeyCode::KeyF)
|
||||
&& self.insertion_debounce
|
||||
{
|
||||
self.insertion_debounce = false;
|
||||
}
|
||||
|
||||
// if (self
|
||||
// .camera
|
||||
// .pressed_keyset
|
||||
// .contains(&winit::keyboard::KeyCode::KeyF))
|
||||
// && !self.insertion_debounce
|
||||
// {
|
||||
|
||||
// Report frame time
|
||||
// ~~ Get Ray-marching timestamps, report time ~~
|
||||
let cloned_rm_time = self.rm_time.clone();
|
||||
let cloned_queue = self.queue.clone();
|
||||
DownloadBuffer::read_buffer(
|
||||
@@ -602,30 +576,52 @@ impl State
|
||||
},
|
||||
);
|
||||
|
||||
// ~~ Do cache managment
|
||||
if !self
|
||||
.camera
|
||||
.pressed_keyset
|
||||
.contains(&winit::keyboard::KeyCode::KeyF)
|
||||
{
|
||||
self.voxel_cache
|
||||
.lock()
|
||||
.cache_post_render(&mut encoder, &self.cache_interface);
|
||||
}
|
||||
|
||||
// ~~ Submit command buffer ~~
|
||||
self.queue.submit([encoder.finish()]);
|
||||
self.window.pre_present_notify();
|
||||
self.queue.present(surface_texture);
|
||||
|
||||
// ~~ Do cache managment
|
||||
if !self
|
||||
.camera
|
||||
.pressed_keyset
|
||||
.contains(&winit::keyboard::KeyCode::KeyF)
|
||||
{
|
||||
self.insertion_debounce = true;
|
||||
let request_count = self.voxel_cache.lock().total_request_count();
|
||||
let request_count = self
|
||||
.cache_interface
|
||||
.total_request_count(&self.device, &self.queue);
|
||||
let cloned_cache = self.voxel_cache.clone();
|
||||
let cloned_device = self.device.clone();
|
||||
let cloned_queue = self.queue.clone();
|
||||
let cloned_generator = self.terrain_generator.clone();
|
||||
let cloned_map = self.chunk_pos_map.clone();
|
||||
let cloned_cache_interface = self.cache_interface.clone();
|
||||
let (tx, rx) = sync_channel(1);
|
||||
|
||||
// ~~ Download request buffer, fullfill requests, writeback to cache ~~
|
||||
DownloadBuffer::read_buffer(
|
||||
&self.device.clone(),
|
||||
&self.queue.clone(),
|
||||
&requests.slice(0..),
|
||||
&self.cache_interface.requests_buffer().slice(..),
|
||||
move |buffer| {
|
||||
if tx.try_send(()).is_err()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let cache_node_requests: Vec<CacheNodeRequest> =
|
||||
let cache_node_requests: Vec<CacheRequest> =
|
||||
bytemuck::pod_collect_to_vec(&buffer.unwrap());
|
||||
|
||||
let generator = cloned_generator;
|
||||
@@ -634,7 +630,6 @@ impl State
|
||||
let mut structure_nodes = vec![];
|
||||
let mut color_nodes: Vec<[ColorBytes; 64]> = vec![];
|
||||
let mut location_nodes = vec![];
|
||||
let mut destinations = vec![];
|
||||
|
||||
cache_node_requests
|
||||
.par_iter()
|
||||
@@ -646,7 +641,7 @@ impl State
|
||||
|
||||
let location;
|
||||
let node;
|
||||
if request.child_index == u32::MAX
|
||||
if request.locator == 0
|
||||
{
|
||||
// Produce root node
|
||||
node =
|
||||
@@ -660,9 +655,8 @@ impl State
|
||||
else
|
||||
{
|
||||
// Figure out depth of request
|
||||
let locator = NTreeNodeLocator::<4>::from_usize(
|
||||
request.structure_locator as usize,
|
||||
);
|
||||
let locator =
|
||||
NTreeNodeLocator::<4>::from_usize(request.locator as usize);
|
||||
let depth = locator.depth();
|
||||
//let (x, y, z) = locator.node_location();
|
||||
|
||||
@@ -692,15 +686,7 @@ impl State
|
||||
};
|
||||
}
|
||||
|
||||
(
|
||||
node.structure,
|
||||
node.colors,
|
||||
location,
|
||||
DestinationElement {
|
||||
node: request.node_index,
|
||||
child: request.child_index,
|
||||
},
|
||||
)
|
||||
(node.structure, node.colors, location)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
@@ -708,46 +694,30 @@ impl State
|
||||
structure_nodes.push(data.0);
|
||||
color_nodes.push(std::array::from_fn(|i| data.1[i].into()));
|
||||
location_nodes.push(data.2);
|
||||
destinations.push(data.3);
|
||||
});
|
||||
|
||||
if structure_nodes.len() != 0
|
||||
{
|
||||
let structre_node_buffer =
|
||||
cloned_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: unsafe { as_raw_bytes(structure_nodes.as_slice()) },
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
let color_node_buffer =
|
||||
cloned_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: unsafe { as_raw_bytes(color_nodes.as_slice()) },
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
let location_node_buffer =
|
||||
cloned_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: unsafe { as_raw_bytes(location_nodes.as_slice()) },
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
let destinations_buffer =
|
||||
cloned_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: unsafe { as_raw_bytes(destinations.as_slice()) },
|
||||
usage: BufferUsages::STORAGE,
|
||||
});
|
||||
cloned_queue.write_buffer(
|
||||
cloned_cache_interface.structure_nodes_buffer(),
|
||||
0,
|
||||
unsafe { as_raw_bytes(structure_nodes.as_slice()) },
|
||||
);
|
||||
cloned_queue.write_buffer(
|
||||
cloned_cache_interface.color_nodes_buffer(),
|
||||
0,
|
||||
unsafe { as_raw_bytes(&color_nodes.as_slice()) },
|
||||
);
|
||||
cloned_queue.write_buffer(
|
||||
cloned_cache_interface.location_nodes_buffer(),
|
||||
0,
|
||||
unsafe { as_raw_bytes(&&location_nodes.as_slice()) },
|
||||
);
|
||||
|
||||
let mut encoder = cloned_device.create_command_encoder(&Default::default());
|
||||
cloned_cache.lock().cache_insert(
|
||||
&mut encoder,
|
||||
&CacheResponse {
|
||||
structure_nodes: structre_node_buffer,
|
||||
color_nodes: color_node_buffer,
|
||||
locations: location_node_buffer,
|
||||
parents: destinations_buffer,
|
||||
},
|
||||
);
|
||||
cloned_cache
|
||||
.lock()
|
||||
.cache_insert(&mut encoder, &cloned_cache_interface);
|
||||
cloned_queue.submit([encoder.finish()]);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user