내 Windows 10을 추가 D3D 디버그 레이어 검사가 포함 된 버전 1607로 업데이트했습니다. 내 버텍스 버퍼 업데이트 코드는 업데이트 전에 경고/오류없이 작동했지만 CopyBufferRegion
를 호출 할 때 지금은 오류를 받고 있어요 :버텍스 버퍼를 업데이트하면 디버그 레이어 오류가 발생합니다.
Resource state (0xAC3: D3D12_RESOURCE_STATE_GENERIC_READ) of resource (0x000001DB301B9750:'') (subresource: 0) is invalid for use as a destination buffer. Expected State Bits: 0x400: D3D12_RESOURCE_STATE_COPY_DEST, Actual State: 0xAC3: D3D12_RESOURCE_STATE_GENERIC_READ
내가 원하는 상태 (D3D12_RESOURCE_STATE_COPY_DEST
)에 vb
를 전환하면 내가 대신 같은 오류가 발생합니다 이 :
D3D12 ERROR: ID3D12CommandList::ResourceBarrier: Certain heaps are restricted to certain D3D12_RESOURCE_STATES states, and cannot be changed. D3D12_HEAP_TYPE_UPLOAD requires D3D12_RESOURCE_STATE_GENERIC_READ. D3D12_HEAP_TYPE_READBACK requires D3D12_RESOURCE_STATE_COPY_DEST. [ RESOURCE_MANIPULATION ERROR #741: RESOURCE_BARRIER_INVALID_HEAP]
여기 내 코드입니다. 버텍스 버퍼를 생성하고 버텍스 데이터를 업로드하고 필요할 경우 버퍼 크기를 조정합니다.
void ae3d::VertexBuffer::UploadVB(void* faces, void* vertices, unsigned ibSize)
{
D3D12_HEAP_PROPERTIES uploadProp = {};
uploadProp.Type = D3D12_HEAP_TYPE_UPLOAD;
uploadProp.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
uploadProp.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
uploadProp.CreationNodeMask = 1;
uploadProp.VisibleNodeMask = 1;
D3D12_RESOURCE_DESC bufferProp = {};
bufferProp.Alignment = 0;
bufferProp.DepthOrArraySize = 1;
bufferProp.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
bufferProp.Flags = D3D12_RESOURCE_FLAG_NONE;
bufferProp.Format = DXGI_FORMAT_UNKNOWN;
bufferProp.Height = 1;
bufferProp.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
bufferProp.MipLevels = 1;
bufferProp.SampleDesc.Count = 1;
bufferProp.SampleDesc.Quality = 0;
bufferProp.Width = ibOffset + ibSize;
// this branch resizes the buffer and causes validation errors.
if (vb != nullptr && bufferProp.Width <= sizeBytes)
{
ID3D12Resource* stagingBuffer = nullptr;
HRESULT hr = GfxDeviceGlobal::device->CreateCommittedResource(&uploadProp, D3D12_HEAP_FLAG_NONE, &bufferProp,
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&stagingBuffer));
AE3D_CHECK_D3D(hr, "Failed to create vertex staging resource");
char* vbUploadPtr = nullptr;
hr = stagingBuffer->Map(0, nullptr, reinterpret_cast<void**>(&vbUploadPtr));
if (FAILED(hr))
{
ae3d::System::Assert(false, "Unable to map vertex staging buffer!\n");
return;
}
memcpy_s(vbUploadPtr, ibOffset, vertices, ibOffset);
memcpy_s(vbUploadPtr + ibOffset, ibSize, faces, ibSize);
stagingBuffer->Unmap(0, nullptr);
// vb state is invalid at this point, needs D3D12_RESOURCE_STATE_COPY_DEST
GfxDeviceGlobal::graphicsCommandList->CopyBufferRegion(vb, 0, stagingBuffer, 0, ibOffset + ibSize);
Global::frameVBUploads.push_back(stagingBuffer);
sizeBytes = ibOffset + ibSize;
return;
}
sizeBytes = ibOffset + ibSize;
HRESULT hr = GfxDeviceGlobal::device->CreateCommittedResource(
&uploadProp,
D3D12_HEAP_FLAG_NONE,
&bufferProp,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&vb));
if (FAILED(hr))
{
ae3d::System::Assert(false, "Unable to create vertex buffer!\n");
return;
}
Global::vbs.push_back(vb);
char* vbUploadPtr = nullptr;
hr = vb->Map(0, nullptr, reinterpret_cast<void**>(&vbUploadPtr));
if (FAILED(hr))
{
ae3d::System::Assert(false, "Unable to map vertex buffer!\n");
return;
}
memcpy_s(vbUploadPtr, ibOffset, vertices, ibOffset);
memcpy_s(vbUploadPtr + ibOffset, ibSize, faces, ibSize);
vb->Unmap(0, nullptr);
}
어떻게 디버그 레이어 오류를 수정할 수 있습니까?
감사합니다.하지만 내 질문의 코드에 적용하는 방법에 대해 좀 더 구체적으로 설명해 주실 수 있습니까? 특히 버퍼 및 힙 생성 매개 변수 또한 기본 버퍼 작성을 이해하지 못합니다. 현재 코드의 버퍼 중 하나를 대체하거나 새 버퍼를 작성해야합니까? – SurvivalMachine
[여기] (https://github.com/d3dcoder/d3d12book/blob/master/Common/d3dUtil.cpp#L38)의 예를 찾을 수 있습니다. 기본적으로 버퍼 2 개가 필요합니다. 기본 버퍼는 버텍스 버퍼가 더 이상 필요하지 않을 때까지 살아 있어야하며 업로드 할 때까지 복사해야합니다. – nikitablack