Quick answer: Insert RHICmdList.Transition(FRHITransitionInfo(Texture, FromState, ToState)) before binding a texture in a new state. Validation layer messages name the texture and required state.
A custom post-process pass in Unreal’s renderer triggers Vulkan validation errors: VUID-vkCmdDrawIndexed: image layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL doesn’t match expected layout. Layout transitions missed.
Diagnose with Validation Layer
UE5Game.exe -vulkanvalidation
Console window shows validation messages with full call stack into the RHI. Look for the texture name and required state.
Insert Transition
RHICmdList.Transition(FRHITransitionInfo(SceneColor, ERHIAccess::RTV, ERHIAccess::SRVCompute));
// now safe to bind as compute SRV
SetUAVParameter(...);
RHICmdList.DispatchComputeShader(...);
Transitions are required between any pair of incompatible accesses: RTV ↔ SRV, UAV ↔ SRV, etc.
Common Patterns
| From | To | When |
|---|---|---|
| RTV | SRV | after render-to-texture, read in next pass |
| UAVCompute | SRV | compute writes, fragment reads |
| CopySrc | CopyDest | chained copies |
| Present | RTV | back-buffer at frame start |
RDG to the Rescue
Unreal’s Render Dependency Graph (RDG) auto-inserts transitions. Migrate custom passes from RHI to RDG:
GraphBuilder.AddPass(...); // RDG handles transitions
For performance-critical passes, RDG’s overhead is negligible and the safety win is large.
Verify with RenderDoc
RenderDoc capture; inspect resource states in the Pipeline State panel. Each texture binding shows expected vs actual state. Mismatch is highlighted.
Verifying
Re-run with validation. No image layout errors. RenderDoc shows clean state transitions per draw. Visual output unchanged.
“Vulkan barriers are explicit. Either transition manually before each cross-state use, or let RDG do it for you.”
For console targets (Xbox / PS5), the lower-level GNM/D3D12 APIs have similar transition concepts — RDG normalizes across all RHIs.