Merge branch 'main' into nanoserde

This commit is contained in:
Johan Andersson 2022-08-12 22:26:36 +02:00
commit c78d7db769
43 changed files with 830 additions and 121 deletions

2
.github/CODEOWNERS vendored
View File

@ -1,3 +1,3 @@
* @eddyb
* @eddyb @oisyn
/examples/ @fu5ha @VZout

View File

@ -22,7 +22,7 @@ jobs:
target: aarch64-linux-android
runs-on: ${{ matrix.os }}
env:
spirv_tools_version: "20210805"
spirv_tools_version: "20220414" # get platform-specific download link from https://github.com/KhronosGroup/SPIRV-Tools/blob/master/docs/downloads.md
RUSTUP_UNPACK_RAM: "26214400"
RUSTUP_IO_THREADS: "1"
steps:
@ -33,8 +33,8 @@ jobs:
name: Linux - Install native dependencies
run: |
sudo apt install libwayland-cursor0 libxkbcommon-dev libwayland-dev
mkdir "${HOME}/spirv-tools"
curl -fL https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/linux-clang-release/continuous/1530/20210805-040049/install.tgz | tar -xz -C "${HOME}/spirv-tools"
mkdir "${HOME}/spirv-tools"
curl -fL https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/linux-clang-release/continuous/1744/20220414-060821/install.tgz | tar -xz -C "${HOME}/spirv-tools"
echo "${HOME}/spirv-tools/install/bin" >> $GITHUB_PATH
- if: ${{ runner.os == 'macOS' }}
name: Mac - Install spirv-tools
@ -47,7 +47,7 @@ jobs:
run: |
tmparch=$(mktemp)
mkdir "${HOME}/spirv-tools"
curl -fL -o "$tmparch" https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/windows-msvc-2017-release/continuous/1517/20210805-040116/install.zip
curl -fL -o "$tmparch" https://storage.googleapis.com/spirv-tools/artifacts/prod/graphics_shader_compiler/spirv-tools/windows-msvc-2017-release/continuous/1732/20220414-060824/install.zip
unzip "$tmparch" -d "${HOME}/spirv-tools"
- if: ${{ runner.os == 'Windows' }}
# Runs separately to add spir-v tools to Powershell's Path.
@ -94,7 +94,8 @@ jobs:
echo "::endgroup::"
echo "::group::Install cargo-apk"
cargo install cargo-apk
echo "FIXME(eddyb) working around libc 0.2.127 breakage by using stable Rust!"
cargo +stable install cargo-apk
echo "::endgroup::"
echo "::group::Add aarch64-linux-android target"

58
Cargo.lock generated
View File

