reduce register pressure

This commit is contained in:
2025-07-05 00:32:58 +01:00
parent 1a200ea65e
commit 362d2e7338
8 changed files with 129 additions and 108 deletions
+1 -2
View File
@@ -18,6 +18,5 @@ void main() {
} }
pos = vec4((((position / 8.0) + internal_pos) * pc.dimensions) + pc.lowest_corner, 1.); pos = vec4((((position / 8.0) + internal_pos) * pc.dimensions) + pc.lowest_corner, 1.);
vec4 worldview = camera_uniforms.view * pc.world * pos; gl_Position = camera_uniforms.proj_view * pc.world * pos;
gl_Position = camera_uniforms.proj * worldview;
} }
+3 -2
View File
@@ -3,6 +3,7 @@
layout(push_constant) uniform PushConstantData { layout(push_constant) uniform PushConstantData {
mat4 world; mat4 world;
mat4 inv_world;
vec3 dimensions; vec3 dimensions;
vec3 lowest_corner; vec3 lowest_corner;
uint enable[16]; uint enable[16];
@@ -16,8 +17,8 @@ layout(set = 0, binding = 0) uniform Lights {
} light_uniforms; } light_uniforms;
layout(set = 0, binding = 1) uniform Camera { layout(set = 0, binding = 1) uniform Camera {
mat4 view; mat4 proj_view;
mat4 proj; mat4 inv_proj_view;
vec4 campos_and_time; vec4 campos_and_time;
} camera_uniforms; } camera_uniforms;
+11 -6
View File
@@ -9,12 +9,17 @@ layout(input_attachment_index = 2, set = 1, binding = 2) uniform subpassInput u_
layout(location = 0) in vec2 v_pos; layout(location = 0) in vec2 v_pos;
layout(location = 0) out vec4 f_color; layout(location = 0) out vec4 f_color;
vec3 WorldPosFromDepth(float depth) { vec3 calculate_view_position(float depth)
vec4 clipSpacePosition = vec4(v_pos, depth, 1.0); {
vec4 view_position = camera_uniforms.inv_proj_view * vec4(v_pos, depth, 1.0);
//vec4 view_position = vec4(
// fma(camera_uniforms.inv_proj_view[0][0], v_pos.x, camera_uniforms.inv_proj_view[3][0]),
// fma(camera_uniforms.inv_proj_view[1][1], v_pos.y, camera_uniforms.inv_proj_view[3][1]),
// fma(camera_uniforms.inv_proj_view[2][2], depth, camera_uniforms.inv_proj_view[3][2]),
// fma(camera_uniforms.inv_proj_view[2][3], depth, camera_uniforms.inv_proj_view[3][3])
// );
vec4 worldSpacePosition = inverse(camera_uniforms.proj * camera_uniforms.view) * clipSpacePosition; return (view_position.xyz / view_position.w);
return worldSpacePosition.xyz /= worldSpacePosition.w;
} }
vec3 shading(vec3 normal, vec3 position) vec3 shading(vec3 normal, vec3 position)
@@ -37,6 +42,6 @@ void main() {
if (depth == 1.0) { if (depth == 1.0) {
discard; discard;
} }
vec3 position = WorldPosFromDepth(depth); vec3 position = calculate_view_position(depth);
f_color = vec4(col * shading(normal, position), 1.0); f_color = vec4(col * shading(normal, position), 1.0);
} }
+94 -84
View File
@@ -189,6 +189,7 @@ struct App {
command_buffer_allocator: Arc<StandardCommandBufferAllocator>, command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
uniform_buffer_allocator: SubbufferAllocator, uniform_buffer_allocator: SubbufferAllocator,
pipeline_cache: Arc<PipelineCache>, pipeline_cache: Arc<PipelineCache>,
draw_gui: bool,
gstate: GState, gstate: GState,
csg_count: usize, csg_count: usize,
previous_debug: PreviousDebug, previous_debug: PreviousDebug,
@@ -305,9 +306,7 @@ impl App {
_ => 5, _ => 5,
} }
}) })
.expect( .expect("No suitable physical device found.");
"No suitable physical device found.",
);
// Some little debug infos. // Some little debug infos.
info!( info!(
@@ -442,6 +441,7 @@ impl App {
uniform_buffer_allocator, uniform_buffer_allocator,
pipeline_cache, pipeline_cache,
csg_count: gstate.csg.len(), csg_count: gstate.csg.len(),
draw_gui: true,
gstate, gstate,
previous_debug: PreviousDebug::default(), previous_debug: PreviousDebug::default(),
cstate, cstate,
@@ -751,74 +751,82 @@ impl ApplicationHandler for App {
let rcx_clone = self.rcx.clone(); let rcx_clone = self.rcx.clone();
let mut rcx_lock = rcx_clone.lock().unwrap(); let mut rcx_lock = rcx_clone.lock().unwrap();
let rcx = rcx_lock.as_mut().unwrap(); let rcx = rcx_lock.as_mut().unwrap();
if !rcx.gui.update(&event) { if self.draw_gui {
match &event { if rcx.gui.update(&event) {
WindowEvent::CloseRequested => { return;
event_loop.exit(); }
}
match &event {
WindowEvent::CloseRequested => {
event_loop.exit();
},
WindowEvent::Resized(_) => {
rcx.recreate_swapchain = true;
},
WindowEvent::ScaleFactorChanged { .. } => {
rcx.recreate_swapchain = true;
},
WindowEvent::DroppedFile(_file) => {
todo!()
},
WindowEvent::MouseInput {
device_id: d,
state: s,
button: b,
..
} => {
trace!("MOUSE {d:?}, {s:?}, {b:?}");
if b == &MouseButton::Right {
self.cstate.looking = s == &ElementState::Pressed;
}
},
WindowEvent::KeyboardInput {
device_id: _,
event: input,
is_synthetic: _,
} => match input.physical_key {
PhysicalKey::Code(KeyCode::KeyW) => {
self.cstate.keys.w = input.state == ElementState::Pressed;
}, },
WindowEvent::Resized(_) => { PhysicalKey::Code(KeyCode::KeyS) => {
rcx.recreate_swapchain = true; self.cstate.keys.s = input.state == ElementState::Pressed;
}, },
WindowEvent::ScaleFactorChanged { .. } => { PhysicalKey::Code(KeyCode::KeyA) => {
rcx.recreate_swapchain = true; self.cstate.keys.a = input.state == ElementState::Pressed;
}, },
WindowEvent::DroppedFile(_file) => { PhysicalKey::Code(KeyCode::KeyD) => {
todo!() self.cstate.keys.d = input.state == ElementState::Pressed;
}, },
WindowEvent::MouseInput { PhysicalKey::Code(KeyCode::ShiftLeft) => {
device_id: d, self.cstate.looking = input.state == ElementState::Pressed;
state: s, },
button: b, PhysicalKey::Code(KeyCode::Space) => {
.. if input.state == ElementState::Pressed {
} => { self.thread_work_creation
trace!("MOUSE {d:?}, {s:?}, {b:?}"); .send(WorkItem::CreateCSG(
if b == &MouseButton::Right { self.device.clone(),
self.cstate.looking = s == &ElementState::Pressed; self.trace_module.clone(),
self.normals_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
self.previous_debug.clone(),
0,
))
.unwrap();
} }
}, },
WindowEvent::KeyboardInput { PhysicalKey::Code(KeyCode::KeyG) => {
device_id: _, if input.state == ElementState::Pressed {
event: input, self.draw_gui = !self.draw_gui;
is_synthetic: _, }
} => match input.physical_key {
PhysicalKey::Code(KeyCode::KeyW) => {
self.cstate.keys.w = input.state == ElementState::Pressed;
},
PhysicalKey::Code(KeyCode::KeyS) => {
self.cstate.keys.s = input.state == ElementState::Pressed;
},
PhysicalKey::Code(KeyCode::KeyA) => {
self.cstate.keys.a = input.state == ElementState::Pressed;
},
PhysicalKey::Code(KeyCode::KeyD) => {
self.cstate.keys.d = input.state == ElementState::Pressed;
},
PhysicalKey::Code(KeyCode::ShiftLeft) => {
self.cstate.looking = input.state == ElementState::Pressed;
},
PhysicalKey::Code(KeyCode::Space) => {
if input.state == ElementState::Pressed {
self.thread_work_creation
.send(WorkItem::CreateCSG(
self.device.clone(),
self.trace_module.clone(),
self.normals_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
self.previous_debug.clone(),
0,
))
.unwrap();
}
},
_ => {},
},
WindowEvent::RedrawRequested => {
self.redraw(rcx);
}, },
_ => {}, _ => {},
} },
WindowEvent::RedrawRequested => {
self.redraw(rcx);
},
_ => {},
} }
} }
@@ -885,8 +893,8 @@ impl App {
* 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 = implicit_vs::Camera {
view: view.to_cols_array_2d(), proj_view: (proj * view).to_cols_array_2d(),
proj: proj.to_cols_array_2d(), inv_proj_view: (proj * view).inverse().to_cols_array_2d(),
campos_and_time: [ campos_and_time: [
self.cstate.position.x, self.cstate.position.x,
self.cstate.position.y, self.cstate.position.y,
@@ -1096,9 +1104,7 @@ impl App {
.push_constants(csg.deferred_pipeline.layout().clone(), 0, push_constants[i]) .push_constants(csg.deferred_pipeline.layout().clone(), 0, push_constants[i])
.unwrap(); .unwrap();
for i in 0..(8 * 8 * 8) { unsafe { builder.draw(VERTEX_COUNT as u32, 8 * 8 * 8, 0, 0) }.unwrap();
unsafe { builder.draw(VERTEX_COUNT as u32, 1, 0, i) }.unwrap();
}
} }
} }
@@ -1196,21 +1202,23 @@ impl App {
rcx.render_start = Instant::now(); rcx.render_start = Instant::now();
let mut csg_needed = false; if self.draw_gui {
gui_up(&mut rcx.gui, &mut self.gstate, &mut csg_needed); let mut csg_needed = false;
if csg_needed { gui_up(&mut rcx.gui, &mut self.gstate, &mut csg_needed);
self.thread_work_creation if csg_needed {
.send(WorkItem::CreateCSG( self.thread_work_creation
self.device.clone(), .send(WorkItem::CreateCSG(
self.trace_module.clone(), self.device.clone(),
self.normals_module.clone(), self.trace_module.clone(),
rcx.render_pass.clone(), self.normals_module.clone(),
self.pipeline_cache.clone(), rcx.render_pass.clone(),
rcx.shader_modules.clone(), self.pipeline_cache.clone(),
self.previous_debug.clone(), rcx.shader_modules.clone(),
-1, self.previous_debug.clone(),
)) -1,
.unwrap(); ))
.unwrap();
}
} }
let mut push_constants = vec![PushConstantData::default(); self.gstate.csg.len()]; let mut push_constants = vec![PushConstantData::default(); self.gstate.csg.len()];
@@ -1352,7 +1360,9 @@ impl App {
self.add_commands_primary_subpass(&mut builder); self.add_commands_primary_subpass(&mut builder);
self.add_commands_lighting_pass(&mut builder, rcx, lighting_set1, lighting_set2); self.add_commands_lighting_pass(&mut builder, rcx, lighting_set1, lighting_set2);
self.add_commands_secondary_subpass(&mut builder); self.add_commands_secondary_subpass(&mut builder);
self.add_commands_gui(&mut builder, rcx, window_size); if self.draw_gui {
self.add_commands_gui(&mut builder, rcx, window_size);
}
builder.end_render_pass(Default::default()).unwrap(); builder.end_render_pass(Default::default()).unwrap();
let command_buffer = builder.build().unwrap(); let command_buffer = builder.build().unwrap();
+11 -6
View File
@@ -16,12 +16,17 @@ float scene(vec4 p) {
return length(p.xyz) - 1.0; return length(p.xyz) - 1.0;
} }
vec3 WorldPosFromDepth(float depth) { vec3 calculate_view_position(float depth)
vec4 clipSpacePosition = vec4(v_pos, depth, 1.0); {
vec4 view_position = camera_uniforms.inv_proj_view * vec4(v_pos, depth, 1.0);
//vec4 view_position = vec4(
// fma(camera_uniforms.inv_proj_view[0][0], v_pos.x, camera_uniforms.inv_proj_view[3][0]),
// fma(camera_uniforms.inv_proj_view[1][1], v_pos.y, camera_uniforms.inv_proj_view[3][1]),
// fma(camera_uniforms.inv_proj_view[2][2], depth, camera_uniforms.inv_proj_view[3][2]),
// fma(camera_uniforms.inv_proj_view[2][3], depth, camera_uniforms.inv_proj_view[3][3])
// );
vec4 worldSpacePosition = inverse(camera_uniforms.proj * camera_uniforms.view) * clipSpacePosition; return (view_position.xyz / view_position.w);
return worldSpacePosition.xyz /= worldSpacePosition.w;
} }
const float EPSILON = .0001; const float EPSILON = .0001;
@@ -44,7 +49,7 @@ void main() {
if (depth == 1.0) { if (depth == 1.0) {
discard; discard;
} }
vec3 position = (inverse(pc.world) * vec4(WorldPosFromDepth(depth), 1.0)).xyz; vec3 position = (pc.inv_world * vec4(calculate_view_position(depth), 1.0)).xyz;
vec3 n = getNormal(position); vec3 n = getNormal(position);
-2
View File
@@ -1,5 +1,3 @@
use std::sync::Arc;
use egui::ahash::HashMapExt; use egui::ahash::HashMapExt;
use foldhash::HashMap; use foldhash::HashMap;
use rspirv::{dr::Module, spirv}; use rspirv::{dr::Module, spirv};
+7 -4
View File
@@ -118,6 +118,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
WorkItem::GetPushConstants(csg, time, index) => { WorkItem::GetPushConstants(csg, time, index) => {
let mut push_constants = PushConstantData { let mut push_constants = PushConstantData {
world: Mat4::IDENTITY.to_cols_array_2d(), world: Mat4::IDENTITY.to_cols_array_2d(),
inv_world: Mat4::IDENTITY.to_cols_array_2d(),
dimensions: Vec3::ONE.to_array().into(), dimensions: Vec3::ONE.to_array().into(),
lowest_corner: Vec3::ZERO.into(), lowest_corner: Vec3::ZERO.into(),
enable: [0; 16], enable: [0; 16],
@@ -126,19 +127,21 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
let csg = csg.read().unwrap(); let csg = csg.read().unwrap();
push_constants.world = (Mat4::from_translation(csg.pos * 0.01) let world = Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler( * Mat4::from_euler(
EulerRot::XYZ, EulerRot::XYZ,
csg.rot.x.to_radians(), csg.rot.x.to_radians(),
csg.rot.y.to_radians(), csg.rot.y.to_radians(),
csg.rot.z.to_radians(), csg.rot.z.to_radians(),
) )
* Mat4::from_scale(csg.scale * 2.0)) * Mat4::from_scale(csg.scale * 2.0);
.to_cols_array_2d();
push_constants.world = world.to_cols_array_2d();
push_constants.inv_world = world.inverse().to_cols_array_2d();
interval_check(&csg, &mut push_constants, time); interval_check(&csg, &mut push_constants, time);
push_constants.material = index as _; push_constants.material = index as u32 + 1;
send.send(WorkComplete::GetPushConstants(push_constants, index)) send.send(WorkComplete::GetPushConstants(push_constants, index))
.unwrap(); .unwrap();
+2 -2
View File
@@ -38,13 +38,13 @@ void main() {
vec3 raypos = pos.xyz; vec3 raypos = pos.xyz;
vec3 p; vec3 p;
vec3 raydir = normalize(raypos - (inverse(pc.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);
vec2 td = spheretracing(raypos, raydir, p); vec2 td = spheretracing(raypos, raydir, p);
if (td.y < EPSILON) if (td.y < EPSILON)
{ {
vec4 tpoint = camera_uniforms.proj * camera_uniforms.view * pc.world * vec4(p, 1); vec4 tpoint = camera_uniforms.proj_view * pc.world * vec4(p, 1);
gl_FragDepth = (tpoint.z / tpoint.w); gl_FragDepth = (tpoint.z / tpoint.w);
material = pc.material; material = pc.material;
} }