Skip to content

Commit

Permalink
Add SampledImage::sample_by_lod (#755)
Browse files Browse the repository at this point in the history
* Add 'SampledImage::sample_by_lod'

* Add a compiletest

* Format the compiletest, but manually because running cargo fmt doesn't seem to do anything 🤷

* Run rustfmt
  • Loading branch information
expenses authored Oct 8, 2021
1 parent b692ab5 commit 4e5f347
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
32 changes: 31 additions & 1 deletion crates/spirv-std/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ impl<
Image<SampledType, DIM, DEPTH, ARRAYED, { Multisampled::False as u32 }, SAMPLED, FORMAT>,
>
{
/// 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
Expand All @@ -974,6 +974,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<F, V>(
&self,
coord: impl ImageCoordinate<F, DIM, ARRAYED>,
lod: f32,
) -> V
where
F: Float,
V: Vector<SampledType, 4>,
{
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
Expand Down
8 changes: 6 additions & 2 deletions tests/ui/image/sample_lod.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
// Test `OpImageSampleExplicitLod` Lod
// build-pass

use spirv_std::{arch, Image, Sampler};
use spirv_std::{arch, image::SampledImage, Image, Sampler};

#[spirv(fragment)]
pub fn main(
#[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled),
#[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);
let v3 = glam::Vec3::new(0.0, 1.0, 0.5);
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;
}

0 comments on commit 4e5f347

Please sign in to comment.