Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an read_clock_khr function that calls OpReadClockKHR #757

Merged
merged 10 commits into from
Oct 8, 2021
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/spirv_type_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ pub fn instruction_signatures(op: Op) -> Option<&'static [InstSig<'static>]> {
// SPV_AMD_shader_fragment_mask
Op::FragmentMaskFetchAMD | Op::FragmentFetchAMD => reserved!(SPV_AMD_shader_fragment_mask),
// SPV_KHR_shader_clock
Op::ReadClockKHR => reserved!(SPV_KHR_shader_clock),
Op::ReadClockKHR => {}
expenses marked this conversation as resolved.
Show resolved Hide resolved
// SPV_NV_mesh_shader
Op::WritePackedPrimitiveIndices4x8NV => reserved!(SPV_NV_mesh_shader),
// SPV_NV_ray_tracing
Expand Down
44 changes: 44 additions & 0 deletions crates/spirv-std/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,47 @@ pub unsafe fn vector_insert_dynamic<T: Scalar, V: Vector<T, N>, const N: usize>(
pub fn kill() -> ! {
unsafe { asm!("OpKill", options(noreturn)) }
}

/// Read from the subgroup shader clock.
///
/// Requires the `SPV_KHR_shader_clock` extension and both the `Int64` and `ShaderClockKHR` capabilities.
///
/// See:
/// <https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_shader_clock.html>
#[cfg(target_feature = "Int64")]
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpReadClockKHR")]
pub unsafe fn read_clock_khr() -> u64 {
expenses marked this conversation as resolved.
Show resolved Hide resolved
let mut result: u64;

asm! {
"%uint = OpTypeInt 32 0",
"%scope = OpConstant %uint {scope}",
"{result} = OpReadClockKHR typeof*{result} %scope",
result = out(reg) result,
scope = const crate::memory::Scope::Subgroup as _,
};

result
}

/// Like `read_clock_khr` but returns a vector to avoid requiring the `Int64`
/// capability. It returns a 'vector of two-components of 32-bit unsigned
/// integer type with the first component containing the 32 least significant
/// bits and the second component containing the 32 most significant bits.'
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpReadClockKHR")]
pub unsafe fn read_clock_uvec2_khr<V: Vector<u32, 2>>() -> V {
let mut result = V::default();

asm! {
"%uint = OpTypeInt 32 0",
"%scope = OpConstant %uint {scope}",
"%result = OpReadClockKHR typeof*{result} %scope",
"OpStore {result} %result",
result = in(reg) &mut result,
expenses marked this conversation as resolved.
Show resolved Hide resolved
scope = const crate::memory::Scope::Subgroup as _,
expenses marked this conversation as resolved.
Show resolved Hide resolved
};

result
}
16 changes: 16 additions & 0 deletions tests/ui/arch/read_clock_khr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// build-pass
// compile-flags: -Ctarget-feature=+Int64,+ShaderClockKHR,+ext:SPV_KHR_shader_clock
expenses marked this conversation as resolved.
Show resolved Hide resolved

use glam::UVec2;
use spirv_std::arch::{read_clock_khr, read_clock_uvec2_khr};

#[spirv(fragment)]
pub fn main() {
let clock_time = unsafe {
read_clock_khr()
};

let clock_time_uvec2: UVec2 = unsafe {
read_clock_uvec2_khr()
};
}