Skip to content
This repository was archived by the owner on Oct 31, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/clippy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ clippy rustc_codegen_spirv
clippy spirv-builder

# Examples
clippy examples/example-runner

# disabled due to https://github.com/EmbarkStudios/rust-gpu/issues/186
#clippy examples/example-runner

clippy examples/wgpu-example-runner

clippy_no_features examples/example-runner-cpu
Expand Down
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ members = [
"spirv-tools",
"spirv-tools-sys",
]

[patch.crates-io]
# https://github.com/bitshifter/glam-rs/pull/85
glam = { git = "https://github.com/EmbarkStudios/glam-rs", rev = "262e4e1b86e54dbd7772a9c1f342abd30a438282" }
3 changes: 1 addition & 2 deletions examples/example-runner-cpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ license = "MIT OR Apache-2.0"
minifb = "0.19.1"
# bring in the shader as natively compiled code
example-shader = { path = "../example-shader" }
# for math types, likely get from glam directly later instead
spirv-std = { path = "../../spirv-std" }
glam = { version = "0.9", default_features = false }

# for parallelism, not really needed though
rayon = "1.5"
2 changes: 1 addition & 1 deletion examples/example-runner-cpu/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use glam::{vec2, Vec4};
use minifb::{Key, Window, WindowOptions};
use rayon::prelude::*;
use spirv_std::{vec2, Vec4};
use std::time::Instant;

