@@ -219,11 +219,23 @@ class ConvertUBOToPushConstantPass : public spvtools::opt::Pass
219219 return Status::Failure;
220220 }
221221
222- // Note: We don't need to manually reorder the pointer type instruction.
223- // SPIR-V does not require types to appear in any specific relative order,
224- // as long as they are valid type declarations. FindPointerToType handles
225- // type creation correctly, and the SPIRV-Tools framework manages instruction
226- // ordering appropriately.
222+ // IMPORTANT: FindPointerToType() may create a new type instruction at the end of
223+ // the types_values section. However, SPIR-V requires all IDs to be defined before
224+ // use (SSA form). If the new pointer type was just created, it will appear AFTER
225+ // the OpVariable that uses it, which violates SPIR-V validation rules.
226+ //
227+ // We need to move the newly created pointer type instruction to appear BEFORE
228+ // the OpVariable instruction that will reference it.
229+ spvtools::opt::Instruction* new_ptr_type_inst = get_def_use_mgr ()->GetDef (new_ptr_type_id);
230+ if (new_ptr_type_inst != nullptr && new_ptr_type_inst != ptr_type_inst)
231+ {
232+ // The new pointer type was created (not reused). Move it before the variable.
233+ // In SPIR-V, types appear in the types_values section before variables.
234+ // We insert the new type right after the original pointer type to maintain
235+ // proper ordering within the types section.
236+ new_ptr_type_inst->RemoveFromList ();
237+ new_ptr_type_inst->InsertAfter (ptr_type_inst);
238+ }
227239
228240 // Update the variable's type to the new pointer type
229241 target_var->SetResultType (new_ptr_type_id);
@@ -374,6 +386,17 @@ class ConvertUBOToPushConstantPass : public spvtools::opt::Pass
374386 if (new_result_type_id == 0 )
375387 return ;
376388
389+ // If a new type was created, ensure it's properly positioned in the types section.
390+ // FindPointerToType may append new types at the end, but they need to appear
391+ // before any instructions that use them (SPIR-V SSA requirement).
392+ spvtools::opt::Instruction* new_type_inst = get_def_use_mgr ()->GetDef (new_result_type_id);
393+ if (new_type_inst != nullptr && new_type_inst != result_type_inst)
394+ {
395+ // Move the new type to appear after the original type in the types section
396+ new_type_inst->RemoveFromList ();
397+ new_type_inst->InsertAfter (result_type_inst);
398+ }
399+
377400 inst.SetResultType (new_result_type_id);
378401 context ()->UpdateDefUse (&inst);
379402 }
0 commit comments