diff --git a/luisa_compute/Cargo.toml b/luisa_compute/Cargo.toml index 9756d5a..412430d 100644 --- a/luisa_compute/Cargo.toml +++ b/luisa_compute/Cargo.toml @@ -16,8 +16,8 @@ parking_lot = "0.12.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -winit = "0.28.3" -raw-window-handle = "0.5.1" +winit = "0.29.4" +raw-window-handle = "0.6.0" indexmap = "2.0.0" luisa_compute_api_types = { path = "../luisa_compute_sys/LuisaCompute/src/rust/luisa_compute_api_types", version = "0.1.1-alpha.1" } diff --git a/luisa_compute/examples/denoiser.rs b/luisa_compute/examples/denoiser.rs index 3cf7d75..0fa2653 100644 --- a/luisa_compute/examples/denoiser.rs +++ b/luisa_compute/examples/denoiser.rs @@ -6,7 +6,7 @@ use luisa_compute_api_types::StreamTag; use rand::Rng; use std::time::Instant; use winit::event::{Event as WinitEvent, WindowEvent}; -use winit::event_loop::EventLoop; +use winit::event_loop::{ControlFlow, EventLoop}; use luisa::lang::types::vector::alias::*; use luisa::lang::types::vector::*; @@ -555,7 +555,7 @@ fn run_pt(device: Device) { .collect::>(); seed_img.view(0).copy_from(&seed_buffer); } - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - Ray Tracing") .with_inner_size(winit::dpi::LogicalSize::new(img_w, img_h)) @@ -572,72 +572,77 @@ fn run_pt(device: Device) { 3, ); let display_img = device.create_tex2d::(swapchain.pixel_storage(), img_w, img_h, 1); - event_loop.run(move |event, _, control_flow| { - control_flow.set_poll(); - match event { - WinitEvent::WindowEvent { - event: WindowEvent::CloseRequested, - window_id, - } if window_id == window.id() => { - // FIXME: support half4 pixel storage - let mut img_buffer = vec![[0u8; 4]; (img_w * img_h) as usize]; - { - let scope = device.default_stream().scope(); - scope.submit([display_img.view(0).copy_to_async(&mut img_buffer)]); + event_loop.set_control_flow(ControlFlow::Poll); + event_loop + .run(move |event, elwt| { + match event { + WinitEvent::WindowEvent { + event: WindowEvent::CloseRequested, + window_id, + } if window_id == window.id() => { + // FIXME: support half4 pixel storage + let mut img_buffer = vec![[0u8; 4]; (img_w * img_h) as usize]; + { + let scope = device.default_stream().scope(); + scope.submit([display_img.view(0).copy_to_async(&mut img_buffer)]); + } + { + let img = image::RgbImage::from_fn(img_w, img_h, |x, y| { + let i = x + y * img_w; + let px = img_buffer[i as usize]; + Rgb([px[0], px[1], px[2]]) + }); + img.save("cbox.png").unwrap(); + } + elwt.exit(); } - { - let img = image::RgbImage::from_fn(img_w, img_h, |x, y| { - let i = x + y * img_w; - let px = img_buffer[i as usize]; - Rgb([px[0], px[1], px[2]]) - }); - img.save("cbox.png").unwrap(); + WinitEvent::AboutToWait => { + window.request_redraw(); } - control_flow.set_exit(); - } - WinitEvent::MainEventsCleared => { - window.request_redraw(); - } - WinitEvent::RedrawRequested(_) => { - let tic = Instant::now(); - { - let scope = device.default_stream().scope(); - scope.present(&swapchain, &display_img); - scope.submit([ - path_tracer.dispatch_async( - [img_w, img_h, 1], - &acc_img, - &albedo_img, - &normal_img, - &seed_img, - &accel, - &Uint2::new(img_w, img_h), - ), - acc_to_hdr.dispatch_async([img_w, img_h, 1], &acc_img, &hdr_img), - hdr_img.view(0).copy_to_buffer_async(&color_buf.view(..)), - albedo_img - .view(0) - .copy_to_buffer_async(&albedo_buf.view(..)), - normal_img - .view(0) - .copy_to_buffer_async(&normal_buf.view(..)), - ]); - denoiser.execute(true); - scope.submit([ - hdr_img.view(0).copy_from_buffer_async(&output_buf.view(..)), - display.dispatch_async([img_w, img_h, 1], &hdr_img, &display_img), - ]); + WinitEvent::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { + let tic = Instant::now(); + { + let scope = device.default_stream().scope(); + scope.present(&swapchain, &display_img); + scope.submit([ + path_tracer.dispatch_async( + [img_w, img_h, 1], + &acc_img, + &albedo_img, + &normal_img, + &seed_img, + &accel, + &Uint2::new(img_w, img_h), + ), + acc_to_hdr.dispatch_async([img_w, img_h, 1], &acc_img, &hdr_img), + hdr_img.view(0).copy_to_buffer_async(&color_buf.view(..)), + albedo_img + .view(0) + .copy_to_buffer_async(&albedo_buf.view(..)), + normal_img + .view(0) + .copy_to_buffer_async(&normal_buf.view(..)), + ]); + denoiser.execute(true); + scope.submit([ + hdr_img.view(0).copy_from_buffer_async(&output_buf.view(..)), + display.dispatch_async([img_w, img_h, 1], &hdr_img, &display_img), + ]); + } + let toc = Instant::now(); + let elapsed = (toc - tic).as_secs_f32(); + log::info!( + "time: {}ms {}ms/spp", + elapsed * 1e3, + elapsed * 1e3 / SPP_PER_DISPATCH as f32 + ); + window.request_redraw(); } - let toc = Instant::now(); - let elapsed = (toc - tic).as_secs_f32(); - log::info!( - "time: {}ms {}ms/spp", - elapsed * 1e3, - elapsed * 1e3 / SPP_PER_DISPATCH as f32 - ); - window.request_redraw(); + _ => (), } - _ => (), - } - }); + }) + .unwrap(); } diff --git a/luisa_compute/examples/fluid.rs b/luisa_compute/examples/fluid.rs index 95b1282..c502ad9 100644 --- a/luisa_compute/examples/fluid.rs +++ b/luisa_compute/examples/fluid.rs @@ -30,7 +30,7 @@ fn main() { "cpu" }); - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - Fluid") .with_inner_size(winit::dpi::LogicalSize::new(N_GRID, N_GRID)) @@ -225,7 +225,6 @@ fn main() { }), ); - let clear_pressure = Kernel::::new_async(&device, &|| { let idx = index(dispatch_id().xy()); p0.var().write(idx, 0.0f32); @@ -244,20 +243,22 @@ fn main() { ); }), ); - - event_loop.run(move |event, _, control_flow| { - control_flow.set_poll(); + event_loop.set_control_flow(ControlFlow::Poll); + event_loop.run(move |event, elwt| { match event { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, } if window_id == window.id() => { - *control_flow = ControlFlow::Exit; + elwt.exit(); } - Event::MainEventsCleared => { + Event::AboutToWait => { window.request_redraw(); } - Event::RedrawRequested(_) => { + Event::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { let tic = Instant::now(); { let scope = device.default_stream().scope(); @@ -330,5 +331,5 @@ fn main() { } _ => (), } - }); + }).unwrap(); } diff --git a/luisa_compute/examples/mpm.rs b/luisa_compute/examples/mpm.rs index 194a19c..e279bf0 100644 --- a/luisa_compute/examples/mpm.rs +++ b/luisa_compute/examples/mpm.rs @@ -63,7 +63,7 @@ fn main() { let grid_v = device.create_buffer::(N_GRID * N_GRID * 2); let grid_m = device.create_buffer::(N_GRID * N_GRID); - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - MPM") .with_inner_size(winit::dpi::LogicalSize::new(RESOLUTION, RESOLUTION)) @@ -94,14 +94,14 @@ fn main() { let clear_grid = Kernel::::new(&device, &|| { let idx = index(dispatch_id().xy()); - grid_v.var().write(idx * 2, 0.0f32); - grid_v.var().write(idx * 2 + 1, 0.0f32); - grid_m.var().write(idx, 0.0f32); + grid_v.write(idx * 2, 0.0f32); + grid_v.write(idx * 2 + 1, 0.0f32); + grid_m.write(idx, 0.0f32); }); let point_to_grid = Kernel::::new(&device, &|| { let p = dispatch_id().x; - let xp = x.var().read(p) / DX; + let xp = x.read(p) / DX; let base = (xp - 0.5f32).cast_i32(); let fx = xp - base.cast_f32(); @@ -110,10 +110,9 @@ fn main() { 0.75f32 - (fx - 1.0f32) * (fx - 1.0f32), 0.5f32 * (fx - 0.5f32) * (fx - 0.5f32), ]; - let stress = -4.0f32 * DT * E * P_VOL * (J.var().read(p) - 1.0f32) / (DX * DX); - let affine = - Mat2::diag_expr(Float2::expr(stress, stress)) + P_MASS as f32 * C.var().read(p); - let vp = v.var().read(p); + let stress = -4.0f32 * DT * E * P_VOL * (J.read(p) - 1.0f32) / (DX * DX); + let affine = Mat2::diag_expr(Float2::expr(stress, stress)) + P_MASS as f32 * C.read(p); + let vp = v.read(p); for_unrolled(0..9usize, |ii| { let (i, j) = (ii % 3, ii / 3); let offset = Int2::expr(i as i32, j as i32); @@ -132,10 +131,10 @@ fn main() { let i = index(coord); let v = Var::::zeroed(); v.store(Float2::expr( - grid_v.var().read(i * 2u32), - grid_v.var().read(i * 2u32 + 1u32), + grid_v.read(i * 2u32), + grid_v.read(i * 2u32 + 1u32), )); - let m = grid_m.var().read(i); + let m = grid_m.read(i); v.store(select(m > 0.0f32, v.load() / m, v.load())); let vx = v.load().x; @@ -150,13 +149,13 @@ fn main() { 0.0f32.expr(), vy, ); - grid_v.var().write(i * 2, vx); - grid_v.var().write(i * 2 + 1, vy); + grid_v.write(i * 2, vx); + grid_v.write(i * 2 + 1, vy); }); let grid_to_point = Kernel::::new(&device, &|| { let p = dispatch_id().x; - let xp = x.var().read(p) / DX; + let xp = x.read(p) / DX; let base = (xp - 0.5f32).cast_i32(); let fx = xp - base.cast_f32(); @@ -176,23 +175,20 @@ fn main() { let dpos = (offset.cast_f32() - fx) * DX.expr(); let weight = w[i].x * w[j].y; let idx = index((base + offset).cast_u32()); - let g_v = Float2::expr( - grid_v.var().read(idx * 2u32), - grid_v.var().read(idx * 2u32 + 1u32), - ); + let g_v = Float2::expr(grid_v.read(idx * 2u32), grid_v.read(idx * 2u32 + 1u32)); new_v.store(new_v.load() + weight * g_v); new_C.store(new_C.load() + 4.0f32 * weight * g_v.outer_product(dpos) / (DX * DX)); }); - v.var().write(p, new_v); - x.var().write(p, x.var().read(p) + new_v.load() * DT); + v.write(p, new_v); + x.write(p, x.read(p) + new_v.load() * DT); J.var() - .write(p, J.var().read(p) * (1.0f32 + DT * trace(new_C.load()))); - C.var().write(p, new_C); + .write(p, J.read(p) * (1.0f32 + DT * trace(new_C.load()))); + C.write(p, new_C); }); let clear_display = Kernel::::new(&device, &|| { - display.var().write( + display.write( dispatch_id().xy(), Float4::expr(0.1f32, 0.2f32, 0.3f32, 1.0f32), ); @@ -201,13 +197,13 @@ fn main() { let p = dispatch_id().x; for i in -1..=1 { for j in -1..=1 { - let pos = (x.var().read(p) * RESOLUTION as f32).cast_i32() + Int2::expr(i, j); + let pos = (x.read(p) * RESOLUTION as f32).cast_i32() + Int2::expr(i, j); if pos.x >= (0i32) && pos.x < (RESOLUTION as i32) && pos.y >= (0i32) && pos.y < (RESOLUTION as i32) { - display.var().write( + display.write( Uint2::expr(pos.x.cast_u32(), RESOLUTION - 1u32 - pos.y.cast_u32()), Float4::expr(0.4f32, 0.6f32, 0.6f32, 1.0f32), ); @@ -216,19 +212,22 @@ fn main() { } }); escape!({ - event_loop.run(move |event, _, control_flow| { - control_flow.set_poll(); + event_loop.set_control_flow(ControlFlow::Poll); + event_loop.run(move |event, elwt| { match event { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, } if window_id == window.id() => { - *control_flow = ControlFlow::Exit; + elwt.exit(); } - Event::MainEventsCleared => { + Event::AboutToWait => { window.request_redraw(); } - Event::RedrawRequested(_) => { + Event::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { let tic = Instant::now(); { let scope = device.default_stream().scope(); @@ -263,6 +262,6 @@ fn main() { } _ => (), } - }); + }).unwrap(); }); } diff --git a/luisa_compute/examples/path_tracer.rs b/luisa_compute/examples/path_tracer.rs index 38777ed..62370bb 100644 --- a/luisa_compute/examples/path_tracer.rs +++ b/luisa_compute/examples/path_tracer.rs @@ -4,13 +4,14 @@ use rand::Rng; use std::env::current_exe; use std::time::Instant; use winit::event::{Event as WinitEvent, WindowEvent}; -use winit::event_loop::EventLoop; +use winit::event_loop::{ControlFlow, EventLoop}; use luisa::lang::types::vector::alias::*; use luisa::lang::types::vector::*; use luisa::prelude::*; use luisa::rtx::{ - offset_ray_origin, Accel, AccelBuildRequest, AccelOption, AccelVar, Index, Ray, RayComps, AccelTraceOptions, TriangleInterpolate, + offset_ray_origin, Accel, AccelBuildRequest, AccelOption, AccelTraceOptions, AccelVar, Index, + Ray, RayComps, TriangleInterpolate, }; use luisa_compute as luisa; @@ -488,7 +489,7 @@ fn main() { .collect::>(); seed_img.view(0).copy_from(&seed_buffer); } - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - Ray Tracing") .with_inner_size(winit::dpi::LogicalSize::new(img_w, img_h)) @@ -505,58 +506,64 @@ fn main() { 3, ); let display_img = device.create_tex2d::(swapchain.pixel_storage(), img_w, img_h, 1); - event_loop.run(move |event, _, control_flow| { - control_flow.set_poll(); - match event { - WinitEvent::WindowEvent { - event: WindowEvent::CloseRequested, - window_id, - } if window_id == window.id() => { - // FIXME: support half4 pixel storage - let mut img_buffer = vec![[0u8; 4]; (img_w * img_h) as usize]; - { - let scope = device.default_stream().scope(); - scope.submit([display_img.view(0).copy_to_async(&mut img_buffer)]); + event_loop.set_control_flow(ControlFlow::Poll); + event_loop + .run(move |event, elwt| { + match event { + WinitEvent::WindowEvent { + event: WindowEvent::CloseRequested, + window_id, + } if window_id == window.id() => { + // FIXME: support half4 pixel storage + let mut img_buffer = vec![[0u8; 4]; (img_w * img_h) as usize]; + { + let scope = device.default_stream().scope(); + scope.submit([display_img.view(0).copy_to_async(&mut img_buffer)]); + } + { + let img = image::RgbImage::from_fn(img_w, img_h, |x, y| { + let i = x + y * img_w; + let px = img_buffer[i as usize]; + Rgb([px[0], px[1], px[2]]) + }); + img.save("cbox.png").unwrap(); + } + elwt.exit(); } - { - let img = image::RgbImage::from_fn(img_w, img_h, |x, y| { - let i = x + y * img_w; - let px = img_buffer[i as usize]; - Rgb([px[0], px[1], px[2]]) - }); - img.save("cbox.png").unwrap(); + WinitEvent::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { + let tic = Instant::now(); + { + let scope = device.default_stream().scope(); + scope.present(&swapchain, &display_img); + scope.submit([ + path_tracer.dispatch_async( + [img_w, img_h, 1], + &acc_img, + &seed_img, + &accel, + &Uint2::new(img_w, img_h), + ), + display.dispatch_async([img_w, img_h, 1], &acc_img, &display_img), + ]); + } + let toc = Instant::now(); + let elapsed = (toc - tic).as_secs_f32(); + log::info!( + "time: {}ms {}ms/spp", + elapsed * 1e3, + elapsed * 1e3 / SPP_PER_DISPATCH as f32 + ); + window.request_redraw(); } - control_flow.set_exit(); - } - WinitEvent::MainEventsCleared => { - window.request_redraw(); - } - WinitEvent::RedrawRequested(_) => { - let tic = Instant::now(); - { - let scope = device.default_stream().scope(); - scope.present(&swapchain, &display_img); - scope.submit([ - path_tracer.dispatch_async( - [img_w, img_h, 1], - &acc_img, - &seed_img, - &accel, - &Uint2::new(img_w, img_h), - ), - display.dispatch_async([img_w, img_h, 1], &acc_img, &display_img), - ]); + WinitEvent::AboutToWait => { + window.request_redraw(); } - let toc = Instant::now(); - let elapsed = (toc - tic).as_secs_f32(); - log::info!( - "time: {}ms {}ms/spp", - elapsed * 1e3, - elapsed * 1e3 / SPP_PER_DISPATCH as f32 - ); - window.request_redraw(); + + _ => (), } - _ => (), - } - }); + }) + .unwrap(); } diff --git a/luisa_compute/examples/path_tracer_cutout.rs b/luisa_compute/examples/path_tracer_cutout.rs index 43338cd..62edb26 100644 --- a/luisa_compute/examples/path_tracer_cutout.rs +++ b/luisa_compute/examples/path_tracer_cutout.rs @@ -8,7 +8,7 @@ use rand::Rng; use std::env::current_exe; use std::time::Instant; use winit::event::{Event as WinitEvent, WindowEvent}; -use winit::event_loop::EventLoop; +use winit::event_loop::{ControlFlow, EventLoop}; use luisa::prelude::*; use luisa::rtx::{ @@ -524,7 +524,7 @@ fn main() { .collect::>(); seed_img.view(0).copy_from(&seed_buffer); } - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - Ray Tracing") .with_inner_size(winit::dpi::LogicalSize::new(img_w, img_h)) @@ -541,58 +541,64 @@ fn main() { 3, ); let display_img = device.create_tex2d::(swapchain.pixel_storage(), img_w, img_h, 1); - event_loop.run(move |event, _, control_flow| { - control_flow.set_poll(); - match event { - WinitEvent::WindowEvent { - event: WindowEvent::CloseRequested, - window_id, - } if window_id == window.id() => { - // FIXME: support half4 pixel storage - let mut img_buffer = vec![[0u8; 4]; (img_w * img_h) as usize]; - { - let scope = device.default_stream().scope(); - scope.submit([display_img.view(0).copy_to_async(&mut img_buffer)]); + event_loop.set_control_flow(ControlFlow::Poll); + event_loop + .run(move |event, elwt| { + match event { + WinitEvent::WindowEvent { + event: WindowEvent::CloseRequested, + window_id, + } if window_id == window.id() => { + // FIXME: support half4 pixel storage + let mut img_buffer = vec![[0u8; 4]; (img_w * img_h) as usize]; + { + let scope = device.default_stream().scope(); + scope.submit([display_img.view(0).copy_to_async(&mut img_buffer)]); + } + { + let img = image::RgbImage::from_fn(img_w, img_h, |x, y| { + let i = x + y * img_w; + let px = img_buffer[i as usize]; + Rgb([px[0], px[1], px[2]]) + }); + img.save("cbox.png").unwrap(); + } + elwt.exit(); } - { - let img = image::RgbImage::from_fn(img_w, img_h, |x, y| { - let i = x + y * img_w; - let px = img_buffer[i as usize]; - Rgb([px[0], px[1], px[2]]) - }); - img.save("cbox.png").unwrap(); + WinitEvent::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { + let tic = Instant::now(); + { + let scope = device.default_stream().scope(); + scope.present(&swapchain, &display_img); + scope.submit([ + path_tracer.dispatch_async( + [img_w, img_h, 1], + &acc_img, + &seed_img, + &accel, + &Uint2::new(img_w, img_h), + ), + display.dispatch_async([img_w, img_h, 1], &acc_img, &display_img), + ]); + } + let toc = Instant::now(); + let elapsed = (toc - tic).as_secs_f32(); + log::info!( + "time: {}ms {}ms/spp", + elapsed * 1e3, + elapsed * 1e3 / spp_per_dispatch as f32 + ); + window.request_redraw(); } - control_flow.set_exit(); - } - WinitEvent::MainEventsCleared => { - window.request_redraw(); - } - WinitEvent::RedrawRequested(_) => { - let tic = Instant::now(); - { - let scope = device.default_stream().scope(); - scope.present(&swapchain, &display_img); - scope.submit([ - path_tracer.dispatch_async( - [img_w, img_h, 1], - &acc_img, - &seed_img, - &accel, - &Uint2::new(img_w, img_h), - ), - display.dispatch_async([img_w, img_h, 1], &acc_img, &display_img), - ]); + WinitEvent::AboutToWait => { + window.request_redraw(); } - let toc = Instant::now(); - let elapsed = (toc - tic).as_secs_f32(); - log::info!( - "time: {}ms {}ms/spp", - elapsed * 1e3, - elapsed * 1e3 / spp_per_dispatch as f32 - ); - window.request_redraw(); + + _ => (), } - _ => (), - } - }); + }) + .unwrap(); } diff --git a/luisa_compute/examples/ray_query.rs b/luisa_compute/examples/ray_query.rs index fbf77aa..9f96666 100644 --- a/luisa_compute/examples/ray_query.rs +++ b/luisa_compute/examples/ray_query.rs @@ -211,7 +211,7 @@ fn main() { img.write(px, Float4::expr(color.x, color.y, color.z, 1.0)); }), ); - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - Ray Query") .with_inner_size(winit::dpi::LogicalSize::new(img_w, img_h)) @@ -243,21 +243,24 @@ fn main() { }); img.save("rq.png").unwrap(); } - event_loop.run(move |event, _, control_flow| { - control_flow.set_wait(); - match event { + event_loop.set_control_flow(ControlFlow::Wait); + event_loop + .run(move |event, elwt| match event { WinitEvent::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => *control_flow = ControlFlow::Exit, - WinitEvent::MainEventsCleared => { + } if window_id == window.id() => elwt.exit(), + WinitEvent::AboutToWait => { window.request_redraw(); } - WinitEvent::RedrawRequested(_) => { + WinitEvent::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { let scope = device.default_stream().scope(); scope.present(&swapchain, &img); } _ => (), - } - }); + }) + .unwrap(); } diff --git a/luisa_compute/examples/raytracing.rs b/luisa_compute/examples/raytracing.rs index 2404916..363281b 100644 --- a/luisa_compute/examples/raytracing.rs +++ b/luisa_compute/examples/raytracing.rs @@ -69,7 +69,7 @@ fn main() { ); img.write(px, Float4::expr(color.x, color.y, color.z, 1.0)); }); - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = winit::window::WindowBuilder::new() .with_title("Luisa Compute Rust - Ray Tracing") .with_inner_size(winit::dpi::LogicalSize::new(img_w, img_h)) @@ -100,21 +100,23 @@ fn main() { }); img.save("triangle.png").unwrap(); } - event_loop.run(move |event, _, control_flow| { - control_flow.set_wait(); - match event { + event_loop + .run(move |event, elwt| match event { WinitEvent::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => escape!(*control_flow = ControlFlow::Exit), - WinitEvent::MainEventsCleared => { + } if window_id == window.id() => elwt.exit(), + WinitEvent::AboutToWait => { window.request_redraw(); } - WinitEvent::RedrawRequested(_) => { + WinitEvent::WindowEvent { + event: WindowEvent::RedrawRequested, + window_id, + } if window_id == window.id() => { let scope = device.default_stream().scope(); scope.present(&swapchain, &img); } _ => (), - } - }); + }) + .unwrap(); } diff --git a/luisa_compute/src/resource.rs b/luisa_compute/src/resource.rs index 86f3e6e..c23960a 100644 --- a/luisa_compute/src/resource.rs +++ b/luisa_compute/src/resource.rs @@ -268,11 +268,7 @@ impl BufferVar { .into(), ) } - pub fn write_as( - &self, - index_bytes: impl IntoIndex, - value: impl AsExpr, - ) { + pub fn write_as(&self, index_bytes: impl IntoIndex, value: impl AsExpr) { let i = index_bytes.to_u64().node().get(); let value = value.as_expr().node().get(); let self_node = self.node.get(); @@ -361,7 +357,6 @@ macro_rules! impl_resource_deref_to_var { }) } } - }; ($r:ident, $v:ident) => { impl std::ops::Deref for $r { @@ -377,7 +372,6 @@ macro_rules! impl_resource_deref_to_var { }) } } - }; } impl_resource_deref_to_var!(BufferView, BufferVar [T: Value]); @@ -1513,7 +1507,7 @@ impl ToNode for BindlessByteBufferVar { } } impl BindlessByteBufferVar { - pub unsafe fn read_as(&self, index_bytes: impl IntoIndex) -> Expr { + pub fn read_as(&self, index_bytes: impl IntoIndex) -> Expr { let i = index_bytes.to_u64().node().get(); let array = self.array.get(); let buffer_index = self.buffer_index.node().get(); diff --git a/luisa_compute/src/runtime.rs b/luisa_compute/src/runtime.rs index 93db078..8ac785a 100644 --- a/luisa_compute/src/runtime.rs +++ b/luisa_compute/src/runtime.rs @@ -9,11 +9,11 @@ use std::path::PathBuf; use std::rc::Rc; use std::sync::{Arc, Weak}; -use std::ffi::c_void; use parking_lot::lock_api::RawMutex as RawMutexTrait; use parking_lot::{Condvar, Mutex, RawMutex, RwLock}; +use std::ffi::c_void; -use raw_window_handle::HasRawWindowHandle; +use raw_window_handle::HasWindowHandle; use winit::window::Window; use crate::internal_prelude::*; @@ -40,10 +40,12 @@ pub use kernel::*; pub struct Device { pub(crate) inner: Arc, } + #[derive(Clone)] pub struct WeakDevice { pub(crate) inner: Weak, } + impl WeakDevice { pub fn new(device: &Device) -> Self { Self { @@ -54,6 +56,7 @@ impl WeakDevice { self.inner.upgrade().map(|inner| Device { inner }) } } + impl Hash for Device { fn hash(&self, state: &mut H) { let ptr = Arc::as_ptr(&self.inner); @@ -99,10 +102,12 @@ impl Drop for DeviceHandle { } } } + pub mod extension { use super::*; use api::denoiser_ext::{Feature, Image}; pub use api::denoiser_ext::{FilterQuality, ImageColorSpace, ImageFormat, PrefilterMode}; + pub struct DenoiserInput { inner: api::denoiser_ext::DenoiserInput, inputs: Vec, @@ -111,6 +116,7 @@ pub mod extension { rt: ResourceTracker, names: Vec, } + impl DenoiserInput { pub fn new(width: u32, height: u32) -> Self { Self { @@ -145,7 +151,10 @@ pub mod extension { format.size() <= std::mem::size_of::(), "format size must be less than or equal to the size of T" ); - assert!((self.inner.width as usize) * (self.inner.height as usize) == buffer.len); + assert_eq!( + (self.inner.width as usize) * (self.inner.height as usize), + buffer.len + ); let image = Image { format, buffer_handle: buffer.handle().0, @@ -209,11 +218,13 @@ pub mod extension { self } } + /// Denoiser extension pub struct DenoiserExt { pub(crate) device: Device, pub(crate) inner: api::DenoiserExt, } + pub struct Denoiser { api: api::DenoiserExt, inner: *mut api::denoiser_ext::Denoiser, @@ -221,6 +232,7 @@ pub mod extension { device: Device, stream: Arc, } + impl DenoiserExt { /// Create a denoiser instance that executes on the given stream. pub fn create(&self, stream: &Stream) -> Denoiser { @@ -235,6 +247,7 @@ pub mod extension { } } } + impl Denoiser { /// Initialize the denoiser with the given input. /// Blocks if the denoiser is still running. @@ -269,17 +282,21 @@ pub mod extension { } } } + impl Drop for Denoiser { fn drop(&mut self) { unsafe { (self.api.destroy)(&mut self.api, self.inner) } } } } + pub use extension::DenoiserExt; + pub trait DeviceExtensions { /// Gets the denoiser extension if available. fn denoiser_ext(&self) -> Option; } + impl DeviceExtensions for Device { fn denoiser_ext(&self) -> Option { let ext = self.inner.denoiser_ext(); @@ -293,6 +310,7 @@ impl DeviceExtensions for Device { } } } + impl Device { pub fn query(&self, name: &str) -> Option { self.inner.query(name) @@ -311,20 +329,20 @@ impl Device { vsync: bool, back_buffer_size: u32, ) -> Swapchain { - let handle = window.raw_window_handle(); + let handle = window.window_handle().unwrap().as_raw(); let window_handle = match handle { - raw_window_handle::RawWindowHandle::UiKit(h) => h.ui_window as u64, - raw_window_handle::RawWindowHandle::AppKit(h) => h.ns_window as u64, + raw_window_handle::RawWindowHandle::UiKit(h) => h.ui_view.as_ptr() as u64, + raw_window_handle::RawWindowHandle::AppKit(h) => h.ns_view.as_ptr() as u64, raw_window_handle::RawWindowHandle::Orbital(_) => todo!(), raw_window_handle::RawWindowHandle::Xlib(h) => h.window as u64, - raw_window_handle::RawWindowHandle::Xcb(h) => h.window as u64, + raw_window_handle::RawWindowHandle::Xcb(h) => h.window.get() as u64, raw_window_handle::RawWindowHandle::Wayland(_h) => { panic!("Wayland not supported, use X11 instead") } raw_window_handle::RawWindowHandle::Drm(_) => todo!(), raw_window_handle::RawWindowHandle::Gbm(_) => todo!(), - raw_window_handle::RawWindowHandle::Win32(h) => h.hwnd as u64, - raw_window_handle::RawWindowHandle::WinRt(h) => h.core_window as u64, + raw_window_handle::RawWindowHandle::Win32(h) => h.hwnd.get() as u64, + raw_window_handle::RawWindowHandle::WinRt(h) => h.core_window.as_ptr() as u64, raw_window_handle::RawWindowHandle::Web(_) => todo!(), raw_window_handle::RawWindowHandle::AndroidNdk(_) => todo!(), raw_window_handle::RawWindowHandle::Haiku(_) => todo!(), @@ -754,6 +772,7 @@ impl Device { } } } + pub(crate) enum StreamHandle { Default { device: Weak, @@ -766,7 +785,9 @@ pub(crate) enum StreamHandle { native_handle: *mut std::ffi::c_void, }, } + unsafe impl Send for StreamHandle {} + unsafe impl Sync for StreamHandle {} pub(crate) struct SwapchainHandle { @@ -845,7 +866,9 @@ pub(crate) struct EventHandle { handle: api::Event, native_handle: *mut std::ffi::c_void, } + unsafe impl Send for EventHandle {} + unsafe impl Sync for EventHandle {} impl Drop for EventHandle { @@ -870,6 +893,7 @@ pub struct Stream { } unsafe impl Send for Stream {} + unsafe impl Sync for Stream {} impl StreamHandle { @@ -1008,11 +1032,10 @@ impl<'a> Scope<'a> { cb(); callback(); }); - return self; } else { self.submit_impl(commands, callback); - return self; } + return self; } else { self.submit_impl(commands, cb.unwrap()); } @@ -1047,11 +1070,13 @@ impl<'a> Scope<'a> { self } } + impl Scope<'static> { pub fn detach(self) { self.synchronized.set(true); } } + impl<'a> Drop for Scope<'a> { fn drop(&mut self) { if !self.synchronized.get() { @@ -1179,12 +1204,14 @@ pub struct RawKernel { pub(crate) resource_tracker: ResourceTracker, pub(crate) module: CArc, } + impl Drop for RawKernel { fn drop(&mut self) { let shader = self.unwrap(); self.device.inner.destroy_shader(shader); } } + pub struct CallableArgEncoder { pub(crate) args: Vec, } @@ -1317,18 +1344,21 @@ impl KernelArg for Buffer { encoder.buffer(self); } } + impl KernelArg for SoaBuffer { type Parameter = SoaBufferVar; fn encode(&self, encoder: &mut KernelArgEncoder) { encoder.soa_buffer(self); } } + impl<'a, T: SoaValue> KernelArg for SoaBufferView<'a, T> { type Parameter = SoaBufferVar; fn encode(&self, encoder: &mut KernelArgEncoder) { encoder.soa_buffer_view(self); } } + // impl KernelArg for ByteBuffer { // type Parameter = ByteBufferVar; // fn encode(&self, encoder: &mut KernelArgEncoder) { @@ -1471,16 +1501,19 @@ pub struct Callable { pub(crate) inner: RawCallable, pub(crate) _marker: PhantomData, } + pub(crate) struct DynCallableInner { builder: Box, &mut KernelBuilder) -> Callable>, callables: Vec>, } + pub struct DynCallable { #[allow(dead_code)] pub(crate) inner: RefCell>, pub(crate) device: Device, pub(crate) init_once: bool, } + impl DynCallable { pub(crate) fn _new( device: Device, @@ -1554,8 +1587,11 @@ impl DynCallable { )) } } + unsafe impl Send for RawCallable {} + unsafe impl Sync for RawCallable {} + pub struct RawCallable { #[allow(dead_code)] pub(crate) device: Option, @@ -1564,17 +1600,19 @@ pub struct RawCallable { pub(crate) resource_tracker: ResourceTracker, pub(crate) captured_args: Vec, } + impl RawCallable { pub(crate) fn check_on_same_device(&self) { with_recorder(|r| { if let Some(device) = &self.device { if let Some((a, b)) = r.check_on_same_device(device) { - panic!("Callable created on a different device than the one it is called on: {:?} vs {:?}", a,b); + panic!("Callable created on a different device than the one it is called on: {:?} vs {:?}", a, b); } } }); } } + pub struct RawKernelDef { #[allow(dead_code)] pub(crate) device: Option, @@ -1635,8 +1673,11 @@ pub struct Kernel { pub(crate) inner: Arc, pub(crate) _marker: PhantomData, } + unsafe impl Send for Kernel {} + unsafe impl Sync for Kernel {} + impl Kernel { pub fn cache_dir(&self) -> Option { let handle = self.inner.unwrap(); @@ -1678,12 +1719,15 @@ impl AsKernelArg for Buffer { impl<'a, T: Value> AsKernelArg for BufferView { type Output = Buffer; } + impl AsKernelArg for SoaBuffer { type Output = SoaBuffer; } + impl<'a, T: SoaValue> AsKernelArg for SoaBufferView<'a, T> { type Output = SoaBuffer; } + impl<'a, T: IoTexel> AsKernelArg for Tex2dView { type Output = Tex2d; } diff --git a/luisa_compute/tests/misc.rs b/luisa_compute/tests/misc.rs index 30a646d..1bff4d5 100644 --- a/luisa_compute/tests/misc.rs +++ b/luisa_compute/tests/misc.rs @@ -1321,7 +1321,7 @@ fn bindless_byte_buffer() { let i3 = push!(f32, 1f32); Kernel::::new( &device, - &track!(|out: ByteBufferVar| unsafe { + &track!(|out: ByteBufferVar| { let heap = heap.var(); let buf = heap.byte_address_buffer(0u32); let i0 = i0 as u64; diff --git a/luisa_compute_sys/LuisaCompute b/luisa_compute_sys/LuisaCompute index 830e628..4b2f0c2 160000 --- a/luisa_compute_sys/LuisaCompute +++ b/luisa_compute_sys/LuisaCompute @@ -1 +1 @@ -Subproject commit 830e628b099819d3f585ceaa5407be543d8c7d7a +Subproject commit 4b2f0c2492f33c78a37008de96d555aaaf9e33a2