Skip to content

Commit

Permalink
Add Const Generic Image Type (#359)
Browse files Browse the repository at this point in the history
* Add parameterized Image type

* nits

* Update crates/spirv-std/src/lib.rs

* Update crates/rustc_codegen_spirv/src/symbols.rs

* Update crates/rustc_codegen_spirv/src/symbols.rs

* Update symbols.rs
  • Loading branch information
XAMPPRocky committed May 3, 2021
1 parent 83fcf46 commit 64edcf3
Show file tree
Hide file tree
Showing 45 changed files with 1,920 additions and 123 deletions.
48 changes: 26 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ members = [
"crates/rustc_codegen_spirv",
"crates/spirv-builder",
"crates/spirv-std",
"crates/spirv-std/shared",
"crates/spirv-std/macros",

"tests",
"tests/deps-helper",
Expand All @@ -34,7 +36,7 @@ codegen-units = 256

[patch.crates-io]
spirv-std = { path = "./crates/spirv-std" }
spirv-std-macros = { path = "./crates/spirv-std-macros" }
spirv-std-macros = { path = "./crates/spirv-std/macros" }
# TODO: Remove once next version is released - needed to include these two PRs:
# * Manishearth/compiletest-rs#240 (for handling SPIR-V extension across platforms)
# * Manishearth/compiletest-rs#241 (for the `$TEST_BUILD_DIR` path normalization)
Expand Down
95 changes: 94 additions & 1 deletion crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use rustc_errors::ErrorReported;
use rustc_middle::bug;
use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{GeneratorSubsts, PolyFnSig, Ty, TyKind, TypeAndMut};
use rustc_middle::ty::{
Const, FloatTy, GeneratorSubsts, IntTy, ParamEnv, PolyFnSig, Ty, TyKind, TypeAndMut, UintTy,
};
use rustc_span::def_id::DefId;
use rustc_span::Span;
use rustc_target::abi::call::{CastTarget, FnAbi, PassMode, Reg, RegKind};
Expand All @@ -21,6 +23,9 @@ use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::fmt;

use num_traits::cast::FromPrimitive;
use rspirv::spirv;

/// If a struct contains a pointer to itself, even indirectly, then doing a naiive recursive walk
/// of the fields will result in an infinite loop. Because pointers are the only thing that are
/// allowed to be recursive, keep track of what pointers we've translated, or are currently in the
Expand Down Expand Up @@ -768,6 +773,94 @@ fn trans_intrinsic_type<'tcx>(
}
// Hardcode to float for now
let sampled_type = SpirvType::Float(32).def(span, cx);

let ty = SpirvType::Image {
sampled_type,
dim,
depth,
arrayed,
multisampled,
sampled,
image_format,
access_qualifier,
};

Ok(ty.def(span, cx))
}
IntrinsicType::GenericImageType => {
// see SpirvType::sizeof
if ty.size != Size::from_bytes(4) {
cx.tcx
.sess
.err("#[spirv(generic_image)] type must have size 4");
return Err(ErrorReported);
}

fn type_from_variant_discriminant<'tcx, P: FromPrimitive>(
cx: &CodegenCx<'tcx>,
const_: &'tcx Const<'tcx>,
) -> P {
let adt_def = const_.ty.ty_adt_def().unwrap();
assert!(adt_def.is_enum());
let destructured = cx.tcx.destructure_const(ParamEnv::reveal_all().and(const_));
let idx = destructured.variant.unwrap();
let value = const_.ty.discriminant_for_variant(cx.tcx, idx).unwrap().val as u64;
<_>::from_u64(value).unwrap()
}

