2016-08-11 2 views
1

내 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); 
} 

어떻게 디버그 레이어 오류를 수정할 수 있습니까?

답변

1

업로드 버퍼는 D3D12_RESOURCE_STATE_GENERIC_READ 상태 (link) 일 수 있습니다. D3D12_RESOURCE_STATE_COPY_DEST 상태의 기본 버퍼를 만들어야합니다. 그런 다음 CPU에 업로드 힙을 매핑 한 후 업로드 버퍼의 내용을 ID3D12GraphicsCommandList::CopyBufferRegion() 메서드로 gpu의 기본 버퍼에 복사 할 수 있습니다. 이후 기본 버퍼를 사용 가능한 상태로 전환하는 것을 잊지 말고 gpu가 복사를 실행 한 순간에 업로드 힙이 여전히 존재하는지 확인하십시오.

+0

감사합니다.하지만 내 질문의 코드에 적용하는 방법에 대해 좀 더 구체적으로 설명해 주실 수 있습니까? 특히 버퍼 및 힙 생성 매개 변수 또한 기본 버퍼 작성을 이해하지 못합니다. 현재 코드의 버퍼 중 하나를 대체하거나 새 버퍼를 작성해야합니까? – SurvivalMachine

+0

[여기] (https://github.com/d3dcoder/d3d12book/blob/master/Common/d3dUtil.cpp#L38)의 예를 찾을 수 있습니다. 기본적으로 버퍼 2 개가 필요합니다. 기본 버퍼는 버텍스 버퍼가 더 이상 필요하지 않을 때까지 살아 있어야하며 업로드 할 때까지 복사해야합니다. – nikitablack

관련 문제