|
3 | 3 |
|
4 | 4 | use crate::attr::{AggregatedSpirvAttributes, IntrinsicType}; |
5 | 5 | use crate::codegen_cx::CodegenCx; |
| 6 | +use crate::maybe_pqp_cg_ssa::traits::ConstCodegenMethods as _; |
6 | 7 | use crate::spirv_type::SpirvType; |
7 | 8 | use itertools::Itertools; |
8 | 9 | use rspirv::spirv::{Dim, ImageFormat, StorageClass, Word}; |
@@ -885,6 +886,48 @@ fn trans_intrinsic_type<'tcx>( |
885 | 886 | args: GenericArgsRef<'tcx>, |
886 | 887 | intrinsic_type_attr: IntrinsicType, |
887 | 888 | ) -> Result<Word, ErrorGuaranteed> { |
| 889 | + trait FromScalarInt: Sized { |
| 890 | + fn from_scalar_int(n: ScalarInt) -> Option<Self>; |
| 891 | + } |
| 892 | + |
| 893 | + impl FromScalarInt for u32 { |
| 894 | + fn from_scalar_int(n: ScalarInt) -> Option<Self> { |
| 895 | + Some(n.try_to_bits(Size::from_bits(32)).ok()?.try_into().unwrap()) |
| 896 | + } |
| 897 | + } |
| 898 | + |
| 899 | + impl FromScalarInt for Dim { |
| 900 | + fn from_scalar_int(n: ScalarInt) -> Option<Self> { |
| 901 | + Dim::from_u32(u32::from_scalar_int(n)?) |
| 902 | + } |
| 903 | + } |
| 904 | + |
| 905 | + impl FromScalarInt for ImageFormat { |
| 906 | + fn from_scalar_int(n: ScalarInt) -> Option<Self> { |
| 907 | + ImageFormat::from_u32(u32::from_scalar_int(n)?) |
| 908 | + } |
| 909 | + } |
| 910 | + |
| 911 | + fn const_int_value<'tcx, P: FromScalarInt>( |
| 912 | + cx: &CodegenCx<'tcx>, |
| 913 | + const_: Const<'tcx>, |
| 914 | + ) -> Result<P, ErrorGuaranteed> { |
| 915 | + let ty::Value { |
| 916 | + ty: const_ty, |
| 917 | + valtree: const_val, |
| 918 | + } = const_.to_value(); |
| 919 | + assert!(const_ty.is_integral()); |
| 920 | + const_val |
| 921 | + .try_to_scalar() |
| 922 | + .and_then(|scalar| scalar.try_to_scalar_int().ok()) |
| 923 | + .and_then(P::from_scalar_int) |
| 924 | + .ok_or_else(|| { |
| 925 | + cx.tcx |
| 926 | + .dcx() |
| 927 | + .err(format!("invalid value for const generic: {const_}")) |
| 928 | + }) |
| 929 | + } |
| 930 | + |
888 | 931 | match intrinsic_type_attr { |
889 | 932 | IntrinsicType::GenericImageType => { |
890 | 933 | // see SpirvType::sizeof |
@@ -948,48 +991,6 @@ fn trans_intrinsic_type<'tcx>( |
948 | 991 | // let image_format: spirv::ImageFormat = |
949 | 992 | // type_from_variant_discriminant(cx, args.const_at(6)); |
950 | 993 |
|
951 | | - trait FromScalarInt: Sized { |
952 | | - fn from_scalar_int(n: ScalarInt) -> Option<Self>; |
953 | | - } |
954 | | - |
955 | | - impl FromScalarInt for u32 { |
956 | | - fn from_scalar_int(n: ScalarInt) -> Option<Self> { |
957 | | - Some(n.try_to_bits(Size::from_bits(32)).ok()?.try_into().unwrap()) |
958 | | - } |
959 | | - } |
960 | | - |
961 | | - impl FromScalarInt for Dim { |
962 | | - fn from_scalar_int(n: ScalarInt) -> Option<Self> { |
963 | | - Dim::from_u32(u32::from_scalar_int(n)?) |
964 | | - } |
965 | | - } |
966 | | - |
967 | | - impl FromScalarInt for ImageFormat { |
968 | | - fn from_scalar_int(n: ScalarInt) -> Option<Self> { |
969 | | - ImageFormat::from_u32(u32::from_scalar_int(n)?) |
970 | | - } |
971 | | - } |
972 | | - |
973 | | - fn const_int_value<'tcx, P: FromScalarInt>( |
974 | | - cx: &CodegenCx<'tcx>, |
975 | | - const_: Const<'tcx>, |
976 | | - ) -> Result<P, ErrorGuaranteed> { |
977 | | - let ty::Value { |
978 | | - ty: const_ty, |
979 | | - valtree: const_val, |
980 | | - } = const_.to_value(); |
981 | | - assert!(const_ty.is_integral()); |
982 | | - const_val |
983 | | - .try_to_scalar() |
984 | | - .and_then(|scalar| scalar.try_to_scalar_int().ok()) |
985 | | - .and_then(P::from_scalar_int) |
986 | | - .ok_or_else(|| { |
987 | | - cx.tcx |
988 | | - .dcx() |
989 | | - .err(format!("invalid value for Image const generic: {const_}")) |
990 | | - }) |
991 | | - } |
992 | | - |
993 | 994 | let dim = const_int_value(cx, args.const_at(1))?; |
994 | 995 | let depth = const_int_value(cx, args.const_at(2))?; |
995 | 996 | let arrayed = const_int_value(cx, args.const_at(3))?; |
@@ -1019,6 +1020,31 @@ fn trans_intrinsic_type<'tcx>( |
1019 | 1020 | Ok(SpirvType::AccelerationStructureKhr.def(span, cx)) |
1020 | 1021 | } |
1021 | 1022 | IntrinsicType::RayQueryKhr => Ok(SpirvType::RayQueryKhr.def(span, cx)), |
| 1023 | + IntrinsicType::CooperativeMatrixKhr => { |
| 1024 | + if ty.size != Size::from_bytes(4) { |
| 1025 | + return Err(cx.tcx.dcx().err("cooperative_matrix type must have size 4")); |
| 1026 | + } |
| 1027 | + |
| 1028 | + // Generic arg 0: component type T |
| 1029 | + let component_type = cx.layout_of(args.type_at(0)).spirv_type(span, cx); |
| 1030 | + // Const generic 1: USE (MatrixA=0, MatrixB=1, MatrixAccumulator=2) |
| 1031 | + let usage = cx.const_u32(const_int_value(cx, args.const_at(1))?).def_cx(cx); |
| 1032 | + // Const generic 2: ROWS |
| 1033 | + let rows = cx.const_u32(const_int_value(cx, args.const_at(2))?).def_cx(cx); |
| 1034 | + // Const generic 3: COLS |
| 1035 | + let columns = cx.const_u32(const_int_value(cx, args.const_at(3))?).def_cx(cx); |
| 1036 | + // Scope: Subgroup = 3 |
| 1037 | + let scope = cx.const_u32(3).def_cx(cx); |
| 1038 | + |
| 1039 | + Ok(SpirvType::CooperativeMatrixKhr { |
| 1040 | + component_type, |
| 1041 | + usage, |
| 1042 | + rows, |
| 1043 | + columns, |
| 1044 | + scope, |
| 1045 | + } |
| 1046 | + .def(span, cx)) |
| 1047 | + } |
1022 | 1048 | IntrinsicType::SampledImage => { |
1023 | 1049 | // see SpirvType::sizeof |
1024 | 1050 | if ty.size != Size::from_bytes(4) { |
|
0 commit comments