diff --git a/rspirv/dr/build/mod.rs b/rspirv/dr/build/mod.rs index 62d6b87..0c8ca97 100644 --- a/rspirv/dr/build/mod.rs +++ b/rspirv/dr/build/mod.rs @@ -587,8 +587,24 @@ impl Builder { dr::Operand::IdRef(entry_point), dr::Operand::ExecutionMode(execution_mode), ]; - for v in params.as_ref() { - operands.push(dr::Operand::LiteralBit32(*v)); + + // Different execution modes require different operand types + match execution_mode { + // From SPIRV spec section 3.6.38: + // "Same as the LocalSize Mode, but using operands instead of literals. + // The operands are consumed as unsigned and each must be an integer type + // scalar." + spirv::ExecutionMode::LocalSizeId => { + for v in params.as_ref() { + operands.push(dr::Operand::IdRef(*v)); + } + } + // Other execution modes use literal values + _ => { + for v in params.as_ref() { + operands.push(dr::Operand::LiteralBit32(*v)); + } + } } let inst = dr::Instruction::new(spirv::Op::ExecutionModeId, None, None, operands); diff --git a/rspirv/dr/loader.rs b/rspirv/dr/loader.rs index c29bddb..a6c2c51 100644 --- a/rspirv/dr/loader.rs +++ b/rspirv/dr/loader.rs @@ -136,6 +136,7 @@ impl binary::Consumer for Loader { spirv::Op::MemoryModel => self.module.memory_model = Some(inst), spirv::Op::EntryPoint => self.module.entry_points.push(inst), spirv::Op::ExecutionMode => self.module.execution_modes.push(inst), + spirv::Op::ExecutionModeId => self.module.execution_modes.push(inst), spirv::Op::String | spirv::Op::SourceExtension | spirv::Op::Source