fn color_u32_from_vec4(v: Vec4) -> u32 {
Expand Down
1 change: 1 addition & 0 deletions examples/example-shader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ crate-type = ["dylib"]

[dependencies]
spirv-std = { path = "../../spirv-std" }
glam = { version = "0.9", default_features = false }
102 changes: 47 additions & 55 deletions examples/example-shader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,39 @@
#![register_attr(spirv)]

use core::f32::consts::PI;
use spirv_std::{Input, Mat4, MathExt, Output, Vec2, Vec3, Vec4};
use glam::{const_vec3, Mat4, Vec2, Vec3, Vec4};
use spirv_std::{Input, MathExt, Output};

const DEPOLARIZATION_FACTOR: f32 = 0.035;
const LUMINANCE: f32 = 1.0;
const MIE_COEFFICIENT: f32 = 0.005;
const MIE_DIRECTIONAL_G: f32 = 0.8;
const MIE_K_COEFFICIENT: Vec3 = Vec3::new(0.686, 0.678, 0.666);
const MIE_K_COEFFICIENT: Vec3 = const_vec3!([0.686, 0.678, 0.666]);
const MIE_V: f32 = 4.0;
const MIE_ZENITH_LENGTH: f32 = 1.25e3;
const NUM_MOLECULES: f32 = 2.542e25f32;
const PRIMARIES: Vec3 = Vec3::new(6.8e-7f32, 5.5e-7f32, 4.5e-7f32);
const PRIMARIES: Vec3 = const_vec3!([6.8e-7f32, 5.5e-7f32, 4.5e-7f32]);
const RAYLEIGH: f32 = 1.0;
const RAYLEIGH_ZENITH_LENGTH: f32 = 8.4e3;
const REFRACTIVE_INDEX: f32 = 1.0003;
const SUN_ANGULAR_DIAMETER_DEGREES: f32 = 0.0093333;
const SUN_INTENSITY_FACTOR: f32 = 1000.0;
const SUN_INTENSITY_FALLOFF_STEEPNESS: f32 = 1.5;
const TONEMAP_WEIGHTING: Vec3 = Vec3::splat(9.50);
const TONEMAP_WEIGHTING: Vec3 = const_vec3!([9.50; 3]);
const TURBIDITY: f32 = 2.0;

// TODO: add this to glam? Rust std has it on f32/f64
fn pow(v: Vec3, power: f32) -> Vec3 {
let v: [f32; 3] = v.into();
Vec3::new(v[0].pow(power), v[1].pow(power), v[2].pow(power))
}

// TODO: add this to glam? Rust std has it on f32/f64
fn exp(v: Vec3) -> Vec3 {
let v: [f32; 3] = v.into();
Vec3::new(v[0].exp(), v[1].exp(), v[2].exp())
}

/// Based on: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
fn acos_approx(v: f32) -> f32 {
let x = v.abs();
Expand All @@ -51,12 +64,12 @@ fn total_rayleigh(lambda: Vec3) -> Vec3 {
(8.0 * PI.pow(3.0)
* (REFRACTIVE_INDEX.pow(2.0) - 1.0).pow(2.0)
* (6.0 + 3.0 * DEPOLARIZATION_FACTOR))
/ (3.0 * NUM_MOLECULES * lambda.pow(4.0) * (6.0 - 7.0 * DEPOLARIZATION_FACTOR))
/ (3.0 * NUM_MOLECULES * pow(lambda, 4.0) * (6.0 - 7.0 * DEPOLARIZATION_FACTOR))
}

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

fn rayleigh_phase(cos_theta: f32) -> f32 {
Expand All @@ -78,19 +91,19 @@ fn sun_intensity(zenith_angle_cos: f32) -> f32 {
}

fn uncharted2_tonemap(w: Vec3) -> Vec3 {
const A: Vec3 = Vec3::splat(0.15); // Shoulder strength
const B: Vec3 = Vec3::splat(0.50); // Linear strength
const C: Vec3 = Vec3::splat(0.10); // Linear angle
const D: Vec3 = Vec3::splat(0.20); // Toe strength
const E: Vec3 = Vec3::splat(0.02); // Toe numerator
const F: Vec3 = Vec3::splat(0.30); // Toe denominator
const A: Vec3 = const_vec3!([0.15; 3]); // Shoulder strength
const B: Vec3 = const_vec3!([0.50; 3]); // Linear strength
const C: Vec3 = const_vec3!([0.10; 3]); // Linear angle
const D: Vec3 = const_vec3!([0.20; 3]); // Toe strength
const E: Vec3 = const_vec3!([0.02; 3]); // Toe numerator
const F: Vec3 = const_vec3!([0.30; 3]); // Toe denominator

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

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

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

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

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

let beta_m_theta = beta_m * henyey_greenstein_phase(cos_theta, MIE_DIRECTIONAL_G);
let sun_e = sun_intensity(sun_direction.dot(up));
let mut lin =
(sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex))
.pow(1.5);
let mut lin = pow(
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex),
1.5,
);

lin *= Vec3::splat(1.0).lerp(
(sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * fex).pow(0.5),
pow(
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * fex,
0.5,
),
((1.0 - up.dot(sun_direction)).pow(5.0)).saturate(),
);

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

color.pow(1.0 / (1.2 + (1.2 * sunfade)))
}

pub fn main_fs_test(screen_pos: Vec2) -> Vec4 {
// hard-code information because we can't bind buffers at the moment
let eye_pos = Vec3(0.0, 0.0997, 0.2);
let sun_pos = Vec3::new(0.0, 75.0, -1000.0);
let clip_to_world = Mat4 {
x_axis: Vec4(-0.5522849, 0.0, 0.0, 0.0),
y_axis: Vec4(0.0, 0.4096309, -0.061444636, 0.0),
z_axis: Vec4(0.0, 99.99999, 199.99998, 999.99994),
w_axis: Vec4(0.0, -0.14834046, -0.98893654, 0.0),
};

let cs_pos = Vec4(screen_pos.0, -screen_pos.1, 1.0, 1.0);
let ws_pos = {
let p = clip_to_world.mul_vec4(cs_pos);
p.truncate() / p.3
};
let dir = (ws_pos - eye_pos).normalize();

// evaluate Preetham sky model
let color = sky(dir, sun_pos);

// let color = dir;

color.extend(1.0)
pow(color, 1.0 / (1.2 + (1.2 * sunfade)))
}

pub fn fs(screen_pos: Vec2) -> Vec4 {
// hard-code information because we can't bind buffers at the moment
let eye_pos = Vec3(0.0, 0.0997, 0.2);
let eye_pos = Vec3::new(0.0, 0.0997, 0.2);
let sun_pos = Vec3::new(0.0, 75.0, -1000.0);
let clip_to_world = Mat4 {
x_axis: Vec4(-0.5522849, 0.0, 0.0, 0.0),
y_axis: Vec4(0.0, 0.4096309, -0.061444636, 0.0),
z_axis: Vec4(0.0, 99.99999, 199.99998, 999.99994),
w_axis: Vec4(0.0, -0.14834046, -0.98893654, 0.0),
};
let clip_to_world = Mat4::from_cols(
Vec4::new(-0.5522849, 0.0, 0.0, 0.0),
Vec4::new(0.0, 0.4096309, -0.061444636, 0.0),
Vec4::new(0.0, 99.99999, 199.99998, 999.99994),
Vec4::new(0.0, -0.14834046, -0.98893654, 0.0),
);

let cs_pos = Vec4(screen_pos.0, -screen_pos.1, 1.0, 1.0);
let cs_pos = Vec4::new(screen_pos.x(), -screen_pos.y(), 1.0, 1.0);
let ws_pos = {
let p = clip_to_world.mul_vec4(cs_pos);
p.truncate() / p.3
p.truncate() / p.w()
};
let dir = (ws_pos - eye_pos).normalize();

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

Expand Down
1 change: 1 addition & 0 deletions examples/wgpu-example-shader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ crate-type = ["dylib"]

[dependencies]
spirv-std = { path = "../../spirv-std" }
glam = { version = "0.9", default_features = false }
3 changes: 2 additions & 1 deletion examples/wgpu-example-shader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#![feature(register_attr)]
#![register_attr(spirv)]

use spirv_std::{Input, Output, Vec4};
use glam::Vec4;
use spirv_std::{Input, Output};

#[allow(unused_attributes)]
#[spirv(fragment)]
Expand Down
19 changes: 0 additions & 19 deletions rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use rustc_middle::ty::layout::TyAndLayout;
use rustc_mir::interpret::Scalar;
use rustc_span::symbol::Symbol;
use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Primitive, Size};
use std::ops::Range;

impl<'tcx> CodegenCx<'tcx> {
pub fn constant_u8(&self, val: u8) -> SpirvValue {
Expand Down Expand Up @@ -405,7 +404,6 @@ impl<'tcx> CodegenCx<'tcx> {
"create_const_alloc must consume all bytes of an Allocation after an unsized struct"
);
}
Self::assert_uninit(alloc, base, *offset, occupied_spaces);
self.constant_composite(ty, values)
}
SpirvType::Opaque { name } => self.tcx.sess.fatal(&format!(
Expand Down Expand Up @@ -508,21 +506,4 @@ impl<'tcx> CodegenCx<'tcx> {
*offset += Size::from_bytes(len);
Pointer::new_with_tag(alloc_id, Size::from_bytes(inner_offset), ())
}

fn assert_uninit(
alloc: &Allocation,
start: Size,
end: Size,
occupied_ranges: Vec<Range<Size>>,
) {
// Range<Size> doesn't impl Iterator, so manually do it.
let mut index = start;
while index < end {
assert_eq!(
occupied_ranges.iter().any(|range| range.contains(&index)),
alloc.init_mask().get(index)
);
index += Size::from_bytes(1);
}
}
}
6 changes: 2 additions & 4 deletions spirv-std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
clippy::enum_glob_use,
clippy::pub_enum_variant_names,
clippy::mem_forget,
clippy::use_self,
clippy::filter_map_next,
clippy::needless_continue,
clippy::needless_borrow,
Expand All @@ -37,9 +36,8 @@
nonstandard_style
)]

pub mod math;
pub use crate::math::MathExt;
pub use crate::math::*;
mod math_ext;
pub use math_ext::MathExt;

macro_rules! pointer_addrspace_write {
(false) => {};
Expand Down
Loading