@@ -214,11 +214,23 @@ class ConvertUBOToPushConstantPass : public spvtools::opt::Pass
214214 return Status::Failure;
215215 }
216216
217- // Note: We don't need to manually reorder the pointer type instruction.
218- // SPIR-V does not require types to appear in any specific relative order,
219- // as long as they are valid type declarations. FindPointerToType handles
220- // type creation correctly, and the SPIRV-Tools framework manages instruction
221- // ordering appropriately.
217+ // IMPORTANT: FindPointerToType() may create a new type instruction at the end of
218+ // the types_values section. However, SPIR-V requires all IDs to be defined before
219+ // use (SSA form). If the new pointer type was just created, it will appear AFTER
220+ // the OpVariable that uses it, which violates SPIR-V validation rules.
221+ //
222+ // We need to move the newly created pointer type instruction to appear BEFORE
223+ // the OpVariable instruction that will reference it.
224+ spvtools::opt::Instruction* new_ptr_type_inst = get_def_use_mgr ()->GetDef (new_ptr_type_id);
225+ if (new_ptr_type_inst != nullptr && new_ptr_type_inst != ptr_type_inst)
226+ {
227+ // The new pointer type was created (not reused). Move it before the variable.
228+ // In SPIR-V, types appear in the types_values section before variables.
229+ // We insert the new type right after the original pointer type to maintain
230+ // proper ordering within the types section.
231+ new_ptr_type_inst->RemoveFromList ();
232+ new_ptr_type_inst->InsertAfter (ptr_type_inst);
233+ }
222234
223235 // Update the variable's type to the new pointer type
224236 target_var->SetResultType (new_ptr_type_id);
@@ -368,6 +380,17 @@ class ConvertUBOToPushConstantPass : public spvtools::opt::Pass
368380 uint32_t new_result_type_id =
369381 type_mgr->FindPointerToType (pointee_type_id, spv::StorageClass::PushConstant);
370382
383+ // If a new type was created, ensure it's properly positioned in the types section.
384+ // FindPointerToType may append new types at the end, but they need to appear
385+ // before any instructions that use them (SPIR-V SSA requirement).
386+ spvtools::opt::Instruction* new_type_inst = get_def_use_mgr ()->GetDef (new_result_type_id);
387+ if (new_type_inst != nullptr && new_type_inst != result_type_inst)
388+ {
389+ // Move the new type to appear after the original type in the types section
390+ new_type_inst->RemoveFromList ();
391+ new_type_inst->InsertAfter (result_type_inst);
392+ }
393+
371394 inst->SetResultType (new_result_type_id);
372395 context ()->UpdateDefUse (inst);
373396 }
0 commit comments