Skip to content

Commit

Permalink
feat: add OpImageSampleExplicitLod to spirv-std
Browse files Browse the repository at this point in the history
  • Loading branch information
DeanBDean committed Mar 18, 2021
1 parent 27eb1d1 commit 8344a74
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
118 changes: 118 additions & 0 deletions crates/spirv-std/src/textures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,65 @@ impl Image2d {
result
}
}
#[spirv_std_macros::gpu_only]
#[cfg(feature = "const-generics")]
/// Sample the image at a coordinate by a lod
pub fn sample_by_lod<V: Vector<f32, 4>>(
&self,
sampler: Sampler,
coordinate: impl Vector<f32, 2>,
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")]
/// Sample the image based on a gradient formed by (dx, dy). Specifically, ([du/dx, dv/dx], [du/dy, dv/dy])
pub fn sample_by_gradient<V: Vector<f32, 4>>(
&self,
sampler: Sampler,
coordinate: impl Vector<f32, 2>,
gradient_dx: impl Vector<f32, 2>,
gradient_dy: impl Vector<f32, 2>,
) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%image = OpLoad _ {this}",
"%sampler = OpLoad _ {sampler}",
"%coordinate = OpLoad _ {coordinate}",
"%gradient_dx = OpLoad _ {gradient_dx}",
"%gradient_dy = OpLoad _ {gradient_dy}",
"%sampledImage = OpSampledImage _ %image %sampler",
"%result = OpImageSampleExplicitLod _ %sampledImage %coordinate Grad %gradient_dx %gradient_dy",
"OpStore {result} %result",
result = in(reg) &mut result,
this = in(reg) self,
sampler = in(reg) &sampler,
coordinate = in(reg) &coordinate,
gradient_dx = in(reg) &gradient_dx,
gradient_dy = in(reg) &gradient_dy,
);
}
result
}
/// Fetch a single texel with a sampler set at compile time
#[spirv_std_macros::gpu_only]
#[cfg(feature = "const-generics")]
Expand Down Expand Up @@ -172,6 +231,65 @@ impl Image2dArray {
result
}
}
#[spirv_std_macros::gpu_only]
#[cfg(feature = "const-generics")]
/// Sample the image at a coordinate by a lod
pub fn sample_by_lod<V: Vector<f32, 4>>(
&self,
sampler: Sampler,
coordinate: impl Vector<f32, 3>,
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")]
/// Sample the image based on a gradient formed by (dx, dy). Specifically, ([du/dx, dv/dx], [du/dy, dv/dy])
pub fn sample_by_gradient<V: Vector<f32, 4>>(
&self,
sampler: Sampler,
coordinate: impl Vector<f32, 3>,
gradient_dx: impl Vector<f32, 2>,
gradient_dy: impl Vector<f32, 2>,
) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%image = OpLoad _ {this}",
"%sampler = OpLoad _ {sampler}",
"%coordinate = OpLoad _ {coordinate}",
"%gradient_dx = OpLoad _ {gradient_dx}",
"%gradient_dy = OpLoad _ {gradient_dy}",
"%sampledImage = OpSampledImage _ %image %sampler",
"%result = OpImageSampleExplicitLod _ %sampledImage %coordinate Grad %gradient_dx %gradient_dy",
"OpStore {result} %result",
result = in(reg) &mut result,
this = in(reg) self,
sampler = in(reg) &sampler,
coordinate = in(reg) &coordinate,
gradient_dx = in(reg) &gradient_dx,
gradient_dy = in(reg) &gradient_dy,
);
}
result
}
}

#[spirv(sampled_image)]
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/image/sample_gradient.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Test `OpImageSampleExplicitLod`
// build-pass

use spirv_std::{arch, storage_class::{Output, UniformConstant}, Image2d, Image2dArray, Sampler};

#[spirv(fragment)]
pub fn main(
image: UniformConstant<Image2d>,
image_array: UniformConstant<Image2dArray>,
sampler: UniformConstant<Sampler>,
mut image_output: Output<glam::Vec4>,
mut image_array_output: Output<glam::Vec4>,
) {
let image_result = image.sample_by_gradient(*sampler, glam::Vec2::new(0.0, 1.0), glam::Vec2::new(0.0, 1.0), glam::Vec2::new(0.0, 1.0));
*image_output = image_result;
let image_array_result = image_array.sample_by_gradient(*sampler, glam::Vec3A::new(0.0, 0.0, 1.0), glam::Vec2::new(0.0, 1.0), glam::Vec2::new(0.0, 1.0));
*image_array_output = image_array_result;
}
18 changes: 18 additions & 0 deletions tests/ui/image/sample_lod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Test `OpImageSampleExplicitLod`
// build-pass

use spirv_std::{arch, storage_class::{Output, UniformConstant}, Image2d, Image2dArray, Sampler};

#[spirv(fragment)]
pub fn main(
image: UniformConstant<Image2d>,
image_array: UniformConstant<Image2dArray>,
sampler: UniformConstant<Sampler>,
mut image_output: Output<glam::Vec4>,
mut image_array_output: Output<glam::Vec4>,
) {
let image_result = image.sample_by_lod(*sampler, glam::Vec2::new(0.0, 1.0), 0.0);
*image_output = image_result;
let image_array_result = image_array.sample_by_lod(*sampler, glam::Vec3A::new(0.0, 0.0, 1.0), 0.0);
*image_array_output = image_array_result;
}

0 comments on commit 8344a74

Please sign in to comment.