Skip to content
This repository was archived by the owner on Oct 31, 2025. It is now read-only.

Commit bb6ae0a

Browse files
committed
Add parameterized Image type
1 parent a42a9f2 commit bb6ae0a

File tree

44 files changed

+1784
-122
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1784
-122
lines changed

Cargo.lock

Lines changed: 28 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ members = [
1212
"crates/rustc_codegen_spirv",
1313
"crates/spirv-builder",
1414
"crates/spirv-std",
15+
"crates/spirv-std/shared",
16+
"crates/spirv-std/macros",
1517

1618
"tests",
1719
"tests/deps-helper",
@@ -34,7 +36,7 @@ codegen-units = 256
3436

3537
[patch.crates-io]
3638
spirv-std = { path = "./crates/spirv-std" }
37-
spirv-std-macros = { path = "./crates/spirv-std-macros" }
39+
spirv-std-macros = { path = "./crates/spirv-std/macros" }
3840
# TODO: Remove once next version is released - needed to include these two PRs:
3941
# * Manishearth/compiletest-rs#240 (for handling SPIR-V extension across platforms)
4042
# * Manishearth/compiletest-rs#241 (for the `$TEST_BUILD_DIR` path normalization)

crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use rustc_errors::ErrorReported;
1010
use rustc_middle::bug;
1111
use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
1212
use rustc_middle::ty::subst::SubstsRef;
13-
use rustc_middle::ty::{GeneratorSubsts, PolyFnSig, Ty, TyKind, TypeAndMut};
13+
use rustc_middle::ty::{
14+
Const, FloatTy, GeneratorSubsts, IntTy, ParamEnv, PolyFnSig, Ty, TyKind, TypeAndMut, UintTy,
15+
};
1416
use rustc_span::def_id::DefId;
1517
use rustc_span::Span;
1618
use rustc_target::abi::call::{CastTarget, FnAbi, PassMode, Reg, RegKind};
@@ -21,6 +23,9 @@ use std::cell::RefCell;
2123
use std::collections::hash_map::Entry;
2224
use std::fmt;
2325

26+
use num_traits::cast::FromPrimitive;
27+
use rspirv::spirv;
28+
2429
/// If a struct contains a pointer to itself, even indirectly, then doing a naiive recursive walk
2530
/// of the fields will result in an infinite loop. Because pointers are the only thing that are
2631
/// allowed to be recursive, keep track of what pointers we've translated, or are currently in the
@@ -768,6 +773,94 @@ fn trans_intrinsic_type<'tcx>(
768773
}
769774
// Hardcode to float for now
770775
let sampled_type = SpirvType::Float(32).def(span, cx);
776+
777+
let ty = SpirvType::Image {
778+
sampled_type,
779+
dim,
780+
depth,
781+
arrayed,
782+
multisampled,
783+
sampled,
784+
image_format,
785+
access_qualifier,
786+
};
787+
788+
Ok(ty.def(span, cx))
789+
}
790+
IntrinsicType::GenericImageType => {
791+
// see SpirvType::sizeof
792+
if ty.size != Size::from_bytes(4) {
793+
cx.tcx
794+
.sess
795+
.err("#[spirv(generic_image)] type must have size 4");
796+
return Err(ErrorReported);
797+
}
798+
799+
fn type_from_variant_discriminant<'tcx, P: FromPrimitive>(
800+
cx: &CodegenCx<'tcx>,
801+
const_: &'tcx Const<'tcx>,
802+
) -> P {
803+
let adt_def = const_.ty.ty_adt_def().unwrap();
804+
assert!(adt_def.is_enum());
805+
let destructured = cx.tcx.destructure_const(ParamEnv::reveal_all().and(const_));
806+
let idx = destructured.variant.unwrap();
807+
let value = const_.ty.discriminant_for_variant(cx.tcx, idx).unwrap().val as u64;
808+
<_>::from_u64(value).unwrap()
809+
}
810+
811+
let sampled_type = match substs.type_at(0).kind() {
812+
TyKind::Int(int) => match int {
813+
IntTy::Isize => {
814+
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, true)
815+
.def(span, cx)
816+
}
817+
IntTy::I8 => SpirvType::Integer(8, true).def(span, cx),
818+
IntTy::I16 => SpirvType::Integer(16, true).def(span, cx),
819+
IntTy::I32 => SpirvType::Integer(32, true).def(span, cx),
820+
IntTy::I64 => SpirvType::Integer(64, true).def(span, cx),
821+
IntTy::I128 => SpirvType::Integer(128, true).def(span, cx),
822+
},
823+
TyKind::Uint(uint) => match uint {
824+
UintTy::Usize => {
825+
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, false)
826+
.def(span, cx)
827+
}
828+
UintTy::U8 => SpirvType::Integer(8, false).def(span, cx),
829+
UintTy::U16 => SpirvType::Integer(16, false).def(span, cx),
830+
UintTy::U32 => SpirvType::Integer(32, false).def(span, cx),
831+
UintTy::U64 => SpirvType::Integer(64, false).def(span, cx),
832+
UintTy::U128 => SpirvType::Integer(128, false).def(span, cx),
833+
},
834+
TyKind::Float(FloatTy::F32) => SpirvType::Float(32).def(span, cx),
835+
TyKind::Float(FloatTy::F64) => SpirvType::Float(64).def(span, cx),
836+
_ => {
837+
cx.tcx
838+
.sess
839+
.span_err(span, "Invalid sampled type to `Image`.");
840+
return Err(ErrorReported);
841+
}
842+
};
843+
844+
let dim: spirv::Dim = type_from_variant_discriminant(cx, substs.const_at(1));
845+
let depth: u32 = type_from_variant_discriminant(cx, substs.const_at(2));
846+
let arrayed: u32 = type_from_variant_discriminant(cx, substs.const_at(3));
847+
let multisampled: u32 = type_from_variant_discriminant(cx, substs.const_at(4));
848+
let sampled: u32 = type_from_variant_discriminant(cx, substs.const_at(5));
849+
let image_format: spirv::ImageFormat =
850+
type_from_variant_discriminant(cx, substs.const_at(6));
851+
852+
let access_qualifier = {
853+
let option = cx
854+
.tcx
855+
.destructure_const(ParamEnv::reveal_all().and(substs.const_at(7)));
856+
857+
match option.variant.map(|i| i.as_u32()).unwrap_or(0) {
858+
0 => None,
859+
1 => Some(type_from_variant_discriminant(cx, option.fields[0])),
860+
_ => unreachable!(),
861+
}
862+
};
863+
771864
let ty = SpirvType::Image {
772865
sampled_type,
773866
dim,

crates/rustc_codegen_spirv/src/attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ impl From<ExecutionModel> for Entry {
6161
/// `struct` types that are used to represent special SPIR-V types.
6262
#[derive(Debug, Clone)]
6363
pub enum IntrinsicType {
64+
GenericImageType,
6465
ImageType {
6566
dim: Dim,
6667
depth: u32,

crates/rustc_codegen_spirv/src/symbols.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub struct Symbols {
2424
descriptor_set: Symbol,
2525
binding: Symbol,
2626
image_type: Symbol,
27+
generic_image_type: Symbol,
2728
dim: Symbol,
2829
depth: Symbol,
2930
arrayed: Symbol,
@@ -366,6 +367,7 @@ impl Symbols {
366367
descriptor_set: Symbol::intern("descriptor_set"),
367368
binding: Symbol::intern("binding"),
368369
image_type: Symbol::intern("image_type"),
370+
generic_image_type: Symbol::intern("generic_image_type"),
369371
dim: Symbol::intern("dim"),
370372
depth: Symbol::intern("depth"),
371373
arrayed: Symbol::intern("arrayed"),
@@ -430,7 +432,9 @@ pub(crate) fn parse_attrs_for_checking<'a>(
430432
.into_iter()
431433
.chain(args.into_iter().map(move |ref arg| {
432434
let span = arg.span();
433-
let parsed_attr = if arg.has_name(sym.image_type) {
435+
let parsed_attr = if arg.has_name(sym.generic_image_type) {
436+
SpirvAttribute::IntrinsicType(IntrinsicType::GenericImageType)
437+
} else if arg.has_name(sym.image_type) {
434438
parse_image_type(sym, arg)?
435439
} else if arg.has_name(sym.descriptor_set) {
436440
SpirvAttribute::DescriptorSet(parse_attr_int_value(arg)?)

crates/spirv-builder/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ fn invoke_rustc(builder: &SpirvBuilder, multimodule: bool) -> Result<PathBuf, Sp
204204
.unwrap_or_default();
205205

206206
let rustflags = format!(
207-
"-Z codegen-backend={} -Z symbol-mangling-version=v0{}",
207+
"-Z codegen-backend={} -Zsymbol-mangling-version=v0 {}",
208208
rustc_codegen_spirv.display(),
209209
llvm_args,
210210
);

crates/spirv-std/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ description = "Standard functions and types for SPIR-V"
1010
[dependencies]
1111
bitflags = "1.2.1"
1212
num-traits = { version = "0.2.14", default-features = false, features = ["libm"] }
13-
spirv-std-macros = { path = "../spirv-std-macros", version = "0.4.0-alpha.0" }
13+
spirv-types = { path = "./shared", version = "0.4.0-alpha.3" }
14+
spirv-std-macros = { path = "./macros", version = "0.4.0-alpha.3" }
15+
spirv_headers = { git = "https://github.com/gfx-rs/rspirv", rev = "719cf08" }
1416

1517
[features]
1618
default = []
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ description = "Macros for spirv-std"
1111
proc-macro = true
1212

1313
[dependencies]
14+
spirv-types = { path = "../shared", version = "0.4.0-alpha.3" }
15+
heck = "0.3.2"
1416
proc-macro2 = "1.0.24"
1517
quote = "1.0.8"
1618
syn = { version = "1.0.58", features=["full"] }
19+
spirv_headers = { git = "https://github.com/gfx-rs/rspirv", rev = "719cf08" }

0 commit comments

Comments
 (0)