Skip to content
This repository was archived by the owner on Oct 31, 2025. It is now read-only.

Commit 98eb8d3

Browse files
authored
Convert to use glam for math types (#149)
* [spirv-std] Remove math types * Temp implementation of copysign #148 * Convert shader to use glam * Rustfmt * Fix wgpu-example-shader to use glam * [spirv-std] Disable clippy::use_self * Upgrade to latest glam branch * Use latest glam fork * Remove incorrect assert_uninit After discussions with @khyperia * Update lockfile * Update to latest glam fork with fixes * Use real copysign intrinsic * Disable clippy on example-shader for now Tracked in #186
1 parent b47ff73 commit 98eb8d3

File tree

19 files changed

+156
-2719
lines changed

19 files changed

+156
-2719
lines changed

.github/workflows/clippy.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ clippy rustc_codegen_spirv
3434
clippy spirv-builder
3535

3636
# Examples
37-
clippy examples/example-runner
37+
38+
# disabled due to https://github.com/EmbarkStudios/rust-gpu/issues/186
39+
#clippy examples/example-runner
40+
3841
clippy examples/wgpu-example-runner
3942

4043
clippy_no_features examples/example-runner-cpu

Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ members = [
1212
"spirv-tools",
1313
"spirv-tools-sys",
1414
]
15+
16+
[patch.crates-io]
17+
# https://github.com/bitshifter/glam-rs/pull/85
18+
glam = { git = "https://github.com/EmbarkStudios/glam-rs", rev = "262e4e1b86e54dbd7772a9c1f342abd30a438282" }

examples/example-runner-cpu/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ license = "MIT OR Apache-2.0"
99
minifb = "0.19.1"
1010
# bring in the shader as natively compiled code
1111
example-shader = { path = "../example-shader" }
12-
# for math types, likely get from glam directly later instead
13-
spirv-std = { path = "../../spirv-std" }
12+
glam = { version = "0.9", default_features = false }
1413

1514
# for parallelism, not really needed though
1615
rayon = "1.5"

examples/example-runner-cpu/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
use glam::{vec2, Vec4};
12
use minifb::{Key, Window, WindowOptions};
23
use rayon::prelude::*;
3-
use spirv_std::{vec2, Vec4};
44
use std::time::Instant;
55

66
fn color_u32_from_vec4(v: Vec4) -> u32 {

examples/example-shader/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ crate-type = ["dylib"]
1010

1111
[dependencies]
1212
spirv-std = { path = "../../spirv-std" }
13+
glam = { version = "0.9", default_features = false }

examples/example-shader/src/lib.rs

Lines changed: 47 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,39 @@
66
#![register_attr(spirv)]
77

88
use core::f32::consts::PI;
9-
use spirv_std::{Input, Mat4, MathExt, Output, Vec2, Vec3, Vec4};
9+
use glam::{const_vec3, Mat4, Vec2, Vec3, Vec4};
10+
use spirv_std::{Input, MathExt, Output};
1011

1112
const DEPOLARIZATION_FACTOR: f32 = 0.035;
1213
const LUMINANCE: f32 = 1.0;
1314
const MIE_COEFFICIENT: f32 = 0.005;
1415
const MIE_DIRECTIONAL_G: f32 = 0.8;
15-
const MIE_K_COEFFICIENT: Vec3 = Vec3::new(0.686, 0.678, 0.666);
16+
const MIE_K_COEFFICIENT: Vec3 = const_vec3!([0.686, 0.678, 0.666]);
1617
const MIE_V: f32 = 4.0;
1718
const MIE_ZENITH_LENGTH: f32 = 1.25e3;
1819
const NUM_MOLECULES: f32 = 2.542e25f32;
19-
const PRIMARIES: Vec3 = Vec3::new(6.8e-7f32, 5.5e-7f32, 4.5e-7f32);
20+
const PRIMARIES: Vec3 = const_vec3!([6.8e-7f32, 5.5e-7f32, 4.5e-7f32]);
2021
const RAYLEIGH: f32 = 1.0;
2122
const RAYLEIGH_ZENITH_LENGTH: f32 = 8.4e3;
2223
const REFRACTIVE_INDEX: f32 = 1.0003;
2324
const SUN_ANGULAR_DIAMETER_DEGREES: f32 = 0.0093333;
2425
const SUN_INTENSITY_FACTOR: f32 = 1000.0;
2526
const SUN_INTENSITY_FALLOFF_STEEPNESS: f32 = 1.5;
26-
const TONEMAP_WEIGHTING: Vec3 = Vec3::splat(9.50);
27+
const TONEMAP_WEIGHTING: Vec3 = const_vec3!([9.50; 3]);
2728
const TURBIDITY: f32 = 2.0;
2829

30+
// TODO: add this to glam? Rust std has it on f32/f64
31+
fn pow(v: Vec3, power: f32) -> Vec3 {
32+
let v: [f32; 3] = v.into();
33+
Vec3::new(v[0].pow(power), v[1].pow(power), v[2].pow(power))
34+
}
35+
36+
// TODO: add this to glam? Rust std has it on f32/f64
37+
fn exp(v: Vec3) -> Vec3 {
38+
let v: [f32; 3] = v.into();
39+
Vec3::new(v[0].exp(), v[1].exp(), v[2].exp())
40+
}
41+
2942
/// Based on: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
3043
fn acos_approx(v: f32) -> f32 {
3144
let x = v.abs();
@@ -51,12 +64,12 @@ fn total_rayleigh(lambda: Vec3) -> Vec3 {
5164
(8.0 * PI.pow(3.0)
5265
* (REFRACTIVE_INDEX.pow(2.0) - 1.0).pow(2.0)
5366
* (6.0 + 3.0 * DEPOLARIZATION_FACTOR))
54-
/ (3.0 * NUM_MOLECULES * lambda.pow(4.0) * (6.0 - 7.0 * DEPOLARIZATION_FACTOR))
67+
/ (3.0 * NUM_MOLECULES * pow(lambda, 4.0) * (6.0 - 7.0 * DEPOLARIZATION_FACTOR))
5568
}
5669

5770
fn total_mie(lambda: Vec3, k: Vec3, t: f32) -> Vec3 {
5871
let c = 0.2 * t * 10e-18;
59-
0.434 * c * PI * ((2.0 * PI) / lambda).pow(MIE_V - 2.0) * k
72+
0.434 * c * PI * pow((2.0 * PI) / lambda, MIE_V - 2.0) * k
6073
}
6174

6275
fn rayleigh_phase(cos_theta: f32) -> f32 {
@@ -78,19 +91,19 @@ fn sun_intensity(zenith_angle_cos: f32) -> f32 {
7891
}
7992

8093
fn uncharted2_tonemap(w: Vec3) -> Vec3 {
81-
const A: Vec3 = Vec3::splat(0.15); // Shoulder strength
82-
const B: Vec3 = Vec3::splat(0.50); // Linear strength
83-
const C: Vec3 = Vec3::splat(0.10); // Linear angle
84-
const D: Vec3 = Vec3::splat(0.20); // Toe strength
85-
const E: Vec3 = Vec3::splat(0.02); // Toe numerator
86-
const F: Vec3 = Vec3::splat(0.30); // Toe denominator
94+
const A: Vec3 = const_vec3!([0.15; 3]); // Shoulder strength
95+
const B: Vec3 = const_vec3!([0.50; 3]); // Linear strength
96+
const C: Vec3 = const_vec3!([0.10; 3]); // Linear angle
97+
const D: Vec3 = const_vec3!([0.20; 3]); // Toe strength
98+
const E: Vec3 = const_vec3!([0.02; 3]); // Toe numerator
99+
const F: Vec3 = const_vec3!([0.30; 3]); // Toe denominator
87100

88101
((w * (A * w + C * B) + D * E) / (w * (A * w + B) + D * F)) - E / F
89102
}
90103

91104
fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
92105
let up = Vec3::new(0.0, 1.0, 0.0);
93-
let sunfade = 1.0 - (1.0 - (sun_position.1 / 450000.0).exp()).saturate();
106+
let sunfade = 1.0 - (1.0 - (sun_position.y() / 450000.0).exp()).saturate();
94107
let rayleigh_coefficient = RAYLEIGH - (1.0 * (1.0 - sunfade));
95108
let beta_r = total_rayleigh(PRIMARIES) * rayleigh_coefficient;
96109

@@ -105,7 +118,7 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
105118
let s_m = MIE_ZENITH_LENGTH / denom;
106119

107120
// Combined extinction factor
108-
let fex = (-(beta_r * s_r + beta_m * s_m)).exp();
121+
let fex = exp(-(beta_r * s_r + beta_m * s_m));
109122

110123
// In-scattering
111124
let sun_direction = sun_position.normalize();
@@ -114,11 +127,16 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
114127

115128
let beta_m_theta = beta_m * henyey_greenstein_phase(cos_theta, MIE_DIRECTIONAL_G);
116129
let sun_e = sun_intensity(sun_direction.dot(up));
117-
let mut lin =
118-
(sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex))
119-
.pow(1.5);
130+
let mut lin = pow(
131+
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex),
132+
1.5,
133+
);
134+
120135
lin *= Vec3::splat(1.0).lerp(
121-
(sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * fex).pow(0.5),
136+
pow(
137+
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * fex,
138+
0.5,
139+
),
122140
((1.0 - up.dot(sun_direction)).pow(5.0)).saturate(),
123141
);
124142

@@ -140,50 +158,24 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
140158
let curr = uncharted2_tonemap(((2.0 / LUMINANCE.pow(4.0)).log2()) * tex_color);
141159
let color = curr * white_scale;
142160

143-
color.pow(1.0 / (1.2 + (1.2 * sunfade)))
144-
}
145-
146-
pub fn main_fs_test(screen_pos: Vec2) -> Vec4 {
147-
// hard-code information because we can't bind buffers at the moment
148-
let eye_pos = Vec3(0.0, 0.0997, 0.2);
149-
let sun_pos = Vec3::new(0.0, 75.0, -1000.0);
150-
let clip_to_world = Mat4 {
151-
x_axis: Vec4(-0.5522849, 0.0, 0.0, 0.0),
152-
y_axis: Vec4(0.0, 0.4096309, -0.061444636, 0.0),
153-
z_axis: Vec4(0.0, 99.99999, 199.99998, 999.99994),
154-
w_axis: Vec4(0.0, -0.14834046, -0.98893654, 0.0),
155-
};
156-
157-
let cs_pos = Vec4(screen_pos.0, -screen_pos.1, 1.0, 1.0);
158-
let ws_pos = {
159-
let p = clip_to_world.mul_vec4(cs_pos);
160-
p.truncate() / p.3
161-
};
162-
let dir = (ws_pos - eye_pos).normalize();
163-
164-
// evaluate Preetham sky model
165-
let color = sky(dir, sun_pos);
166-
167-
// let color = dir;
168-
169-
color.extend(1.0)
161+
pow(color, 1.0 / (1.2 + (1.2 * sunfade)))
170162
}
171163

172164
pub fn fs(screen_pos: Vec2) -> Vec4 {
173165
// hard-code information because we can't bind buffers at the moment
174-
let eye_pos = Vec3(0.0, 0.0997, 0.2);
166+
let eye_pos = Vec3::new(0.0, 0.0997, 0.2);
175167
let sun_pos = Vec3::new(0.0, 75.0, -1000.0);
176-
let clip_to_world = Mat4 {
177-
x_axis: Vec4(-0.5522849, 0.0, 0.0, 0.0),
178-
y_axis: Vec4(0.0, 0.4096309, -0.061444636, 0.0),
179-
z_axis: Vec4(0.0, 99.99999, 199.99998, 999.99994),
180-
w_axis: Vec4(0.0, -0.14834046, -0.98893654, 0.0),
181-
};
168+
let clip_to_world = Mat4::from_cols(
169+
Vec4::new(-0.5522849, 0.0, 0.0, 0.0),
170+
Vec4::new(0.0, 0.4096309, -0.061444636, 0.0),
171+
Vec4::new(0.0, 99.99999, 199.99998, 999.99994),
172+
Vec4::new(0.0, -0.14834046, -0.98893654, 0.0),
173+
);
182174

183-
let cs_pos = Vec4(screen_pos.0, -screen_pos.1, 1.0, 1.0);
175+
let cs_pos = Vec4::new(screen_pos.x(), -screen_pos.y(), 1.0, 1.0);
184176
let ws_pos = {
185177
let p = clip_to_world.mul_vec4(cs_pos);
186-
p.truncate() / p.3
178+
p.truncate() / p.w()
187179
};
188180
let dir = (ws_pos - eye_pos).normalize();
189181

@@ -197,7 +189,7 @@ pub fn fs(screen_pos: Vec2) -> Vec4 {
197189
#[spirv(fragment)]
198190
pub fn main_fs(input: Input<Vec4>, mut output: Output<Vec4>) {
199191
let v = input.load();
200-
let color = fs(Vec2::new(v.0, v.1));
192+
let color = fs(Vec2::new(v.x(), v.y()));
201193
output.store(color)
202194
}
203195

examples/wgpu-example-shader/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ crate-type = ["dylib"]
1010

1111
[dependencies]
1212
spirv-std = { path = "../../spirv-std" }
13+
glam = { version = "0.9", default_features = false }

examples/wgpu-example-shader/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#![feature(register_attr)]
44
#![register_attr(spirv)]
55

6-
use spirv_std::{Input, Output, Vec4};
6+
use glam::Vec4;
7+
use spirv_std::{Input, Output};
78

89
#[allow(unused_attributes)]
910
#[spirv(fragment)]

rustc_codegen_spirv/src/codegen_cx/constant.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_middle::ty::layout::TyAndLayout;
1111
use rustc_mir::interpret::Scalar;
1212
use rustc_span::symbol::Symbol;
1313
use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Primitive, Size};
14-
use std::ops::Range;
1514

1615
impl<'tcx> CodegenCx<'tcx> {
1716
pub fn constant_u8(&self, val: u8) -> SpirvValue {
@@ -405,7 +404,6 @@ impl<'tcx> CodegenCx<'tcx> {
405404
"create_const_alloc must consume all bytes of an Allocation after an unsized struct"
406405
);
407406
}
408-
Self::assert_uninit(alloc, base, *offset, occupied_spaces);
409407
self.constant_composite(ty, values)
410408
}
411409
SpirvType::Opaque { name } => self.tcx.sess.fatal(&format!(
@@ -508,21 +506,4 @@ impl<'tcx> CodegenCx<'tcx> {
508506
*offset += Size::from_bytes(len);
509507
Pointer::new_with_tag(alloc_id, Size::from_bytes(inner_offset), ())
510508
}
511-
512-
fn assert_uninit(
513-
alloc: &Allocation,
514-
start: Size,
515-
end: Size,
516-
occupied_ranges: Vec<Range<Size>>,
517-
) {
518-
// Range<Size> doesn't impl Iterator, so manually do it.
519-
let mut index = start;
520-
while index < end {
521-
assert_eq!(
522-
occupied_ranges.iter().any(|range| range.contains(&index)),
523-
alloc.init_mask().get(index)
524-
);
525-
index += Size::from_bytes(1);
526-
}
527-
}
528509
}

0 commit comments

Comments
 (0)