reorder acceleration structure build

This commit is contained in:
2026-02-01 17:57:33 +00:00
parent bba02e0805
commit 06a173e207
4 changed files with 45 additions and 65 deletions
@@ -26,7 +26,7 @@ void main() {
total_dist += dist; total_dist += dist;
p = fma(raydir, vec3(total_dist), raypos); p = fma(raydir, vec3(total_dist), raypos);
if (abs(dist) < EPSILON) { if (abs(dist) < EPSILON) {
reportIntersectionEXT(total_dist, 0); reportIntersectionEXT(max(total_dist, gl_RayTminEXT), 0);
return; return;
} else if (total_dist > farplane) { } else if (total_dist > farplane) {
break; break;
+7 -4
View File
@@ -66,7 +66,7 @@ impl Default for GState {
lights: vec![], lights: vec![],
csg: vec![], csg: vec![],
new_csgs_needed: 0, new_csgs_needed: 1,
cpu_mpf: [0.0; 1024], cpu_mpf: [0.0; 1024],
gpu_mpf: [0.0; 1024], gpu_mpf: [0.0; 1024],
@@ -130,11 +130,12 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
.text("Clear Coat Gloss"), .text("Clear Coat Gloss"),
); );
let meshes_len = state.meshes.len(); let meshes_len = state.meshes.len();
let csg_len = state.csg.len();
ui.heading(format!("Meshes ({})", meshes_len)); ui.heading(format!("Meshes ({})", meshes_len));
let mut meshdel = vec![]; let mut meshdel = vec![];
for mesh in &mut state.meshes { for mesh in &mut state.meshes {
ui.label(mesh.name.clone()); ui.label(mesh.name.clone());
if meshes_len > 1 { if meshes_len > 1 || csg_len > 0 {
meshdel.push(ui.small_button("remove mesh").clicked()); meshdel.push(ui.small_button("remove mesh").clicked());
} }
ui.add( ui.add(
@@ -169,12 +170,14 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
{ {
state.meshes.remove(i); state.meshes.remove(i);
} }
ui.heading(format!("Implicit Surfaces ({})", state.csg.len())); ui.heading(format!("Implicit Surfaces ({})", csg_len));
let mut csgdel = vec![]; let mut csgdel = vec![];
for csg in &mut state.csg { for csg in &mut state.csg {
let mut csg = csg.write().unwrap(); let mut csg = csg.write().unwrap();
ui.label(csg.name.clone()); ui.label(csg.name.clone());
csgdel.push(ui.small_button("remove csg").clicked()); if meshes_len > 0 || csg_len > 1 {
csgdel.push(ui.small_button("remove csg").clicked());
}
ui.add( ui.add(
egui::Slider::new(&mut csg.pos.x, -100.0..=100.0) egui::Slider::new(&mut csg.pos.x, -100.0..=100.0)
.text("Position.x"), .text("Position.x"),
+31 -13
View File
@@ -48,7 +48,7 @@ use vulkano::{
}, },
command_buffer::{ command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer,
RenderPassBeginInfo, SubpassBeginInfo, SubpassContents, PrimaryCommandBufferAbstract, RenderPassBeginInfo, SubpassBeginInfo, SubpassContents,
allocator::{CommandBufferAllocator, StandardCommandBufferAllocator}, allocator::{CommandBufferAllocator, StandardCommandBufferAllocator},
}, },
descriptor_set::{ descriptor_set::{
@@ -1007,16 +1007,32 @@ impl ApplicationHandler for App {
&self.gstate.csg, &self.gstate.csg,
); );
let mut builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.clone(),
self.graphics_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
let scene = Scene::new( let scene = Scene::new(
&self.device, &self.device,
&self.compute_queue, &mut builder,
&self.memory_allocator, &self.memory_allocator,
&self.command_buffer_allocator,
&self.gstate.meshes, &self.gstate.meshes,
&self.gstate.csg, &self.gstate.csg,
0, 0,
); );
builder
.build()
.unwrap()
.execute(self.graphics_queue.clone())
.unwrap()
.then_signal_fence_and_flush()
.unwrap()
.wait(None)
.unwrap();
let ( let (
camera_buffers, camera_buffers,
camera_buffers_host_visible, camera_buffers_host_visible,
@@ -1867,6 +1883,9 @@ impl App {
)) ))
.unwrap(); .unwrap();
}, },
WorkComplete::RecompilePipelines(_index) => {
csg_pipelines_left -= 1;
},
other => work_for_later.push(other), other => work_for_later.push(other),
} }
} }
@@ -2228,16 +2247,6 @@ impl App {
let image_index = image_index as usize; let image_index = image_index as usize;
rcx.scene = Scene::new(
&self.device,
&self.compute_queue,
&self.memory_allocator,
&self.command_buffer_allocator,
&self.gstate.meshes,
&self.gstate.csg,
image_index,
);
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
@@ -2336,6 +2345,15 @@ impl App {
} }
if RUN_RT_PIPELINE { if RUN_RT_PIPELINE {
rcx.scene = Scene::new(
&self.device,
&mut builder,
&self.memory_allocator,
&self.gstate.meshes,
&self.gstate.csg,
image_index,
);
self.add_commands_raytrace(&mut builder, rcx, rt_set1, rt_set2, rt_set3, rt_set4); self.add_commands_raytrace(&mut builder, rcx, rt_set1, rt_set2, rt_set3, rt_set4);
} }
+6 -47
View File
@@ -16,14 +16,10 @@ use vulkano::{
BuildAccelerationStructureMode, GeometryInstanceFlags, BuildAccelerationStructureMode, GeometryInstanceFlags,
}, },
buffer::{Buffer, BufferCreateInfo, BufferUsage, IndexBuffer, Subbuffer}, buffer::{Buffer, BufferCreateInfo, BufferUsage, IndexBuffer, Subbuffer},
command_buffer::{ command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer},
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, device::Device,
PrimaryCommandBufferAbstract, allocator::CommandBufferAllocator,
},
device::{Device, Queue},
format::Format, format::Format,
memory::allocator::{AllocationCreateInfo, DeviceLayout, MemoryAllocator, MemoryTypeFilter}, memory::allocator::{AllocationCreateInfo, DeviceLayout, MemoryAllocator, MemoryTypeFilter},
sync::GpuFuture,
}; };
use crate::objects::{CSG, Mesh, OVertex}; use crate::objects::{CSG, Mesh, OVertex};
@@ -39,22 +35,12 @@ pub struct Scene {
impl Scene { impl Scene {
pub fn new( pub fn new(
device: &Arc<Device>, device: &Arc<Device>,
compute_queue: &Arc<Queue>, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
memory_allocator: &Arc<dyn MemoryAllocator>, memory_allocator: &Arc<dyn MemoryAllocator>,
command_buffer_allocator: &Arc<dyn CommandBufferAllocator>,
meshes: &[Mesh], meshes: &[Mesh],
csgs: &[Arc<RwLock<CSG>>], csgs: &[Arc<RwLock<CSG>>],
image_index: usize, image_index: usize,
) -> Self { ) -> Self {
// For simplicity, we build a single command buffer that builds the acceleration
// structure, then waits for its execution to complete.
let mut builder = AutoCommandBufferBuilder::primary(
command_buffer_allocator.clone(),
compute_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
// Build the bottom-level acceleration structure and then the top-level // Build the bottom-level acceleration structure and then the top-level
// acceleration structure. Acceleration structures are used to // acceleration structure. Acceleration structures are used to
// accelerate ray tracing. The bottom-level acceleration structure // accelerate ray tracing. The bottom-level acceleration structure
@@ -69,7 +55,7 @@ impl Scene {
mesh, mesh,
memory_allocator.clone(), memory_allocator.clone(),
device.clone(), device.clone(),
&mut builder, builder,
) )
}) })
.collect(); .collect();
@@ -82,28 +68,11 @@ impl Scene {
image_index, image_index,
memory_allocator.clone(), memory_allocator.clone(),
device.clone(), device.clone(),
&mut builder, builder,
) )
}) })
.collect(); .collect();
let blas_fence = builder
.build()
.unwrap()
.execute(compute_queue.clone())
.unwrap()
.then_signal_semaphore_and_flush()
.unwrap();
// For simplicity, we build a single command buffer that builds the acceleration
// structure, then waits for its execution to complete.
let mut builder = AutoCommandBufferBuilder::primary(
command_buffer_allocator.clone(),
compute_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)
.unwrap();
let tlas = unsafe { let tlas = unsafe {
build_top_level_acceleration_structure( build_top_level_acceleration_structure(
mesh_blases mesh_blases
@@ -129,20 +98,10 @@ impl Scene {
.collect(), .collect(),
memory_allocator.clone(), memory_allocator.clone(),
device.clone(), device.clone(),
&mut builder, builder,
) )
}; };
builder
.build()
.unwrap()
.execute_after(blas_fence, compute_queue.clone())
.unwrap()
.then_signal_fence_and_flush()
.unwrap()
.wait(None)
.unwrap();
Scene { Scene {
_mesh_blases: mesh_blases, _mesh_blases: mesh_blases,
_csg_blases: csg_blases, _csg_blases: csg_blases,