diff --git a/crates/spirv-std/src/image.rs b/crates/spirv-std/src/image.rs index 9e38533a30..445bd4059f 100644 --- a/crates/spirv-std/src/image.rs +++ b/crates/spirv-std/src/image.rs @@ -1010,7 +1010,7 @@ impl< >, > { - /// Sample texels at `coord` from the sampled image. + /// Sample texels at `coord` from the sampled image with an implicit lod. /// /// # Safety /// Sampling with a type (`S`) that doesn't match the image's image format @@ -1033,6 +1033,36 @@ impl< ); result } + + /// Sample texels at `coord` from the sampled image with an explicit lod. + /// + /// # Safety + /// Sampling with a type (`S`) that doesn't match the image's image format + /// will result in undefined behaviour. + #[crate::macros::gpu_only] + pub unsafe fn sample_by_lod( + &self, + coord: impl ImageCoordinate, + lod: f32, + ) -> V + where + F: Float, + V: Vector, + { + let mut result = Default::default(); + asm!( + "%sampledImage = OpLoad typeof*{1} {1}", + "%coord = OpLoad typeof*{2} {2}", + "%lod = OpLoad typeof*{3} {3}", + "%result = OpImageSampleExplicitLod typeof*{0} %sampledImage %coord Lod %lod", + "OpStore {0} %result", + in(reg) &mut result, + in(reg) self, + in(reg) &coord, + in(reg) &lod, + ); + result + } } /// This is a marker trait to represent the constraints on `OpImageGather` too complex to be diff --git a/tests/ui/image/sample_lod.rs b/tests/ui/image/sample_lod.rs index 086995158c..719ebbb3ff 100644 --- a/tests/ui/image/sample_lod.rs +++ b/tests/ui/image/sample_lod.rs @@ -1,7 +1,7 @@ // Test `OpImageSampleExplicitLod` Lod // build-pass -use spirv_std::{arch, Image, Sampler}; +use spirv_std::{arch, image::SampledImage, Image, Sampler}; #[spirv(fragment)] pub fn main( @@ -9,6 +9,9 @@ pub fn main( #[spirv(descriptor_set = 1, binding = 1)] image2d_array: &Image!(2D, type=f32, arrayed, sampled), #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(3D, type=f32, sampled), #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, + #[spirv(descriptor_set = 4, binding = 4)] sampled_image: &SampledImage< + Image!(2D, type=f32, sampled), + >, output: &mut glam::Vec4, ) { let v2 = glam::Vec2::new(0.0, 1.0); @@ -16,5 +19,6 @@ pub fn main( let r1: glam::Vec4 = image2d.sample_by_lod(*sampler, v2, 0.0); let r2: glam::Vec4 = image2d_array.sample_by_lod(*sampler, v3, 0.0); let r3: glam::Vec4 = cubemap.sample_by_lod(*sampler, v3, 0.0); - *output = r1 + r2 + r3; + let r4: glam::Vec4 = unsafe { sampled_image.sample_by_lod(v2, 0.0) }; + *output = r1 + r2 + r3 + r4; }