Skip to content

Commit f5379d3

Browse files
committed
Feat: rust OptiX hardware raytracing MVP
1 parent f517516 commit f5379d3

File tree

17 files changed

+482
-186
lines changed

17 files changed

+482
-186
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ members = [
33
"crates/*",
44
"crates/optix/examples/ex*",
55
"crates/optix/examples/ex*/device",
6+
"crates/optix/examples/rust/ex*",
7+
68
"xtask",
79

810
"examples/optix/*",

crates/optix/examples/ex04_mesh/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ glam = { version = "0.20", features=["cuda"] }
1616

1717
[build-dependencies]
1818
find_cuda_helper = { version = "0.2", path = "../../../find_cuda_helper" }
19+
cuda_builder = { version = "0.2", path = "../../../cuda_builder" }
Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,8 @@
1-
use find_cuda_helper::find_optix_root;
1+
use cuda_builder::CudaBuilder;
22

33
fn main() {
4-
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
5-
6-
let mut optix_include = find_optix_root().expect(
7-
"Unable to find the OptiX SDK, make sure you installed it and
8-
that OPTIX_ROOT or OPTIX_ROOT_DIR are set",
9-
);
10-
optix_include = optix_include.join("include");
11-
12-
let args = vec![
13-
format!("-I{}", optix_include.display()),
14-
format!("-I{}/../common/gdt", manifest_dir),
15-
];
16-
17-
compile_to_ptx("src/ex04_mesh.cu", &args);
18-
}
19-
20-
fn compile_to_ptx(cu_path: &str, args: &[String]) {
21-
println!("cargo:rerun-if-changed={}", cu_path);
22-
23-
let full_path =
24-
std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()).join(cu_path);
25-
26-
let mut ptx_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()).join(cu_path);
27-
ptx_path.set_extension("ptx");
28-
std::fs::create_dir_all(ptx_path.parent().unwrap()).unwrap();
29-
30-
let output = std::process::Command::new("nvcc")
31-
.arg("-ptx")
32-
.arg(&full_path)
33-
.arg("-o")
34-
.arg(&ptx_path)
35-
.args(args)
36-
.output()
37-
.expect("failed to fun nvcc");
38-
39-
if !output.status.success() {
40-
panic!("{}", unsafe { String::from_utf8_unchecked(output.stderr) });
41-
}
4+
CudaBuilder::new("../rust/ex04_mesh_gpu")
5+
.copy_to("../resources/ex04_mesh.ptx")
6+
.build()
7+
.unwrap();
428
}

crates/optix/examples/ex04_mesh/src/ex04_mesh.cu

Lines changed: 0 additions & 145 deletions
This file was deleted.