@ -343,7 +343,7 @@ dependencies = [
[[package]]
name = "compiletests"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"compiletest_rs",
"rustc_codegen_spirv",
@ -352,14 +352,14 @@ dependencies = [
[[package]]
name = "compiletests-deps-helper"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"spirv-std",
]
[[package]]
name = "compute-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"rayon",
"spirv-std",
@ -518,12 +518,12 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if 1.0.0",
"lazy_static",
"once_cell",
]
[[package]]
@ -725,7 +725,7 @@ dependencies = [
[[package]]
name = "example-runner-ash"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"ash",
"ash-molten",
@ -740,7 +740,7 @@ dependencies = [
[[package]]
name = "example-runner-cpu"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"minifb",
"rayon",
@ -750,7 +750,7 @@ dependencies = [
[[package]]
name = "example-runner-wgpu"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"bytemuck",
"cfg-if 1.0.0",
@ -771,7 +771,7 @@ dependencies = [
[[package]]
name = "example-runner-wgpu-builder"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"spirv-builder",
]
@ -1348,7 +1348,7 @@ dependencies = [
[[package]]
name = "mouse-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"shared",
"spirv-std",
@ -1356,7 +1356,7 @@ dependencies = [
[[package]]
name = "multibuilder"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"spirv-builder",
]
@ -1947,7 +1947,7 @@ dependencies = [
[[package]]
name = "reduce"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"spirv-std",
]
@ -2009,7 +2009,7 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_codegen_spirv"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
dependencies = [
"ar",
"bimap",
@ -2032,7 +2032,7 @@ dependencies = [
[[package]]
name = "rustc_codegen_spirv-types"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
dependencies = [
"nanoserde",
"rspirv",
@ -2079,9 +2079,9 @@ dependencies = [
[[package]]
name = "sanitize-filename"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf18934a12018228c5b55a6dae9df5d0641e3566b3630cb46cc55564068e7c2f"
checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c"
dependencies = [
"lazy_static",
"regex",
@ -2160,7 +2160,7 @@ dependencies = [
[[package]]
name = "shared"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"bytemuck",
"spirv-std",
@ -2174,7 +2174,7 @@ checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
name = "simplest-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"shared",
"spirv-std",
@ -2182,7 +2182,7 @@ dependencies = [
[[package]]
name = "sky-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
dependencies = [
"shared",
"spirv-std",
@ -2240,7 +2240,7 @@ dependencies = [
[[package]]
name = "spirv-builder"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
dependencies = [
"memchr",
"nanoserde",
@ -2252,25 +2252,29 @@ dependencies = [
[[package]]
name = "spirv-std"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
dependencies = [
"bitflags",
"glam",
"num-traits",
"spirv-std-macros",
"spirv-types",
"spirv-std-types",
]
[[package]]
name = "spirv-std-macros"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
dependencies = [
"proc-macro2",
"quote",
"spirv-types",
"spirv-std-types",
"syn",
]
[[package]]
name = "spirv-std-types"
version = "0.4.0-alpha.14"
[[package]]
name = "spirv-tools"
version = "0.8.0"
@ -2291,10 +2295,6 @@ dependencies = [
"cc",
]
[[package]]
name = "spirv-types"
version = "0.4.0-alpha.12"
[[package]]
name = "strsim"
version = "0.8.0"

View File

@ -1,7 +1,7 @@
[package]
name = "rustc_codegen_spirv-types"
description = "SPIR-V backend types shared between rustc_codegen_spirv and spirv-builder"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,10 +1,11 @@
[package]
name = "rustc_codegen_spirv"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
repository = "https://github.com/EmbarkStudios/rust-gpu"
description = "SPIR-V code generator backend for rustc"
#keywords = []
#categories = []
#readme = "README.md"
@ -40,11 +41,11 @@ bimap = "0.6"
indexmap = "1.6.0"
rspirv = "0.11"
rustc-demangle = "0.1.21"
sanitize-filename = "0.3"
sanitize-filename = "0.4"
nanoserde = "0.1.9"
smallvec = "1.6.1"
spirv-tools = { version = "0.8", default-features = false }
rustc_codegen_spirv-types = { path = "../rustc_codegen_spirv-types", version = "0.4.0-alpha.12" }
rustc_codegen_spirv-types = { path = "../rustc_codegen_spirv-types", version = "0.4.0-alpha.14" }
[dev-dependencies]
pipe = "0.4"

View File

@ -412,6 +412,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if field_ty_kind
.sizeof(self)
.map_or(true, |size| offset_in_field < size)
// If the field is a zero sized type, check the type to
// get the correct entry
|| offset_in_field == Size::ZERO && leaf_ty == field_ty
{
Some((i, field_ty, field_ty_kind, offset_in_field))
} else {

View File

@ -35,8 +35,12 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
// Drop all the functions we'll be inlining. (This also means we won't waste time processing
// inlines in functions that will get inlined)
let mut dropped_ids = FxHashSet::default();
let mut inlined_dont_inlines = Vec::new();
module.functions.retain(|f| {
if should_inline(&disallowed_argument_types, &disallowed_return_types, f) {
if has_dont_inline(f) {
inlined_dont_inlines.push(f.def_id().unwrap());
}
// TODO: We should insert all defined IDs in this function.
dropped_ids.insert(f.def_id().unwrap());
false
@ -44,6 +48,17 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
true
}
});
if !inlined_dont_inlines.is_empty() {
let names = get_names(module);
for f in inlined_dont_inlines {
sess.warn(&format!(
"`#[inline(never)]` function `{}` needs to be inlined \
because it has illegal argument or return types",
get_name(&names, f)
));
}
}
// Drop OpName etc. for inlined functions
module.debug_names.retain(|inst| {
!inst.operands.iter().any(|op| {
@ -204,6 +219,12 @@ fn compute_disallowed_argument_and_return_types(
(disallowed_argument_types, disallowed_return_types)
}
fn has_dont_inline(function: &Function) -> bool {
let def = function.def.as_ref().unwrap();
let control = def.operands[0].unwrap_function_control();
control.contains(FunctionControl::DONT_INLINE)
}
fn should_inline(
disallowed_argument_types: &FxHashSet<Word>,
disallowed_return_types: &FxHashSet<Word>,

View File

@ -651,7 +651,7 @@ fn parse_entry_attrs(
.execution_modes
.push((origin_mode, ExecutionModeExtra::new([])));
}
GLCompute => {
GLCompute | MeshNV | TaskNV => {
if let Some(local_size) = local_size {
entry
.execution_modes
@ -660,7 +660,7 @@ fn parse_entry_attrs(
return Err((
arg.span(),
String::from(
"The `threads` argument must be specified when using `#[spirv(compute)]`",
"The `threads` argument must be specified when using `#[spirv(compute)]`, `#[spirv(mesh_nv)]` or `#[spirv(task_nv)]`",
),
));
}

View File

@ -1,9 +1,11 @@
[package]
name = "spirv-builder"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
repository = "https://github.com/EmbarkStudios/rust-gpu"
description = "Helper for building shaders with rust-gpu"
# See rustc_codegen_spirv/Cargo.toml for details on these features
[features]
@ -16,8 +18,8 @@ watch = ["notify"]
memchr = "2.4"
raw-string = "0.3.5"
nanoserde = "0.1.9"
rustc_codegen_spirv-types = { path = "../rustc_codegen_spirv-types" }
rustc_codegen_spirv-types = { path = "../rustc_codegen_spirv-types", version = "0.4.0-alpha.14" }
# See comment in lib.rs invoke_rustc for why this is here
rustc_codegen_spirv = { path = "../rustc_codegen_spirv", default-features = false }
rustc_codegen_spirv = { path = "../rustc_codegen_spirv", version = "0.4.0-alpha.14", default-features = false }
notify = { version = "5.0.0-pre.11", optional = true }

View File

@ -1,6 +1,6 @@
[package]
name = "spirv-std"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
@ -10,9 +10,9 @@ description = "Standard functions and types for SPIR-V"
[dependencies]
bitflags = "1.2.1"
num-traits = { version = "0.2.14", default-features = false, features = ["libm"] }
spirv-types = { path = "./shared", version = "0.4.0-alpha.12" }
spirv-std-macros = { path = "./macros", version = "0.4.0-alpha.12" }
glam = { version = ">=0.17, <=0.20", default-features = false, features = ["libm"], optional = true }
spirv-std-types = { path = "./shared", version = "0.4.0-alpha.14" }
spirv-std-macros = { path = "./macros", version = "0.4.0-alpha.13" }
glam = { version = ">=0.17, <=0.21", default-features = false, features = ["libm"], optional = true }
[features]
default = []

View File

@ -1,6 +1,6 @@
[package]
name = "spirv-std-macros"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
@ -11,7 +11,7 @@ description = "Macros for spirv-std"
proc-macro = true
[dependencies]
spirv-types = { path = "../shared", version = "0.4.0-alpha.12" }
spirv-std-types = { path = "../shared", version = "0.4.0-alpha.14" }
proc-macro2 = "1.0.24"
quote = "1.0.8"
syn = { version = "1.0.58", features=["full"] }

View File

@ -1,7 +1,7 @@
use proc_macro2::Ident;
use quote::{quote, TokenStreamExt};
use spirv_types::image_params::*;
use spirv_std_types::image_params::*;
use syn::parse::{Parse, ParseStream};
use self::params::SampledType;

View File

@ -121,7 +121,7 @@ use quote::ToTokens;
/// - `depth` — Whether it is known that the image is a depth image.
/// Accepted values: `true` or `false`. Default: `unknown`.
///
/// [`ImageFormat`]: spirv_types::image_params::ImageFormat
/// [`ImageFormat`]: spirv_std_types::image_params::ImageFormat
///
/// Keep in mind that `sampled` here is a different concept than the `SampledImage` type:
/// `sampled=true` means that this image requires a sampler to be able to access, while the

View File

@ -1,7 +1,7 @@
[package]
name = "spirv-types"
name = "spirv-std-types"
description = "SPIR-V types shared between spirv-std and spirv-std-macros"
version = "0.4.0-alpha.12"
version = "0.4.0-alpha.14"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -11,12 +11,14 @@ use crate::{
#[cfg(target_arch = "spirv")]
use core::arch::asm;
mod atomics;
mod barrier;
mod demote_to_helper_invocation_ext;
mod derivative;
mod primitive;
mod ray_tracing;
pub use atomics::*;
pub use barrier::*;
pub use demote_to_helper_invocation_ext::*;
pub use derivative::*;
@ -226,29 +228,6 @@ pub fn signed_max<T: SignedInteger>(a: T, b: T) -> T {
unsafe { call_glsl_op_with_ints::<_, 42>(a, b) }
}
/// Atomically increment an integer and return the old value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicIIncrement")]
pub unsafe fn atomic_i_increment<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%old = OpAtomicIIncrement _ {ptr} %scope %semantics",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
}
old
}
/// Index into an array without bounds checking.
///
/// The main purpose of this trait is to work around the fact that the regular `get_unchecked*`

View File

@ -0,0 +1,611 @@
#[cfg(target_arch = "spirv")]
use core::arch::asm;
use crate::{
float::Float,
integer::{Integer, SignedInteger, UnsignedInteger},
number::Number,
};
/// Atomically load through `ptr` using the given `SEMANTICS`. All subparts of
/// the value that is loaded are read atomically with respect to all other
/// atomic accesses to it within `SCOPE`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicLoad")]
#[inline]
pub unsafe fn atomic_load<N: Number, const SCOPE: u32, const SEMANTICS: u32>(ptr: &N) -> N {
let mut result = N::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%result = OpAtomicLoad _ {ptr} %scope %semantics",
"OpStore {result} %result",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
result = in(reg) &mut result
}
result
}
/// Atomically store through `ptr` using the given `SEMANTICS`. All subparts of
/// `value` are written atomically with respect to all other atomic accesses to
/// it within `SCOPE`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicStore")]
#[inline]
pub unsafe fn atomic_store<N: Number, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut N,
value: N,
) {
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"OpAtomicStore {ptr} %scope %semantics %value",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
value = in(reg) &value
}
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1. Load through `ptr` to get the original value,
/// 2. Get a new value from copying `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicExchange")]
#[inline]
pub unsafe fn atomic_exchange<N: Number, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut N,
value: N,
) -> N {
let mut old = N::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicExchange _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1. Load through `ptr` to get the original value
/// 2. Get a new value from `value` only if the original value equals
/// `comparator`, and
/// 3. Store the new value back through `ptr`, only if the original value
/// equaled `comparator`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicCompareExchange")]
#[inline]
pub unsafe fn atomic_compare_exchange<
I: Integer,
const SCOPE: u32,
const EQUAL: u32,
const UNEQUAL: u32,
>(
ptr: &mut I,
value: I,
comparator: I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%equal = OpConstant %u32 {equal}",
"%unequal = OpConstant %u32 {unequal}",
"%value = OpLoad _ {value}",
"%comparator = OpLoad _ {comparator}",
"%old = OpAtomicCompareExchange _ {ptr} %scope %equal %unequal %value %comparator",
"OpStore {old} %old",
scope = const SCOPE,
equal = const EQUAL,
unequal = const UNEQUAL,
ptr = in(reg) ptr,
value = in(reg) &value,
comparator = in(reg) &comparator,
old = in(reg) &mut old,
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value through integer addition of 1 to original value, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicIIncrement")]
#[inline]
pub unsafe fn atomic_i_increment<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%old = OpAtomicIIncrement _ {ptr} %scope %semantics",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1) load through `ptr` to get an original value,
/// 2) get a new value through integer subtraction of 1 from original value, and
/// 3) store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicIDecrement")]
#[inline]
pub unsafe fn atomic_i_decrement<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%old = OpAtomicIDecrement _ {ptr} %scope %semantics",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1) load through `ptr` to get an original value,
/// 2) get a new value by integer addition of original value and `value`, and
/// 3) store the new value back through `ptr`.
///
/// The result is the Original Value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicIAdd")]
#[inline]
pub unsafe fn atomic_i_add<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
value: I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicIAdd _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1) load through `ptr` to get an original value,
/// 2) get a new value by integer subtraction of original value and `value`, and
/// 3) store the new value back through `ptr`.
///
/// The result is the Original Value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicISub")]
#[inline]
pub unsafe fn atomic_i_sub<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
value: I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicISub _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by finding the smallest signed integer of original value
/// and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicSMin")]
#[inline]
pub unsafe fn atomic_s_min<S: SignedInteger, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut S,
value: S,
) -> S {
let mut old = S::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicSMin _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by finding the smallest unsigned integer of original
/// value and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicUMin")]
#[inline]
pub unsafe fn atomic_u_min<U: UnsignedInteger, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut U,
value: U,
) -> U {
let mut old = U::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicUMin _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by finding the largest signed integer of original value
/// and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicSMax")]
#[inline]
pub unsafe fn atomic_s_max<S: SignedInteger, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut S,
value: S,
) -> S {
let mut old = S::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicSMax _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by finding the largest unsigned integer of original
/// value and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicUMax")]
#[inline]
pub unsafe fn atomic_u_max<U: UnsignedInteger, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut U,
value: U,
) -> U {
let mut old = U::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicUMax _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by the bitwise AND of the original value and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicAnd")]
#[inline]
pub unsafe fn atomic_and<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
value: I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicAnd _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by the bitwise OR of the original value and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicOr")]
#[inline]
pub unsafe fn atomic_or<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
value: I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicOr _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by the bitwise XOR of the original value and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicXor")]
#[inline]
pub unsafe fn atomic_xor<I: Integer, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut I,
value: I,
) -> I {
let mut old = I::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicXor _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by finding the smallest signed integer of original value
/// and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicFMinEXT")]
#[inline]
pub unsafe fn atomic_f_min<F: Float, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut F,
value: F,
) -> F {
let mut old = F::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicFMinEXT _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within Scope to the same location:
///
/// 1. Load through `ptr` to get an original value,
/// 2. Get a new value by finding the largest signed integer of original value
/// and `value`, and
/// 3. Store the new value back through `ptr`.
///
/// The result is the original value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicFMaxEXT")]
#[inline]
pub unsafe fn atomic_f_max<F: Float, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut F,
value: F,
) -> F {
let mut old = F::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicFMaxEXT _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}
/// Perform the following steps atomically with respect to any other atomic
/// accesses within `SCOPE` to the same location:
///
/// 1) load through `ptr` to get an original value,
/// 2) get a new value by integer addition of original value and `value`, and
/// 3) store the new value back through `ptr`.
///
/// The result is the Original Value.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpAtomicFAddEXT")]
#[inline]
pub unsafe fn atomic_f_add<F: Float, const SCOPE: u32, const SEMANTICS: u32>(
ptr: &mut F,
value: F,
) -> F {
let mut old = F::default();
asm! {
"%u32 = OpTypeInt 32 0",
"%scope = OpConstant %u32 {scope}",
"%semantics = OpConstant %u32 {semantics}",
"%value = OpLoad _ {value}",
"%old = OpAtomicFMaxEXT _ {ptr} %scope %semantics %value",
"OpStore {old} %old",
scope = const SCOPE,
semantics = const SEMANTICS,
ptr = in(reg) ptr,
old = in(reg) &mut old,
value = in(reg) &value
}
old
}

View File

@ -10,7 +10,7 @@ mod params;
pub use self::params::{ImageCoordinate, ImageCoordinateSubpassData, SampleType};
pub use crate::macros::Image;
pub use spirv_types::image_params::{
pub use spirv_std_types::image_params::{
AccessQualifier, Arrayed, Dimensionality, ImageDepth, ImageFormat, Multisampled, Sampled,
};

View File

@ -102,6 +102,7 @@ pub mod float;
pub mod image;
pub mod integer;
pub mod memory;
pub mod number;
pub mod ray_tracing;
mod runtime_array;
mod sampler;
@ -130,7 +131,7 @@ extern "C" fn rust_eh_personality() {}
// See: https://github.com/rust-lang/rust/issues/84738
#[doc(hidden)]
/// [spirv_types]
/// [spirv_std_types]
pub fn workaround_rustdoc_ice_84738() {}
#[doc(hidden)]

View File

@ -0,0 +1,15 @@
//! Traits and helper functions related to numbers.
/// Abstract trait representing a SPIR-V integer or floating-point type.
pub trait Number: crate::scalar::Scalar {}
impl Number for u8 {}
impl Number for u16 {}
impl Number for u32 {}
impl Number for u64 {}
impl Number for i8 {}
impl Number for i16 {}
impl Number for i32 {}
impl Number for i64 {}
impl Number for f32 {}
impl Number for f64 {}

View File

@ -36,11 +36,11 @@ skip = [
# by default infinite
skip-tree = [
# we don't really care if our example brings in some duplicate dependencies, for now
{ name = "example-runner-ash", version = "0.4.0-alpha.12", depth = 20 },
{ name = "example-runner-cpu", version = "0.4.0-alpha.12", depth = 20 },
{ name = "example-runner-wgpu", version = "0.4.0-alpha.12", depth = 20 },
{ name = "compiletests", version = "0.4.0-alpha.12", depth = 20 },
{ name = "compiletests-deps-helper", version = "0.4.0-alpha.12", depth = 20 },
{ name = "example-runner-ash", version = "0.0.0", depth = 20 },
{ name = "example-runner-cpu", version = "0.0.0", depth = 20 },
{ name = "example-runner-wgpu", version = "0.0.0", depth = 20 },
{ name = "compiletests", version = "0.0.0", depth = 20 },
{ name = "compiletests-deps-helper", version = "0.0.0", depth = 20 },
]

View File

@ -67,6 +67,8 @@ rustdoc for documentation.
const SHADER: &[u8] = include_bytes!(env!("<shader_name>.spv"));
```
> **Note** If your shader name contains hyphens, the name of environment variable will be the name with hyphens changed to underscores.
Keep in mind that by default, build-dependencies are built in debug mode. This
means that the rust-gpu compiler (`rustc_codegen_spirv`) will be built in debug
mode, and will be *incredibly* slow. You can solve this by placing this bit of

View File

@ -1,6 +1,6 @@
[package]
name = "multibuilder"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "example-runner-ash"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "example-runner-cpu"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "example-runner-wgpu"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -35,6 +35,7 @@ fn main() -> Result<(), Box<dyn Error>> {
"--target-dir",
])
.arg(dir)
.env_remove("CARGO_ENCODED_RUSTFLAGS")
.stderr(std::process::Stdio::inherit())
.stdout(std::process::Stdio::inherit())
.status()?;

View File

@ -1,6 +1,6 @@
[package]
name = "example-runner-wgpu-builder"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -2,7 +2,7 @@ use wgpu::util::DeviceExt;
use super::Options;
use futures::future::join;
use std::{convert::TryInto, future::Future, num::NonZeroU64, time::Duration};
use std::{convert::TryInto, future::Future, time::Duration};
fn block_on<T>(future: impl Future<Output = T>) -> T {
cfg_if::cfg_if! {
@ -63,20 +63,16 @@ pub async fn start_internal(
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
entries: &[
// XXX - some graphics cards do not support empty bind layout groups, so
// create a dummy entry.
wgpu::BindGroupLayoutEntry {
binding: 0,
count: None,
visibility: wgpu::ShaderStages::COMPUTE,
ty: wgpu::BindingType::Buffer {
has_dynamic_offset: false,
min_binding_size: Some(NonZeroU64::new(1).unwrap()),
ty: wgpu::BufferBindingType::Storage { read_only: false },
},
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
count: None,
visibility: wgpu::ShaderStages::COMPUTE,
ty: wgpu::BindingType::Buffer {
has_dynamic_offset: false,
min_binding_size: None,
ty: wgpu::BufferBindingType::Storage { read_only: false },
},
],
}],
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {

View File

@ -1,6 +1,6 @@
[package]
name = "compute-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "mouse-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "reduce"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "shared"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "simplest-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "sky-shader"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "compiletests"
version = "0.4.0-alpha.12"
version = "0.0.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
@ -14,5 +14,5 @@ use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"]
[dependencies]
compiletest = { version = "0.7.0", package = "compiletest_rs" }
rustc_codegen_spirv = { path = "../crates/rustc_codegen_spirv", default-features = false }
rustc_codegen_spirv = { path = "../crates/rustc_codegen_spirv", version = "0.4.0-alpha.14", default-features = false }
structopt = "0.3.21"

View File

@ -1,6 +1,6 @@
[package]
name = "compiletests-deps-helper"
version = "0.4.0-alpha.12"
version = "0.0.0"
description = "Shared dependencies of all the compiletest tests"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"

View File

@ -260,14 +260,16 @@ fn find_lib(
.map(|entry| entry.path())
.filter(|path| {
let name = {
let name = path.file_name();
let name = path.file_stem();
if name.is_none() {
return false;
}
name.unwrap()
};
let name_matches = name.to_str().unwrap().starts_with(&expected_name);
let name_matches = name.to_str().unwrap().starts_with(&expected_name)
&& name.len() == expected_name.len() + 17 // we expect our name, '-', and then 16 hexadecimal digits
&& ends_with_dash_hash(name.to_str().unwrap());
let extension_matches = path
.extension()
.map_or(false, |ext| ext == expected_extension);
@ -283,6 +285,20 @@ fn find_lib(
})
}
/// Returns whether this string ends with a dash ('-'), followed by 16 lowercase hexadecimal characters
fn ends_with_dash_hash(s: &str) -> bool {
let n = s.len();
if n < 17 {
return false;
}
let mut bytes = s.bytes().skip(n - 17);
if bytes.next() != Some(b'-') {
return false;
}
bytes.all(|b| b.is_ascii_hexdigit())
}
/// Paths to all of the library artifacts of dependencies needed to compile tests.
struct TestDeps {
core: PathBuf,

View File

@ -100,9 +100,9 @@ error[E0277]: the trait bound `{float}: Vector<f32, 2_usize>` is not satisfied
<IVec3 as Vector<i32, 3_usize>>
and 9 others
note: required by a bound in `debug_printf_assert_is_vector`
--> $SPIRV_STD_SRC/lib.rs:144:8
--> $SPIRV_STD_SRC/lib.rs:145:8
|
144 | V: crate::vector::Vector<TY, SIZE>,
145 | V: crate::vector::Vector<TY, SIZE>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `debug_printf_assert_is_vector`
error[E0308]: mismatched types

View File

@ -9,7 +9,7 @@ OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main"
OpExecutionMode %1 OriginUpperLeft
%2 = OpString "$OPSTRING_FILENAME/generic-fn-op-name.rs"
OpName %3 "generic_fn_op_name::generic::<f32, {spirv_types::image_params::Dimensionality::TwoD}>"
OpName %3 "generic_fn_op_name::generic::<f32, {spirv_std_types::image_params::Dimensionality::TwoD}>"
OpName %4 "generic_fn_op_name::main"
%5 = OpTypeVoid
%6 = OpTypeFunction %5

View File

@ -8,16 +8,34 @@ pub fn main(
#[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled),
#[spirv(descriptor_set = 1, binding = 1)] image_array: &Image!(2D, type=f32, arrayed, sampled),
#[spirv(descriptor_set = 2, binding = 2)] sampler: &Sampler,
#[spirv(descriptor_set = 3, binding = 3)] cubemap: &Image!(3D, type=f32, sampled),
output: &mut f32,
) {
let v2 = glam::Vec2::new(0.0, 1.0);
let v2_dx = glam::Vec2::new(0.0, 1.0);
let v2_dy = glam::Vec2::new(0.0, 1.0);
let v3 = glam::Vec3A::new(0.0, 0.0, 1.0);
let v3_dx = glam::Vec3A::new(0.0, 1.0, 0.5);
let v3_dy = glam::Vec3A::new(0.0, 1.0, 0.5);
*output = image.sample_depth_reference_by_gradient(*sampler, v2, 1.0, v2_dx, v2_dy);
*output += image_array.sample_depth_reference_by_gradient(*sampler, v3, 1.0, v2_dx, v2_dy);
}
// NOTE(eddyb) this is separate because it runs afoul of this rule:
// > VUID-StandaloneSpirv-OpImage-04777
// > `OpImage*Dref*` instructions **must** not consume an image whose `Dim` is 3D
// FIXME(eddyb) look into whether non-Vulkan `OpImage*Dref*` usage can ever be 3D
#[cfg(not(any(
target_env = "vulkan1.0",
target_env = "vulkan1.1",
target_env = "vulkan1.1spv1.4",
target_env = "vulkan1.2"
)))]
#[spirv(fragment)]
pub fn main_cubemap(
#[spirv(descriptor_set = 2, binding = 2)] sampler: &Sampler,
#[spirv(descriptor_set = 3, binding = 3)] cubemap: &Image!(3D, type=f32, sampled),
output: &mut f32,
) {
let v3 = glam::Vec3A::new(0.0, 0.0, 1.0);
let v3_dx = glam::Vec3A::new(0.0, 1.0, 0.5);
let v3_dy = glam::Vec3A::new(0.0, 1.0, 0.5);
*output += cubemap.sample_depth_reference_by_gradient(*sampler, v3, 1.0, v3_dx, v3_dy);
}

View File

@ -8,12 +8,30 @@ pub fn main(
#[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled),
#[spirv(descriptor_set = 1, binding = 1)] image_array: &Image!(2D, type=f32, arrayed, sampled),
#[spirv(descriptor_set = 2, binding = 2)] sampler: &Sampler,
#[spirv(descriptor_set = 3, binding = 3)] cubemap: &Image!(3D, type=f32, sampled),
output: &mut f32,
) {
let v2 = glam::Vec2::new(0.0, 1.0);
let v3 = glam::Vec3A::new(0.0, 0.0, 1.0);
*output = image.sample_depth_reference_by_lod(*sampler, v2, 1.0, 0.0);
*output += image_array.sample_depth_reference_by_lod(*sampler, v3, 1.0, 0.0);
}
// NOTE(eddyb) this is separate because it runs afoul of this rule:
// > VUID-StandaloneSpirv-OpImage-04777
// > `OpImage*Dref*` instructions **must** not consume an image whose `Dim` is 3D
// FIXME(eddyb) look into whether non-Vulkan `OpImage*Dref*` usage can ever be 3D
#[cfg(not(any(
target_env = "vulkan1.0",
target_env = "vulkan1.1",
target_env = "vulkan1.1spv1.4",
target_env = "vulkan1.2"
)))]
#[spirv(fragment)]
pub fn main_cubemap(
#[spirv(descriptor_set = 2, binding = 2)] sampler: &Sampler,
#[spirv(descriptor_set = 3, binding = 3)] cubemap: &Image!(3D, type=f32, sampled),
output: &mut f32,
) {
let v3 = glam::Vec3A::new(0.0, 0.0, 1.0);
*output += cubemap.sample_depth_reference_by_lod(*sampler, v3, 1.0, 0.0);
}

View File

@ -0,0 +1,6 @@
warning: `#[inline(never)]` function `nested_ref::deep_load` needs to be inlined because it has illegal argument or return types
warning: `#[inline(never)]` function `nested_ref::deep_transpose` needs to be inlined because it has illegal argument or return types
warning: 2 warnings emitted

View File

@ -0,0 +1,18 @@
// build-pass
use spirv_std as _;
struct A;
struct B;
struct S {
x: A,
y: B,
}
fn f(x: &B) {}
#[spirv(fragment)]
pub fn main() {
let s = S { x: A, y: B };
f(&s.y);
}