Quick answer: Direct3D 12 debug layer screaming about resource state mismatch on draw? Insert a ResourceBarrier transitioning the resource to the expected state before each pipeline stage uses it.

A texture rendered into in pass 1 and sampled in pass 2 triggers a state-tracking error. The transition from RTV to SRV wasn’t inserted.

Explicit Transitions

D3D12_RESOURCE_BARRIER b = {};
b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
b.Transition.pResource = tex.Get();
b.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
b.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
cmd->ResourceBarrier(1, &b);

Batch Barriers

Issue all barriers at the start of a pass as a single ResourceBarrier call. The driver can re-order them; one call beats many.

Initial State

The resource’s initial state at creation determines what state it’s in for the first frame. InitialState in CreateCommittedResource must match how you first use it.

Enhanced Barriers

D3D12 enhanced barriers (later API) split sync and access — cleaner but more verbose. Convert to them gradually if you’re on a recent SDK.

Verifying

Debug layer is silent. Capture in PIX shows the resource cycling through correct states across the frame graph.

“Every state transition needs an explicit barrier. Batch them per pass.”

Build a tiny state-tracker on top of your resources — debug builds assert when usage doesn’t match the current state, finding bugs before the driver does.