redo how acceleration structures build

This commit is contained in:
2025-12-23 22:24:37 +00:00
parent f3768db3e6
commit 55152e7767
6 changed files with 300 additions and 190 deletions
+5 -2
View File
@@ -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
View File
@@ -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>) {
+12 -8
View File
@@ -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
View File
@@ -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,
)
}
}
+35 -3
View File
@@ -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;
}
+8 -10
View File
@@ -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 =