redo how acceleration structures build
This commit is contained in:
@@ -126,11 +126,14 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
|
||||
egui::Slider::new(&mut state.clear_coat_gloss, 0.0..=1.0)
|
||||
.text("Clear Coat Gloss"),
|
||||
);
|
||||
ui.heading(format!("Meshes ({})", state.meshes.len()));
|
||||
let meshes_len = state.meshes.len();
|
||||
ui.heading(format!("Meshes ({})", meshes_len));
|
||||
let mut meshdel = vec![];
|
||||
for mesh in &mut state.meshes {
|
||||
ui.label(mesh.name.clone());
|
||||
meshdel.push(ui.small_button("remove mesh").clicked());
|
||||
if meshes_len > 1 {
|
||||
meshdel.push(ui.small_button("remove mesh").clicked());
|
||||
}
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.pos.x, -100.0..=100.0)
|
||||
.text("Position.x"),
|
||||
|
||||
+162
-93
@@ -38,12 +38,13 @@ use vulkano::{
|
||||
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
||||
},
|
||||
command_buffer::{
|
||||
AutoCommandBufferBuilder, CommandBufferExecFuture, CommandBufferUsage, CopyBufferInfo,
|
||||
PrimaryAutoCommandBuffer, PrimaryCommandBufferAbstract, RenderPassBeginInfo,
|
||||
SubpassBeginInfo, SubpassContents, allocator::StandardCommandBufferAllocator,
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, CopyBufferInfo, PrimaryAutoCommandBuffer,
|
||||
PrimaryCommandBufferAbstract, RenderPassBeginInfo, SubpassBeginInfo, SubpassContents,
|
||||
allocator::{CommandBufferAllocator, StandardCommandBufferAllocator},
|
||||
},
|
||||
descriptor_set::{
|
||||
DescriptorSet, WriteDescriptorSet, allocator::StandardDescriptorSetAllocator,
|
||||
DescriptorSet, WriteDescriptorSet,
|
||||
allocator::{DescriptorSetAllocator, StandardDescriptorSetAllocator},
|
||||
},
|
||||
device::{
|
||||
Device, DeviceCreateInfo, DeviceExtensions, DeviceFeatures, DeviceOwned, Queue,
|
||||
@@ -56,7 +57,9 @@ use vulkano::{
|
||||
view::{ImageView, ImageViewCreateInfo},
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
||||
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
|
||||
memory::allocator::{
|
||||
AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter, StandardMemoryAllocator,
|
||||
},
|
||||
pipeline::{
|
||||
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
|
||||
PipelineShaderStageCreateInfo,
|
||||
@@ -83,10 +86,7 @@ use vulkano::{
|
||||
PresentMode, Surface, SurfaceInfo, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
|
||||
acquire_next_image,
|
||||
},
|
||||
sync::{
|
||||
self, GpuFuture, PipelineStage,
|
||||
future::{FenceSignalFuture, NowFuture},
|
||||
},
|
||||
sync::{self, GpuFuture, PipelineStage, future::FenceSignalFuture},
|
||||
};
|
||||
#[cfg(target_os = "linux")]
|
||||
use winit::platform::x11::EventLoopBuilderExtX11;
|
||||
@@ -106,7 +106,7 @@ use crate::{
|
||||
trace_vs::{Camera, Lights, PushConstantData},
|
||||
};
|
||||
mod objects;
|
||||
use tape_load::{instruction_set, interpreters, ssa, types, vm};
|
||||
use tape_load::{interpreters, ssa, types};
|
||||
|
||||
use crate::objects::*;
|
||||
|
||||
@@ -200,9 +200,10 @@ struct App {
|
||||
depth_format: Format,
|
||||
graphics_queue: Arc<Queue>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
memory_allocator: Arc<StandardMemoryAllocator>,
|
||||
descriptor_set_allocator: Arc<StandardDescriptorSetAllocator>,
|
||||
command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
|
||||
compute_queue: Arc<Queue>,
|
||||
memory_allocator: Arc<dyn MemoryAllocator>,
|
||||
descriptor_set_allocator: Arc<dyn DescriptorSetAllocator>,
|
||||
command_buffer_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
uniform_buffer_allocator: Arc<Mutex<SubbufferAllocator>>,
|
||||
block_enable_allocator: Arc<Mutex<SubbufferAllocator>>,
|
||||
host_visible_allocator: Arc<Mutex<SubbufferAllocator>>,
|
||||
@@ -318,52 +319,76 @@ impl App {
|
||||
..DeviceFeatures::empty()
|
||||
};
|
||||
|
||||
let (physical_device, (graphics_queue_index, transfer_queue_index)) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.api_version() >= Version::V1_3)
|
||||
.filter(|p| {
|
||||
p.supported_extensions().contains(&device_extensions)
|
||||
&& p.supported_features().contains(&device_features)
|
||||
})
|
||||
.filter_map(|p| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags
|
||||
.contains(QueueFlags::GRAPHICS | QueueFlags::COMPUTE)
|
||||
&& p.presentation_support(i as u32, event_loop)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.and_then(|graphics| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.contains(QueueFlags::TRANSFER) && i != graphics
|
||||
})
|
||||
.or_else(|| {
|
||||
p.queue_family_properties().iter().enumerate().position(
|
||||
|(_i, q)| q.queue_flags.contains(QueueFlags::TRANSFER),
|
||||
)
|
||||
})
|
||||
.map(|i| (graphics as u32, i as u32))
|
||||
})
|
||||
.map(|i| (p, i))
|
||||
})
|
||||
.min_by_key(|(p, _)| {
|
||||
// We assign a lower score to device types that are likely to be faster/better.
|
||||
match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
PhysicalDeviceType::IntegratedGpu => 1,
|
||||
PhysicalDeviceType::VirtualGpu => 2,
|
||||
PhysicalDeviceType::Cpu => 3,
|
||||
PhysicalDeviceType::Other => 4,
|
||||
_ => 5,
|
||||
}
|
||||
})
|
||||
.expect("No suitable physical device found.");
|
||||
let (physical_device, (graphics_queue_index, transfer_queue_index, compute_queue_index)) =
|
||||
instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.api_version() >= Version::V1_3)
|
||||
.filter(|p| {
|
||||
p.supported_extensions().contains(&device_extensions)
|
||||
&& p.supported_features().contains(&device_features)
|
||||
})
|
||||
.filter_map(|p| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.contains(QueueFlags::GRAPHICS)
|
||||
&& p.presentation_support(i as u32, event_loop)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.and_then(|graphics| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.contains(QueueFlags::TRANSFER) && i != graphics
|
||||
})
|
||||
.or_else(|| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.contains(QueueFlags::TRANSFER))
|
||||
})
|
||||
.map(|i| (graphics, i))
|
||||
})
|
||||
.and_then(|(graphics, transfer)| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.contains(QueueFlags::COMPUTE)
|
||||
&& i != graphics
|
||||
&& i != transfer
|
||||
})
|
||||
.or_else(|| {
|
||||
p.queue_family_properties().iter().enumerate().position(
|
||||
|(i, q)| {
|
||||
q.queue_flags.contains(QueueFlags::COMPUTE)
|
||||
&& i != graphics
|
||||
},
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.contains(QueueFlags::COMPUTE))
|
||||
})
|
||||
.map(|i| (graphics as u32, transfer as u32, i as u32))
|
||||
})
|
||||
.map(|i| (p, i))
|
||||
})
|
||||
.min_by_key(|(p, _)| {
|
||||
// We assign a lower score to device types that are likely to be faster/better.
|
||||
match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
PhysicalDeviceType::IntegratedGpu => 1,
|
||||
PhysicalDeviceType::VirtualGpu => 2,
|
||||
PhysicalDeviceType::Cpu => 3,
|
||||
PhysicalDeviceType::Other => 4,
|
||||
_ => 5,
|
||||
}
|
||||
})
|
||||
.expect("No suitable physical device found.");
|
||||
|
||||
// Some little debug infos.
|
||||
info!(
|
||||
@@ -372,6 +397,10 @@ impl App {
|
||||
physical_device.properties().device_type,
|
||||
);
|
||||
|
||||
info!("Graphics queue index: {}", graphics_queue_index);
|
||||
info!("Transfer queue index: {}", transfer_queue_index);
|
||||
info!("Compute queue index: {}", compute_queue_index);
|
||||
|
||||
const DEPTH_FORMAT_ORDERING: [Format; 4] = [
|
||||
Format::D24_UNORM_S8_UINT,
|
||||
Format::X8_D24_UNORM_PACK32,
|
||||
@@ -406,28 +435,65 @@ impl App {
|
||||
|
||||
info!("Using depth format {:?}", depth_format);
|
||||
|
||||
let (device, mut queues) = Device::new(
|
||||
let mut queue_create_infos = vec![];
|
||||
if !queue_create_infos
|
||||
.iter()
|
||||
.any(|info: &QueueCreateInfo| info.queue_family_index == graphics_queue_index)
|
||||
{
|
||||
queue_create_infos.push(QueueCreateInfo {
|
||||
queue_family_index: graphics_queue_index,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
if !queue_create_infos
|
||||
.iter()
|
||||
.any(|info: &QueueCreateInfo| info.queue_family_index == transfer_queue_index)
|
||||
{
|
||||
queue_create_infos.push(QueueCreateInfo {
|
||||
queue_family_index: transfer_queue_index,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
if !queue_create_infos
|
||||
.iter()
|
||||
.any(|info: &QueueCreateInfo| info.queue_family_index == compute_queue_index)
|
||||
{
|
||||
queue_create_infos.push(QueueCreateInfo {
|
||||
queue_family_index: compute_queue_index,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
let (device, queues) = Device::new(
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![
|
||||
QueueCreateInfo {
|
||||
queue_family_index: graphics_queue_index,
|
||||
..Default::default()
|
||||
},
|
||||
QueueCreateInfo {
|
||||
queue_family_index: transfer_queue_index,
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
queue_create_infos: queue_create_infos.clone(),
|
||||
enabled_features: device_features,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.expect("Unable to initialize device");
|
||||
|
||||
let graphics_queue = queues.next().expect("Unable to retrieve queues");
|
||||
let transfer_queue = queues.next().expect("Unable to retrieve queues");
|
||||
let queues = queues.collect::<Vec<_>>();
|
||||
|
||||
let graphics_queue = queues[queue_create_infos
|
||||
.iter()
|
||||
.position(|info: &QueueCreateInfo| info.queue_family_index == graphics_queue_index)
|
||||
.unwrap()]
|
||||
.clone();
|
||||
let transfer_queue = queues[queue_create_infos
|
||||
.iter()
|
||||
.position(|info: &QueueCreateInfo| info.queue_family_index == transfer_queue_index)
|
||||
.unwrap()]
|
||||
.clone();
|
||||
let compute_queue = queues[queue_create_infos
|
||||
.iter()
|
||||
.position(|info: &QueueCreateInfo| info.queue_family_index == compute_queue_index)
|
||||
.unwrap()]
|
||||
.clone();
|
||||
|
||||
drop(queues);
|
||||
|
||||
let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone()));
|
||||
let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new(
|
||||
@@ -479,7 +545,8 @@ impl App {
|
||||
&memory_allocator,
|
||||
&mut Cursor::new(PLATONIC_SOLIDS[0].1),
|
||||
PLATONIC_SOLIDS[0].0.to_string(),
|
||||
BufferUsage::empty(),
|
||||
BufferUsage::SHADER_DEVICE_ADDRESS
|
||||
| BufferUsage::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
@@ -587,6 +654,7 @@ impl App {
|
||||
depth_format,
|
||||
graphics_queue,
|
||||
transfer_queue,
|
||||
compute_queue,
|
||||
memory_allocator,
|
||||
descriptor_set_allocator,
|
||||
command_buffer_allocator,
|
||||
@@ -923,9 +991,10 @@ impl ApplicationHandler for App {
|
||||
|
||||
let scene = Scene::new(
|
||||
&self.device,
|
||||
&self.graphics_queue,
|
||||
&self.compute_queue,
|
||||
&self.memory_allocator,
|
||||
&self.command_buffer_allocator,
|
||||
&self.gstate.meshes,
|
||||
);
|
||||
|
||||
let (
|
||||
@@ -1160,11 +1229,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_camera_uniform(
|
||||
&self,
|
||||
rcx: &mut RenderContext,
|
||||
index: usize,
|
||||
) -> CommandBufferExecFuture<NowFuture> {
|
||||
fn update_camera_uniform(&self, rcx: &mut RenderContext, index: usize) -> Box<dyn GpuFuture> {
|
||||
let near = 0.01;
|
||||
|
||||
let aspect_ratio =
|
||||
@@ -1211,11 +1276,7 @@ impl App {
|
||||
)
|
||||
}
|
||||
|
||||
fn update_lights_uniform(
|
||||
&self,
|
||||
rcx: &mut RenderContext,
|
||||
index: usize,
|
||||
) -> CommandBufferExecFuture<NowFuture> {
|
||||
fn update_lights_uniform(&self, rcx: &mut RenderContext, index: usize) -> Box<dyn GpuFuture> {
|
||||
let mut pos = [[0f32; 4]; 32];
|
||||
let mut col = [[0f32; 4]; 32];
|
||||
|
||||
@@ -1784,6 +1845,14 @@ impl App {
|
||||
self.gstate.new_csgs_needed -= 1;
|
||||
}
|
||||
|
||||
rcx.scene = Scene::new(
|
||||
&self.device,
|
||||
&self.compute_queue,
|
||||
&self.memory_allocator,
|
||||
&self.command_buffer_allocator,
|
||||
&self.gstate.meshes,
|
||||
);
|
||||
|
||||
rcx.recreate_pipelines |= self.gstate.recreate_pipelines;
|
||||
|
||||
let mut push_constants = vec![
|
||||
@@ -2119,7 +2188,7 @@ impl App {
|
||||
fn framebuffer_generation(
|
||||
images: &[Arc<Image>],
|
||||
render_pass: &Arc<RenderPass>,
|
||||
allocator: &Arc<StandardMemoryAllocator>,
|
||||
allocator: &Arc<dyn MemoryAllocator>,
|
||||
depth_format: Format,
|
||||
) -> (
|
||||
Vec<(Arc<ImageView>, Arc<Framebuffer>)>,
|
||||
@@ -2324,7 +2393,7 @@ fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConst
|
||||
}
|
||||
|
||||
fn pipeline_recompile(
|
||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||
memory_allocator: &Arc<dyn MemoryAllocator>,
|
||||
render_pass: &Arc<RenderPass>,
|
||||
cache: &Arc<PipelineCache>,
|
||||
shader_modules: &ShaderModules,
|
||||
@@ -2477,9 +2546,9 @@ fn gpu_upload<T>(
|
||||
input: T,
|
||||
device_local: Subbuffer<T>,
|
||||
host_visible: Subbuffer<T>,
|
||||
command_allocator: Arc<StandardCommandBufferAllocator>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> CommandBufferExecFuture<NowFuture>
|
||||
) -> Box<dyn GpuFuture + Send + Sync>
|
||||
where
|
||||
T: BufferContents,
|
||||
{
|
||||
@@ -2500,9 +2569,9 @@ fn gpu_upload_slice<T>(
|
||||
input: &[T],
|
||||
device_local: Subbuffer<[T]>,
|
||||
host_visible: Subbuffer<[T]>,
|
||||
command_allocator: Arc<StandardCommandBufferAllocator>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> CommandBufferExecFuture<NowFuture>
|
||||
) -> Box<dyn GpuFuture + Send + Sync>
|
||||
where
|
||||
T: BufferContents + Copy,
|
||||
{
|
||||
@@ -2522,9 +2591,9 @@ where
|
||||
fn gpu_upload_command_buffer<T>(
|
||||
device_local: Subbuffer<T>,
|
||||
host_visible: Subbuffer<T>,
|
||||
command_allocator: Arc<StandardCommandBufferAllocator>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> CommandBufferExecFuture<NowFuture>
|
||||
) -> Box<dyn GpuFuture + Send + Sync>
|
||||
where
|
||||
T: BufferContents + ?Sized,
|
||||
{
|
||||
@@ -2540,7 +2609,7 @@ where
|
||||
.unwrap();
|
||||
let commands = builder.build().unwrap();
|
||||
|
||||
commands.execute(transfer_queue).unwrap()
|
||||
commands.execute(transfer_queue).unwrap().boxed_send_sync()
|
||||
}
|
||||
|
||||
fn dump_pipeline_cache(cache: Arc<PipelineCache>) {
|
||||
|
||||
@@ -18,12 +18,13 @@ use crate::{ssa::SSATape, trace_vs::Object};
|
||||
pub(crate) const PLATONIC_SOLIDS: [(&str, &[u8]); 1] = [("Buny", include_bytes!("data/bunny.obj"))];
|
||||
|
||||
#[repr(C)]
|
||||
#[repr(align(16))]
|
||||
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod, Vertex)]
|
||||
pub(crate) struct OVertex {
|
||||
#[format(R32G32B32_SFLOAT)]
|
||||
position: [f32; 3],
|
||||
#[format(R32G32B32_SFLOAT)]
|
||||
normal: [f32; 3],
|
||||
#[format(R32G32B32A32_SFLOAT)]
|
||||
position: [f32; 4],
|
||||
#[format(R32G32B32A32_SFLOAT)]
|
||||
normal: [f32; 4],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -86,10 +87,13 @@ pub(crate) fn load_obj(
|
||||
//trace!("{:?}", exist);
|
||||
indices.push(exist);
|
||||
} else {
|
||||
vertices.push(OVertex {
|
||||
position: object.position[mapping.0 as usize],
|
||||
normal: object.normal[mapping.1 as usize],
|
||||
});
|
||||
let mut vertex = OVertex {
|
||||
position: [0.; 4],
|
||||
normal: [0.; 4],
|
||||
};
|
||||
vertex.position[0..3].copy_from_slice(&object.position[mapping.0 as usize]);
|
||||
vertex.normal[0..3].copy_from_slice(&object.normal[mapping.1 as usize]);
|
||||
vertices.push(vertex);
|
||||
temp_hash_map.insert(mapping, (vertices.len() - 1) as u32);
|
||||
indices.push((vertices.len() - 1) as u32);
|
||||
}
|
||||
|
||||
+78
-74
@@ -1,4 +1,4 @@
|
||||
use std::{io::Cursor, iter, mem::size_of, sync::Arc};
|
||||
use std::{iter, mem::size_of, sync::Arc};
|
||||
|
||||
use vulkano::{
|
||||
Packed24_8,
|
||||
@@ -13,44 +13,39 @@ use vulkano::{
|
||||
},
|
||||
buffer::{Buffer, BufferCreateInfo, BufferUsage, IndexBuffer, Subbuffer},
|
||||
command_buffer::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract,
|
||||
allocator::{CommandBufferAllocator, StandardCommandBufferAllocator},
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer,
|
||||
PrimaryCommandBufferAbstract, allocator::CommandBufferAllocator,
|
||||
},
|
||||
device::{Device, Queue},
|
||||
format::Format,
|
||||
memory::allocator::{
|
||||
AllocationCreateInfo, DeviceLayout, MemoryAllocator, MemoryTypeFilter,
|
||||
StandardMemoryAllocator,
|
||||
},
|
||||
memory::allocator::{AllocationCreateInfo, DeviceLayout, MemoryAllocator, MemoryTypeFilter},
|
||||
sync::GpuFuture,
|
||||
};
|
||||
|
||||
use crate::objects::{Mesh, OVertex, PLATONIC_SOLIDS, load_obj};
|
||||
use crate::objects::{Mesh, OVertex};
|
||||
|
||||
pub struct Scene {
|
||||
// The bottom-level acceleration structure is required to be kept alive
|
||||
// as we reference it in the top-level acceleration structure.
|
||||
pub _blas: Arc<AccelerationStructure>,
|
||||
pub tlas: Arc<AccelerationStructure>,
|
||||
pub _blases: Vec<Arc<AccelerationStructure>>,
|
||||
pub tlas: Arc<AccelerationStructure>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn new(
|
||||
device: &Arc<Device>,
|
||||
graphics_queue: &Arc<Queue>,
|
||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||
command_buffer_allocator: &Arc<StandardCommandBufferAllocator>,
|
||||
compute_queue: &Arc<Queue>,
|
||||
memory_allocator: &Arc<dyn MemoryAllocator>,
|
||||
command_buffer_allocator: &Arc<dyn CommandBufferAllocator>,
|
||||
meshes: &Vec<Mesh>,
|
||||
) -> Self {
|
||||
let mesh = load_obj(
|
||||
&memory_allocator,
|
||||
&mut Cursor::new(PLATONIC_SOLIDS[0].1),
|
||||
PLATONIC_SOLIDS[0].0.to_string(),
|
||||
BufferUsage::SHADER_DEVICE_ADDRESS
|
||||
| BufferUsage::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY,
|
||||
// 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()
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
// Build the bottom-level acceleration structure and then the top-level
|
||||
@@ -60,35 +55,68 @@ impl Scene {
|
||||
// contains the instances of the bottom-level acceleration structures. In our
|
||||
// shader, we will trace rays against the top-level acceleration
|
||||
// structure.
|
||||
let blas = unsafe {
|
||||
build_acceleration_structure_triangles(
|
||||
&mesh,
|
||||
memory_allocator.clone(),
|
||||
command_buffer_allocator.clone(),
|
||||
device.clone(),
|
||||
graphics_queue.clone(),
|
||||
)
|
||||
};
|
||||
let blases: Vec<Arc<AccelerationStructure>> = meshes
|
||||
.iter()
|
||||
.map(|mesh| unsafe {
|
||||
build_acceleration_structure_triangles(
|
||||
mesh,
|
||||
memory_allocator.clone(),
|
||||
device.clone(),
|
||||
&mut builder,
|
||||
)
|
||||
})
|
||||
.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 {
|
||||
build_top_level_acceleration_structure(
|
||||
vec![AccelerationStructureInstance {
|
||||
instance_shader_binding_table_record_offset_and_flags: Packed24_8::new(
|
||||
0,
|
||||
(GeometryInstanceFlags::TRIANGLE_FACING_CULL_DISABLE
|
||||
| GeometryInstanceFlags::FORCE_OPAQUE)
|
||||
.into(),
|
||||
),
|
||||
acceleration_structure_reference: blas.device_address().into(),
|
||||
..Default::default()
|
||||
}],
|
||||
blases
|
||||
.iter()
|
||||
.map(|blas| AccelerationStructureInstance {
|
||||
instance_shader_binding_table_record_offset_and_flags: Packed24_8::new(
|
||||
0,
|
||||
(GeometryInstanceFlags::FORCE_OPAQUE).into(),
|
||||
),
|
||||
acceleration_structure_reference: blas.device_address().into(),
|
||||
..Default::default()
|
||||
})
|
||||
.collect(),
|
||||
memory_allocator.clone(),
|
||||
command_buffer_allocator.clone(),
|
||||
device.clone(),
|
||||
graphics_queue.clone(),
|
||||
&mut builder,
|
||||
)
|
||||
};
|
||||
|
||||
Scene { _blas: blas, tlas }
|
||||
builder
|
||||
.build()
|
||||
.unwrap()
|
||||
.execute_after(blas_fence, compute_queue.clone())
|
||||
.unwrap()
|
||||
.then_signal_fence_and_flush()
|
||||
.unwrap()
|
||||
.wait(None)
|
||||
.unwrap();
|
||||
|
||||
Scene {
|
||||
_blases: blases,
|
||||
tlas,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,9 +133,8 @@ unsafe fn build_acceleration_structure_common(
|
||||
primitive_count: u32,
|
||||
ty: AccelerationStructureType,
|
||||
memory_allocator: Arc<dyn MemoryAllocator>,
|
||||
command_buffer_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<Queue>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
) -> Arc<AccelerationStructure> {
|
||||
let min_acceleration_structure_scratch_offset_alignment = device
|
||||
.physical_device()
|
||||
@@ -176,15 +203,6 @@ unsafe fn build_acceleration_structure_common(
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// 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,
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
unsafe {
|
||||
builder
|
||||
.build_acceleration_structure(
|
||||
@@ -194,25 +212,14 @@ unsafe fn build_acceleration_structure_common(
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
builder
|
||||
.build()
|
||||
.unwrap()
|
||||
.execute(queue)
|
||||
.unwrap()
|
||||
.then_signal_fence_and_flush()
|
||||
.unwrap()
|
||||
.wait(None)
|
||||
.unwrap();
|
||||
|
||||
acceleration
|
||||
}
|
||||
|
||||
unsafe fn build_acceleration_structure_triangles(
|
||||
mesh: &Mesh,
|
||||
memory_allocator: Arc<dyn MemoryAllocator>,
|
||||
command_buffer_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<Queue>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
) -> Arc<AccelerationStructure> {
|
||||
let primitive_count = (mesh.indices.len() / 3) as u32;
|
||||
let as_geometry_triangles_data = AccelerationStructureGeometryTrianglesData {
|
||||
@@ -220,7 +227,7 @@ unsafe fn build_acceleration_structure_triangles(
|
||||
vertex_data: Some(mesh.vertices.clone().into_bytes()),
|
||||
vertex_stride: size_of::<OVertex>() as _,
|
||||
index_data: Some(IndexBuffer::U32(mesh.indices.clone())),
|
||||
..AccelerationStructureGeometryTrianglesData::new(Format::R32G32B32_SFLOAT)
|
||||
..AccelerationStructureGeometryTrianglesData::new(Format::R32G32B32A32_SFLOAT)
|
||||
};
|
||||
|
||||
let geometries = AccelerationStructureGeometries::Triangles(vec![as_geometry_triangles_data]);
|
||||
@@ -231,9 +238,8 @@ unsafe fn build_acceleration_structure_triangles(
|
||||
primitive_count,
|
||||
AccelerationStructureType::BottomLevel,
|
||||
memory_allocator,
|
||||
command_buffer_allocator,
|
||||
device,
|
||||
queue,
|
||||
builder,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -241,9 +247,8 @@ unsafe fn build_acceleration_structure_triangles(
|
||||
unsafe fn build_top_level_acceleration_structure(
|
||||
as_instances: Vec<AccelerationStructureInstance>,
|
||||
allocator: Arc<dyn MemoryAllocator>,
|
||||
command_buffer_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<Queue>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
) -> Arc<AccelerationStructure> {
|
||||
let primitive_count = as_instances.len() as u32;
|
||||
|
||||
@@ -275,9 +280,8 @@ unsafe fn build_top_level_acceleration_structure(
|
||||
primitive_count,
|
||||
AccelerationStructureType::TopLevel,
|
||||
allocator,
|
||||
command_buffer_allocator,
|
||||
device,
|
||||
queue,
|
||||
builder,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,41 @@
|
||||
#include "include.glsl"
|
||||
|
||||
layout(location = 0) rayPayloadInEXT vec3 hit_value;
|
||||
hitAttributeEXT vec2 attribs;
|
||||
hitAttributeEXT vec2 baryCoord;
|
||||
|
||||
struct OVertex {
|
||||
vec4 pos;
|
||||
vec4 normal;
|
||||
};
|
||||
|
||||
layout(set = 3, binding = 0, std140) restrict readonly buffer Verts {
|
||||
OVertex verts[];
|
||||
} verts;
|
||||
|
||||
layout(set = 3, binding = 1, std140) restrict readonly buffer Indicies {
|
||||
uint indicies[];
|
||||
} indicies;
|
||||
|
||||
void main() {
|
||||
vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||
hit_value = barycentrics;
|
||||
// get mesh vertex data in object space
|
||||
vec3 p0, p1, p2;
|
||||
//gsnGetPositions(gl_InstanceID, gl_PrimitiveID, p0, p1, p2);
|
||||
vec3 n0, n1, n2;
|
||||
//gsnGetNormals(gl_InstanceID, gl_PrimitiveID, n0, n1, n2);
|
||||
vec2 t0, t1, t2;
|
||||
//gsnGetTexCoords(gl_InstanceID, gl_PrimitiveID, t0, t1, t2);
|
||||
|
||||
// interpolate with barycentric coordinates
|
||||
vec3 barys = vec3(1.0f - baryCoord.x - baryCoord.y, baryCoord.x, baryCoord.y);
|
||||
vec3 localNormal = normalize(n0 * barys.x + n1 * barys.y + n2 * barys.z);
|
||||
vec3 localPosition = p0 * barys.x + p1 * barys.y + p2 * barys.z;
|
||||
vec2 texCoords = t0 * barys.x + t1 * barys.y + t2 * barys.z;
|
||||
|
||||
// transform to world space
|
||||
mat3 normalMat;
|
||||
//gsnGetNormal3x3Matrix(gl_InstanceID, normalMat);
|
||||
vec3 normal = normalize(normalMat * localNormal);
|
||||
vec3 position = gl_ObjectToWorldEXT * vec4(localPosition, 1.0);
|
||||
|
||||
hit_value = normal;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@ use rspirv::{binary::Assemble, dr::Module};
|
||||
use tape_load::interpreters;
|
||||
use vulkano::{
|
||||
buffer::{Subbuffer, allocator::SubbufferAllocator},
|
||||
command_buffer::{CommandBufferExecFuture, allocator::StandardCommandBufferAllocator},
|
||||
descriptor_set::{
|
||||
DescriptorSet, WriteDescriptorSet, allocator::StandardDescriptorSetAllocator,
|
||||
},
|
||||
command_buffer::allocator::CommandBufferAllocator,
|
||||
descriptor_set::{DescriptorSet, WriteDescriptorSet, allocator::DescriptorSetAllocator},
|
||||
device::{Device, Queue},
|
||||
pipeline::{
|
||||
DynamicState, GraphicsPipeline, Pipeline, PipelineCreateFlags, PipelineLayout,
|
||||
@@ -36,7 +34,7 @@ use vulkano::{
|
||||
},
|
||||
render_pass::{RenderPass, Subpass},
|
||||
shader::{ShaderModule, ShaderModuleCreateInfo},
|
||||
sync::future::NowFuture,
|
||||
sync::GpuFuture,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -62,7 +60,7 @@ pub enum WorkItem {
|
||||
PreviousDebug,
|
||||
Arc<Mutex<SubbufferAllocator>>,
|
||||
Arc<Mutex<SubbufferAllocator>>,
|
||||
Arc<StandardDescriptorSetAllocator>,
|
||||
Arc<dyn DescriptorSetAllocator>,
|
||||
u32,
|
||||
u32,
|
||||
u64,
|
||||
@@ -72,7 +70,7 @@ pub enum WorkItem {
|
||||
Arc<RwLock<CSG>>,
|
||||
f32,
|
||||
usize,
|
||||
Arc<StandardCommandBufferAllocator>,
|
||||
Arc<dyn CommandBufferAllocator>,
|
||||
Arc<Queue>,
|
||||
usize,
|
||||
),
|
||||
@@ -91,7 +89,7 @@ pub enum WorkItem {
|
||||
|
||||
pub enum WorkComplete {
|
||||
CreateCSG(Arc<RwLock<CSG>>, isize),
|
||||
GetPushConstants(PushConstantData, CommandBufferExecFuture<NowFuture>, usize),
|
||||
GetPushConstants(PushConstantData, Box<dyn GpuFuture + Send + Sync>, usize),
|
||||
RecompilePipelines(usize),
|
||||
}
|
||||
|
||||
@@ -518,9 +516,9 @@ fn interval_check(
|
||||
material: u32,
|
||||
time: f32,
|
||||
frame_index: usize,
|
||||
command_allocator: Arc<StandardCommandBufferAllocator>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> CommandBufferExecFuture<NowFuture> {
|
||||
) -> Box<dyn GpuFuture + Send + Sync> {
|
||||
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]);
|
||||
const INTERPRET_INPUT_Y: interpreters::Value =
|
||||
|
||||
Reference in New Issue
Block a user