crates/optix/examples/ex04_mesh/src/renderer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl Renderer {
6363
.traversable_graph_flags(TraversableGraphFlags::ALLOW_SINGLE_GAS)
6464
.exception_flags(ExceptionFlags::NONE);
6565

66-
let ptx = include_str!(concat!(env!("OUT_DIR"), "/src/ex04_mesh.ptx"));
66+
let ptx = include_str!("../../resources/ex04_mesh.ptx");
6767

6868
let (module, _log) = Module::new(
6969
&mut ctx,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.ptx
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "ex04_mesh_gpu"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
cuda_std = { version = "0.2.0", path = "../../../../cuda_std" }
8+
optix_device = { version = "0.1.0", path = "../../../../optix_device" }
9+
10+
[lib]
11+
crate-type = ["cdylib", "rlib"]
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#![cfg_attr(
2+
target_os = "cuda",
3+
no_std,
4+
feature(register_attr),
5+
register_attr(nvvm_internal)
6+
)]
7+
#![allow(non_snake_case, clippy::missing_safety_doc)]
8+
9+
use cuda_std::kernel;
10+
use optix_device::{
11+
get_launch_index,
12+
glam::*,
13+
misc::*,
14+
payload,
15+
trace::TraversableHandle,
16+
trace::{trace, RayFlags},
17+
util::*,
18+
};
19+
20+
#[derive(Debug, Clone, Copy)]
21+
#[repr(C)]
22+
pub struct LaunchParams {
23+
pub frame: Frame,
24+
pub camera: Camera,
25+
pub traversable: TraversableHandle,
26+
}
27+
28+
#[derive(Debug, Clone, Copy)]
29+
#[repr(C)]
30+
pub struct Frame {
31+
pub color_buf: *mut Vec4,
32+
pub size: UVec2,
33+
}
34+
35+
#[derive(Debug, Clone, Copy)]
36+
#[repr(C)]
37+
pub struct Camera {
38+
pub position: Vec3,
39+
pub direction: Vec3,
40+
pub horizontal: Vec3,
41+
pub vertical: Vec3,
42+
}
43+
44+
#[repr(u32)]
45+
#[derive(Debug, Clone, Copy)]
46+
pub enum RayType {
47+
SurfaceRay = 0,
48+
}
49+
50+
fn get_color_buf() -> *mut Vec4 {
51+
unsafe { unpack_pointer(payload::get_payload(0), payload::get_payload(1)) }
52+
}
53+
54+
fn random_color(i: u32) -> Vec4 {
55+
let r = i * 13 * 17 + 0x234235;
56+
let g = i * 7 * 3 * 5 + 0x773477;
57+
let b = i * 11 * 19 + 0x223766;
58+
Vec4::new(
59+
(r & 255) as f32 / 255.0,
60+
(g & 255) as f32 / 255.0,
61+
(b & 255) as f32 / 255.0,
62+
1.0,
63+
)
64+
}
65+
66+
#[kernel]
67+
pub unsafe fn __closesthit__radiance() {
68+
let prim_id = primitive_index();
69+
let buf = get_color_buf();
70+
*buf = random_color(prim_id);
71+
}
72+
73+
#[kernel]
74+
pub unsafe fn __anyhit__radiance() {}
75+
76+
#[kernel]
77+
pub unsafe fn __miss__radiance() {
78+
let buf = get_color_buf();
79+
// pure white background
80+
*buf = Vec4::ONE;
81+
}
82+
83+
extern "C" {
84+
#[cfg_attr(target_os = "cuda", nvvm_internal(addrspace(4)))]
85+
static PARAMS: LaunchParams;
86+
}
87+
88+
#[kernel]
89+
pub unsafe fn __raygen__renderFrame() {
90+
let i = get_launch_index();
91+
let i = UVec2::new(i.x, i.y);
92+
93+
let camera = PARAMS.camera;
94+
95+
let px_color = Vec3::ZERO;
96+
let (mut p0, mut p1) = pack_pointer(&px_color as *const _ as *mut Vec3);
97+
98+
let screen = (i.as_vec2() + Vec2::splat(0.5)) / PARAMS.frame.size.as_vec2();
99+
let ray_dir = (camera.direction
100+
+ (screen.x - 0.5) * camera.horizontal
101+
+ (screen.y - 0.5) * camera.vertical)
102+
.normalize();
103+
104+
trace(
105+
PARAMS.traversable,
106+
camera.position,
107+
ray_dir,
108+
0.0,
109+
1e20,
110+
0.0,
111+
255,
112+
RayFlags::DISABLE_ANYHIT,
113+
RayType::SurfaceRay as u32,
114+
1,
115+
RayType::SurfaceRay as u32,
116+
&mut p0,
117+
&mut p1,
118+
);
119+
120+
let fb_index = i.x + i.y * PARAMS.frame.size.x;
121+
*PARAMS.frame.color_buf.add(fb_index as usize) =
122+
Vec4::new(px_color.x, px_color.y, px_color.z, 1.0);
123+
}

crates/optix_device/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ edition = "2021"
55
authors = ["Anders Langlands <[email protected]>", "Riccardo D'Ambrosio <[email protected]>"]
66

77
[dependencies]
8+
bitflags = "1.3.2"
89
cuda_std = { version = "0.2", path = "../cuda_std" }
910
glam = { version = "0.20", features=["cuda", "libm"], default-features=false }
11+
paste = "1.0.6"

crates/optix_device/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
#![cfg_attr(
22
target_arch = "nvptx64",
33
no_std,
4-
feature(register_attr, asm),
4+
feature(register_attr, asm, asm_experimental_arch),
55
register_attr(nvvm_internal)
66
)]
77

88
extern crate alloc;
99

10+
pub mod misc;
11+
pub mod payload;
12+
pub mod sys;
13+
pub mod trace;
14+
pub mod util;
15+
1016
use cuda_std::*;
17+
pub use glam;
1118
use glam::UVec3;
1219

1320
extern "C" {
@@ -45,3 +52,7 @@ pub fn get_launch_dimensions() -> UVec3 {
4552

4653
UVec3::new(x, y, z)
4754
}
55+
56+
pub mod raygen {
57+
pub use crate::trace::*;
58+
}

0 commit comments

Comments
 (0)