Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 27 additions & 28 deletions crates/rustc_codegen_spirv/src/codegen_cx/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'tcx> CodegenCx<'tcx> {
};
for (arg_abi, hir_param) in fn_abi.args.iter().zip(hir_params) {
match arg_abi.mode {
PassMode::Direct(_) => {}
PassMode::Direct(_) | PassMode::Ignore => {}
PassMode::Pair(..) => {
// FIXME(eddyb) implement `ScalarPair` `Input`s, or change
// the `FnAbi` readjustment to only use `PassMode::Pair` for
Expand All @@ -103,16 +103,6 @@ impl<'tcx> CodegenCx<'tcx> {
);
}
}
// FIXME(eddyb) support these (by just ignoring them) - if there
// is any validation concern, it should be done on the types.
PassMode::Ignore => self.tcx.dcx().span_fatal(
hir_param.ty_span,
format!(
"entry point parameter type not yet supported \
(`{}` has size `0`)",
arg_abi.layout.ty
),
),
_ => span_bug!(
hir_param.ty_span,
"query hooks should've made this `PassMode` impossible: {:#?}",
Expand Down Expand Up @@ -674,28 +664,37 @@ impl<'tcx> CodegenCx<'tcx> {
// starting from the `value_ptr` pointing to a `value_spirv_type`
// (e.g. `Input` doesn't use indirection, so we have to load from it).
if let ty::Ref(..) = entry_arg_abi.layout.ty.kind() {
call_args.push(value_ptr.unwrap());
match entry_arg_abi.mode {
PassMode::Direct(_) => assert_eq!(value_len, None),
PassMode::Pair(..) => call_args.push(value_len.unwrap()),
PassMode::Direct(_) => {
assert_eq!(value_len, None);
call_args.push(value_ptr.unwrap());
}
PassMode::Pair(..) => call_args.extend([value_ptr.unwrap(), value_len.unwrap()]),
PassMode::Ignore => (),
_ => unreachable!(),
}
} else {
assert_matches!(entry_arg_abi.mode, PassMode::Direct(_));

let value = match storage_class {
Ok(_) => {
assert_eq!(storage_class, Ok(StorageClass::Input));
bx.load(
entry_arg_abi.layout.spirv_type(hir_param.ty_span, bx),
value_ptr.unwrap(),
entry_arg_abi.layout.align.abi,
)
match entry_arg_abi.mode {
PassMode::Ignore => {}
PassMode::Direct(_) => {
let value = match storage_class {
Ok(_) => {
assert_eq!(storage_class, Ok(StorageClass::Input));
bx.load(
entry_arg_abi.layout.spirv_type(hir_param.ty_span, bx),
value_ptr.unwrap(),
entry_arg_abi.layout.align.abi,
)
}
Err(SpecConstant { .. }) => {
spec_const_id.unwrap().with_type(value_spirv_type)
}
};
call_args.push(value);
assert_eq!(value_len, None);
}
Err(SpecConstant { .. }) => spec_const_id.unwrap().with_type(value_spirv_type),
};
call_args.push(value);
assert_eq!(value_len, None);
_ => unreachable!(),
}
}

// FIXME(eddyb) check whether the storage class is compatible with the
Expand Down
28 changes: 28 additions & 0 deletions tests/compiletests/ui/spirv-attr/entry_generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble
// normalize-stderr-test "OpSource .*\n" -> ""
// normalize-stderr-test "OpLine .*\n" -> ""
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
// normalize-stderr-test "(^|\n); .*" -> ""
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
// ignore-spv1.0
// ignore-spv1.1
// ignore-spv1.2
// ignore-spv1.3
// ignore-vulkan1.0
// ignore-vulkan1.1

use spirv_std::glam::*;
use spirv_std::{Image, spirv};

#[spirv(vertex)]
pub fn main<T: Copy>(in1: T, out1: &mut T) {
*out1 = in1;
}

pub fn dummy() {
main::<u32>(0, &mut 0);
main::<f32>(0., &mut 0.);
main::<()>((), &mut ());
}
44 changes: 44 additions & 0 deletions tests/compiletests/ui/spirv-attr/entry_generic.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

OpCapability Shader
OpMemoryModel Logical Simple
OpEntryPoint Vertex %1 "main::<f32>" %2 %3
OpEntryPoint Vertex %4 "main::<u32>" %5 %6
OpEntryPoint Vertex %7 "main::<()>"
OpName %2 "in1"
OpName %3 "out1"
OpName %5 "in1"
OpName %6 "out1"
OpDecorate %2 Location 0
OpDecorate %3 Location 0
OpDecorate %5 Location 0
OpDecorate %6 Location 0
%9 = OpTypeFloat 32
%10 = OpTypePointer Input %9
%11 = OpTypePointer Output %9
%12 = OpTypeVoid
%13 = OpTypeFunction %12
%2 = OpVariable %10 Input
%3 = OpVariable %11 Output
%14 = OpTypeInt 32 0
%15 = OpTypePointer Input %14
%16 = OpTypePointer Output %14
%5 = OpVariable %15 Input
%6 = OpVariable %16 Output
%1 = OpFunction %12 None %13
%17 = OpLabel
%18 = OpLoad %9 %2
OpStore %3 %18
OpNoLine
OpReturn
OpFunctionEnd
%4 = OpFunction %12 None %13
%19 = OpLabel
%20 = OpLoad %14 %5
OpStore %6 %20
OpNoLine
OpReturn
OpFunctionEnd
%7 = OpFunction %12 None %13
%21 = OpLabel
OpReturn
OpFunctionEnd
24 changes: 24 additions & 0 deletions tests/compiletests/ui/spirv-attr/entry_unit_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble
// normalize-stderr-test "OpSource .*\n" -> ""
// normalize-stderr-test "OpLine .*\n" -> ""
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
// normalize-stderr-test "(^|\n); .*" -> ""
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
// ignore-spv1.0
// ignore-spv1.1
// ignore-spv1.2
// ignore-spv1.3
// ignore-vulkan1.0
// ignore-vulkan1.1

use spirv_std::glam::*;
use spirv_std::{Image, spirv};

#[spirv(vertex)]
pub fn main(in1: (), in2: u32, out1: &mut [f32; 3], out2: &mut (), out3: &mut f32) {
*out1 = Default::default();
*out2 = Default::default();
*out3 = in2 as f32;
}
47 changes: 47 additions & 0 deletions tests/compiletests/ui/spirv-attr/entry_unit_type.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

OpCapability Shader
OpMemoryModel Logical Simple
OpEntryPoint Vertex %1 "main" %2 %3 %4
OpName %2 "in2"
OpName %3 "out1"
OpName %4 "out3"
OpName %7 "<[f32; 3] as core::default::Default>::default"
OpDecorate %2 Location 0
OpDecorate %8 ArrayStride 4
OpDecorate %3 Location 0
OpDecorate %4 Location 3
%9 = OpTypeInt 32 0
%10 = OpTypePointer Input %9
%11 = OpTypeFloat 32
%12 = OpConstant %9 3
%13 = OpTypeArray %11 %12
%14 = OpTypePointer Output %13
%15 = OpTypePointer Output %11
%16 = OpTypeVoid
%17 = OpTypeFunction %16
%2 = OpVariable %10 Input
%8 = OpTypeArray %11 %12
%18 = OpTypeFunction %8
%19 = OpConstant %11 0
%3 = OpVariable %14 Output
%4 = OpVariable %15 Output
%1 = OpFunction %16 None %17
%20 = OpLabel
%21 = OpLoad %9 %2
%22 = OpFunctionCall %8 %7
%23 = OpCompositeExtract %11 %22 0
%24 = OpCompositeExtract %11 %22 1
%25 = OpCompositeExtract %11 %22 2
%26 = OpCompositeConstruct %13 %23 %24 %25
OpStore %3 %26
%27 = OpConvertUToF %11 %21
OpStore %4 %27
OpNoLine
OpReturn
OpFunctionEnd
%7 = OpFunction %8 None %18
%28 = OpLabel
%29 = OpCompositeConstruct %8 %19 %19 %19
OpNoLine
OpReturnValue %29
OpFunctionEnd
Loading