reimplement spec constants

This commit is contained in:
2025-07-11 13:57:08 +01:00
parent d84c1babd0
commit fcac31e796
10 changed files with 303 additions and 169 deletions
+35 -24
View File
@@ -13,11 +13,13 @@ fn sized_text(ui: &mut egui::Ui, text: impl Into<String>, size: f32) {
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub(crate) struct PreviousDebug { pub(crate) struct PreviousDebug {
pub(crate) bounding_boxes: bool, pub(crate) bounding_boxes: bool,
pub(crate) disable_meshcull: bool,
pub(crate) disable_meshscale1: bool,
pub(crate) disable_meshscale2: bool,
pub(crate) disable_taskcull: bool,
pub(crate) brute_force: bool, pub(crate) brute_force: bool,
pub(crate) show_ao: bool,
pub(crate) show_normals: bool,
pub(crate) show_depth: bool,
pub(crate) show_albedo: bool,
pub(crate) show_all: bool,
pub(crate) disable_ao: bool,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -76,7 +78,7 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState, new_csg_needed: &mut boo
egui::Slider::new(&mut state.move_speed, 0.0..=2.0) egui::Slider::new(&mut state.move_speed, 0.0..=2.0)
.text("Movement Speed"), .text("Movement Speed"),
); );
ui.heading("Meshes"); ui.heading(format!("Meshes ({})", state.meshes.len()));
let mut meshdel = vec![]; let mut meshdel = vec![];
for mesh in &mut state.meshes { for mesh in &mut state.meshes {
ui.label(mesh.name.clone()); ui.label(mesh.name.clone());
@@ -113,7 +115,7 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState, new_csg_needed: &mut boo
{ {
state.meshes.remove(i); state.meshes.remove(i);
} }
ui.heading("Implicit Surfaces"); ui.heading(format!("Implicit Surfaces ({})", state.csg.len()));
let mut csgdel = vec![]; let mut csgdel = vec![];
for csg in &mut state.csg { for csg in &mut state.csg {
let mut csg = csg.write().unwrap(); let mut csg = csg.write().unwrap();
@@ -154,7 +156,7 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState, new_csg_needed: &mut boo
if state.csg.len() < 32 && ui.small_button("add csg").clicked() { if state.csg.len() < 32 && ui.small_button("add csg").clicked() {
*new_csg_needed = true; *new_csg_needed = true;
} }
ui.heading("Lights"); ui.heading(format!("Lights ({})", state.lights.len()));
let mut lightdel = vec![]; let mut lightdel = vec![];
for light in &mut state.lights { for light in &mut state.lights {
ui.label("Light"); ui.label("Light");
@@ -199,8 +201,9 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState, new_csg_needed: &mut boo
.map(|(x, y)| [x as f64, *y]) .map(|(x, y)| [x as f64, *y])
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into(); .into();
let average_fps = state.fps.iter().sum::<f64>() / state.fps.len() as f64;
let line = Line::new("fps_line", fps); let line = Line::new("fps_line", fps);
ui.heading("FPS"); ui.heading(format!("FPS ({:.2})", average_fps));
Plot::new("fps") Plot::new("fps")
.view_aspect(2.0) .view_aspect(2.0)
.show(ui, |plot_ui| plot_ui.line(line)); .show(ui, |plot_ui| plot_ui.line(line));
@@ -210,26 +213,34 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState, new_csg_needed: &mut boo
&mut state.debug.bounding_boxes, &mut state.debug.bounding_boxes,
"Render bounding boxes instead", "Render bounding boxes instead",
); );
ui.toggle_value(
&mut state.debug.disable_meshcull,
"Disable mesh shader culling",
);
ui.toggle_value(
&mut state.debug.disable_meshscale1,
"Disable mesh shader scaling part 1",
);
ui.toggle_value(
&mut state.debug.disable_meshscale2,
"Disable mesh shader scaling part 2",
);
ui.toggle_value(
&mut state.debug.disable_taskcull,
"Disable task shader culling",
);
ui.toggle_value( ui.toggle_value(
&mut state.debug.brute_force, &mut state.debug.brute_force,
"Brute force the render (use no new techniques)", "Brute force the render (use no new techniques)",
); );
ui.toggle_value(
&mut state.debug.show_ao,
"Display the ambient occlusion render attachment",
);
ui.toggle_value(
&mut state.debug.show_normals,
"Display the normals render attachment",
);
ui.toggle_value(
&mut state.debug.show_depth,
"Display the depth render attachment",
);
ui.toggle_value(
&mut state.debug.show_albedo,
"Display the albedo render attachment",
);
ui.toggle_value(
&mut state.debug.show_all,
"Display all render attachments",
);
ui.toggle_value(
&mut state.debug.disable_ao,
"Disable ambient occlusion calculation",
);
}); });
}); });
}); });
-42
View File
@@ -1,42 +0,0 @@
#version 460
#include "include.glsl"
#include "implicit_include.glsl"
layout(location = 0) in vec3 position;
layout(location = 0) out vec4 pos;
void main() {
uint base_index = gl_InstanceIndex; //gl_BaseInstance;
vec3 internal_pos = vec3(
float((base_index >> 8) & 15) / 16.0,
float((base_index >> 4) & 15) / 16.0,
float((base_index >> 0) & 15) / 16.0
);
bool enable;
switch ((base_index >> 5) & 3) {
default:
case 0:
enable = (object_uniforms.enable[base_index >> 7].x & (1 << (base_index & 31))) != 0;
break;
case 1:
enable = (object_uniforms.enable[base_index >> 7].y & (1 << (base_index & 31))) != 0;
break;
case 2:
enable = (object_uniforms.enable[base_index >> 7].z & (1 << (base_index & 31))) != 0;
break;
case 3:
enable = (object_uniforms.enable[base_index >> 7].w & (1 << (base_index & 31))) != 0;
break;
}
if (!enable) {
gl_Position = vec4(0.0 / 0.0);
return;
}
pos = vec4((((position / 16.0) + internal_pos) * object_uniforms.dimensions) + object_uniforms.lowest_corner, 1.);
gl_Position = camera_uniforms.proj_view * pc.world * pos;
}
+9
View File
@@ -18,4 +18,13 @@ layout(set = 0, binding = 1) uniform Camera {
vec4 campos_and_time; vec4 campos_and_time;
} camera_uniforms; } camera_uniforms;
layout(constant_id = 0) const bool SPEC_BOUNDING_BOXES = false;
layout(constant_id = 1) const bool SPEC_BRUTE_FORCE = false;
layout(constant_id = 2) const bool SPEC_SHOW_AO = false;
layout(constant_id = 3) const bool SPEC_SHOW_NORMALS = false;
layout(constant_id = 4) const bool SPEC_SHOW_DEPTH = false;
layout(constant_id = 5) const bool SPEC_SHOW_ALBEDO = false;
layout(constant_id = 6) const bool SPEC_SHOW_ALL = false;
layout(constant_id = 7) const bool SPEC_DISABLE_AO = false;
#endif #endif
+38 -5
View File
@@ -16,7 +16,7 @@ vec3 calculate_view_position(float depth)
return (view_position.xyz / view_position.w); return (view_position.xyz / view_position.w);
} }
vec3 shading(vec3 normal, vec3 position, float ao) vec3 shading(vec3 albedo, vec3 normal, vec3 position, float ao)
{ {
vec3 accum = vec3(0., 0., 0.); vec3 accum = vec3(0., 0., 0.);
@@ -26,17 +26,50 @@ vec3 shading(vec3 normal, vec3 position, float ao)
} }
//return vec3(int(position.x * 256.0) ^ int(position.y * 256.0) ^ int(position.z * 256.0)); //return vec3(int(position.x * 256.0) ^ int(position.y * 256.0) ^ int(position.z * 256.0));
return accum * ao; return albedo * accum * ao;
} }
void main() { void main() {
if (SPEC_SHOW_AO) {
f_color = subpassLoad(u_ao_r_m);
} else if (SPEC_SHOW_NORMALS) {
f_color = subpassLoad(u_normals);
} else if (SPEC_SHOW_DEPTH) {
f_color = subpassLoad(u_depth);
} else if (SPEC_SHOW_ALBEDO) {
f_color = subpassLoad(u_color);
} else {
float depth = subpassLoad(u_depth).x; float depth = subpassLoad(u_depth).x;
if (depth == 1.0) { if (depth == 1.0 && !SPEC_SHOW_ALL) {
discard; discard;
} }
vec3 col = subpassLoad(u_color).xyz; vec3 albedo = subpassLoad(u_color).xyz;
vec3 normal = subpassLoad(u_normals).xyz; vec3 normal = subpassLoad(u_normals).xyz;
float ao = subpassLoad(u_ao_r_m).x; float ao = subpassLoad(u_ao_r_m).x;
vec3 position = calculate_view_position(depth); vec3 position = calculate_view_position(depth);
f_color = vec4(col * shading(normal, position, ao), 1.0); vec3 shading = shading(albedo, normal, position, ao);
if (SPEC_SHOW_ALL) {
switch (uint(floor((v_pos.x + 1.0) * (5.0 / 2.0)))) {
default:
case 0:
f_color = vec4(shading, 1.0);
break;
case 1:
f_color = subpassLoad(u_ao_r_m);
break;
case 2:
f_color = subpassLoad(u_normals);
break;
case 3:
f_color = subpassLoad(u_depth);
break;
case 4:
f_color = subpassLoad(u_color);
break;
}
} else {
f_color = vec4(shading, 1.0);
}
}
} }
+76 -47
View File
@@ -89,8 +89,8 @@ use winit::{
mod gui; mod gui;
use crate::{ use crate::{
gui::*, gui::*,
implicit_vs::{Camera, Lights, PushConstantData},
threads::{WorkComplete, WorkItem}, threads::{WorkComplete, WorkItem},
trace_vs::{Camera, Lights, PushConstantData},
}; };
mod objects; mod objects;
use crate::objects::*; use crate::objects::*;
@@ -212,7 +212,7 @@ struct App {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct ShaderModules { struct ShaderModules {
implicit_vs: Arc<ShaderModule>, trace_vs: Arc<ShaderModule>,
fullscreen_vs: Arc<ShaderModule>, fullscreen_vs: Arc<ShaderModule>,
lighting_fs: Arc<ShaderModule>, lighting_fs: Arc<ShaderModule>,
} }
@@ -502,10 +502,10 @@ impl App {
} }
} }
mod implicit_vs { mod trace_vs {
vulkano_shaders::shader! { vulkano_shaders::shader! {
ty: "vertex", ty: "vertex",
path: "src/implicit.vert.glsl", path: "src/trace.vert.glsl",
vulkan_version: "1.3", vulkan_version: "1.3",
spirv_version: "1.6", spirv_version: "1.6",
custom_derives: [Debug, Clone, Copy], custom_derives: [Debug, Clone, Copy],
@@ -618,7 +618,7 @@ impl ApplicationHandler for App {
::vulkano::Validated<::vulkano::VulkanError>, ::vulkano::Validated<::vulkano::VulkanError>,
>, >,
> = vec![ > = vec![
((implicit_vs::load) ((trace_vs::load)
as fn( as fn(
::std::sync::Arc<::vulkano::device::Device>, ::std::sync::Arc<::vulkano::device::Device>,
) -> Result< ) -> Result<
@@ -647,7 +647,7 @@ impl ApplicationHandler for App {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let shader_modules = ShaderModules { let shader_modules = ShaderModules {
implicit_vs: pariter[0].clone(), trace_vs: pariter[0].clone(),
fullscreen_vs: pariter[1].clone(), fullscreen_vs: pariter[1].clone(),
lighting_fs: pariter[2].clone(), lighting_fs: pariter[2].clone(),
}; };
@@ -958,7 +958,7 @@ impl App {
//* Mat4::from_rotation_z(std::f32::consts::PI) //* Mat4::from_rotation_z(std::f32::consts::PI)
* Mat4::from_translation(Vec3::ZERO - self.cstate.position); * Mat4::from_translation(Vec3::ZERO - self.cstate.position);
let uniform_data = implicit_vs::Camera { let uniform_data = trace_vs::Camera {
proj_view: (proj * view).to_cols_array_2d(), proj_view: (proj * view).to_cols_array_2d(),
inv_proj_view: (proj * view).inverse().to_cols_array_2d(), inv_proj_view: (proj * view).inverse().to_cols_array_2d(),
campos_and_time: [ campos_and_time: [
@@ -992,7 +992,7 @@ impl App {
col[i][2] = light.colour.z; col[i][2] = light.colour.z;
} }
let uniform_data = implicit_vs::Lights { let uniform_data = trace_vs::Lights {
pos, pos,
col, col,
light_count: self.gstate.lights.len() as u32, light_count: self.gstate.lights.len() as u32,
@@ -1012,17 +1012,17 @@ impl App {
Arc<DescriptorSet>, Arc<DescriptorSet>,
Arc<DescriptorSet>, Arc<DescriptorSet>,
) { ) {
let implicit_set1 = if self.csg_count > 0 { let trace_set1 = if self.csg_count > 0 {
let implicit_layout = &self.gstate.csg[0] let trace_layout = &self.gstate.csg[0]
.read() .read()
.unwrap() .unwrap()
.deferred_pipeline .trace_pipeline
.layout() .layout()
.set_layouts()[0] .set_layouts()[0]
.clone(); .clone();
let implicit_set = DescriptorSet::new( let trace_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(), self.descriptor_set_allocator.clone(),
implicit_layout.clone(), trace_layout.clone(),
[WriteDescriptorSet::buffer( [WriteDescriptorSet::buffer(
1, 1,
rcx.camera_buffers[index].clone(), rcx.camera_buffers[index].clone(),
@@ -1030,7 +1030,7 @@ impl App {
[], [],
) )
.unwrap(); .unwrap();
Some(implicit_set) Some(trace_set)
} else { } else {
None None
}; };
@@ -1108,7 +1108,7 @@ impl App {
.unwrap(); .unwrap();
( (
implicit_set1, trace_set1,
normals_set1, normals_set1,
normals_set3, normals_set3,
lighting_set1, lighting_set1,
@@ -1150,21 +1150,21 @@ impl App {
&self, &self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
push_constants: &Vec<PushConstantData>, push_constants: &Vec<PushConstantData>,
implicit_set: Arc<DescriptorSet>, trace_set: Arc<DescriptorSet>,
frame_index: usize, frame_index: usize,
) { ) {
for (i, csg) in self.gstate.csg.iter().enumerate() { for (i, csg) in self.gstate.csg.iter().enumerate() {
let csg = csg.read().unwrap(); let csg = csg.read().unwrap();
builder builder
.bind_pipeline_graphics(csg.deferred_pipeline.clone()) .bind_pipeline_graphics(csg.trace_pipeline.clone())
.unwrap() .unwrap()
.bind_descriptor_sets( .bind_descriptor_sets(
PipelineBindPoint::Graphics, PipelineBindPoint::Graphics,
csg.deferred_pipeline.layout().clone(), csg.trace_pipeline.layout().clone(),
0, 0,
vec![ vec![
implicit_set.clone(), trace_set.clone(),
csg.deferred_descriptor_set[frame_index].clone(), csg.trace_descriptor_set[frame_index].clone(),
], ],
) )
.unwrap() .unwrap()
@@ -1172,7 +1172,7 @@ impl App {
.unwrap(); .unwrap();
builder builder
.push_constants(csg.deferred_pipeline.layout().clone(), 0, push_constants[i]) .push_constants(csg.trace_pipeline.layout().clone(), 0, push_constants[i])
.unwrap(); .unwrap();
unsafe { builder.draw(VERTEX_COUNT as u32, 16 * 16 * 16, 0, 0) }.unwrap(); unsafe { builder.draw(VERTEX_COUNT as u32, 16 * 16 * 16, 0, 0) }.unwrap();
@@ -1253,6 +1253,7 @@ impl App {
} }
}, },
WorkComplete::GetPushConstants(..) => {}, WorkComplete::GetPushConstants(..) => {},
WorkComplete::RecompilePipelines(..) => {},
} }
} }
@@ -1278,6 +1279,8 @@ impl App {
rcx.render_start = Instant::now(); rcx.render_start = Instant::now();
let mut work_for_later = vec![];
if self.draw_gui { if self.draw_gui {
let mut csg_needed = false; let mut csg_needed = false;
gui_up(&mut rcx.gui, &mut self.gstate, &mut csg_needed); gui_up(&mut rcx.gui, &mut self.gstate, &mut csg_needed);
@@ -1307,7 +1310,6 @@ impl App {
}; };
self.gstate.csg.len() self.gstate.csg.len()
]; ];
let mut push_constants_left = self.gstate.csg.len();
if self.previous_debug != self.gstate.debug { if self.previous_debug != self.gstate.debug {
rcx.recreate_pipelines = true; rcx.recreate_pipelines = true;
@@ -1350,12 +1352,36 @@ impl App {
} }
if rcx.recreate_pipelines { if rcx.recreate_pipelines {
let mut csg_left = self.gstate.csg.len();
for (i, csg) in self.gstate.csg.iter().enumerate() {
self.thread_work_creation
.send(WorkItem::RecompilePipelines(
csg.clone(),
self.device.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
self.previous_debug.clone(),
i,
))
.unwrap();
}
rcx.lighting_pipeline = pipeline_recompile( rcx.lighting_pipeline = pipeline_recompile(
&rcx.render_pass, &rcx.render_pass,
&self.pipeline_cache, &self.pipeline_cache,
&rcx.shader_modules, &rcx.shader_modules,
&self.gstate.debug, &self.gstate.debug,
); );
while csg_left > 0 {
for work in self.thread_work_completion.try_iter() {
match work {
WorkComplete::RecompilePipelines(index) => {
csg_left -= 1;
},
other => work_for_later.push(other),
}
}
}
rcx.recreate_pipelines = false; rcx.recreate_pipelines = false;
} }
@@ -1377,6 +1403,7 @@ impl App {
let image_index = image_index as usize; let image_index = image_index as usize;
let mut push_constants_left = self.gstate.csg.len();
for (i, csg) in self.gstate.csg.iter().enumerate() { for (i, csg) in self.gstate.csg.iter().enumerate() {
self.thread_work_creation self.thread_work_creation
.send(WorkItem::GetPushConstants( .send(WorkItem::GetPushConstants(
@@ -1396,7 +1423,7 @@ impl App {
self.update_camera_uniform(rcx, image_index); self.update_camera_uniform(rcx, image_index);
self.update_lights_uniform(rcx, image_index); self.update_lights_uniform(rcx, image_index);
let (implicit_set, normals_set1, normals_set2, lighting_set1, lighting_set2) = let (trace_set, normals_set1, normals_set2, lighting_set1, lighting_set2) =
self.get_descriptor_sets(rcx, image_index); self.get_descriptor_sets(rcx, image_index);
let mut builder = AutoCommandBufferBuilder::primary( let mut builder = AutoCommandBufferBuilder::primary(
@@ -1428,8 +1455,6 @@ impl App {
.set_viewport(0, [rcx.viewport.clone()].into_iter().collect()) .set_viewport(0, [rcx.viewport.clone()].into_iter().collect())
.unwrap(); .unwrap();
let mut work_for_later = vec![];
while push_constants_left > 0 { while push_constants_left > 0 {
for work in self.thread_work_completion.try_iter() { for work in self.thread_work_completion.try_iter() {
match work { match work {
@@ -1446,7 +1471,7 @@ impl App {
self.add_commands_depth_pass( self.add_commands_depth_pass(
&mut builder, &mut builder,
&push_constants, &push_constants,
implicit_set.unwrap(), trace_set.unwrap(),
image_index, image_index,
); );
} }
@@ -1669,37 +1694,41 @@ fn framebuffer_generation(
fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConstant> { fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConstant> {
const SPEC_BOUNDING_BOXES: u32 = 0; const SPEC_BOUNDING_BOXES: u32 = 0;
const SPEC_DISABLE_MESHCULL: u32 = 1; const SPEC_BRUTE_FORCE: u32 = 1;
const SPEC_DISABLE_MESHSCALING1: u32 = 2; const SPEC_SHOW_AO: u32 = 2;
const SPEC_DISABLE_MESHSCALING2: u32 = 3; const SPEC_SHOW_NORMALS: u32 = 3;
const SPEC_DISABLE_TASKCULL: u32 = 4; const SPEC_SHOW_DEPTH: u32 = 4;
const SPEC_BRUTE_FORCE: u32 = 5; const SPEC_SHOW_ALBEDO: u32 = 5;
const SPEC_SHOW_ALL: u32 = 6;
const SPEC_DISABLE_AO: u32 = 7;
let mut spec_constants = HashMap::with_capacity(6); let mut spec_constants = HashMap::with_capacity(6);
spec_constants.insert( spec_constants.insert(
SPEC_BOUNDING_BOXES, SPEC_BOUNDING_BOXES,
SpecializationConstant::Bool(debug.bounding_boxes), SpecializationConstant::Bool(debug.bounding_boxes),
); );
spec_constants.insert(
SPEC_DISABLE_MESHCULL,
SpecializationConstant::Bool(debug.disable_meshcull),
);
spec_constants.insert(
SPEC_DISABLE_MESHSCALING1,
SpecializationConstant::Bool(debug.disable_meshscale1),
);
spec_constants.insert(
SPEC_DISABLE_MESHSCALING2,
SpecializationConstant::Bool(debug.disable_meshscale2),
);
spec_constants.insert(
SPEC_DISABLE_TASKCULL,
SpecializationConstant::Bool(debug.disable_taskcull),
);
spec_constants.insert( spec_constants.insert(
SPEC_BRUTE_FORCE, SPEC_BRUTE_FORCE,
SpecializationConstant::Bool(debug.brute_force), SpecializationConstant::Bool(debug.brute_force),
); );
spec_constants.insert(SPEC_SHOW_AO, SpecializationConstant::Bool(debug.show_ao));
spec_constants.insert(
SPEC_SHOW_NORMALS,
SpecializationConstant::Bool(debug.show_normals),
);
spec_constants.insert(
SPEC_SHOW_DEPTH,
SpecializationConstant::Bool(debug.show_depth),
);
spec_constants.insert(
SPEC_SHOW_ALBEDO,
SpecializationConstant::Bool(debug.show_albedo),
);
spec_constants.insert(SPEC_SHOW_ALL, SpecializationConstant::Bool(debug.show_all));
spec_constants.insert(
SPEC_DISABLE_AO,
SpecializationConstant::Bool(debug.disable_ao),
);
trace!("Specs: {:?}", spec_constants); trace!("Specs: {:?}", spec_constants);
+4
View File
@@ -63,7 +63,11 @@ void main() {
f_normal = vec4(normalize(rotation * n), 1.0); f_normal = vec4(normalize(rotation * n), 1.0);
if (SPEC_DISABLE_AO) {
f_ao_r_m.x = 1.0;
} else {
f_ao_r_m.x = getOcclusion(position, n); f_ao_r_m.x = getOcclusion(position, n);
}
return; return;
} }
+6 -4
View File
@@ -9,10 +9,10 @@ use vulkano::{
memory::allocator::{ memory::allocator::{
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator, AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
}, },
pipeline::{GraphicsPipeline, graphics::vertex_input::Vertex}, pipeline::{graphics::vertex_input::Vertex, GraphicsPipeline}, shader::ShaderModule,
}; };
use crate::{implicit_vs::Object, ssa::SSATape}; use crate::{ssa::SSATape, trace_vs::Object};
pub(crate) const PLATONIC_SOLIDS: [(&str, &[u8]); 1] = [("Buny", include_bytes!("bunny.obj"))]; pub(crate) const PLATONIC_SOLIDS: [(&str, &[u8]); 1] = [("Buny", include_bytes!("bunny.obj"))];
@@ -42,10 +42,12 @@ pub(crate) struct CSG {
pub(crate) pos: Vec3, pub(crate) pos: Vec3,
pub(crate) rot: Vec3, pub(crate) rot: Vec3,
pub(crate) scale: Vec3, pub(crate) scale: Vec3,
pub(crate) deferred_pipeline: Arc<GraphicsPipeline>, pub(crate) trace_shader_module: Arc<ShaderModule>,
pub(crate) normals_shader_module: Arc<ShaderModule>,
pub(crate) trace_pipeline: Arc<GraphicsPipeline>,
pub(crate) normals_pipeline: Arc<GraphicsPipeline>, pub(crate) normals_pipeline: Arc<GraphicsPipeline>,
pub(crate) enable_buffer: Vec<Subbuffer<Object>>, pub(crate) enable_buffer: Vec<Subbuffer<Object>>,
pub(crate) deferred_descriptor_set: Vec<Arc<DescriptorSet>>, pub(crate) trace_descriptor_set: Vec<Arc<DescriptorSet>>,
pub(crate) normals_descriptor_set: Vec<Arc<DescriptorSet>>, pub(crate) normals_descriptor_set: Vec<Arc<DescriptorSet>>,
} }
+63 -30
View File
@@ -38,10 +38,10 @@ use vulkano::{
use crate::{ use crate::{
DUMP_SPV_TO_FILE, IVertex, ShaderModules, get_spec_constants, DUMP_SPV_TO_FILE, IVertex, ShaderModules, get_spec_constants,
gui::PreviousDebug, gui::PreviousDebug,
implicit_vs::{Object, PushConstantData},
interpreter::{self, IntervalInterpreter, PointInterpreter, VALUE_0}, interpreter::{self, IntervalInterpreter, PointInterpreter, VALUE_0},
objects::CSG, objects::CSG,
ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape}, ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape},
trace_vs::{Object, PushConstantData},
types::Interval, types::Interval,
}; };
@@ -61,12 +61,22 @@ pub enum WorkItem {
isize, isize,
), ),
GetPushConstants(Arc<RwLock<CSG>>, f32, usize, usize), GetPushConstants(Arc<RwLock<CSG>>, f32, usize, usize),
RecompilePipelines(
Arc<RwLock<CSG>>,
Arc<Device>,
Arc<RenderPass>,
Arc<PipelineCache>,
ShaderModules,
PreviousDebug,
usize,
),
} }
#[derive(Debug)] #[derive(Debug)]
pub enum WorkComplete { pub enum WorkComplete {
CreateCSG(Arc<RwLock<CSG>>, isize), CreateCSG(Arc<RwLock<CSG>>, isize),
GetPushConstants(PushConstantData, usize), GetPushConstants(PushConstantData, usize),
RecompilePipelines(usize),
} }
pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkComplete>) { pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkComplete>) {
@@ -97,13 +107,13 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
&format!("normals"), &format!("normals"),
); );
let (deferred_pipeline, normals_pipeline) = deferred_pipelines_recompile( let (trace_pipeline, normals_pipeline) = deferred_pipelines_recompile(
device, device,
render_pass, render_pass,
cache, cache,
modules, modules,
trace_shader_module, trace_shader_module.clone(),
normals_shader_module, normals_shader_module.clone(),
debug, debug,
); );
@@ -118,13 +128,13 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
}) })
.collect(); .collect();
let deferred_layout = deferred_pipeline.layout().set_layouts()[1].clone(); let trace_layout = trace_pipeline.layout().set_layouts()[1].clone();
let deferred_descriptor_set = (0..frames) let trace_descriptor_set = (0..frames)
.into_iter() .into_iter()
.map(|f| { .map(|f| {
DescriptorSet::new( DescriptorSet::new(
descriptor_set_allocator.clone(), descriptor_set_allocator.clone(),
deferred_layout.clone(), trace_layout.clone(),
[WriteDescriptorSet::buffer( [WriteDescriptorSet::buffer(
0, 0,
enable_buffer[f as usize].clone(), enable_buffer[f as usize].clone(),
@@ -158,10 +168,12 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
pos: Vec3::ZERO, pos: Vec3::ZERO,
rot: Vec3::ZERO, rot: Vec3::ZERO,
scale: Vec3::ONE, scale: Vec3::ONE,
deferred_pipeline, trace_shader_module,
normals_shader_module,
trace_pipeline,
normals_pipeline, normals_pipeline,
enable_buffer, enable_buffer,
deferred_descriptor_set, trace_descriptor_set,
normals_descriptor_set, normals_descriptor_set,
})); }));
@@ -174,7 +186,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
); );
}, },
WorkItem::GetPushConstants(csg, time, frame_index, index) => { WorkItem::GetPushConstants(csg, time, frame_index, index) => {
let mut csg = csg.write().unwrap(); let csg = csg.read().unwrap();
let world = Mat4::from_translation(csg.pos * 0.01) let world = Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler( * Mat4::from_euler(
@@ -190,11 +202,32 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
inv_world: world.inverse().to_cols_array_2d(), inv_world: world.inverse().to_cols_array_2d(),
}; };
interval_check(&mut csg, index as u32 + 1, time, frame_index); interval_check(&csg, index as u32 + 1, time, frame_index);
send.send(WorkComplete::GetPushConstants(push_constants, index)) send.send(WorkComplete::GetPushConstants(push_constants, index))
.unwrap(); .unwrap();
}, },
WorkItem::RecompilePipelines(
csg,
device,
render_pass,
cache,
modules,
debug,
index,
) => {
let mut csg = csg.write().unwrap();
(csg.trace_pipeline, csg.normals_pipeline) = deferred_pipelines_recompile(
device,
render_pass,
cache,
modules,
csg.trace_shader_module.clone(),
csg.normals_shader_module.clone(),
debug,
);
send.send(WorkComplete::RecompilePipelines(index)).unwrap();
},
} }
} }
} }
@@ -212,20 +245,18 @@ fn deferred_pipelines_recompile(
let dynamic_state = [DynamicState::Viewport].into_iter().collect::<HashSet<_>>(); let dynamic_state = [DynamicState::Viewport].into_iter().collect::<HashSet<_>>();
let implicit_vs_entry = shader_modules let trace_vs_entry = shader_modules
.implicit_vs .trace_vs
.specialize(specs.clone()) .specialize(specs.clone())
.unwrap() .unwrap()
.single_entry_point() .single_entry_point()
.unwrap(); .unwrap();
let vertex_input_state = [IVertex::per_vertex()] let vertex_input_state = [IVertex::per_vertex()].definition(&trace_vs_entry).unwrap();
.definition(&implicit_vs_entry)
.unwrap();
let implicit_vs_info = PipelineShaderStageCreateInfo::new(implicit_vs_entry); let trace_vs_info = PipelineShaderStageCreateInfo::new(trace_vs_entry);
let implicit_fs_info = PipelineShaderStageCreateInfo::new( let trace_fs_info = PipelineShaderStageCreateInfo::new(
trace_shader_module trace_shader_module
.specialize(specs.clone()) .specialize(specs.clone())
.unwrap() .unwrap()
@@ -235,19 +266,17 @@ fn deferred_pipelines_recompile(
let layout = PipelineLayout::new( let layout = PipelineLayout::new(
device.clone(), device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([&implicit_vs_info, &implicit_fs_info]) PipelineDescriptorSetLayoutCreateInfo::from_stages([&trace_vs_info, &trace_fs_info])
.into_pipeline_layout_create_info(device.clone()) .into_pipeline_layout_create_info(device.clone())
.unwrap(), .unwrap(),
) )
.unwrap(); .unwrap();
let stages = [implicit_vs_info.clone(), implicit_fs_info] let stages = [trace_vs_info.clone(), trace_fs_info].into_iter().collect();
.into_iter()
.collect();
let deferred_subpass = Subpass::from(render_pass.clone(), 0).unwrap(); let trace_subpass = Subpass::from(render_pass.clone(), 0).unwrap();
let implicit_pipeline = GraphicsPipeline::new( let trace_pipeline = GraphicsPipeline::new(
device.clone(), device.clone(),
Some(cache.clone()), Some(cache.clone()),
GraphicsPipelineCreateInfo { GraphicsPipelineCreateInfo {
@@ -269,10 +298,10 @@ fn deferred_pipelines_recompile(
}), }),
multisample_state: Some(MultisampleState::default()), multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::with_attachment_states( color_blend_state: Some(ColorBlendState::with_attachment_states(
deferred_subpass.num_color_attachments(), trace_subpass.num_color_attachments(),
ColorBlendAttachmentState::default(), ColorBlendAttachmentState::default(),
)), )),
subpass: Some(deferred_subpass.into()), subpass: Some(trace_subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout.clone()) ..GraphicsPipelineCreateInfo::layout(layout.clone())
}, },
) )
@@ -338,7 +367,7 @@ fn deferred_pipelines_recompile(
) )
.unwrap(); .unwrap();
(implicit_pipeline, normals_pipeline) (trace_pipeline, normals_pipeline)
} }
fn create_csg() -> SSATape { fn create_csg() -> SSATape {
@@ -406,7 +435,7 @@ fn create_csg() -> SSATape {
tape tape
} }
fn interval_check(csg: &mut CSG, material: u32, time: f32, frame_index: usize) { fn interval_check(csg: &CSG, material: u32, time: f32, frame_index: usize) {
const INTERPRET_INPUT_X: interpreter::Value = const INTERPRET_INPUT_X: interpreter::Value =
interpreter::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]); interpreter::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]);
const INTERPRET_INPUT_Y: interpreter::Value = const INTERPRET_INPUT_Y: interpreter::Value =
@@ -430,8 +459,12 @@ fn interval_check(csg: &mut CSG, material: u32, time: f32, frame_index: usize) {
.mul_add(INTERPRET_MUL, INTERPRET_ADD) .mul_add(INTERPRET_MUL, INTERPRET_ADD)
.to_array(); .to_array();
let highest_corner = Vec3::new(interpreter_out[0], interpreter_out[1], interpreter_out[2]); const EPSILON: f32 = 0.1;
let lowest_corner = Vec3::new(interpreter_out[3], interpreter_out[4], interpreter_out[5]);
let highest_corner =
Vec3::new(interpreter_out[0], interpreter_out[1], interpreter_out[2]) + EPSILON;
let lowest_corner =
Vec3::new(interpreter_out[3], interpreter_out[4], interpreter_out[5]) - EPSILON;
const XDIM: usize = 16; const XDIM: usize = 16;
const YDIM: usize = 16; const YDIM: usize = 16;
+6 -1
View File
@@ -10,9 +10,14 @@ layout(depth_greater) out float gl_FragDepth;
layout(location = 0) out uint material; layout(location = 0) out uint material;
const float EPSILON = .001; const float EPSILON = .001;
float FARPLANE = length(object_uniforms.dimensions / 16.); float FARPLANE = SPEC_BRUTE_FORCE ? length(object_uniforms.dimensions) : length(object_uniforms.dimensions / 16.);
void main() { void main() {
if (SPEC_BOUNDING_BOXES) {
material = object_uniforms.material;
return;
}
vec3 raypos = pos.xyz; vec3 raypos = pos.xyz;
vec3 raydir = normalize(raypos - (pc.inv_world * vec4(camera_uniforms.campos_and_time.xyz, 1)).xyz); vec3 raydir = normalize(raypos - (pc.inv_world * vec4(camera_uniforms.campos_and_time.xyz, 1)).xyz);
+50
View File
@@ -0,0 +1,50 @@
#version 460
#include "include.glsl"
#include "implicit_include.glsl"
layout(location = 0) in vec3 position;
layout(location = 0) out vec4 pos;
void main() {
uint base_index = gl_InstanceIndex; //gl_BaseInstance;
if (SPEC_BRUTE_FORCE) {
if (base_index > 0) {
gl_Position = vec4(0.0 / 0.0);
return;
}
pos = vec4((position * object_uniforms.dimensions) + object_uniforms.lowest_corner, 1.);
} else {
vec3 internal_pos = vec3(
float((base_index >> 8) & 15) / 16.0,
float((base_index >> 4) & 15) / 16.0,
float((base_index >> 0) & 15) / 16.0
);
bool enable;
switch ((base_index >> 5) & 3) {
default:
case 0:
enable = (object_uniforms.enable[base_index >> 7].x & (1 << (base_index & 31))) != 0;
break;
case 1:
enable = (object_uniforms.enable[base_index >> 7].y & (1 << (base_index & 31))) != 0;
break;
case 2:
enable = (object_uniforms.enable[base_index >> 7].z & (1 << (base_index & 31))) != 0;
break;
case 3:
enable = (object_uniforms.enable[base_index >> 7].w & (1 << (base_index & 31))) != 0;
break;
}
if (!enable) {
gl_Position = vec4(0.0 / 0.0);
return;
}
pos = vec4((((position / 16.0) + internal_pos) * object_uniforms.dimensions) + object_uniforms.lowest_corner, 1.);
}
gl_Position = camera_uniforms.proj_view * pc.world * pos;
}