Skip to content

Commit bfc47a7

Browse files
committed
location assignment2: fix location assignment for shader types with arrayed input/outputs
1 parent 44201c2 commit bfc47a7

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

crates/rustc_codegen_spirv/src/codegen_cx/entry.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,9 @@ impl<'tcx> CodegenCx<'tcx> {
722722
Ok(StorageClass::Input | StorageClass::Output | StorageClass::UniformConstant)
723723
);
724724
let mut assign_location = |var_id: Result<Word, &str>, explicit: Option<u32>| {
725+
let storage_class = storage_class.unwrap();
725726
let location = decoration_locations
726-
.entry(storage_class.unwrap())
727+
.entry(storage_class)
727728
.or_insert_with(|| 0);
728729
if let Some(explicit) = explicit {
729730
*location = explicit;
@@ -733,7 +734,46 @@ impl<'tcx> CodegenCx<'tcx> {
733734
Decoration::Location,
734735
std::iter::once(Operand::LiteralBit32(*location)),
735736
);
736-
let spirv_type = self.lookup_type(value_spirv_type);
737+
let mut spirv_type = self.lookup_type(value_spirv_type);
738+
739+
// These shader types and storage classes skip the outer array or pointer of the declaration when computing
740+
// the location layout, see bug at https://github.com/Rust-GPU/rust-gpu/issues/500.
741+
//
742+
// The match statment follows the rules at:
743+
// https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#interfaces-iointerfaces-matching
744+
#[allow(clippy::match_same_arms)]
745+
let can_skip_outer_array =
746+
match (execution_model, storage_class, attrs.per_primitive_ext) {
747+
// > if the input is declared in a tessellation control or geometry shader...
748+
(
749+
ExecutionModel::TessellationControl | ExecutionModel::Geometry,
750+
StorageClass::Input,
751+
_,
752+
) => true,
753+
// > if the maintenance4 feature is enabled, they are declared as OpTypeVector variables, and the
754+
// > output has a Component Count value higher than that of the input but the same Component Type
755+
// Irrelevant: This allows a vertex shader to output a Vec4 and a fragment shader to accept a vector
756+
// type with fewer components, like Vec3, Vec2 (or f32?). Which has no influence on locations.
757+
// > if the output is declared in a mesh shader...
758+
(ExecutionModel::MeshEXT | ExecutionModel::MeshNV, StorageClass::Output, _) => {
759+
true
760+
}
761+
// > if the input is decorated with PerVertexKHR, and is declared in a fragment shader...
762+
(ExecutionModel::Fragment, StorageClass::Input, Some(_)) => true,
763+
// > if in any other case...
764+
(_, _, _) => false,
765+
};
766+
if can_skip_outer_array {
767+
spirv_type = match spirv_type {
768+
SpirvType::Array { element, .. }
769+
| SpirvType::RuntimeArray { element, .. }
770+
| SpirvType::Pointer {
771+
pointee: element, ..
772+
} => self.lookup_type(element),
773+
e => e,
774+
};
775+
}
776+
737777
if let Some(location_size) = spirv_type.location_size(self) {
738778
*location += location_size;
739779
} else {

tests/compiletests/ui/spirv-attr/location_assignment/geometry_shader.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ OpName %7 "position_out"
1313
OpDecorate %2 BuiltIn Position
1414
OpDecorate %3 Location 0
1515
OpDecorate %12 ArrayStride 4
16-
OpDecorate %4 Location 2
16+
OpDecorate %4 Location 1
1717
OpDecorate %13 ArrayStride 4
1818
OpDecorate %5 Location 0
1919
OpDecorate %6 Location 1

tests/compiletests/ui/spirv-attr/location_assignment/mesh_shader.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ OpMemberDecorate %16 0 Offset 0
2020
OpMemberDecorate %16 1 Offset 4
2121
OpDecorate %2 BuiltIn Position
2222
OpDecorate %3 Location 0
23-
OpDecorate %4 Location 9
23+
OpDecorate %4 Location 1
2424
OpDecorate %5 BuiltIn PrimitiveTriangleIndicesEXT
25-
OpDecorate %6 Location 18
25+
OpDecorate %6 Location 2
2626
OpDecorate %6 PerPrimitiveNV
27-
OpDecorate %7 Location 21
27+
OpDecorate %7 Location 3
2828
OpDecorate %7 PerPrimitiveNV
2929
%17 = OpTypeFloat 32
3030
%18 = OpTypeVector %17 4

0 commit comments

Comments
 (0)