From f61e38c2566552c5ebba878066124da959a866e1 Mon Sep 17 00:00:00 2001 From: khyperia Date: Mon, 22 Mar 2021 11:02:17 +0100 Subject: [PATCH] Add cubemaps --- crates/spirv-std/src/textures.rs | 100 ++++++++++++++++++++++++++++++ tests/ui/image/read.rs | 6 +- tests/ui/image/sample.rs | 23 +++++++ tests/ui/image/sample_gradient.rs | 25 +++++--- tests/ui/image/sample_lod.rs | 25 +++++--- 5 files changed, 158 insertions(+), 21 deletions(-) create mode 100644 tests/ui/image/sample.rs diff --git a/crates/spirv-std/src/textures.rs b/crates/spirv-std/src/textures.rs index 6a2a8003fe..7381d365cf 100644 --- a/crates/spirv-std/src/textures.rs +++ b/crates/spirv-std/src/textures.rs @@ -292,6 +292,106 @@ impl Image2dArray { } } +#[spirv(image_type( + // sampled_type is hardcoded to f32 for now + dim = "DimCube", + depth = 0, + arrayed = 0, + multisampled = 0, + sampled = 1, + image_format = "Unknown" +))] +#[derive(Copy, Clone)] +pub struct Cubemap { + _x: u32, +} + +impl Cubemap { + #[spirv_std_macros::gpu_only] + #[cfg(feature = "const-generics")] + pub fn sample>( + &self, + sampler: Sampler, + coordinate: impl Vector, + ) -> V { + unsafe { + let mut result = Default::default(); + asm!( + "%image = OpLoad _ {this}", + "%sampler = OpLoad _ {sampler}", + "%coordinate = OpLoad _ {coordinate}", + "%sampledImage = OpSampledImage _ %image %sampler", + "%result = OpImageSampleImplicitLod _ %sampledImage %coordinate", + "OpStore {result} %result", + result = in(reg) &mut result, + this = in(reg) self, + sampler = in(reg) &sampler, + coordinate = in(reg) &coordinate, + ); + result + } + } + #[spirv_std_macros::gpu_only] + #[cfg(feature = "const-generics")] + /// Sample the image at a coordinate by a lod + 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")] + /// 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>( + &self, + sampler: Sampler, + coordinate: impl Vector, + gradient_dx: impl Vector, + gradient_dy: impl Vector, + ) -> 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)] #[derive(Copy, Clone)] pub struct SampledImage { diff --git a/tests/ui/image/read.rs b/tests/ui/image/read.rs index 81dcbaea7a..986cacd44e 100644 --- a/tests/ui/image/read.rs +++ b/tests/ui/image/read.rs @@ -1,7 +1,11 @@ // Test `OpImageRead` // build-pass -use spirv_std::{arch, storage_class::{Output, UniformConstant}, StorageImage2d}; +use spirv_std::{ + arch, + storage_class::{Output, UniformConstant}, + StorageImage2d, +}; #[spirv(fragment)] pub fn main(image: UniformConstant, mut output: Output) { diff --git a/tests/ui/image/sample.rs b/tests/ui/image/sample.rs new file mode 100644 index 0000000000..e90c2dce4d --- /dev/null +++ b/tests/ui/image/sample.rs @@ -0,0 +1,23 @@ +// Test `OpImageSampleImplicitLod` +// build-pass + +use spirv_std::{ + arch, + storage_class::{Output, UniformConstant}, + Cubemap, Image2d, Image2dArray, Sampler, +}; + +#[spirv(fragment)] +pub fn main( + image2d: UniformConstant, + image2d_array: UniformConstant, + cubemap: UniformConstant, + sampler: UniformConstant, + mut output: Output, +) { + let v2 = glam::Vec2::new(0.0, 1.0); + let v3 = glam::Vec3::new(0.0, 1.0, 0.5); + *output = image2d.sample(*sampler, v2); + *output += image2d_array.sample(*sampler, v3); + *output += cubemap.sample(*sampler, v3); +} diff --git a/tests/ui/image/sample_gradient.rs b/tests/ui/image/sample_gradient.rs index e6c011ba6c..9ba2bc5b8c 100644 --- a/tests/ui/image/sample_gradient.rs +++ b/tests/ui/image/sample_gradient.rs @@ -1,18 +1,23 @@ -// Test `OpImageSampleExplicitLod` +// Test `OpImageSampleExplicitLod` Grad // build-pass -use spirv_std::{arch, storage_class::{Output, UniformConstant}, Image2d, Image2dArray, Sampler}; +use spirv_std::{ + arch, + storage_class::{Output, UniformConstant}, + Cubemap, Image2d, Image2dArray, Sampler, +}; #[spirv(fragment)] pub fn main( - image: UniformConstant, - image_array: UniformConstant, + image2d: UniformConstant, + image2d_array: UniformConstant, + cubemap: UniformConstant, sampler: UniformConstant, - mut image_output: Output, - mut image_array_output: Output, + mut output: Output, ) { - 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; + let v2 = glam::Vec2::new(0.0, 1.0); + let v3 = glam::Vec3::new(0.0, 1.0, 0.5); + *output = image2d.sample_by_gradient(*sampler, v2, v2, v2); + *output += image2d_array.sample_by_gradient(*sampler, v3, v2, v2); + *output += cubemap.sample_by_gradient(*sampler, v3, v3, v3); } diff --git a/tests/ui/image/sample_lod.rs b/tests/ui/image/sample_lod.rs index 2e5659dcef..78d3f4d0f2 100644 --- a/tests/ui/image/sample_lod.rs +++ b/tests/ui/image/sample_lod.rs @@ -1,18 +1,23 @@ -// Test `OpImageSampleExplicitLod` +// Test `OpImageSampleExplicitLod` Lod // build-pass -use spirv_std::{arch, storage_class::{Output, UniformConstant}, Image2d, Image2dArray, Sampler}; +use spirv_std::{ + arch, + storage_class::{Output, UniformConstant}, + Cubemap, Image2d, Image2dArray, Sampler, +}; #[spirv(fragment)] pub fn main( - image: UniformConstant, - image_array: UniformConstant, + image2d: UniformConstant, + image2d_array: UniformConstant, + cubemap: UniformConstant, sampler: UniformConstant, - mut image_output: Output, - mut image_array_output: Output, + mut output: Output, ) { - 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; + let v2 = glam::Vec2::new(0.0, 1.0); + let v3 = glam::Vec3::new(0.0, 1.0, 0.5); + *output = image2d.sample_by_lod(*sampler, v2, 0.0); + *output += image2d_array.sample_by_lod(*sampler, v3, 0.0); + *output += cubemap.sample_by_lod(*sampler, v3, 0.0); }