refactor: remove dead input and readback paths
Amp-Thread-ID: https://ampcode.com/threads/T-019f9d91-77c1-7206-a60f-ed6554ce92ab Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -21,7 +21,6 @@ web-sys = { version = "0.3.77", features = [
|
|||||||
"MouseEvent",
|
"MouseEvent",
|
||||||
"PointerEvent",
|
"PointerEvent",
|
||||||
"WheelEvent",
|
"WheelEvent",
|
||||||
"KeyboardEvent",
|
|
||||||
"Worker",
|
"Worker",
|
||||||
"DedicatedWorkerGlobalScope",
|
"DedicatedWorkerGlobalScope",
|
||||||
"Event",
|
"Event",
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ pub struct EventListeners {
|
|||||||
pub click_listener: Option<Closure<dyn FnMut(web_sys::MouseEvent)>>,
|
pub click_listener: Option<Closure<dyn FnMut(web_sys::MouseEvent)>>,
|
||||||
pub wheel_listener: Option<Closure<dyn FnMut(web_sys::WheelEvent)>>,
|
pub wheel_listener: Option<Closure<dyn FnMut(web_sys::WheelEvent)>>,
|
||||||
pub contextmenu_listener: Option<Closure<dyn FnMut(web_sys::MouseEvent)>>,
|
pub contextmenu_listener: Option<Closure<dyn FnMut(web_sys::MouseEvent)>>,
|
||||||
pub keyboard_listener: Option<Closure<dyn FnMut(web_sys::KeyboardEvent)>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
@@ -34,7 +33,6 @@ impl EventListeners {
|
|||||||
click_listener: None,
|
click_listener: None,
|
||||||
wheel_listener: None,
|
wheel_listener: None,
|
||||||
contextmenu_listener: None,
|
contextmenu_listener: None,
|
||||||
keyboard_listener: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,26 +151,12 @@ pub fn setup_event_listeners(
|
|||||||
contextmenu_listener.as_ref().unchecked_ref(),
|
contextmenu_listener.as_ref().unchecked_ref(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let keyboard_worker_chan = worker_chan.clone();
|
|
||||||
let keyboard_listener: Closure<dyn FnMut(web_sys::KeyboardEvent)> =
|
|
||||||
Closure::new(move |event: web_sys::KeyboardEvent| {
|
|
||||||
use crate::message::KeyboardMessage;
|
|
||||||
|
|
||||||
let keyboard_event_data = KeyboardMessage::from_evt(event);
|
|
||||||
|
|
||||||
let _ = keyboard_worker_chan.send(WindowEvent::Keyboard(keyboard_event_data));
|
|
||||||
});
|
|
||||||
|
|
||||||
window
|
|
||||||
.add_event_listener_with_callback("keydown", keyboard_listener.as_ref().unchecked_ref())?;
|
|
||||||
|
|
||||||
Ok(EventListeners {
|
Ok(EventListeners {
|
||||||
resize_listener: Some(resize_listener),
|
resize_listener: Some(resize_listener),
|
||||||
pointer_listener: Some(pointer_listener),
|
pointer_listener: Some(pointer_listener),
|
||||||
click_listener: Some(click_listener),
|
click_listener: Some(click_listener),
|
||||||
wheel_listener: Some(wheel_listener),
|
wheel_listener: Some(wheel_listener),
|
||||||
contextmenu_listener: Some(contextmenu_listener),
|
contextmenu_listener: Some(contextmenu_listener),
|
||||||
keyboard_listener: Some(keyboard_listener),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,20 +42,6 @@ pub enum WindowEvent {
|
|||||||
PointerMove(MouseMessage),
|
PointerMove(MouseMessage),
|
||||||
PointerClick(MouseMessage),
|
PointerClick(MouseMessage),
|
||||||
PointerWheel(WheelMessage),
|
PointerWheel(WheelMessage),
|
||||||
Keyboard(KeyboardMessage),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display for WindowEvent
|
|
||||||
impl fmt::Display for WindowEvent {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
WindowEvent::Resize(msg) => write!(f, "Resize: {:?}", msg),
|
|
||||||
WindowEvent::PointerMove(msg) => write!(f, "PointerMove: {:?}", msg),
|
|
||||||
WindowEvent::PointerClick(msg) => write!(f, "PointerClick: {:?}", msg),
|
|
||||||
WindowEvent::PointerWheel(msg) => write!(f, "PointerWheel: {:?}", msg),
|
|
||||||
WindowEvent::Keyboard(msg) => write!(f, "Keyboard: {:?}", msg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -68,10 +54,7 @@ pub struct ResizeMessage {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MouseMessage {
|
pub struct MouseMessage {
|
||||||
pub scale_factor: f64,
|
pub scale_factor: f64,
|
||||||
pub button: f64,
|
|
||||||
pub buttons: u16,
|
pub buttons: u16,
|
||||||
pub client_x: f64,
|
|
||||||
pub client_y: f64,
|
|
||||||
pub movement_x: f64,
|
pub movement_x: f64,
|
||||||
pub movement_y: f64,
|
pub movement_y: f64,
|
||||||
pub offset_x: f64,
|
pub offset_x: f64,
|
||||||
@@ -84,10 +67,7 @@ impl MouseMessage {
|
|||||||
let window = web_sys::window().unwrap();
|
let window = web_sys::window().unwrap();
|
||||||
Self {
|
Self {
|
||||||
scale_factor: window.device_pixel_ratio(),
|
scale_factor: window.device_pixel_ratio(),
|
||||||
button: event.button() as f64,
|
|
||||||
buttons: event.buttons(),
|
buttons: event.buttons(),
|
||||||
client_x: event.client_x() as f64,
|
|
||||||
client_y: event.client_y() as f64,
|
|
||||||
movement_x: event.movement_x() as f64,
|
movement_x: event.movement_x() as f64,
|
||||||
movement_y: event.movement_y() as f64,
|
movement_y: event.movement_y() as f64,
|
||||||
offset_x: event.offset_x() as f64,
|
offset_x: event.offset_x() as f64,
|
||||||
@@ -113,33 +93,6 @@ impl WheelMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct KeyboardMessage {
|
|
||||||
pub key: String,
|
|
||||||
pub code: String,
|
|
||||||
pub alt_key: bool,
|
|
||||||
pub ctrl_key: bool,
|
|
||||||
pub meta_key: bool,
|
|
||||||
pub shift_key: bool,
|
|
||||||
pub location: u32,
|
|
||||||
pub repeat: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KeyboardMessage {
|
|
||||||
pub fn from_evt(event: web_sys::KeyboardEvent) -> Self {
|
|
||||||
Self {
|
|
||||||
key: event.key(),
|
|
||||||
code: event.code(),
|
|
||||||
alt_key: event.alt_key(),
|
|
||||||
ctrl_key: event.ctrl_key(),
|
|
||||||
meta_key: event.meta_key(),
|
|
||||||
shift_key: event.shift_key(),
|
|
||||||
location: event.location(),
|
|
||||||
repeat: event.repeat(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DrainEventError {
|
pub enum DrainEventError {
|
||||||
BorrowError(BorrowMutError),
|
BorrowError(BorrowMutError),
|
||||||
|
|||||||
@@ -136,13 +136,14 @@ pub fn generate_wgsl(plan: &InstanceTraversalPlan) -> Result<String, String> {
|
|||||||
fixed_index(*index, 32, "u32 bit projection")?;
|
fixed_index(*index, 32, "u32 bit projection")?;
|
||||||
format!("(({} & (1u<<{}u))!=0u)", x(*value), index)
|
format!("(({} & (1u<<{}u))!=0u)", x(*value), index)
|
||||||
}
|
}
|
||||||
ExpressionOp::U32Construct { bits } => bits
|
ExpressionOp::U32Construct { bits } => format!(
|
||||||
.iter()
|
"({})",
|
||||||
|
bits.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(bit, id)| format!("select(0u,{}u,{})", 1u32 << bit, x(*id)))
|
.map(|(bit, id)| format!("select(0u,{}u,{})", 1u32 << bit, x(*id)))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("|")
|
.join("|")
|
||||||
.pipe(|terms| format!("({terms})")),
|
),
|
||||||
ExpressionOp::AabbMin { aabb } => format!("{}.min", x(*aabb)),
|
ExpressionOp::AabbMin { aabb } => format!("{}.min", x(*aabb)),
|
||||||
ExpressionOp::AabbMax { aabb } => format!("{}.max", x(*aabb)),
|
ExpressionOp::AabbMax { aabb } => format!("{}.max", x(*aabb)),
|
||||||
ExpressionOp::FrustumCulled { local_aabb, .. } => {
|
ExpressionOp::FrustumCulled { local_aabb, .. } => {
|
||||||
@@ -201,13 +202,6 @@ fn matrix_literal<const N: usize>(name: &str, columns: &[[f32; N]; N]) -> Result
|
|||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(format!("{name}({})", values.join(",")))
|
Ok(format!("{name}({})", values.join(",")))
|
||||||
}
|
}
|
||||||
trait Pipe: Sized {
|
|
||||||
fn pipe<R>(self, f: impl FnOnce(Self) -> R) -> R {
|
|
||||||
f(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> Pipe for T {}
|
|
||||||
|
|
||||||
pub fn dispatch_count(instances: u32, pipelines: u32) -> u32 {
|
pub fn dispatch_count(instances: u32, pipelines: u32) -> u32 {
|
||||||
if pipelines == 0 {
|
if pipelines == 0 {
|
||||||
0
|
0
|
||||||
@@ -403,6 +397,19 @@ impl TraversalGpu {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::render_graph::{Expression, ExpressionPlan, NodeOutputRef};
|
||||||
|
|
||||||
|
fn expression(semantic_type: SemanticType, op: ExpressionOp) -> Expression {
|
||||||
|
Expression {
|
||||||
|
semantic_type,
|
||||||
|
op,
|
||||||
|
origin: NodeOutputRef {
|
||||||
|
node: "test".into(),
|
||||||
|
socket: "value".into(),
|
||||||
|
},
|
||||||
|
mesh_provenance: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pipeline_major_offsets_and_single_dispatch_are_deterministic() {
|
fn pipeline_major_offsets_and_single_dispatch_are_deterministic() {
|
||||||
@@ -424,4 +431,44 @@ mod tests {
|
|||||||
assert!(fixed_index(3, 3, "vector projection").is_err());
|
assert!(fixed_index(3, 3, "vector projection").is_err());
|
||||||
assert_eq!(wgsl_type(&SemanticType::Mat4).unwrap(), "mat4x4<f32>");
|
assert_eq!(wgsl_type(&SemanticType::Mat4).unwrap(), "mat4x4<f32>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn u32_construct_wgsl_is_parenthesized() {
|
||||||
|
let plan = InstanceTraversalPlan {
|
||||||
|
mesh: 0,
|
||||||
|
expressions: ExpressionPlan {
|
||||||
|
expressions: vec![
|
||||||
|
expression(
|
||||||
|
SemanticType::Bool,
|
||||||
|
ExpressionOp::Literal {
|
||||||
|
literal: TypedLiteral::Bool(true),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
expression(
|
||||||
|
SemanticType::Bool,
|
||||||
|
ExpressionOp::Literal {
|
||||||
|
literal: TypedLiteral::Bool(false),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
expression(
|
||||||
|
SemanticType::U32,
|
||||||
|
ExpressionOp::U32Construct {
|
||||||
|
bits: vec![
|
||||||
|
crate::render_graph::ExprId(0),
|
||||||
|
crate::render_graph::ExprId(1),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
pipelines: vec![],
|
||||||
|
requires_camera: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let wgsl = generate_wgsl(&plan).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
wgsl.lines().find(|line| line.starts_with("let e2=")),
|
||||||
|
Some("let e2=(select(0u,1u,e0)|select(0u,2u,e1));")
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use std::{cell::RefCell, rc::Rc, sync::mpsc::Receiver};
|
use std::{cell::RefCell, rc::Rc, sync::mpsc::Receiver};
|
||||||
|
|
||||||
use futures::channel::oneshot;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use ultraviolet::Vec4;
|
|
||||||
use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
|
use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
|
||||||
use wasm_bindgen_futures::spawn_local;
|
use wasm_bindgen_futures::spawn_local;
|
||||||
use web_sys::DedicatedWorkerGlobalScope;
|
use web_sys::DedicatedWorkerGlobalScope;
|
||||||
@@ -1632,7 +1630,7 @@ impl<T: Scene + 'static> Renderer<T> {
|
|||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: DEPTH_FORMAT,
|
format: DEPTH_FORMAT,
|
||||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC,
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
view_formats: &[],
|
view_formats: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2860,98 +2858,6 @@ impl<T: Scene + 'static> Renderer<T> {
|
|||||||
let _ = global.post_message(&value);
|
let _ = global.post_message(&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_pixel_from_texture(&self, x: u32, y: u32) -> Vec4 {
|
|
||||||
let width = self.context.depth_texture.width();
|
|
||||||
let height = self.context.depth_texture.height();
|
|
||||||
|
|
||||||
if width == 0 || height == 0 {
|
|
||||||
log::warn!("Depth texture has zero extent ({} x {})", width, height);
|
|
||||||
return Vec4::zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate coordinates
|
|
||||||
if x >= width || y >= height {
|
|
||||||
log::warn!(
|
|
||||||
"Pixel coordinates ({}, {}) out of bounds for texture size {}x{}",
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
);
|
|
||||||
return Vec4::zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
let pixel_size = std::mem::size_of::<f32>() as u32;
|
|
||||||
let unpadded_row_bytes = width * pixel_size;
|
|
||||||
let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
|
|
||||||
let padded_row_bytes = if unpadded_row_bytes % align == 0 {
|
|
||||||
unpadded_row_bytes
|
|
||||||
} else {
|
|
||||||
(unpadded_row_bytes / align + 1) * align
|
|
||||||
};
|
|
||||||
let buffer_size = padded_row_bytes as u64 * height as u64;
|
|
||||||
let buffer = self.context.device.create_buffer(&wgpu::BufferDescriptor {
|
|
||||||
label: Some("depth pixel read buffer"),
|
|
||||||
size: buffer_size,
|
|
||||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
|
|
||||||
mapped_at_creation: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Copy just the single pixel
|
|
||||||
let mut encoder =
|
|
||||||
self.context
|
|
||||||
.device
|
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
|
||||||
label: Some("copy depth pixel to buffer"),
|
|
||||||
});
|
|
||||||
|
|
||||||
encoder.copy_texture_to_buffer(
|
|
||||||
wgpu::TexelCopyTextureInfo {
|
|
||||||
texture: &self.context.depth_texture,
|
|
||||||
mip_level: 0,
|
|
||||||
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
|
|
||||||
aspect: wgpu::TextureAspect::DepthOnly,
|
|
||||||
},
|
|
||||||
wgpu::TexelCopyBufferInfo {
|
|
||||||
buffer: &buffer,
|
|
||||||
layout: wgpu::TexelCopyBufferLayout {
|
|
||||||
offset: 0,
|
|
||||||
bytes_per_row: Some(padded_row_bytes),
|
|
||||||
rows_per_image: Some(height),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wgpu::Extent3d {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
self.context.queue.submit(std::iter::once(encoder.finish()));
|
|
||||||
|
|
||||||
// Map the buffer and read the pixel
|
|
||||||
let slice = buffer.slice(..);
|
|
||||||
let (tx, rx) = oneshot::channel();
|
|
||||||
slice.map_async(wgpu::MapMode::Read, move |result| {
|
|
||||||
tx.send(result).unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Poll the device to process the mapping
|
|
||||||
|
|
||||||
rx.await.unwrap().unwrap();
|
|
||||||
let depth_value = {
|
|
||||||
let data = slice.get_mapped_range();
|
|
||||||
let row_pitch = padded_row_bytes as usize;
|
|
||||||
let byte_offset = y as usize * row_pitch + x as usize * pixel_size as usize;
|
|
||||||
let mut depth_bytes = [0u8; 4];
|
|
||||||
depth_bytes.copy_from_slice(&data[byte_offset..byte_offset + 4]);
|
|
||||||
f32::from_le_bytes(depth_bytes)
|
|
||||||
};
|
|
||||||
buffer.unmap();
|
|
||||||
|
|
||||||
Vec4::new(depth_value, 0.0, 0.0, 0.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn handle_event(renderer: Rc<RefCell<Self>>, event: WindowEvent) {
|
pub async fn handle_event(renderer: Rc<RefCell<Self>>, event: WindowEvent) {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::PointerMove(msg) => {
|
WindowEvent::PointerMove(msg) => {
|
||||||
@@ -2961,7 +2867,6 @@ impl<T: Scene + 'static> Renderer<T> {
|
|||||||
renderer.borrow_mut().resize(msg);
|
renderer.borrow_mut().resize(msg);
|
||||||
}
|
}
|
||||||
WindowEvent::PointerClick(msg) => {
|
WindowEvent::PointerClick(msg) => {
|
||||||
{
|
|
||||||
log::info!("click start");
|
log::info!("click start");
|
||||||
|
|
||||||
let mut r = renderer.borrow_mut();
|
let mut r = renderer.borrow_mut();
|
||||||
@@ -2970,27 +2875,10 @@ impl<T: Scene + 'static> Renderer<T> {
|
|||||||
r.scene.handle_mouse_click(x, y);
|
r.scene.handle_mouse_click(x, y);
|
||||||
log::info!("clicked");
|
log::info!("clicked");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read pixel from depth texture at click coordinates
|
|
||||||
// let renderer_clone = renderer.clone();
|
|
||||||
// let x_coord = msg.offset_x as u32;
|
|
||||||
// let y_coord = msg.offset_y as u32;
|
|
||||||
// let pixel_value = renderer_clone
|
|
||||||
// .borrow()
|
|
||||||
// .read_pixel_from_texture(x_coord, y_coord)
|
|
||||||
// .await;
|
|
||||||
// log::info!(
|
|
||||||
// "Depth pixel at ({}, {}): {:?}",
|
|
||||||
// x_coord,
|
|
||||||
// y_coord,
|
|
||||||
// pixel_value
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
WindowEvent::PointerWheel(msg) => {
|
WindowEvent::PointerWheel(msg) => {
|
||||||
let mut r = renderer.borrow_mut();
|
let mut r = renderer.borrow_mut();
|
||||||
r.scene.handle_zoom(msg.delta_y_pixels);
|
r.scene.handle_zoom(msg.delta_y_pixels);
|
||||||
}
|
}
|
||||||
WindowEvent::Keyboard(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user