Skip to content

Commit d4cfa96

Browse files
committed
move mod: make read_clock() better match glsl intrinsic
1 parent 6f7ceac commit d4cfa96

File tree

2 files changed

+29
-25
lines changed

2 files changed

+29
-25
lines changed

crates/spirv-std/src/shader_clock.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,55 @@
33
//! GLSL: [`GL_EXT_shader_realtime_clock`](https://github.com/KhronosGroup/GLSL/blob/main/extensions/ext/GL_EXT_shader_realtime_clock.txt)
44
//! SPIRV: [`SPV_KHR_shader_clock`](https://github.khronos.org/SPIRV-Registry/extensions/KHR/SPV_KHR_shader_clock.html)
55
6+
#[cfg(target_arch = "spirv")]
7+
use crate::memory::Scope;
68
#[cfg(target_arch = "spirv")]
79
use core::arch::asm;
810
use glam::UVec2;
911

10-
/// Read from the shader clock with either the `Subgroup` or `Device` scope.
12+
/// The [`read_clock`] function returns a 64-bit value representing a real-time clock that is globally coherent by
13+
/// all invocations on the GPU. See [`read_clock_uvec2`] for a variant that doesn't require 64-bit support.
14+
///
15+
/// clockRealtime2x32EXT() returns the same value encoded as a two-component vector of 32-bit unsigned integers with the first component containing the 32 least significant bits and the second component containing the 32 most significant bits.
1116
///
12-
/// See: <https://github.khronos.org/SPIRV-Registry/extensions/KHR/SPV_KHR_shader_clock.html>
17+
/// The units of time are not defined for either of these operations and will wrap after exceeding the maximum value
18+
/// representable in 64 bits. These functions serve as code motion barriers.
1319
#[spirv_std_macros::gpu_only]
1420
#[doc(alias = "OpReadClockKHR")]
15-
pub fn read_clock_khr<const SCOPE: u32>() -> u64 {
21+
pub fn read_clock() -> u64 {
1622
unsafe {
17-
let mut result: u64;
18-
23+
let mut result = Default::default();
1924
asm! {
2025
"%uint = OpTypeInt 32 0",
2126
"%scope = OpConstant %uint {scope}",
22-
"{result} = OpReadClockKHR typeof*{result} %scope",
23-
result = out(reg) result,
24-
scope = const SCOPE,
27+
"%result = OpReadClockKHR typeof*{result} %scope",
28+
"OpStore {result} %result",
29+
result = in(reg) &mut result,
30+
scope = const (Scope::Device as u32),
2531
};
26-
2732
result
2833
}
2934
}
3035

31-
/// Like `read_clock_khr` but returns a vector to avoid requiring the `Int64`
32-
/// capability. It returns a 'vector of two-components of 32-bit unsigned
33-
/// integer type with the first component containing the 32 least significant
34-
/// bits and the second component containing the 32 most significant bits.'
36+
/// [`read_clock_uvec2`] returns the same value encoded as a two-component vector of 32-bit unsigned integers with the
37+
/// first component containing the 32 least significant bits and the second component containing the 32 most significant
38+
/// bits. See [`read_clock`] for a variant that returns a single `u64`.
3539
///
36-
/// See:
37-
/// <https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_shader_clock.html>
40+
/// The units of time are not defined for either of these operations and will wrap after exceeding the maximum value
41+
/// representable in 64 bits. These functions serve as code motion barriers.
3842
#[spirv_std_macros::gpu_only]
3943
#[doc(alias = "OpReadClockKHR")]
40-
pub fn read_clock_uvec2_khr<const SCOPE: u32>() -> UVec2 {
44+
pub fn read_clock_uvec2() -> UVec2 {
4145
unsafe {
42-
let mut result = UVec2::default();
43-
46+
let mut result = Default::default();
4447
asm! {
4548
"%uint = OpTypeInt 32 0",
4649
"%scope = OpConstant %uint {scope}",
4750
"%result = OpReadClockKHR typeof*{result} %scope",
4851
"OpStore {result} %result",
4952
result = in(reg) &mut result,
50-
scope = const SCOPE,
53+
scope = const (Scope::Device as u32),
5154
};
52-
5355
result
5456
}
5557
}

tests/compiletests/ui/arch/read_clock_khr.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ use glam::UVec2;
55
use spirv_std::spirv;
66
use spirv_std::{
77
memory::Scope,
8-
shader_clock::{read_clock_khr, read_clock_uvec2_khr},
8+
shader_clock::{read_clock, read_clock_uvec2},
99
};
1010

1111
#[spirv(fragment)]
12-
pub fn main() {
13-
let clock_time = unsafe { read_clock_khr::<{ Scope::Subgroup as u32 }>() };
14-
15-
let clock_time_uvec2: UVec2 = unsafe { read_clock_uvec2_khr::<{ Scope::Subgroup as u32 }>() };
12+
pub fn main(out: &mut u32) {
13+
unsafe {
14+
let clock_time: u64 = read_clock();
15+
let clock_time_uvec2: UVec2 = read_clock_uvec2();
16+
*out = clock_time as u32 + clock_time_uvec2.x;
17+
}
1618
}

0 commit comments

Comments
 (0)