Multiple CSG

This commit is contained in:
2025-07-01 21:31:58 +01:00
parent 8d111786c1
commit 349813c608
2 changed files with 378 additions and 357 deletions
+14 -1
View File
@@ -1,8 +1,12 @@
use egui::{Color32, Frame, Id}; use egui::{Color32, Frame, Id};
use egui_plot::{Line, Plot, PlotPoints}; use egui_plot::{Line, Plot, PlotPoints};
use egui_winit_vulkano::Gui; use egui_winit_vulkano::Gui;
use glam::Vec3;
use crate::objects::{CSG, Light, Mesh}; use crate::{
create_csg,
objects::{CSG, Light, Mesh},
};
fn sized_text(ui: &mut egui::Ui, text: impl Into<String>, size: f32) { fn sized_text(ui: &mut egui::Ui, text: impl Into<String>, size: f32) {
ui.label(egui::RichText::new(text).size(size)); ui.label(egui::RichText::new(text).size(size));
@@ -148,6 +152,15 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
{ {
state.csg.remove(i); state.csg.remove(i);
} }
if state.csg.len() < 32 && ui.small_button("add csg").clicked() {
state.csg.push(CSG {
name: "generated".to_string(),
parts: create_csg(),
pos: Vec3::ZERO,
rot: Vec3::ZERO,
scale: Vec3::ONE,
});
}
ui.heading("Lights"); ui.heading("Lights");
let mut lightdel = vec![]; let mut lightdel = vec![];
for light in &mut state.lights { for light in &mut state.lights {
+364 -356
View File
@@ -81,7 +81,7 @@ use winit::{
event::{DeviceEvent, ElementState, MouseButton, WindowEvent}, event::{DeviceEvent, ElementState, MouseButton, WindowEvent},
event_loop::{ActiveEventLoop, EventLoop}, event_loop::{ActiveEventLoop, EventLoop},
keyboard::{KeyCode, PhysicalKey}, keyboard::{KeyCode, PhysicalKey},
platform::{wayland::EventLoopBuilderExtWayland, x11::EventLoopBuilderExtX11}, platform::x11::EventLoopBuilderExtX11,
window::Window, window::Window,
}; };
@@ -188,6 +188,7 @@ struct App {
uniform_buffer_allocator: SubbufferAllocator, uniform_buffer_allocator: SubbufferAllocator,
pipeline_cache: Arc<PipelineCache>, pipeline_cache: Arc<PipelineCache>,
gstate: GState, gstate: GState,
csg_count: usize,
previous_debug: PreviousDebug, previous_debug: PreviousDebug,
cstate: CState, cstate: CState,
vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]>, vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]>,
@@ -198,32 +199,33 @@ struct App {
struct ShaderModules { struct ShaderModules {
implicit_vs: Arc<ShaderModule>, implicit_vs: Arc<ShaderModule>,
implicit_fs: Arc<ShaderModule>, implicit_fs: Vec<Arc<ShaderModule>>,
fullscreen_vs: Arc<ShaderModule>, fullscreen_vs: Arc<ShaderModule>,
lighting_fs: Arc<ShaderModule>, lighting_fs: Arc<ShaderModule>,
normals_fs: Arc<ShaderModule>, normals_fs: Vec<Arc<ShaderModule>>,
} }
struct RenderContext { struct RenderContext {
window: Arc<Window>, window: Arc<Window>,
swapchain: Arc<Swapchain>, swapchain: Arc<Swapchain>,
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
framebuffers: Vec<Arc<Framebuffer>>, framebuffers: Vec<Arc<Framebuffer>>,
color_buffer: Arc<ImageView>, color_buffer: Arc<ImageView>,
normal_buffer: Arc<ImageView>, normal_buffer: Arc<ImageView>,
depth_buffer: Arc<ImageView>, depth_buffer: Arc<ImageView>,
shader_modules: ShaderModules, shader_modules: ShaderModules,
implicit_pipeline: Arc<GraphicsPipeline>, implicit_pipelines: Vec<Arc<GraphicsPipeline>>,
normals_pipeline: Arc<GraphicsPipeline>, normals_pipelines: Vec<Arc<GraphicsPipeline>>,
lighting_pipeline: Arc<GraphicsPipeline>, lighting_pipeline: Arc<GraphicsPipeline>,
viewport: Viewport, viewport: Viewport,
recreate_swapchain: bool, recreate_swapchain: bool,
recreate_pipelines: bool, recreate_pipelines: bool,
recreate_shaders: bool, recreate_deferred_pipelines: bool,
recreate_shaders: bool,
previous_frame_end: Option<Box<dyn GpuFuture>>, previous_frame_end: Option<Box<dyn GpuFuture>>,
gui: Gui, gui: Gui,
render_start: Instant, render_start: Instant,
new_object_start: Option<Instant>, new_object_start: Option<Instant>,
} }
fn app_version() -> Version { fn app_version() -> Version {
@@ -376,6 +378,35 @@ fn interval_check(csg: &CSG, push_constants: &mut PushConstantData) {
} }
} }
fn sdf_specialize_module(
device: Arc<Device>,
csg: &CSG,
module: Module,
name: &str,
) -> Arc<ShaderModule> {
let new_module = csg.parts.compile_to_spirv(Some(module));
let assembled_module = new_module.assemble();
let module_as_bytes = assembled_module
.iter()
.cloned()
.map(u32::to_le_bytes)
.flatten()
.collect::<Vec<_>>();
if DUMP_SPV_TO_FILE {
File::create(format!("{name}.out.spv"))
.unwrap()
.write(&module_as_bytes)
.unwrap();
}
unsafe {
::vulkano::shader::ShaderModule::new(device, ShaderModuleCreateInfo::new(&assembled_module))
.unwrap()
}
}
impl App { impl App {
fn new(event_loop: &EventLoop<()>) -> Self { fn new(event_loop: &EventLoop<()>) -> Self {
let library = VulkanLibrary::new().expect("Vulkan is not installed???"); let library = VulkanLibrary::new().expect("Vulkan is not installed???");
@@ -528,7 +559,7 @@ impl App {
); );
gstate.csg.push(CSG { gstate.csg.push(CSG {
name: "example".to_string(), name: "generated".to_string(),
parts: create_csg(), parts: create_csg(),
pos: Vec3::ZERO, pos: Vec3::ZERO,
rot: Vec3::ZERO, rot: Vec3::ZERO,
@@ -575,6 +606,7 @@ impl App {
command_buffer_allocator, command_buffer_allocator,
uniform_buffer_allocator, uniform_buffer_allocator,
pipeline_cache, pipeline_cache,
csg_count: gstate.csg.len(),
gstate, gstate,
previous_debug: PreviousDebug::default(), previous_debug: PreviousDebug::default(),
cstate, cstate,
@@ -730,70 +762,12 @@ impl ApplicationHandler for App {
.map(|load| load(self.device.clone()).unwrap()) .map(|load| load(self.device.clone()).unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let trace_module = {
let new_module = self.gstate.csg[0]
.parts
.compile_to_spirv(Some(self.trace_module.clone()));
let assembled_module = new_module.assemble();
let module_as_bytes = assembled_module
.iter()
.cloned()
.map(u32::to_le_bytes)
.flatten()
.collect::<Vec<_>>();
if DUMP_SPV_TO_FILE {
File::create("trace.out.spv")
.unwrap()
.write(&module_as_bytes)
.unwrap();
}
unsafe {
::vulkano::shader::ShaderModule::new(
self.device.clone(),
ShaderModuleCreateInfo::new(&assembled_module),
)
.unwrap()
}
};
let normals_module = {
let new_module = self.gstate.csg[0]
.parts
.compile_to_spirv(Some(self.normals_module.clone()));
let assembled_module = new_module.assemble();
let module_as_bytes = assembled_module
.iter()
.cloned()
.map(u32::to_le_bytes)
.flatten()
.collect::<Vec<_>>();
if DUMP_SPV_TO_FILE {
File::create("normals.out.spv")
.unwrap()
.write(&module_as_bytes)
.unwrap();
}
unsafe {
::vulkano::shader::ShaderModule::new(
self.device.clone(),
ShaderModuleCreateInfo::new(&assembled_module),
)
.unwrap()
}
};
let shader_modules = ShaderModules { let shader_modules = ShaderModules {
implicit_vs: pariter[0].clone(), implicit_vs: pariter[0].clone(),
implicit_fs: trace_module, implicit_fs: vec![],
fullscreen_vs: pariter[1].clone(), fullscreen_vs: pariter[1].clone(),
lighting_fs: pariter[2].clone(), lighting_fs: pariter[2].clone(),
normals_fs: normals_module, normals_fs: vec![],
}; };
drop(pariter); drop(pariter);
@@ -858,7 +832,7 @@ impl ApplicationHandler for App {
let (framebuffers, color_buffer, normal_buffer, depth_buffer) = let (framebuffers, color_buffer, normal_buffer, depth_buffer) =
framebuffer_generation(&images, &render_pass, &self.memory_allocator); framebuffer_generation(&images, &render_pass, &self.memory_allocator);
let (implicit_pipeline, normals_pipeline, lighting_pipeline) = deferred_pipeline_recompile( let lighting_pipeline = pipeline_recompile(
&render_pass, &render_pass,
&self.pipeline_cache, &self.pipeline_cache,
&shader_modules, &shader_modules,
@@ -891,13 +865,14 @@ impl ApplicationHandler for App {
normal_buffer, normal_buffer,
depth_buffer, depth_buffer,
shader_modules, shader_modules,
implicit_pipeline, implicit_pipelines: vec![],
normals_pipeline, normals_pipelines: vec![],
lighting_pipeline, lighting_pipeline,
viewport, viewport,
recreate_swapchain: false, recreate_swapchain: false,
recreate_pipelines: false, recreate_pipelines: false,
recreate_shaders: false, recreate_deferred_pipelines: true,
recreate_shaders: true,
previous_frame_end, previous_frame_end,
gui, gui,
render_start: Instant::now(), render_start: Instant::now(),
@@ -937,12 +912,14 @@ impl ApplicationHandler for App {
rcx.recreate_swapchain = true; rcx.recreate_swapchain = true;
if !DYNAMIC_STATE { if !DYNAMIC_STATE {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
rcx.recreate_deferred_pipelines = true;
} }
}, },
WindowEvent::ScaleFactorChanged { .. } => { WindowEvent::ScaleFactorChanged { .. } => {
rcx.recreate_swapchain = true; rcx.recreate_swapchain = true;
if !DYNAMIC_STATE { if !DYNAMIC_STATE {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
rcx.recreate_deferred_pipelines = true;
} }
}, },
WindowEvent::DroppedFile(_file) => { WindowEvent::DroppedFile(_file) => {
@@ -1027,11 +1004,20 @@ impl App {
rcx.previous_frame_end.as_mut().unwrap().cleanup_finished(); rcx.previous_frame_end.as_mut().unwrap().cleanup_finished();
gui_up(&mut rcx.gui, &mut self.gstate);
if self.previous_debug != self.gstate.debug { if self.previous_debug != self.gstate.debug {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
rcx.recreate_deferred_pipelines = true;
self.previous_debug = self.gstate.debug; self.previous_debug = self.gstate.debug;
} }
if self.csg_count != self.gstate.csg.len() {
rcx.recreate_shaders = true;
rcx.recreate_deferred_pipelines = true;
self.csg_count = self.gstate.csg.len();
}
if rcx.recreate_swapchain { if rcx.recreate_swapchain {
let (new_swapchain, new_images) = rcx let (new_swapchain, new_images) = rcx
.swapchain .swapchain
@@ -1059,77 +1045,65 @@ impl App {
if rcx.recreate_shaders { if rcx.recreate_shaders {
rcx.new_object_start = Some(Instant::now()); rcx.new_object_start = Some(Instant::now());
let trace_module = { rcx.shader_modules.implicit_fs = self
let new_module = self.gstate.csg[0] .gstate
.parts .csg
.compile_to_spirv(Some(self.trace_module.clone())); .iter()
.enumerate()
let assembled_module = new_module.assemble(); .map(|(i, csg)| {
let module_as_bytes = assembled_module sdf_specialize_module(
.iter()
.cloned()
.map(u32::to_le_bytes)
.flatten()
.collect::<Vec<_>>();
if DUMP_SPV_TO_FILE {
File::create("trace.out.spv")
.unwrap()
.write(&module_as_bytes)
.unwrap();
}
unsafe {
::vulkano::shader::ShaderModule::new(
self.device.clone(), self.device.clone(),
ShaderModuleCreateInfo::new(&assembled_module), csg,
self.trace_module.clone(),
&format!("trace{i}"),
) )
.unwrap() })
} .collect::<Vec<_>>();
};
let normals_module = { rcx.shader_modules.normals_fs = self
let new_module = self.gstate.csg[0] .gstate
.parts .csg
.compile_to_spirv(Some(self.normals_module.clone())); .iter()
.enumerate()
let assembled_module = new_module.assemble(); .map(|(i, csg)| {
let module_as_bytes = assembled_module sdf_specialize_module(
.iter()
.cloned()
.map(u32::to_le_bytes)
.flatten()
.collect::<Vec<_>>();
if DUMP_SPV_TO_FILE {
File::create("normals.out.spv")
.unwrap()
.write(&module_as_bytes)
.unwrap();
}
unsafe {
::vulkano::shader::ShaderModule::new(
self.device.clone(), self.device.clone(),
ShaderModuleCreateInfo::new(&assembled_module), csg,
self.normals_module.clone(),
&format!("normals{i}"),
) )
.unwrap() })
} .collect::<Vec<_>>();
};
rcx.shader_modules.implicit_fs = trace_module;
rcx.shader_modules.normals_fs = normals_module;
rcx.recreate_shaders = false; rcx.recreate_shaders = false;
rcx.recreate_pipelines = true; rcx.recreate_deferred_pipelines = true;
}
if rcx.recreate_deferred_pipelines {
(rcx.implicit_pipelines, rcx.normals_pipelines) = deferred_pipelines_recompile(
&rcx.render_pass,
&self.pipeline_cache,
&rcx.shader_modules,
&self.gstate.debug,
if DYNAMIC_STATE {
None
} else {
Some(&rcx.viewport)
},
);
rcx.recreate_deferred_pipelines = false;
if rcx.new_object_start.is_some() {
let end = Instant::now();
info!(
"Object recreation took {} milliseconds",
(end - rcx.new_object_start.unwrap()).as_secs_f64() * 1000.0
);
rcx.new_object_start = None;
}
} }
if rcx.recreate_pipelines { if rcx.recreate_pipelines {
( rcx.lighting_pipeline = pipeline_recompile(
rcx.implicit_pipeline,
rcx.normals_pipeline,
rcx.lighting_pipeline,
) = deferred_pipeline_recompile(
&rcx.render_pass, &rcx.render_pass,
&self.pipeline_cache, &self.pipeline_cache,
&rcx.shader_modules, &rcx.shader_modules,
@@ -1141,14 +1115,6 @@ impl App {
}, },
); );
rcx.recreate_pipelines = false; rcx.recreate_pipelines = false;
if rcx.new_object_start.is_some() {
let end = Instant::now();
info!(
"Object recreation took {} milliseconds",
(end - rcx.new_object_start.unwrap()).as_secs_f64() * 1000.0
);
rcx.new_object_start = None;
}
} }
let (mut push_constants, cam_set) = { let (mut push_constants, cam_set) = {
@@ -1253,55 +1219,47 @@ impl App {
sub sub
}; };
assert!(rcx.implicit_pipeline.layout().set_layouts().len() == 1); let implicit_set = if rcx.implicit_pipelines.len() > 0 {
let implicit_layout = &rcx.implicit_pipelines[0].layout().set_layouts()[0];
let implicit_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
implicit_layout.clone(),
[WriteDescriptorSet::buffer(1, cam_set.clone())],
[],
)
.unwrap();
Some(implicit_set)
} else {
None
};
let implicit_layout = &rcx.implicit_pipeline.layout().set_layouts()[0]; let normals_set1 = if rcx.normals_pipelines.len() > 0 {
let implicit_set = DescriptorSet::new( let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[0];
self.descriptor_set_allocator.clone(), let normals_set = DescriptorSet::new(
implicit_layout.clone(), self.descriptor_set_allocator.clone(),
[ normals_layout.clone(),
//WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()), [WriteDescriptorSet::buffer(1, cam_set.clone())],
WriteDescriptorSet::buffer(1, cam_set.clone()), [],
], )
[], .unwrap();
) Some(normals_set)
.unwrap(); } else {
None
};
//assert!(rcx.lighting_pipeline.layout().set_layouts().len() == 2); let normals_set2 = if rcx.normals_pipelines.len() > 0 {
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[1];
let normals_layout1 = &rcx.normals_pipeline.layout().set_layouts()[0]; let normals_set = DescriptorSet::new(
let normals_set1 = DescriptorSet::new( self.descriptor_set_allocator.clone(),
self.descriptor_set_allocator.clone(), normals_layout.clone(),
normals_layout1.clone(), [WriteDescriptorSet::image_view(0, rcx.depth_buffer.clone())],
[ [],
//WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()), )
WriteDescriptorSet::buffer(1, cam_set.clone()), .unwrap();
], Some(normals_set)
[], } else {
) None
.unwrap(); };
let normals_layout2 = &rcx.normals_pipeline.layout().set_layouts()[1];
let normals_set2 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
normals_layout2.clone(),
[WriteDescriptorSet::image_view(0, rcx.depth_buffer.clone())],
[],
)
.unwrap();
let lighting_layout2 = &rcx.lighting_pipeline.layout().set_layouts()[1];
let lighting_set2 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
lighting_layout2.clone(),
[
WriteDescriptorSet::image_view(0, rcx.color_buffer.clone()),
WriteDescriptorSet::image_view(1, rcx.normal_buffer.clone()),
WriteDescriptorSet::image_view(2, rcx.depth_buffer.clone()),
],
[],
)
.unwrap();
let lighting_layout1 = &rcx.lighting_pipeline.layout().set_layouts()[0]; let lighting_layout1 = &rcx.lighting_pipeline.layout().set_layouts()[0];
let lighting_set1 = DescriptorSet::new( let lighting_set1 = DescriptorSet::new(
@@ -1335,6 +1293,7 @@ impl App {
rcx.recreate_swapchain = true; rcx.recreate_swapchain = true;
if !DYNAMIC_STATE { if !DYNAMIC_STATE {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
rcx.recreate_deferred_pipelines = true;
} }
return; return;
}, },
@@ -1345,11 +1304,10 @@ impl App {
rcx.recreate_swapchain = true; rcx.recreate_swapchain = true;
if !DYNAMIC_STATE { if !DYNAMIC_STATE {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
rcx.recreate_deferred_pipelines = true;
} }
} }
gui_up(&mut rcx.gui, &mut self.gstate);
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.clone(), self.command_buffer_allocator.clone(),
self.graphics_queue.queue_family_index(), self.graphics_queue.queue_family_index(),
@@ -1385,20 +1343,20 @@ impl App {
.unwrap(); .unwrap();
} }
builder for (i, csg) in self.gstate.csg.iter().enumerate() {
.bind_pipeline_graphics(rcx.implicit_pipeline.clone()) builder
.unwrap() .bind_pipeline_graphics(rcx.implicit_pipelines[i].clone())
.bind_descriptor_sets( .unwrap()
PipelineBindPoint::Graphics, .bind_descriptor_sets(
rcx.implicit_pipeline.layout().clone(), PipelineBindPoint::Graphics,
0, rcx.implicit_pipelines[i].layout().clone(),
implicit_set, 0,
) implicit_set.clone().unwrap(),
.unwrap() )
.bind_vertex_buffers(0, self.vertex_buffer.clone()) .unwrap()
.unwrap(); .bind_vertex_buffers(0, self.vertex_buffer.clone())
.unwrap();
for csg in &self.gstate.csg {
push_constants.world = (Mat4::from_translation(csg.pos * 0.01) push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler( * Mat4::from_euler(
EulerRot::XYZ, EulerRot::XYZ,
@@ -1412,7 +1370,11 @@ impl App {
interval_check(csg, &mut push_constants); interval_check(csg, &mut push_constants);
builder builder
.push_constants(rcx.implicit_pipeline.layout().clone(), 0, push_constants) .push_constants(
rcx.implicit_pipelines[i].layout().clone(),
0,
push_constants,
)
.unwrap(); .unwrap();
for i in 0..(8 * 8 * 8) { for i in 0..(8 * 8 * 8) {
@@ -1430,18 +1392,18 @@ impl App {
) )
.unwrap(); .unwrap();
builder for (i, csg) in self.gstate.csg.iter().enumerate() {
.bind_pipeline_graphics(rcx.normals_pipeline.clone()) builder
.unwrap() .bind_pipeline_graphics(rcx.normals_pipelines[i].clone())
.bind_descriptor_sets( .unwrap()
PipelineBindPoint::Graphics, .bind_descriptor_sets(
rcx.normals_pipeline.layout().clone(), PipelineBindPoint::Graphics,
0, rcx.normals_pipelines[i].layout().clone(),
vec![normals_set1, normals_set2], 0,
) vec![normals_set1.clone().unwrap(), normals_set2.clone().unwrap()],
.unwrap(); )
.unwrap();
for csg in &self.gstate.csg {
push_constants.world = (Mat4::from_translation(csg.pos * 0.01) push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler( * Mat4::from_euler(
EulerRot::XYZ, EulerRot::XYZ,
@@ -1453,7 +1415,7 @@ impl App {
.to_cols_array_2d(); .to_cols_array_2d();
builder builder
.push_constants(rcx.normals_pipeline.layout().clone(), 0, push_constants) .push_constants(rcx.normals_pipelines[i].layout().clone(), 0, push_constants)
.unwrap(); .unwrap();
unsafe { builder.draw(3, 1, 0, 0) }.unwrap(); unsafe { builder.draw(3, 1, 0, 0) }.unwrap();
@@ -1519,6 +1481,7 @@ impl App {
rcx.recreate_swapchain = true; rcx.recreate_swapchain = true;
if !DYNAMIC_STATE { if !DYNAMIC_STATE {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
rcx.recreate_deferred_pipelines = true;
} }
rcx.previous_frame_end = Some(sync::now(self.device.clone()).boxed()); rcx.previous_frame_end = Some(sync::now(self.device.clone()).boxed());
}, },
@@ -1619,19 +1582,7 @@ fn framebuffer_generation(
(framebuffers, color_buffer, normal_buffer, depth_buffer) (framebuffers, color_buffer, normal_buffer, depth_buffer)
} }
fn deferred_pipeline_recompile( fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConstant> {
render_pass: &Arc<RenderPass>,
cache: &Arc<PipelineCache>,
shader_modules: &ShaderModules,
debug: &PreviousDebug,
viewport: Option<&Viewport>,
) -> (
Arc<GraphicsPipeline>,
Arc<GraphicsPipeline>,
Arc<GraphicsPipeline>,
) {
let device = cache.device();
const SPEC_BOUNDING_BOXES: u32 = 0; const SPEC_BOUNDING_BOXES: u32 = 0;
const SPEC_DISABLE_MESHCULL: u32 = 1; const SPEC_DISABLE_MESHCULL: u32 = 1;
const SPEC_DISABLE_MESHSCALING1: u32 = 2; const SPEC_DISABLE_MESHSCALING1: u32 = 2;
@@ -1667,40 +1618,21 @@ fn deferred_pipeline_recompile(
trace!("Specs: {:?}", spec_constants); trace!("Specs: {:?}", spec_constants);
let specs = spec_constants; spec_constants
}
let implicit_vs_entry = shader_modules fn deferred_pipelines_recompile(
.implicit_vs render_pass: &Arc<RenderPass>,
.specialize(specs.clone()) cache: &Arc<PipelineCache>,
.unwrap() shader_modules: &ShaderModules,
.single_entry_point() debug: &PreviousDebug,
.unwrap(); viewport: Option<&Viewport>,
) -> (Vec<Arc<GraphicsPipeline>>, Vec<Arc<GraphicsPipeline>>) {
let render_start = Instant::now();
let vertex_input_state = [IVertex::per_vertex()] let device = cache.device();
.definition(&implicit_vs_entry)
.unwrap();
let implicit_vs_info = PipelineShaderStageCreateInfo::new(implicit_vs_entry); let specs = get_spec_constants(debug);
let implicit_fs_info = PipelineShaderStageCreateInfo::new(
shader_modules
.implicit_fs
.specialize(specs.clone())
.unwrap()
.single_entry_point()
.unwrap(),
);
let layout = PipelineLayout::new(
device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([&implicit_vs_info, &implicit_fs_info])
.into_pipeline_layout_create_info(device.clone())
.unwrap(),
)
.unwrap();
if viewport.is_none() {
info!("Using Dynamic State");
}
let (viewport_state, dynamic_state) = if let Some(v) = viewport { let (viewport_state, dynamic_state) = if let Some(v) = viewport {
( (
@@ -1719,41 +1651,77 @@ fn deferred_pipeline_recompile(
info!("Recompiling implicit pipeline... (may take up to 10 minutes)"); info!("Recompiling implicit pipeline... (may take up to 10 minutes)");
let stages = [implicit_vs_info, implicit_fs_info].into_iter().collect(); let implicit_vs_entry = shader_modules
.implicit_vs
let deferred_subpass = Subpass::from(render_pass.clone(), 0).unwrap(); .specialize(specs.clone())
let render_start = Instant::now();
let implicit_pipeline = {
GraphicsPipeline::new(
device.clone(),
Some(cache.clone()),
GraphicsPipelineCreateInfo {
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION,
stages,
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
dynamic_state: dynamic_state.clone(),
viewport_state: Some(viewport_state.clone()),
rasterization_state: Some(RasterizationState {
front_face: FrontFace::Clockwise,
cull_mode: CullMode::Back,
polygon_mode: PolygonMode::Fill,
..RasterizationState::default()
}),
depth_stencil_state: Some(DepthStencilState {
depth: Some(DepthState::simple()),
..Default::default()
}),
multisample_state: Some(MultisampleState::default()),
color_blend_state: None,
subpass: Some(deferred_subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout.clone())
},
)
.unwrap() .unwrap()
}; .single_entry_point()
.unwrap();
let vertex_input_state = [IVertex::per_vertex()]
.definition(&implicit_vs_entry)
.unwrap();
let implicit_vs_info = PipelineShaderStageCreateInfo::new(implicit_vs_entry);
let implicit_pipelines = shader_modules
.implicit_fs
.iter()
.map(|implicit_fs| {
let implicit_fs_info = PipelineShaderStageCreateInfo::new(
implicit_fs
.specialize(specs.clone())
.unwrap()
.single_entry_point()
.unwrap(),
);
let layout = PipelineLayout::new(
device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([
&implicit_vs_info,
&implicit_fs_info,
])
.into_pipeline_layout_create_info(device.clone())
.unwrap(),
)
.unwrap();
let stages = [implicit_vs_info.clone(), implicit_fs_info]
.into_iter()
.collect();
let deferred_subpass = Subpass::from(render_pass.clone(), 0).unwrap();
GraphicsPipeline::new(
device.clone(),
Some(cache.clone()),
GraphicsPipelineCreateInfo {
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION,
stages,
vertex_input_state: Some(vertex_input_state.clone()),
input_assembly_state: Some(InputAssemblyState::default()),
dynamic_state: dynamic_state.clone(),
viewport_state: Some(viewport_state.clone()),
rasterization_state: Some(RasterizationState {
front_face: FrontFace::Clockwise,
cull_mode: CullMode::Back,
polygon_mode: PolygonMode::Fill,
..RasterizationState::default()
}),
depth_stencil_state: Some(DepthStencilState {
depth: Some(DepthState::simple()),
..Default::default()
}),
multisample_state: Some(MultisampleState::default()),
color_blend_state: None,
subpass: Some(deferred_subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout.clone())
},
)
.unwrap()
})
.collect::<Vec<_>>();
let fullscreen_vs_entry = shader_modules let fullscreen_vs_entry = shader_modules
.fullscreen_vs .fullscreen_vs
@@ -1765,54 +1733,102 @@ fn deferred_pipeline_recompile(
let vertex_input_state = VertexInputState::new(); let vertex_input_state = VertexInputState::new();
let fullscreen_vs_info = PipelineShaderStageCreateInfo::new(fullscreen_vs_entry); let fullscreen_vs_info = PipelineShaderStageCreateInfo::new(fullscreen_vs_entry);
let normals_fs_info = PipelineShaderStageCreateInfo::new(
shader_modules let normals_pipelines = shader_modules
.normals_fs .normals_fs
.specialize(specs.clone()) .iter()
.map(|normals_fs| {
let normals_fs_info = PipelineShaderStageCreateInfo::new(
normals_fs
.specialize(specs.clone())
.unwrap()
.single_entry_point()
.unwrap(),
);
let layout = PipelineLayout::new(
device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([
&fullscreen_vs_info,
&normals_fs_info,
])
.into_pipeline_layout_create_info(device.clone())
.unwrap(),
)
.unwrap();
let stages = [fullscreen_vs_info.clone(), normals_fs_info]
.into_iter()
.collect();
let normals_subpass = Subpass::from(render_pass.clone(), 1).unwrap();
GraphicsPipeline::new(
device.clone(),
Some(cache.clone()),
GraphicsPipelineCreateInfo {
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION,
stages,
vertex_input_state: Some(vertex_input_state.clone()),
input_assembly_state: Some(InputAssemblyState::default()),
dynamic_state: dynamic_state.clone(),
viewport_state: Some(viewport_state.clone()),
rasterization_state: Some(RasterizationState {
front_face: FrontFace::Clockwise,
cull_mode: CullMode::Back,
polygon_mode: PolygonMode::Fill,
..RasterizationState::default()
}),
depth_stencil_state: None,
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::with_attachment_states(
normals_subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
subpass: Some(normals_subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout.clone())
},
)
.unwrap() .unwrap()
.single_entry_point() })
.unwrap(), .collect::<Vec<_>>();
let render_end = Instant::now();
info!("Implicit pipeline compiled");
info!(
"Implicit pipeline took {} milliseconds",
(render_end - render_start).as_secs_f64() * 1000.0
); );
let layout = PipelineLayout::new( dump_pipeline_cache(cache.clone());
device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([&fullscreen_vs_info, &normals_fs_info])
.into_pipeline_layout_create_info(device.clone())
.unwrap(),
)
.unwrap();
let stages = [fullscreen_vs_info, normals_fs_info].into_iter().collect(); (implicit_pipelines, normals_pipelines)
let normals_subpass = Subpass::from(render_pass.clone(), 1).unwrap(); }
let normals_pipeline = { fn pipeline_recompile(
GraphicsPipeline::new( render_pass: &Arc<RenderPass>,
device.clone(), cache: &Arc<PipelineCache>,
Some(cache.clone()), shader_modules: &ShaderModules,
GraphicsPipelineCreateInfo { debug: &PreviousDebug,
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION, viewport: Option<&Viewport>,
stages, ) -> Arc<GraphicsPipeline> {
vertex_input_state: Some(vertex_input_state), let device = cache.device();
input_assembly_state: Some(InputAssemblyState::default()),
dynamic_state: dynamic_state.clone(), let specs = get_spec_constants(debug);
viewport_state: Some(viewport_state.clone()),
rasterization_state: Some(RasterizationState { let (viewport_state, dynamic_state) = if let Some(v) = viewport {
front_face: FrontFace::Clockwise, (
cull_mode: CullMode::Back, ViewportState {
polygon_mode: PolygonMode::Fill, viewports: [v.clone()].into_iter().collect(),
..RasterizationState::default() ..Default::default()
}),
depth_stencil_state: None,
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::with_attachment_states(
normals_subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
subpass: Some(normals_subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout.clone())
}, },
Default::default(),
)
} else {
(
Default::default(),
[DynamicState::Viewport].into_iter().collect::<HashSet<_>>(),
) )
.unwrap()
}; };
let fullscreen_vs_entry = shader_modules let fullscreen_vs_entry = shader_modules
@@ -1878,17 +1894,9 @@ fn deferred_pipeline_recompile(
.unwrap() .unwrap()
}; };
let render_end = Instant::now();
info!("Implicit pipeline compiled");
info!(
"Implicit pipeline took {} milliseconds",
(render_end - render_start).as_secs_f64() * 1000.0
);
dump_pipeline_cache(cache.clone()); dump_pipeline_cache(cache.clone());
(implicit_pipeline, normals_pipeline, lighting_pipeline) lighting_pipeline
} }
fn gpu_buffer<T>( fn gpu_buffer<T>(