Multiple CSG
This commit is contained in:
+14
-1
@@ -1,8 +1,12 @@
|
||||
use egui::{Color32, Frame, Id};
|
||||
use egui_plot::{Line, Plot, PlotPoints};
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
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");
|
||||
let mut lightdel = vec![];
|
||||
for light in &mut state.lights {
|
||||
|
||||
+257
-249
@@ -81,7 +81,7 @@ use winit::{
|
||||
event::{DeviceEvent, ElementState, MouseButton, WindowEvent},
|
||||
event_loop::{ActiveEventLoop, EventLoop},
|
||||
keyboard::{KeyCode, PhysicalKey},
|
||||
platform::{wayland::EventLoopBuilderExtWayland, x11::EventLoopBuilderExtX11},
|
||||
platform::x11::EventLoopBuilderExtX11,
|
||||
window::Window,
|
||||
};
|
||||
|
||||
@@ -188,6 +188,7 @@ struct App {
|
||||
uniform_buffer_allocator: SubbufferAllocator,
|
||||
pipeline_cache: Arc<PipelineCache>,
|
||||
gstate: GState,
|
||||
csg_count: usize,
|
||||
previous_debug: PreviousDebug,
|
||||
cstate: CState,
|
||||
vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]>,
|
||||
@@ -198,10 +199,10 @@ struct App {
|
||||
|
||||
struct ShaderModules {
|
||||
implicit_vs: Arc<ShaderModule>,
|
||||
implicit_fs: Arc<ShaderModule>,
|
||||
implicit_fs: Vec<Arc<ShaderModule>>,
|
||||
fullscreen_vs: Arc<ShaderModule>,
|
||||
lighting_fs: Arc<ShaderModule>,
|
||||
normals_fs: Arc<ShaderModule>,
|
||||
normals_fs: Vec<Arc<ShaderModule>>,
|
||||
}
|
||||
|
||||
struct RenderContext {
|
||||
@@ -213,12 +214,13 @@ struct RenderContext {
|
||||
normal_buffer: Arc<ImageView>,
|
||||
depth_buffer: Arc<ImageView>,
|
||||
shader_modules: ShaderModules,
|
||||
implicit_pipeline: Arc<GraphicsPipeline>,
|
||||
normals_pipeline: Arc<GraphicsPipeline>,
|
||||
implicit_pipelines: Vec<Arc<GraphicsPipeline>>,
|
||||
normals_pipelines: Vec<Arc<GraphicsPipeline>>,
|
||||
lighting_pipeline: Arc<GraphicsPipeline>,
|
||||
viewport: Viewport,
|
||||
recreate_swapchain: bool,
|
||||
recreate_pipelines: bool,
|
||||
recreate_deferred_pipelines: bool,
|
||||
recreate_shaders: bool,
|
||||
previous_frame_end: Option<Box<dyn GpuFuture>>,
|
||||
gui: Gui,
|
||||
@@ -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 {
|
||||
fn new(event_loop: &EventLoop<()>) -> Self {
|
||||
let library = VulkanLibrary::new().expect("Vulkan is not installed???");
|
||||
@@ -528,7 +559,7 @@ impl App {
|
||||
);
|
||||
|
||||
gstate.csg.push(CSG {
|
||||
name: "example".to_string(),
|
||||
name: "generated".to_string(),
|
||||
parts: create_csg(),
|
||||
pos: Vec3::ZERO,
|
||||
rot: Vec3::ZERO,
|
||||
@@ -575,6 +606,7 @@ impl App {
|
||||
command_buffer_allocator,
|
||||
uniform_buffer_allocator,
|
||||
pipeline_cache,
|
||||
csg_count: gstate.csg.len(),
|
||||
gstate,
|
||||
previous_debug: PreviousDebug::default(),
|
||||
cstate,
|
||||
@@ -730,70 +762,12 @@ impl ApplicationHandler for App {
|
||||
.map(|load| load(self.device.clone()).unwrap())
|
||||
.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 {
|
||||
implicit_vs: pariter[0].clone(),
|
||||
implicit_fs: trace_module,
|
||||
implicit_fs: vec![],
|
||||
fullscreen_vs: pariter[1].clone(),
|
||||
lighting_fs: pariter[2].clone(),
|
||||
normals_fs: normals_module,
|
||||
normals_fs: vec![],
|
||||
};
|
||||
|
||||
drop(pariter);
|
||||
@@ -858,7 +832,7 @@ impl ApplicationHandler for App {
|
||||
let (framebuffers, color_buffer, normal_buffer, depth_buffer) =
|
||||
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,
|
||||
&self.pipeline_cache,
|
||||
&shader_modules,
|
||||
@@ -891,13 +865,14 @@ impl ApplicationHandler for App {
|
||||
normal_buffer,
|
||||
depth_buffer,
|
||||
shader_modules,
|
||||
implicit_pipeline,
|
||||
normals_pipeline,
|
||||
implicit_pipelines: vec![],
|
||||
normals_pipelines: vec![],
|
||||
lighting_pipeline,
|
||||
viewport,
|
||||
recreate_swapchain: false,
|
||||
recreate_pipelines: false,
|
||||
recreate_shaders: false,
|
||||
recreate_deferred_pipelines: true,
|
||||
recreate_shaders: true,
|
||||
previous_frame_end,
|
||||
gui,
|
||||
render_start: Instant::now(),
|
||||
@@ -937,12 +912,14 @@ impl ApplicationHandler for App {
|
||||
rcx.recreate_swapchain = true;
|
||||
if !DYNAMIC_STATE {
|
||||
rcx.recreate_pipelines = true;
|
||||
rcx.recreate_deferred_pipelines = true;
|
||||
}
|
||||
},
|
||||
WindowEvent::ScaleFactorChanged { .. } => {
|
||||
rcx.recreate_swapchain = true;
|
||||
if !DYNAMIC_STATE {
|
||||
rcx.recreate_pipelines = true;
|
||||
rcx.recreate_deferred_pipelines = true;
|
||||
}
|
||||
},
|
||||
WindowEvent::DroppedFile(_file) => {
|
||||
@@ -1027,11 +1004,20 @@ impl App {
|
||||
|
||||
rcx.previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||
|
||||
gui_up(&mut rcx.gui, &mut self.gstate);
|
||||
|
||||
if self.previous_debug != self.gstate.debug {
|
||||
rcx.recreate_pipelines = true;
|
||||
rcx.recreate_deferred_pipelines = true;
|
||||
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 {
|
||||
let (new_swapchain, new_images) = rcx
|
||||
.swapchain
|
||||
@@ -1059,77 +1045,65 @@ impl App {
|
||||
if rcx.recreate_shaders {
|
||||
rcx.new_object_start = Some(Instant::now());
|
||||
|
||||
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
|
||||
rcx.shader_modules.implicit_fs = self
|
||||
.gstate
|
||||
.csg
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(u32::to_le_bytes)
|
||||
.flatten()
|
||||
.enumerate()
|
||||
.map(|(i, csg)| {
|
||||
sdf_specialize_module(
|
||||
self.device.clone(),
|
||||
csg,
|
||||
self.trace_module.clone(),
|
||||
&format!("trace{i}"),
|
||||
)
|
||||
})
|
||||
.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
|
||||
rcx.shader_modules.normals_fs = self
|
||||
.gstate
|
||||
.csg
|
||||
.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(
|
||||
.enumerate()
|
||||
.map(|(i, csg)| {
|
||||
sdf_specialize_module(
|
||||
self.device.clone(),
|
||||
ShaderModuleCreateInfo::new(&assembled_module),
|
||||
csg,
|
||||
self.normals_module.clone(),
|
||||
&format!("normals{i}"),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
rcx.shader_modules.implicit_fs = trace_module;
|
||||
rcx.shader_modules.normals_fs = normals_module;
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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 {
|
||||
(
|
||||
rcx.implicit_pipeline,
|
||||
rcx.normals_pipeline,
|
||||
rcx.lighting_pipeline,
|
||||
) = deferred_pipeline_recompile(
|
||||
rcx.lighting_pipeline = pipeline_recompile(
|
||||
&rcx.render_pass,
|
||||
&self.pipeline_cache,
|
||||
&rcx.shader_modules,
|
||||
@@ -1141,14 +1115,6 @@ impl App {
|
||||
},
|
||||
);
|
||||
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) = {
|
||||
@@ -1253,55 +1219,47 @@ impl App {
|
||||
sub
|
||||
};
|
||||
|
||||
assert!(rcx.implicit_pipeline.layout().set_layouts().len() == 1);
|
||||
|
||||
let implicit_layout = &rcx.implicit_pipeline.layout().set_layouts()[0];
|
||||
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(0, uniform_buffer_subbuffer.clone()),
|
||||
WriteDescriptorSet::buffer(1, cam_set.clone()),
|
||||
],
|
||||
[WriteDescriptorSet::buffer(1, cam_set.clone())],
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
Some(implicit_set)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
//assert!(rcx.lighting_pipeline.layout().set_layouts().len() == 2);
|
||||
|
||||
let normals_layout1 = &rcx.normals_pipeline.layout().set_layouts()[0];
|
||||
let normals_set1 = DescriptorSet::new(
|
||||
let normals_set1 = if rcx.normals_pipelines.len() > 0 {
|
||||
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[0];
|
||||
let normals_set = DescriptorSet::new(
|
||||
self.descriptor_set_allocator.clone(),
|
||||
normals_layout1.clone(),
|
||||
[
|
||||
//WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()),
|
||||
WriteDescriptorSet::buffer(1, cam_set.clone()),
|
||||
],
|
||||
normals_layout.clone(),
|
||||
[WriteDescriptorSet::buffer(1, cam_set.clone())],
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
Some(normals_set)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let normals_layout2 = &rcx.normals_pipeline.layout().set_layouts()[1];
|
||||
let normals_set2 = DescriptorSet::new(
|
||||
let normals_set2 = if rcx.normals_pipelines.len() > 0 {
|
||||
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[1];
|
||||
let normals_set = DescriptorSet::new(
|
||||
self.descriptor_set_allocator.clone(),
|
||||
normals_layout2.clone(),
|
||||
normals_layout.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();
|
||||
Some(normals_set)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let lighting_layout1 = &rcx.lighting_pipeline.layout().set_layouts()[0];
|
||||
let lighting_set1 = DescriptorSet::new(
|
||||
@@ -1335,6 +1293,7 @@ impl App {
|
||||
rcx.recreate_swapchain = true;
|
||||
if !DYNAMIC_STATE {
|
||||
rcx.recreate_pipelines = true;
|
||||
rcx.recreate_deferred_pipelines = true;
|
||||
}
|
||||
return;
|
||||
},
|
||||
@@ -1345,11 +1304,10 @@ impl App {
|
||||
rcx.recreate_swapchain = true;
|
||||
if !DYNAMIC_STATE {
|
||||
rcx.recreate_pipelines = true;
|
||||
rcx.recreate_deferred_pipelines = true;
|
||||
}
|
||||
}
|
||||
|
||||
gui_up(&mut rcx.gui, &mut self.gstate);
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
self.command_buffer_allocator.clone(),
|
||||
self.graphics_queue.queue_family_index(),
|
||||
@@ -1385,20 +1343,20 @@ impl App {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
for (i, csg) in self.gstate.csg.iter().enumerate() {
|
||||
builder
|
||||
.bind_pipeline_graphics(rcx.implicit_pipeline.clone())
|
||||
.bind_pipeline_graphics(rcx.implicit_pipelines[i].clone())
|
||||
.unwrap()
|
||||
.bind_descriptor_sets(
|
||||
PipelineBindPoint::Graphics,
|
||||
rcx.implicit_pipeline.layout().clone(),
|
||||
rcx.implicit_pipelines[i].layout().clone(),
|
||||
0,
|
||||
implicit_set,
|
||||
implicit_set.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)
|
||||
* Mat4::from_euler(
|
||||
EulerRot::XYZ,
|
||||
@@ -1412,7 +1370,11 @@ impl App {
|
||||
interval_check(csg, &mut push_constants);
|
||||
|
||||
builder
|
||||
.push_constants(rcx.implicit_pipeline.layout().clone(), 0, push_constants)
|
||||
.push_constants(
|
||||
rcx.implicit_pipelines[i].layout().clone(),
|
||||
0,
|
||||
push_constants,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for i in 0..(8 * 8 * 8) {
|
||||
@@ -1430,18 +1392,18 @@ impl App {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for (i, csg) in self.gstate.csg.iter().enumerate() {
|
||||
builder
|
||||
.bind_pipeline_graphics(rcx.normals_pipeline.clone())
|
||||
.bind_pipeline_graphics(rcx.normals_pipelines[i].clone())
|
||||
.unwrap()
|
||||
.bind_descriptor_sets(
|
||||
PipelineBindPoint::Graphics,
|
||||
rcx.normals_pipeline.layout().clone(),
|
||||
rcx.normals_pipelines[i].layout().clone(),
|
||||
0,
|
||||
vec![normals_set1, normals_set2],
|
||||
vec![normals_set1.clone().unwrap(), normals_set2.clone().unwrap()],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for csg in &self.gstate.csg {
|
||||
push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
|
||||
* Mat4::from_euler(
|
||||
EulerRot::XYZ,
|
||||
@@ -1453,7 +1415,7 @@ impl App {
|
||||
.to_cols_array_2d();
|
||||
|
||||
builder
|
||||
.push_constants(rcx.normals_pipeline.layout().clone(), 0, push_constants)
|
||||
.push_constants(rcx.normals_pipelines[i].layout().clone(), 0, push_constants)
|
||||
.unwrap();
|
||||
|
||||
unsafe { builder.draw(3, 1, 0, 0) }.unwrap();
|
||||
@@ -1519,6 +1481,7 @@ impl App {
|
||||
rcx.recreate_swapchain = true;
|
||||
if !DYNAMIC_STATE {
|
||||
rcx.recreate_pipelines = true;
|
||||
rcx.recreate_deferred_pipelines = true;
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
fn deferred_pipeline_recompile(
|
||||
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();
|
||||
|
||||
fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConstant> {
|
||||
const SPEC_BOUNDING_BOXES: u32 = 0;
|
||||
const SPEC_DISABLE_MESHCULL: u32 = 1;
|
||||
const SPEC_DISABLE_MESHSCALING1: u32 = 2;
|
||||
@@ -1667,41 +1618,22 @@ fn deferred_pipeline_recompile(
|
||||
|
||||
trace!("Specs: {:?}", spec_constants);
|
||||
|
||||
let specs = spec_constants;
|
||||
|
||||
let implicit_vs_entry = shader_modules
|
||||
.implicit_vs
|
||||
.specialize(specs.clone())
|
||||
.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_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");
|
||||
spec_constants
|
||||
}
|
||||
|
||||
fn deferred_pipelines_recompile(
|
||||
render_pass: &Arc<RenderPass>,
|
||||
cache: &Arc<PipelineCache>,
|
||||
shader_modules: &ShaderModules,
|
||||
debug: &PreviousDebug,
|
||||
viewport: Option<&Viewport>,
|
||||
) -> (Vec<Arc<GraphicsPipeline>>, Vec<Arc<GraphicsPipeline>>) {
|
||||
let render_start = Instant::now();
|
||||
|
||||
let device = cache.device();
|
||||
|
||||
let specs = get_spec_constants(debug);
|
||||
|
||||
let (viewport_state, dynamic_state) = if let Some(v) = viewport {
|
||||
(
|
||||
ViewportState {
|
||||
@@ -1719,20 +1651,55 @@ fn deferred_pipeline_recompile(
|
||||
|
||||
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
|
||||
.specialize(specs.clone())
|
||||
.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();
|
||||
|
||||
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),
|
||||
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()),
|
||||
@@ -1753,7 +1720,8 @@ fn deferred_pipeline_recompile(
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let fullscreen_vs_entry = shader_modules
|
||||
.fullscreen_vs
|
||||
@@ -1765,9 +1733,13 @@ fn deferred_pipeline_recompile(
|
||||
let vertex_input_state = VertexInputState::new();
|
||||
|
||||
let fullscreen_vs_info = PipelineShaderStageCreateInfo::new(fullscreen_vs_entry);
|
||||
let normals_fs_info = PipelineShaderStageCreateInfo::new(
|
||||
shader_modules
|
||||
|
||||
let normals_pipelines = shader_modules
|
||||
.normals_fs
|
||||
.iter()
|
||||
.map(|normals_fs| {
|
||||
let normals_fs_info = PipelineShaderStageCreateInfo::new(
|
||||
normals_fs
|
||||
.specialize(specs.clone())
|
||||
.unwrap()
|
||||
.single_entry_point()
|
||||
@@ -1776,23 +1748,27 @@ fn deferred_pipeline_recompile(
|
||||
|
||||
let layout = PipelineLayout::new(
|
||||
device.clone(),
|
||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([&fullscreen_vs_info, &normals_fs_info])
|
||||
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();
|
||||
let stages = [fullscreen_vs_info.clone(), normals_fs_info]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let normals_subpass = Subpass::from(render_pass.clone(), 1).unwrap();
|
||||
|
||||
let normals_pipeline = {
|
||||
GraphicsPipeline::new(
|
||||
device.clone(),
|
||||
Some(cache.clone()),
|
||||
GraphicsPipelineCreateInfo {
|
||||
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION,
|
||||
stages,
|
||||
vertex_input_state: Some(vertex_input_state),
|
||||
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()),
|
||||
@@ -1813,6 +1789,46 @@ fn deferred_pipeline_recompile(
|
||||
},
|
||||
)
|
||||
.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
|
||||
);
|
||||
|
||||
dump_pipeline_cache(cache.clone());
|
||||
|
||||
(implicit_pipelines, normals_pipelines)
|
||||
}
|
||||
|
||||
fn pipeline_recompile(
|
||||
render_pass: &Arc<RenderPass>,
|
||||
cache: &Arc<PipelineCache>,
|
||||
shader_modules: &ShaderModules,
|
||||
debug: &PreviousDebug,
|
||||
viewport: Option<&Viewport>,
|
||||
) -> Arc<GraphicsPipeline> {
|
||||
let device = cache.device();
|
||||
|
||||
let specs = get_spec_constants(debug);
|
||||
|
||||
let (viewport_state, dynamic_state) = if let Some(v) = viewport {
|
||||
(
|
||||
ViewportState {
|
||||
viewports: [v.clone()].into_iter().collect(),
|
||||
..Default::default()
|
||||
},
|
||||
Default::default(),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
Default::default(),
|
||||
[DynamicState::Viewport].into_iter().collect::<HashSet<_>>(),
|
||||
)
|
||||
};
|
||||
|
||||
let fullscreen_vs_entry = shader_modules
|
||||
@@ -1878,17 +1894,9 @@ fn deferred_pipeline_recompile(
|
||||
.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());
|
||||
|
||||
(implicit_pipeline, normals_pipeline, lighting_pipeline)
|
||||
lighting_pipeline
|
||||
}
|
||||
|
||||
fn gpu_buffer<T>(
|
||||
|
||||
Reference in New Issue
Block a user