merge csg and object buffers

This commit is contained in:
2026-02-05 13:21:33 +00:00
parent a7c475b0a2
commit c5e6c1c5d8
7 changed files with 160 additions and 147 deletions
+7 -20
View File
@@ -44,10 +44,16 @@ layout(set = 0, binding = 3, std430) restrict readonly buffer Indicies {
} indicies; } indicies;
struct Object { struct Object {
// MESH
uint vert_offset;
uint index_offset;
// CSG
vec3 dimensions; vec3 dimensions;
vec3 lowest_corner; vec3 lowest_corner;
uint subdivision_log2; uint subdivision_log2;
// MATERIAL
vec4 colour_and_roughness; vec4 colour_and_roughness;
float metallic; float metallic;
float subsurface; float subsurface;
@@ -59,26 +65,7 @@ struct Object {
float clear_coat; float clear_coat;
}; };
struct Mesh { layout(set = 0, binding = 4, std430) restrict readonly buffer Objects {
uint vert_offset;
uint index_offset;
vec4 colour_and_roughness;
float metallic;
float subsurface;
float specular;
float specular_tint;
float sheen;
float sheen_tint;
float clear_coat_gloss;
float clear_coat;
};
layout(set = 0, binding = 4, std430) restrict readonly buffer Meshes {
Mesh meshes[];
} meshes;
layout(set = 0, binding = 5, std430) restrict readonly buffer Objects {
Object objects[]; Object objects[];
} objects; } objects;
+3 -3
View File
@@ -6,14 +6,14 @@
layout(location = 0) rayPayloadInEXT vec3 hit_value; layout(location = 0) rayPayloadInEXT vec3 hit_value;
hitAttributeEXT vec2 baryCoord; hitAttributeEXT vec2 baryCoord;
Mesh mesh; Object obj;
OVertex load_vert(uint index) { OVertex load_vert(uint index) {
return verts.verts[mesh.vert_offset + indicies.indicies[mesh.index_offset + index]]; return verts.verts[obj.vert_offset + indicies.indicies[obj.index_offset + index]];
} }
void main() { void main() {
mesh = meshes.meshes[gl_InstanceID]; obj = objects.objects[gl_InstanceID];
// get mesh vertex data in object space // get mesh vertex data in object space
OVertex v0 = load_vert((gl_PrimitiveID * 3) + 0); OVertex v0 = load_vert((gl_PrimitiveID * 3) + 0);
+39 -17
View File
@@ -128,31 +128,40 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
); );
let meshes_len = state.meshes.len(); let meshes_len = state.meshes.len();
let csg_len = state.csg.len(); let csg_len = state.csg.len();
let lights_len = state.lights.len();
let allow_mesh_delete = meshes_len > 1 || csg_len > 0;
let allow_csg_delete = meshes_len > 0 || csg_len > 1;
ui.heading(format!("Meshes ({})", meshes_len)); ui.heading(format!("Meshes ({})", meshes_len));
let mut meshdel = vec![]; let mut meshdel = vec![false; meshes_len];
for mesh in &mut state.meshes { for (i, mesh) in state.meshes.iter_mut().enumerate() {
ui.collapsing(mesh.name.clone(), |ui| { ui.collapsing(mesh.name.clone(), |ui| {
if meshes_len > 1 || csg_len > 0 { if allow_mesh_delete {
meshdel.push(ui.small_button("remove mesh").clicked()); meshdel[i] = ui.small_button("remove mesh").clicked();
} }
draw_position(ui, &mut mesh.position); draw_position(ui, &mut mesh.position);
draw_material(ui, &mut mesh.material); draw_material(ui, &mut mesh.material);
}); });
} }
if allow_mesh_delete && ui.small_button("remove all meshes").clicked() {
for del in meshdel.iter_mut() {
*del = true;
}
}
for i in meshdel for i in meshdel
.into_iter() .into_iter()
.enumerate() .enumerate()
.rev()
.filter_map(|(a, b)| if b { Some(a) } else { None }) .filter_map(|(a, b)| if b { Some(a) } else { None })
{ {
state.meshes.remove(i); state.meshes.remove(i);
} }
ui.heading(format!("Implicit Surfaces ({})", csg_len)); ui.heading(format!("Implicit Surfaces ({})", csg_len));
let mut csgdel = vec![]; let mut csgdel = vec![false; csg_len];
for csg in &mut state.csg { for (i, csg) in state.csg.iter_mut().enumerate() {
let mut csg = csg.write().unwrap(); let mut csg = csg.write().unwrap();
ui.collapsing(csg.name.clone(), |ui| { ui.collapsing(csg.name.clone(), |ui| {
if meshes_len > 0 || csg_len > 1 { if meshes_len > 0 || csg_len > 1 {
csgdel.push(ui.small_button("remove csg").clicked()); csgdel[i] = ui.small_button("remove csg").clicked();
} }
draw_position(ui, &mut csg.position); draw_position(ui, &mut csg.position);
draw_material(ui, &mut csg.material); draw_material(ui, &mut csg.material);
@@ -171,24 +180,30 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
}); });
}); });
} }
for i in csgdel
.into_iter()
.enumerate()
.filter_map(|(a, b)| if b { Some(a) } else { None })
{
state.csg.remove(i);
}
if state.csg.len() < 32 && ui.small_button("add csg").clicked() { if state.csg.len() < 32 && ui.small_button("add csg").clicked() {
state.new_csgs_needed += 1; state.new_csgs_needed += 1;
} }
if state.csg.len() < 32 && ui.small_button("add all csgs").clicked() { if state.csg.len() < 32 && ui.small_button("add all csgs").clicked() {
state.new_csgs_needed = (32 - state.csg.len()) as u8; state.new_csgs_needed = (32 - state.csg.len()) as u8;
} }
if allow_csg_delete && ui.small_button("remove all csgs").clicked() {
for del in csgdel.iter_mut() {
*del = true;
}
}
for i in csgdel
.into_iter()
.enumerate()
.rev()
.filter_map(|(a, b)| if b { Some(a) } else { None })
{
state.csg.remove(i);
}
ui.heading(format!("Lights ({})", state.lights.len())); ui.heading(format!("Lights ({})", state.lights.len()));
let mut lightdel = vec![]; let mut lightdel = vec![false; lights_len];
for (i, light) in state.lights.iter_mut().enumerate() { for (i, light) in state.lights.iter_mut().enumerate() {
ui.collapsing(format!("Light {i}"), |ui| { ui.collapsing(format!("Light {i}"), |ui| {
lightdel.push(ui.small_button("remove light").clicked()); lightdel[i] = ui.small_button("remove light").clicked();
ui.add( ui.add(
egui::Slider::new(&mut light.pos.x, -100.0..=100.0) egui::Slider::new(&mut light.pos.x, -100.0..=100.0)
.text("Position.x"), .text("Position.x"),
@@ -215,14 +230,21 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
); );
}); });
} }
let add_light = ui.small_button("add light").clicked();
if ui.small_button("remove all lights").clicked() {
for del in lightdel.iter_mut() {
*del = true;
}
}
for i in lightdel for i in lightdel
.into_iter() .into_iter()
.enumerate() .enumerate()
.rev()
.filter_map(|(a, b)| if b { Some(a) } else { None }) .filter_map(|(a, b)| if b { Some(a) } else { None })
{ {
state.lights.remove(i); state.lights.remove(i);
} }
if state.lights.len() < 32 && ui.small_button("add light").clicked() { if state.lights.len() < 32 && add_light {
state.lights.push(Light::default()); state.lights.push(Light::default());
} }
+16 -31
View File
@@ -16,8 +16,7 @@ const MINUMUM_SUBDIVISION: u32 = 8;
const MAX_VERTEX_BUFFER: DeviceSize = 1024 * 1024; const MAX_VERTEX_BUFFER: DeviceSize = 1024 * 1024;
const MAX_INDEX_BUFFER: DeviceSize = 1024 * 1024; const MAX_INDEX_BUFFER: DeviceSize = 1024 * 1024;
const MAX_CSG_BUFFER: DeviceSize = 256; const MAX_OBJECT_BUFFER: DeviceSize = 1024;
const MAX_MESH_BUFFER: DeviceSize = 256;
const MAX_TRANSFORM_BUFFER: DeviceSize = 1024; const MAX_TRANSFORM_BUFFER: DeviceSize = 1024;
use std::{ use std::{
@@ -192,10 +191,7 @@ struct App {
vertex_buffer_pointer: Arc<AtomicU64>, vertex_buffer_pointer: Arc<AtomicU64>,
index_buffer: Subbuffer<[u32]>, index_buffer: Subbuffer<[u32]>,
index_buffer_pointer: Arc<AtomicU64>, index_buffer_pointer: Arc<AtomicU64>,
csg_buffer: Subbuffer<[enable_gen_cs::Object]>, object_buffer: Subbuffer<[enable_gen_cs::Object]>,
_csg_buffer_pointer: Arc<AtomicU64>,
mesh_buffer: Subbuffer<[enable_gen_cs::Mesh]>,
_mesh_buffer_pointer: Arc<AtomicU64>,
transform_buffer: Subbuffer<[[[f32; 4]; 3]]>, transform_buffer: Subbuffer<[[[f32; 4]; 3]]>,
transform_buffer_pointer: Arc<AtomicU64>, transform_buffer_pointer: Arc<AtomicU64>,
pipeline_cache: Arc<PipelineCache>, pipeline_cache: Arc<PipelineCache>,
@@ -574,22 +570,18 @@ impl App {
let vertex_buffer; let vertex_buffer;
let index_buffer; let index_buffer;
let csg_buffer; let object_buffer;
let mesh_buffer;
let transform_buffer; let transform_buffer;
{ {
let device_lock = uniform_buffer_allocator.lock().unwrap(); let device_lock = uniform_buffer_allocator.lock().unwrap();
vertex_buffer = device_lock.allocate_slice(MAX_VERTEX_BUFFER).unwrap(); vertex_buffer = device_lock.allocate_slice(MAX_VERTEX_BUFFER).unwrap();
index_buffer = device_lock.allocate_slice(MAX_INDEX_BUFFER).unwrap(); index_buffer = device_lock.allocate_slice(MAX_INDEX_BUFFER).unwrap();
csg_buffer = device_lock.allocate_slice(MAX_CSG_BUFFER).unwrap(); object_buffer = device_lock.allocate_slice(MAX_OBJECT_BUFFER).unwrap();
mesh_buffer = device_lock.allocate_slice(MAX_MESH_BUFFER).unwrap();
transform_buffer = device_lock.allocate_slice(MAX_TRANSFORM_BUFFER).unwrap(); transform_buffer = device_lock.allocate_slice(MAX_TRANSFORM_BUFFER).unwrap();
}; };
let vertex_buffer_pointer = Arc::new(AtomicU64::new(0)); let vertex_buffer_pointer = Arc::new(AtomicU64::new(0));
let index_buffer_pointer = Arc::new(AtomicU64::new(0)); let index_buffer_pointer = Arc::new(AtomicU64::new(0));
let csg_buffer_pointer = Arc::new(AtomicU64::new(0));
let mesh_buffer_pointer = Arc::new(AtomicU64::new(0));
let transform_buffer_pointer = Arc::new(AtomicU64::new(0)); let transform_buffer_pointer = Arc::new(AtomicU64::new(0));
let pipeline_cache = get_pipeline_cache(device.clone()); let pipeline_cache = get_pipeline_cache(device.clone());
@@ -706,13 +698,10 @@ impl App {
aabb_allocator, aabb_allocator,
vertex_buffer, vertex_buffer,
index_buffer, index_buffer,
csg_buffer, object_buffer,
mesh_buffer,
transform_buffer, transform_buffer,
vertex_buffer_pointer, vertex_buffer_pointer,
index_buffer_pointer, index_buffer_pointer,
_csg_buffer_pointer: csg_buffer_pointer,
_mesh_buffer_pointer: mesh_buffer_pointer,
transform_buffer_pointer, transform_buffer_pointer,
pipeline_cache, pipeline_cache,
csg_count: gstate.csg.len(), csg_count: gstate.csg.len(),
@@ -739,7 +728,7 @@ mod enable_gen_cs {
bytes: "shaders_out/replacement/enable_gen.comp.glsl.spv", bytes: "shaders_out/replacement/enable_gen.comp.glsl.spv",
vulkan_version: "1.3", vulkan_version: "1.3",
spirv_version: "1.6", spirv_version: "1.6",
custom_derives: [Debug, Clone, Copy], custom_derives: [Debug, Clone, Copy, Default],
} }
} }
@@ -979,7 +968,7 @@ impl ApplicationHandler for App {
&self.vertex_buffer, &self.vertex_buffer,
&self.index_buffer, &self.index_buffer,
&self.transform_buffer, &self.transform_buffer,
&self.mesh_buffer, &self.object_buffer,
0, 0,
); );
@@ -1290,8 +1279,7 @@ impl App {
WriteDescriptorSet::buffer(1, rcx.camera_buffers[index].clone()), WriteDescriptorSet::buffer(1, rcx.camera_buffers[index].clone()),
WriteDescriptorSet::buffer(2, self.vertex_buffer.clone()), WriteDescriptorSet::buffer(2, self.vertex_buffer.clone()),
WriteDescriptorSet::buffer(3, self.index_buffer.clone()), WriteDescriptorSet::buffer(3, self.index_buffer.clone()),
WriteDescriptorSet::buffer(4, self.mesh_buffer.clone()), WriteDescriptorSet::buffer(4, self.object_buffer.clone()),
//WriteDescriptorSet::buffer(5, self.csg_buffer.clone()),
], ],
[], [],
) )
@@ -1334,7 +1322,7 @@ impl App {
enable_gen_layout.clone(), enable_gen_layout.clone(),
[ [
WriteDescriptorSet::buffer(1, rcx.camera_buffers[index].clone()), WriteDescriptorSet::buffer(1, rcx.camera_buffers[index].clone()),
WriteDescriptorSet::buffer(5, self.csg_buffer.clone()), WriteDescriptorSet::buffer(4, self.object_buffer.clone()),
], ],
[], [],
) )
@@ -1374,7 +1362,7 @@ impl App {
csg.enable_gen_pipeline.layout().clone(), csg.enable_gen_pipeline.layout().clone(),
0, 0,
enable_gen_cs::PushConstantData { enable_gen_cs::PushConstantData {
object_index: i as u32, object_index: (self.gstate.meshes.len() + i) as u32,
}, },
) )
.unwrap(); .unwrap();
@@ -1921,13 +1909,7 @@ impl App {
let mut push_constants_left = self.gstate.csg.len(); let mut push_constants_left = self.gstate.csg.len();
for (i, csg) in self.gstate.csg.iter().enumerate() { for (i, csg) in self.gstate.csg.iter().enumerate() {
self.thread_work_creation self.thread_work_creation
.send(WorkItem::GetPushConstants( .send(WorkItem::GetPushConstants(csg.clone(), self.time, i))
csg.clone(),
self.time,
self.transform_buffer.clone(),
self.csg_buffer.clone(),
i,
))
.unwrap(); .unwrap();
} }
@@ -1962,7 +1944,10 @@ impl App {
while push_constants_left > 0 { while push_constants_left > 0 {
for work in self.thread_work_completion.try_iter() { for work in self.thread_work_completion.try_iter() {
match work { match work {
WorkComplete::GetPushConstants(_index) => { WorkComplete::GetPushConstants(dimensions, lowest_corner, index) => {
let mut write = self.gstate.csg[index].write().unwrap();
write.dimensions = dimensions;
write.lowest_corner = lowest_corner;
push_constants_left -= 1; push_constants_left -= 1;
}, },
other => work_for_later.push(other), other => work_for_later.push(other),
@@ -1983,7 +1968,7 @@ impl App {
&self.vertex_buffer, &self.vertex_buffer,
&self.index_buffer, &self.index_buffer,
&self.transform_buffer, &self.transform_buffer,
&self.mesh_buffer, &self.object_buffer,
image_index, image_index,
); );
+3
View File
@@ -76,6 +76,9 @@ pub(crate) struct CSG {
pub(crate) _seed: u64, pub(crate) _seed: u64,
pub(crate) subdivision: u32, pub(crate) subdivision: u32,
pub(crate) dimensions: Vec3,
pub(crate) lowest_corner: Vec3,
pub(crate) replacement_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>, pub(crate) replacement_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
pub(crate) fuzz_pipeline: Arc<ComputePipeline>, pub(crate) fuzz_pipeline: Arc<ComputePipeline>,
pub(crate) enable_gen_pipeline: Arc<ComputePipeline>, pub(crate) enable_gen_pipeline: Arc<ComputePipeline>,
+81 -28
View File
@@ -24,7 +24,7 @@ use vulkano::{
}; };
use crate::{ use crate::{
enable_gen_cs, MAXIMUM_SUBDIVISION, MINUMUM_SUBDIVISION, enable_gen_cs,
gpu_upload::gpu_upload, gpu_upload::gpu_upload,
objects::{CSG, Mesh, OVertex, Position}, objects::{CSG, Mesh, OVertex, Position},
}; };
@@ -47,7 +47,7 @@ impl Scene {
vertex_buffer: &Subbuffer<[OVertex]>, vertex_buffer: &Subbuffer<[OVertex]>,
index_buffer: &Subbuffer<[u32]>, index_buffer: &Subbuffer<[u32]>,
transform_buffer: &Subbuffer<[[[f32; 4]; 3]]>, transform_buffer: &Subbuffer<[[[f32; 4]; 3]]>,
mesh_buffer: &Subbuffer<[enable_gen_cs::Mesh]>, object_buffer: &Subbuffer<[enable_gen_cs::Object]>,
image_index: usize, image_index: usize,
) -> Self { ) -> Self {
// Build the bottom-level acceleration structure and then the top-level // Build the bottom-level acceleration structure and then the top-level
@@ -57,34 +57,42 @@ impl Scene {
// contains the instances of the bottom-level acceleration structures. In our // contains the instances of the bottom-level acceleration structures. In our
// shader, we will trace rays against the top-level acceleration // shader, we will trace rays against the top-level acceleration
// structure. // structure.
let mut index = 0;
let mesh_blases: Vec<Arc<AccelerationStructure>> = meshes let mesh_blases: Vec<Arc<AccelerationStructure>> = meshes
.iter() .iter()
.enumerate() .map(|mesh| unsafe {
.map(|(i, mesh)| unsafe { let s = build_acceleration_structure_triangles(
build_acceleration_structure_triangles(
mesh, mesh,
vertex_buffer.clone(), vertex_buffer.clone(),
index_buffer.clone(), index_buffer.clone(),
transform_buffer.clone(), transform_buffer.clone(),
mesh_buffer.clone(), object_buffer.clone(),
memory_allocator.clone(), memory_allocator.clone(),
device.clone(), device.clone(),
builder, builder,
i, index,
) );
index += 1;
s
}) })
.collect(); .collect();
let csg_blases: Vec<Arc<AccelerationStructure>> = csgs let csg_blases: Vec<Arc<AccelerationStructure>> = csgs
.iter() .iter()
.map(|csg| unsafe { .map(|csg| unsafe {
build_acceleration_structure_boxes( let s = build_acceleration_structure_boxes(
csg, csg,
image_index, transform_buffer.clone(),
object_buffer.clone(),
memory_allocator.clone(), memory_allocator.clone(),
device.clone(), device.clone(),
builder, builder,
) image_index,
index,
);
index += 1;
s
}) })
.collect(); .collect();
@@ -145,27 +153,66 @@ pub(crate) fn upload_transform(position: &Position, transform_buffer: Subbuffer<
); );
} }
fn upload_mesh_data(mesh: &Mesh, mesh_buffer: Subbuffer<[enable_gen_cs::Mesh]>, index: DeviceSize) { fn upload_mesh_data(
let mesh = enable_gen_cs::Mesh { mesh: &Mesh,
vert_offset: (mesh.vert_offset as u32).into(), object_buffer: Subbuffer<[enable_gen_cs::Object]>,
index_offset: (mesh.index_offset as u32).into(), index: DeviceSize,
) {
let mesh = enable_gen_cs::Object {
vert_offset: (mesh.vert_offset as u32).into(),
index_offset: (mesh.index_offset as u32).into(),
colour_and_roughness: [ colour_and_roughness: [
mesh.material.colour[0], mesh.material.colour[0],
mesh.material.colour[1], mesh.material.colour[1],
mesh.material.colour[2], mesh.material.colour[2],
mesh.material.roughness, mesh.material.roughness,
], ],
metallic: mesh.material.metallic, metallic: mesh.material.metallic,
subsurface: mesh.material.subsurface, subsurface: mesh.material.subsurface,
specular: mesh.material.specular, specular: mesh.material.specular,
specular_tint: mesh.material.specular_tint, specular_tint: mesh.material.specular_tint,
sheen: mesh.material.sheen, sheen: mesh.material.sheen,
sheen_tint: mesh.material.sheen_tint, sheen_tint: mesh.material.sheen_tint,
clear_coat_gloss: mesh.material.clear_coat_gloss, clear_coat_gloss: mesh.material.clear_coat_gloss,
clear_coat: mesh.material.clear_coat, clear_coat: mesh.material.clear_coat,
..Default::default()
}; };
gpu_upload(mesh, mesh_buffer.index(index)); gpu_upload(mesh, object_buffer.index(index));
}
fn upload_csg_data(
csg: &CSG,
object_buffer: Subbuffer<[enable_gen_cs::Object]>,
index: DeviceSize,
) {
// csg.subdivision must be a power of 2
assert_eq!(csg.subdivision.count_ones(), 1);
assert!(csg.subdivision <= MAXIMUM_SUBDIVISION);
assert!(csg.subdivision >= MINUMUM_SUBDIVISION);
let obj = enable_gen_cs::Object {
dimensions: csg.dimensions.to_array().into(),
lowest_corner: csg.lowest_corner.to_array().into(),
subdivision_log2: csg.subdivision.ilog2(),
colour_and_roughness: [
csg.material.colour[0],
csg.material.colour[1],
csg.material.colour[2],
csg.material.roughness,
],
metallic: csg.material.metallic,
subsurface: csg.material.subsurface,
specular: csg.material.specular,
specular_tint: csg.material.specular_tint,
sheen: csg.material.sheen,
sheen_tint: csg.material.sheen_tint,
clear_coat_gloss: csg.material.clear_coat_gloss,
clear_coat: csg.material.clear_coat,
..Default::default()
};
gpu_upload(obj, object_buffer.index(index))
} }
/// A helper function to build a acceleration structure and wait for its /// A helper function to build a acceleration structure and wait for its
@@ -268,14 +315,14 @@ unsafe fn build_acceleration_structure_triangles(
vertex_buffer: Subbuffer<[OVertex]>, vertex_buffer: Subbuffer<[OVertex]>,
index_buffer: Subbuffer<[u32]>, index_buffer: Subbuffer<[u32]>,
transform_buffer: Subbuffer<[[[f32; 4]; 3]]>, transform_buffer: Subbuffer<[[[f32; 4]; 3]]>,
mesh_buffer: Subbuffer<[enable_gen_cs::Mesh]>, object_buffer: Subbuffer<[enable_gen_cs::Object]>,
memory_allocator: Arc<dyn MemoryAllocator>, memory_allocator: Arc<dyn MemoryAllocator>,
device: Arc<Device>, device: Arc<Device>,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
index: usize, index: usize,
) -> Arc<AccelerationStructure> { ) -> Arc<AccelerationStructure> {
upload_transform(&mesh.position, transform_buffer.clone()); upload_transform(&mesh.position, transform_buffer.clone());
upload_mesh_data(&mesh, mesh_buffer, index as _); upload_mesh_data(&mesh, object_buffer, index as _);
let primitive_count = (mesh.index_len / 3) as u32; let primitive_count = (mesh.index_len / 3) as u32;
let as_geometry_triangles_data = AccelerationStructureGeometryTrianglesData { let as_geometry_triangles_data = AccelerationStructureGeometryTrianglesData {
@@ -309,16 +356,22 @@ unsafe fn build_acceleration_structure_triangles(
unsafe fn build_acceleration_structure_boxes( unsafe fn build_acceleration_structure_boxes(
csg: &Arc<RwLock<CSG>>, csg: &Arc<RwLock<CSG>>,
index: usize, transform_buffer: Subbuffer<[[[f32; 4]; 3]]>,
object_buffer: Subbuffer<[enable_gen_cs::Object]>,
memory_allocator: Arc<dyn MemoryAllocator>, memory_allocator: Arc<dyn MemoryAllocator>,
device: Arc<Device>, device: Arc<Device>,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
image_index: usize,
index: usize,
) -> Arc<AccelerationStructure> { ) -> Arc<AccelerationStructure> {
let csg = csg.read().unwrap(); let csg = csg.read().unwrap();
upload_transform(&csg.position, transform_buffer);
upload_csg_data(&csg, object_buffer, index as _);
let primitive_count = (csg.subdivision * csg.subdivision * csg.subdivision) as u32; let primitive_count = (csg.subdivision * csg.subdivision * csg.subdivision) as u32;
let as_geometry_aabb_data = AccelerationStructureGeometryAabbsData { let as_geometry_aabb_data = AccelerationStructureGeometryAabbsData {
stride: 4 * 6, // six floats stride: 4 * 6, // six floats
data: Some(csg.aabb_buffer[index].clone()), data: Some(csg.aabb_buffer[image_index].clone()),
..AccelerationStructureGeometryAabbsData::default() ..AccelerationStructureGeometryAabbsData::default()
}; };
+11 -48
View File
@@ -25,12 +25,10 @@ use vulkano::{
}; };
use crate::{ use crate::{
DUMP_SPV_TO_FILE, MAXIMUM_SUBDIVISION, MINUMUM_SUBDIVISION, enable_gen_cs, get_spec_constants, DUMP_SPV_TO_FILE, MAXIMUM_SUBDIVISION, get_spec_constants,
gpu_upload,
gui::PreviousDebug, gui::PreviousDebug,
interpreters::point::PointInterpreter, interpreters::point::PointInterpreter,
objects::CSG, objects::CSG,
scene::upload_transform,
ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape}, ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape},
}; };
@@ -48,13 +46,7 @@ pub enum WorkItem {
u64, u64,
isize, isize,
), ),
GetPushConstants( GetPushConstants(Arc<RwLock<CSG>>, f32, usize),
Arc<RwLock<CSG>>,
f32,
Subbuffer<[[[f32; 4]; 3]]>,
Subbuffer<[enable_gen_cs::Object]>,
usize,
),
RecompileShaders( RecompileShaders(
Arc<RwLock<CSG>>, Arc<RwLock<CSG>>,
Arc<Device>, Arc<Device>,
@@ -72,7 +64,7 @@ pub enum WorkItem {
pub enum WorkComplete { pub enum WorkComplete {
CreateCSG(Arc<RwLock<CSG>>, isize), CreateCSG(Arc<RwLock<CSG>>, isize),
GetPushConstants(usize), GetPushConstants(Vec3, Vec3, usize),
RecompileShaders(usize), RecompileShaders(usize),
RecompilePipelines(usize), RecompilePipelines(usize),
} }
@@ -150,6 +142,8 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
subdivision, subdivision,
aabb_buffer, aabb_buffer,
enable_gen_descriptor_set, enable_gen_descriptor_set,
dimensions: Default::default(),
lowest_corner: Default::default(),
})); }));
send.send(WorkComplete::CreateCSG(csg, index)).unwrap(); send.send(WorkComplete::CreateCSG(csg, index)).unwrap();
@@ -160,14 +154,13 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
(csg_end - csg_start).as_secs_f64() * 1000.0 (csg_end - csg_start).as_secs_f64() * 1000.0
); );
}, },
WorkItem::GetPushConstants(csg, time, transform_buffer, csg_buffer, index) => { WorkItem::GetPushConstants(csg, time, index) => {
let csg = csg.read().unwrap(); let csg = csg.read().unwrap();
upload_transform(&csg.position, transform_buffer); let (dim, lowest) = interval_check(&csg, time);
interval_check(&csg, time, csg_buffer, index); send.send(WorkComplete::GetPushConstants(dim, lowest, index))
.unwrap();
send.send(WorkComplete::GetPushConstants(index)).unwrap();
}, },
WorkItem::RecompileShaders(csg, device, replacement_modules, index) => { WorkItem::RecompileShaders(csg, device, replacement_modules, index) => {
let csg_start = Instant::now(); let csg_start = Instant::now();
@@ -440,12 +433,7 @@ fn create_csg(seed: u64) -> SSATape {
tape tape
} }
fn interval_check( fn interval_check(csg: &CSG, time: f32) -> (Vec3, Vec3) {
csg: &CSG,
time: f32,
csg_buffer: Subbuffer<[enable_gen_cs::Object]>,
index: usize,
) {
const INTERPRET_INPUT_X: interpreters::Value = const INTERPRET_INPUT_X: interpreters::Value =
interpreters::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]); interpreters::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]);
const INTERPRET_INPUT_Y: interpreters::Value = const INTERPRET_INPUT_Y: interpreters::Value =
@@ -476,32 +464,7 @@ fn interval_check(
let lowest_corner = let lowest_corner =
Vec3::new(interpreter_out[3], interpreter_out[4], interpreter_out[5]) - EPSILON; Vec3::new(interpreter_out[3], interpreter_out[4], interpreter_out[5]) - EPSILON;
// csg.subdivision must be a power of 2 (highest_corner - lowest_corner, lowest_corner)
assert_eq!(csg.subdivision.count_ones(), 1);
assert!(csg.subdivision <= MAXIMUM_SUBDIVISION);
assert!(csg.subdivision >= MINUMUM_SUBDIVISION);
let obj = enable_gen_cs::Object {
dimensions: (highest_corner - lowest_corner).to_array().into(),
lowest_corner: lowest_corner.into(),
subdivision_log2: csg.subdivision.ilog2(),
colour_and_roughness: [
csg.material.colour[0],
csg.material.colour[1],
csg.material.colour[2],
csg.material.roughness,
],
metallic: csg.material.metallic,
subsurface: csg.material.subsurface,
specular: csg.material.specular,
specular_tint: csg.material.specular_tint,
sheen: csg.material.sheen,
sheen_tint: csg.material.sheen_tint,
clear_coat_gloss: csg.material.clear_coat_gloss,
clear_coat: csg.material.clear_coat,
};
gpu_upload(obj, csg_buffer.index(index as _))
} }
fn sdf_specialize_module( fn sdf_specialize_module(