diff --git a/crates/spirv-builder/src/test/basic.rs b/crates/spirv-builder/src/test/basic.rs index b1323d6e17..34217ce868 100644 --- a/crates/spirv-builder/src/test/basic.rs +++ b/crates/spirv-builder/src/test/basic.rs @@ -605,6 +605,28 @@ pub fn main(image: UniformConstant, mut output: Output) { "#); } +#[test] +fn image_sample_lod() { + val(r#" +#[spirv(fragment)] +pub fn main(image: UniformConstant, sampler: UniformConstant, mut output: Output) { + let result = image.sample_by_lod(*sampler, glam::Vec3A::new(0.0, 0.0, 1.0), 0.0); + *output = result; +} +"#); +} + +#[test] +fn image_sample_gradient() { + val(r#" +#[spirv(fragment)] +pub fn main(image: UniformConstant, sampler: UniformConstant, mut output: Output) { + let result = image.sample_by_gradient(*sampler, glam::Vec3A::new(0.0, 0.0, 1.0), glam::Vec3A::new(0.0, 0.0, 1.0)); + *output = result; +} +"#); +} + /// Helper to generate all of the `ptr_*` tests below, which test that the various /// ways to use raw pointer `read`/`write`/`copy`, to copy a single value, work, /// and that the resulting SPIR-V uses either a pair of `OpLoad` and `OpStore`, diff --git a/crates/spirv-std/src/textures.rs b/crates/spirv-std/src/textures.rs index f7f8caf516..88c680ddad 100644 --- a/crates/spirv-std/src/textures.rs +++ b/crates/spirv-std/src/textures.rs @@ -172,6 +172,50 @@ impl Image2dArray { result } } + #[spirv_std_macros::gpu_only] + #[cfg(feature = "const-generics")] + pub fn sample_by_lod>(&self, sampler: Sampler, coordinate: impl Vector, lod: f32) -> V { + let mut result = Default::default(); + unsafe { + asm!( + "%image = OpLoad _ {this}", + "%sampler = OpLoad _ {sampler}", + "%coordinate = OpLoad _ {coordinate}", + "%lod = OpLoad _ {lod}", + "%sampledImage = OpSampledImage _ %image %sampler", + "%result = OpImageSampleExplicitLod _ %sampledImage %coordinate Lod %lod", + "OpStore {result} %result", + result = in(reg) &mut result, + this = in(reg) self, + sampler = in(reg) &sampler, + coordinate = in(reg) &coordinate, + lod = in(reg) &lod + ); + } + result + } + #[spirv_std_macros::gpu_only] + #[cfg(feature = "const-generics")] + pub fn sample_by_gradient>(&self, sampler: Sampler, coordinate: impl Vector, gradient: impl Vector) -> V { + let mut result = Default::default(); + unsafe { + asm!( + "%image = OpLoad _ {this}", + "%sampler = OpLoad _ {sampler}", + "%coordinate = OpLoad _ {coordinate}", + "%gradient = OpLoad _ {gradient}", + "%sampledImage = OpSampledImage _ %image %sampler", + "%result = OpImageSampleExplicitLod _ %sampledImage %coordinate Grad %gradient", + "OpStore {result} %result", + result = in(reg) &mut result, + this = in(reg) self, + sampler = in(reg) &sampler, + coordinate = in(reg) &coordinate, + gradient = in(reg) &gradient, + ); + } + result + } } #[spirv(sampled_image)]