Skip to content

Commit 3ca236b

Browse files
committed
Fix : The pointer type instruction need to be reordered, or the SPIRV might be rejected by vulkan validation layer due to violating SPIR-V validation rules.
1 parent 04feca3 commit 3ca236b

File tree

1 file changed

+28
-5
lines changed

1 file changed

+28
-5
lines changed

Graphics/ShaderTools/src/ConvertUBOToPushConstant.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)