Skip to content

Commit 6a1e259

Browse files
committed
Gate block layout validation on Vulkan environment
Match C++ validate_decorations.cpp line 1478: check_struct_layout (offset alignment, overlap, straddle checks) only runs for Vulkan environments. Pre-checks (Offset, ArrayStride, MatrixStride, RowMajor/ColMajor presence) still run for all environments per C++ lines 1432-1476. Add missing Offset-presence pre-check (isMissingOffsetInStruct equivalent). Update block layout tests to use appropriate Vulkan target environments (Vulkan1_0 for Uniform, Vulkan1_1 for StorageBuffer, Vulkan1_2 for workgroup explicit layout).
1 parent 0773ea4 commit 6a1e259

2 files changed

Lines changed: 128 additions & 57 deletions

File tree

rust/spirv-tools-core/src/validation/rules/block_layout.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rspirv::spirv::{Decoration, Op, StorageClass};
1414

1515
use crate::validation::context::{ValidationContext, ValidationRule};
1616
use crate::validation::error::ValidationError;
17+
use crate::validation::helpers::is_vulkan_env;
1718
use crate::validation::span::SpannedValidationError;
1819
use crate::validation::types::{MemberIndex, ResultId, TypeId};
1920
use crate::validation::ValidationResult;
@@ -68,6 +69,7 @@ impl ValidationRule for BlockLayoutRule {
6869
BlockDecoration::BufferBlock => "BufferBlock",
6970
};
7071

72+
// Pre-checks run for ALL environments (C++ lines 1432-1476).
7173
check_required_block_decorations(
7274
ctx.module,
7375
ctx.definitions,
@@ -76,16 +78,20 @@ impl ValidationRule for BlockLayoutRule {
7678
&mut HashSet::new(),
7779
)?;
7880

79-
check_struct_layout(
80-
ctx.module,
81-
ctx.definitions,
82-
struct_id,
83-
0,
84-
scalar_layout,
85-
extended_alignment,
86-
relax_block_layout,
87-
0,
88-
)?;
81+
// Actual layout validation (offset alignment, overlap, straddle) only
82+
// runs for Vulkan environments (C++ line 1478).
83+
if is_vulkan_env(ctx.env) {
84+
check_struct_layout(
85+
ctx.module,
86+
ctx.definitions,
87+
struct_id,
88+
0,
89+
scalar_layout,
90+
extended_alignment,
91+
relax_block_layout,
92+
0,
93+
)?;
94+
}
8995
}
9096

9197
Ok(())
@@ -749,6 +755,22 @@ fn check_required_block_decorations(
749755
return Ok(());
750756
}
751757

758+
// Check that all members have Offset decorations (C++ isMissingOffsetInStruct, line 1432).
759+
let offsets = collect_member_offsets(module, struct_id);
760+
for idx in 0..struct_inst.operands.len() {
761+
if !offsets.contains_key(&MemberIndex(idx as u32)) {
762+
visiting.remove(&struct_id);
763+
return Err(ValidationError::InvalidBlockLayout {
764+
struct_type: struct_id,
765+
reason: format!(
766+
"Structure decorated as {} must be explicitly laid out with Offset decorations",
767+
deco_name
768+
),
769+
}
770+
.into());
771+
}
772+
}
773+
752774
for (member_idx, op) in struct_inst.operands.iter().enumerate() {
753775
let rspirv::dr::Operand::IdRef(member_type_raw) = op else {
754776
continue;

0 commit comments

Comments
 (0)