Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
XAMPPRocky committed Apr 19, 2021
1 parent 377d207 commit bc2a121
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 204 deletions.
117 changes: 42 additions & 75 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ 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, ParamEnv, PolyFnSig, Ty, TyKind, TypeAndMut};
use rustc_middle::ty::{Const, GeneratorSubsts, ParamEnv, PolyFnSig, Ty, TyKind, IntTy, UintTy, FloatTy, TypeAndMut};
use rustc_span::def_id::DefId;
use rustc_span::Span;
use rustc_target::abi::call::{CastTarget, FnAbi, PassMode, Reg, RegKind};
Expand Down Expand Up @@ -794,92 +794,59 @@ fn trans_intrinsic_type<'tcx>(
return Err(ErrorReported);
}

macro_rules! type_from_variant_discriminant {
($(let $name:ident : $ty:ty = $exp:expr);+ ;) => {
$(let $name = {
let const_ = $exp;
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;
<$ty>::from_u64(value).unwrap()
};)+
}
}

type_from_variant_discriminant! {
let dim: spirv::Dim = substs.const_at(0);
let depth: u32 = substs.const_at(1);
let arrayed: u32 = substs.const_at(2);
let multisampled: u32 = substs.const_at(3);
let sampled: u32 = substs.const_at(4);
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, image_format) = {
let image_format = cx
.tcx
.destructure_const(ParamEnv::reveal_all().and(substs.const_at(5)));

match image_format.variant.map(|i| i.index()) {
Some(0) => {
let sampled_type = match cx
.tcx
.destructure_const(ParamEnv::reveal_all().and(image_format.fields[0]))
.variant
.map(|i| i.index())
{
// u8 u16 u32 u64
// i8 i16 i32 i64
Some(width) if width < 8 => {
let signed = width > 3;
SpirvType::Integer(((width + 1) * 8) as u32, signed).def(span, cx)
}
Some(8) => SpirvType::Float(32).def(span, cx),
Some(9) => SpirvType::Float(64).def(span, cx),
Some(10) => SpirvType::Void.def(span, cx),
_ => {
cx.tcx
.sess
.err("Invalid sampled type variant provided to `Image`.");
return Err(ErrorReported);
}
};

(sampled_type, spirv::ImageFormat::Unknown)
}
Some(format @ 1..=20) => (
SpirvType::Float(32).def(span, cx),
spirv::ImageFormat::from_usize(format).unwrap(),
),
Some(format @ 21..=39) => (
SpirvType::Integer(32, format < 30).def(span, cx),
spirv::ImageFormat::from_usize(format).unwrap(),
),
_ => {
cx.tcx
.sess
.err("Invalid image format type provided to `Image`.");
return Err(ErrorReported);
}
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.err("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(6)));
.destructure_const(ParamEnv::reveal_all().and(substs.const_at(7)));

match option.variant.map(|i| i.as_u32()).unwrap_or(0) {
0 => None,
1 => {
type_from_variant_discriminant! {
let access_qualifier: spirv::AccessQualifier = option.fields[0];
}
Some(access_qualifier)
Some(type_from_variant_discriminant(cx, option.fields[0]))
}
_ => unreachable!(),
}
Expand Down
Loading

0 comments on commit bc2a121

Please sign in to comment.