Direct12 资源状态转换问题

设置如下屏障进行资源状态转换时,出现一下错误,为什么会出现这个错误,如何解决?

D3D12_RESOURCE_TRANSITION_BARRIER dingdianpingzhaungshuxing3 = {};
    dingdianpingzhaungshuxing3.pResource = dingDianHuanChongQu1.Get();
    dingdianpingzhaungshuxing3.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    dingdianpingzhaungshuxing3.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
    dingdianpingzhaungshuxing3.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;

    D3D12_RESOURCE_BARRIER dingdianpingzhang3 = {};
    dingdianpingzhang3.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    dingdianpingzhang3.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    dingdianpingzhang3.Transition = dingdianpingzhaungshuxing3;

    mingLingLieBiaoJiSuan->ResourceBarrier(1, &dingdianpingzhang3);


D3D12 ERROR: ID3D12CommandList::ResourceBarrier: Resource(0x0E146FB8:'Unnamed ID3D12Resource Object') (subresource : 0) was bound as DATA_STATIC on this command list before this ResourceBarrier call to transition from state (0x8: D3D12_RESOURCE_STATE_UNORDERED_ACCESS) to (0x1: D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER), which indicates a change to its data (or possibly resource metadata). But it is invalid to change it until this command list has finished executing for the last time. [ EXECUTION ERROR #1002: DATA_STATIC_DESCRIPTOR_INVALID_DATA_CHANGE]

根签名里的 descriptor range 有没有设置 DATA_STATIC 的标签?

你把报错复制出来发我

【以下回答由 GPT 生成】

这个错误是由于在执行ResourceBarrier之前,资源已经被绑定到了一个数据静态(DATA_STATIC)的状态上导致的。根据错误信息,可能是在前面的命令列表中对资源进行了更改,并且这些更改在当前命令列表完成之前无法生效。

解决这个问题的方法是,在执行ResourceBarrier之前,确保之前的命令列表已经执行完成。可以通过以下步骤来实现:

  1. 使用命令队列执行之前的命令列表。
ID3D12CommandQueue* commandQueue;  // 命令队列
ID3D12CommandList* previousCommandList;  // 之前的命令列表

commandQueue->ExecuteCommandLists(1, &previousCommandList);
  1. 在CommandQueue执行完成后,确认它已经执行完毕。
ID3D12Fence* fence;  // 栅栏对象
UINT64 fenceValue;  // 之前命令列表的栅栏值

fenceValue++;  // 递增栅栏值
commandQueue->Signal(fence, fenceValue);  // 发出栅栏信号

if (fence->GetCompletedValue() < fenceValue)
{
    HANDLE eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);  // 创建事件对象
    fence->SetEventOnCompletion(fenceValue, eventHandle);  // 设置事件侦听
    WaitForSingleObject(eventHandle, INFINITE);  // 等待事件触发
    CloseHandle(eventHandle);  // 关闭事件句柄
}
  1. 之后可以执行资源状态转换。
D3D12_RESOURCE_TRANSITION_BARRIER transitionBarrier = {};
transitionBarrier.pResource = dingDianHuanChongQu1.Get();
transitionBarrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
transitionBarrier.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
transitionBarrier.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;

D3D12_RESOURCE_BARRIER resourceBarrier = {};
resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
resourceBarrier.Transition = transitionBarrier;

mingLingLieBiaoJiSuan->ResourceBarrier(1, &resourceBarrier);

希望这些步骤能够帮助你解决问题。如果仍然有疑问,请告诉我。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^