let sampled_type = match substs.type_at(0).kind() {
TyKind::Int(int) => match int {
IntTy::Isize => {
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, true)
.def(span, cx)
}
IntTy::I8 => SpirvType::Integer(8, true).def(span, cx),
IntTy::I16 => SpirvType::Integer(16, true).def(span, cx),
IntTy::I32 => SpirvType::Integer(32, true).def(span, cx),
IntTy::I64 => SpirvType::Integer(64, true).def(span, cx),
IntTy::I128 => SpirvType::Integer(128, true).def(span, cx),
},
TyKind::Uint(uint) => match uint {
UintTy::Usize => {
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, false)
.def(span, cx)
}
UintTy::U8 => SpirvType::Integer(8, false).def(span, cx),
UintTy::U16 => SpirvType::Integer(16, false).def(span, cx),
UintTy::U32 => SpirvType::Integer(32, false).def(span, cx),
UintTy::U64 => SpirvType::Integer(64, false).def(span, cx),
UintTy::U128 => SpirvType::Integer(128, false).def(span, cx),
},
TyKind::Float(FloatTy::F32) => SpirvType::Float(32).def(span, cx),
TyKind::Float(FloatTy::F64) => SpirvType::Float(64).def(span, cx),
_ => {
cx.tcx
.sess
.span_err(span, "Invalid sampled type to `Image`.");
return Err(ErrorReported);
}
};

let dim: spirv::Dim = type_from_variant_discriminant(cx, substs.const_at(1));
let depth: u32 = type_from_variant_discriminant(cx, substs.const_at(2));
let arrayed: u32 = type_from_variant_discriminant(cx, substs.const_at(3));
let multisampled: u32 = type_from_variant_discriminant(cx, substs.const_at(4));
let sampled: u32 = type_from_variant_discriminant(cx, substs.const_at(5));
let image_format: spirv::ImageFormat =
type_from_variant_discriminant(cx, substs.const_at(6));

let access_qualifier = {
let option = cx
.tcx
.destructure_const(ParamEnv::reveal_all().and(substs.const_at(7)));

match option.variant.map(|i| i.as_u32()).unwrap_or(0) {
0 => None,
1 => Some(type_from_variant_discriminant(cx, option.fields[0])),
_ => unreachable!(),
}
};

let ty = SpirvType::Image {
sampled_type,
dim,
Expand Down
1 change: 1 addition & 0 deletions crates/rustc_codegen_spirv/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ impl From<ExecutionModel> for Entry {
/// `struct` types that are used to represent special SPIR-V types.
#[derive(Debug, Clone)]
pub enum IntrinsicType {
GenericImageType,
ImageType {
dim: Dim,
depth: u32,
Expand Down
4 changes: 4 additions & 0 deletions crates/rustc_codegen_spirv/src/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ impl Symbols {
"sampler",
SpirvAttribute::IntrinsicType(IntrinsicType::Sampler),
),
(
"generic_image_type",
SpirvAttribute::IntrinsicType(IntrinsicType::GenericImageType),
),
(
"acceleration_structure",
SpirvAttribute::IntrinsicType(IntrinsicType::AccelerationStructureKhr),
Expand Down
2 changes: 1 addition & 1 deletion crates/spirv-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ fn invoke_rustc(builder: &SpirvBuilder, multimodule: bool) -> Result<PathBuf, Sp
.unwrap_or_default();

let rustflags = format!(
"-Z codegen-backend={} -Z symbol-mangling-version=v0{}",
"-Z codegen-backend={} -Zsymbol-mangling-version=v0{}",
rustc_codegen_spirv.display(),
llvm_args,
);
Expand Down
3 changes: 2 additions & 1 deletion crates/spirv-std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ 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-std-macros = { path = "../spirv-std-macros", version = "0.4.0-alpha.0" }
spirv-types = { path = "./shared", version = "0.4.0-alpha.3" }
spirv-std-macros = { path = "./macros", version = "0.4.0-alpha.3" }

[features]
default = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ description = "Macros for spirv-std"
proc-macro = true

[dependencies]
spirv-types = { path = "../shared", version = "0.4.0-alpha.3" }
heck = "0.3.2"
proc-macro2 = "1.0.24"
quote = "1.0.8"
syn = { version = "1.0.58", features=["full"] }
Loading

0 comments on commit 64edcf3

Please sign in to comment.