Add command line args

This commit is contained in:
2026-03-01 18:41:52 +00:00
parent 0e6f188de7
commit f8fcb6609a
5 changed files with 376 additions and 220 deletions
Generated
+300 -176
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tape-drive"
version = "0.3.0"
version = "0.3.1"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -41,3 +41,4 @@ num_cpus = "1"
notify = "8.2"
tape-load = { version = "*", path = "../tape-load" }
clap = { version = "4", features = ["derive"] }
+63 -38
View File
@@ -2,15 +2,12 @@
#![feature(mpmc_channel)]
#![feature(duration_millis_float)]
const DUMP_SPV_TO_FILE: bool = false;
const PIPELINE_CACHING: bool = false;
const VSYNC: bool = true;
const COMPUTE_FUZZING: bool = false;
const ROBUST: bool = false;
const DUMP_AABBS: bool = false;
const CRASH_DIAGNOSTIC_LAYER: bool = true;
const DEFAULT_SUBDIVISION: u32 = 16;
const MAXIMUM_SUBDIVISION: u32 = 64;
const MINUMUM_SUBDIVISION: u32 = 8;
@@ -27,7 +24,7 @@ use std::{
path::{Path, PathBuf},
simd::{f32x8, num::SimdFloat},
sync::{
Arc, Mutex, RwLock,
Arc, LazyLock, Mutex, RwLock,
atomic::{AtomicBool, AtomicU64},
mpmc, mpsc,
},
@@ -94,8 +91,6 @@ use vulkano::{
self, AccessConflict, GpuFuture, HostAccessError, PipelineStage, future::FenceSignalFuture,
},
};
#[cfg(target_os = "linux")]
use winit::platform::x11::EventLoopBuilderExtX11;
use winit::{
application::ApplicationHandler,
event::{DeviceEvent, ElementState, MouseButton, WindowEvent},
@@ -118,6 +113,29 @@ mod objects;
mod scene;
mod threads;
use clap::Parser;
#[derive(Parser, Debug)]
#[command(
version,
about = "Tape Drive: Rendering implicit surfaces if you hate yourself.",
long_about = "Tape Drive: Rendering implicit surfaces if you hate yourself.\nHold right click \
or shift to start moving the camera, and then use the mouse and WASD to \
navigate."
)]
pub struct Args {
/// Enable the Vulkan Crash Diagnostic layer. Requires that you have it
/// installed.
#[arg(long)]
cdl: bool,
/// Dumps all generated Spir-V shaders.
#[arg(long)]
spv: bool,
}
pub static ARGS: LazyLock<Args> = LazyLock::new(|| Args::parse());
fn main() -> Result<(), impl Error> {
CombinedLogger::init(vec![
TermLogger::new(
@@ -134,9 +152,9 @@ fn main() -> Result<(), impl Error> {
])
.unwrap();
#[cfg(target_os = "linux")]
let event_loop = EventLoop::builder().with_x11().build().unwrap();
#[cfg(target_os = "windows")]
// force args to be handled
let _ = ARGS.cdl;
let event_loop = EventLoop::builder().build().unwrap();
let mut app = App::new(&event_loop);
@@ -219,7 +237,7 @@ struct RenderContext {
shader_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
rt_pipeline: Arc<RayTracingPipeline>,
rt_shader_binding_table: ShaderBindingTable,
scene: Scene,
scene: Vec<Scene>,
viewport: Viewport,
recreate_swapchain: bool,
recreate_pipelines: bool,
@@ -290,7 +308,7 @@ impl App {
ext_debug_utils: true,
..required_extensions
},
enabled_layers: if CRASH_DIAGNOSTIC_LAYER {
enabled_layers: if ARGS.cdl {
vec![
"VK_LAYER_KHRONOS_validation".into(),
"VK_LAYER_LUNARG_crash_diagnostic".into(),
@@ -497,7 +515,7 @@ impl App {
});
}
if CRASH_DIAGNOSTIC_LAYER {
if ARGS.cdl {
device_extensions.ext_device_fault = true;
device_extensions.ext_device_address_binding_report = true;
device_features.device_fault = true;
@@ -958,18 +976,22 @@ impl ApplicationHandler for App {
)
.unwrap();
let scene = Scene::new(
&self.device,
&mut builder,
&self.memory_allocator,
&self.gstate.meshes,
&self.gstate.csg,
&self.vertex_buffer,
&self.index_buffer,
&self.transform_buffer,
&self.object_buffer,
0,
);
let scene = (0..swapchain.image_count())
.map(|i| {
Scene::new(
&self.device,
&mut builder,
&self.memory_allocator,
&self.gstate.meshes,
&self.gstate.csg,
&self.vertex_buffer,
&self.index_buffer,
&self.transform_buffer,
&self.object_buffer,
i as _,
)
})
.collect();
builder
.build()
@@ -1259,16 +1281,11 @@ impl App {
gpu_upload(uniform_data, rcx.lights_buffers[index].clone())
}
fn get_descriptor_sets(
fn get_rt_descriptor_sets(
&self,
rcx: &mut RenderContext,
index: usize,
) -> (
Arc<DescriptorSet>,
Arc<DescriptorSet>,
Arc<DescriptorSet>,
Option<Arc<DescriptorSet>>,
) {
) -> (Arc<DescriptorSet>, Arc<DescriptorSet>, Arc<DescriptorSet>) {
let rt_layout1 = &rcx.rt_pipeline.layout().set_layouts()[0];
let rt_set1 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
@@ -1291,7 +1308,7 @@ impl App {
rt_layout2.clone(),
[WriteDescriptorSet::acceleration_structure(
0,
rcx.scene.tlas.clone(),
rcx.scene[index].tlas.as_ref().unwrap().clone(),
)],
[],
)
@@ -1309,6 +1326,14 @@ impl App {
)
.unwrap();
(rt_set1, rt_set2, rt_set3)
}
fn get_enable_gen_descriptor_sets(
&self,
rcx: &mut RenderContext,
index: usize,
) -> Option<Arc<DescriptorSet>> {
let enable_gen_set1 = if self.csg_count > 0 {
let enable_gen_layout = &self.gstate.csg[0]
.read()
@@ -1331,8 +1356,7 @@ impl App {
} else {
None
};
(rt_set1, rt_set2, rt_set3, enable_gen_set1)
enable_gen_set1
}
fn add_commands_enable_gen(
@@ -1911,9 +1935,6 @@ impl App {
self.update_camera_uniform(rcx, image_index);
self.update_lights_uniform(rcx, image_index);
let (rt_set1, rt_set2, rt_set3, enable_gen_set1) =
self.get_descriptor_sets(rcx, image_index);
let mut builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.clone(),
self.graphics_queue.queue_family_index(),
@@ -1945,11 +1966,13 @@ impl App {
}
}
let enable_gen_set1 = self.get_enable_gen_descriptor_sets(rcx, image_index);
if !self.gstate.csg.is_empty() {
self.add_commands_enable_gen(&mut builder, enable_gen_set1.unwrap(), image_index);
}
rcx.scene = Scene::new(
rcx.scene[image_index] = Scene::new(
&self.device,
&mut builder,
&self.memory_allocator,
@@ -1962,6 +1985,8 @@ impl App {
image_index,
);
let (rt_set1, rt_set2, rt_set3) = self.get_rt_descriptor_sets(rcx, image_index);
self.add_commands_raytrace(&mut builder, rcx, rt_set1, rt_set2, rt_set3);
unsafe {
+9 -3
View File
@@ -34,7 +34,13 @@ pub struct Scene {
// as we reference it in the top-level acceleration structure.
pub _mesh_blases: Vec<Arc<AccelerationStructure>>,
pub _csg_blases: Vec<Arc<AccelerationStructure>>,
pub tlas: Arc<AccelerationStructure>,
pub tlas: Option<Arc<AccelerationStructure>>,
}
impl Drop for Scene {
fn drop(&mut self) {
self.tlas = None; // The top level structure must be dropped first.
}
}
impl Scene {
@@ -127,8 +133,8 @@ impl Scene {
Scene {
_mesh_blases: mesh_blases,
_csg_blases: csg_blases,
tlas,
_csg_blases: csg_blases,
tlas: Some(tlas),
}
}
}
+2 -2
View File
@@ -29,7 +29,7 @@ use vulkano::{
};
use crate::{
DUMP_SPV_TO_FILE, MAX_TRANSFORM_BUFFER, MAXIMUM_SUBDIVISION, get_spec_constants,
ARGS, MAX_TRANSFORM_BUFFER, MAXIMUM_SUBDIVISION, get_spec_constants,
gui::PreviousDebug,
interpreters::point::PointInterpreter,
objects::{CSG, Position},
@@ -495,7 +495,7 @@ fn sdf_specialize_module(
.flat_map(u32::to_le_bytes)
.collect::<Vec<_>>();
if DUMP_SPV_TO_FILE {
if ARGS.spv {
File::create(format!("{name}.out.spv"))
.unwrap()
.write_all(&module_as_bytes)