Обновление буфера вершин вызывает ошибку уровня отладки

Я обновил Windows 10 до версии 1607, которая включает дополнительную проверку уровня отладки D3D. Мой код обновления буфера вершин работал без предупреждений / ошибок до обновления, но теперь я получаю ошибку при вызове CopyBufferRegion:

Состояние ресурса (0xAC3: D3D12_RESOURCE_STATE_GENERIC_READ) ресурса
(0x000001DB301B9750: ») (подресурс: 0)
недопустимо для использования в качестве буфера назначения. Ожидаемые биты состояния: 0x400:
D3D12_RESOURCE_STATE_COPY_DEST, фактическое состояние: 0xAC3:
D3D12_RESOURCE_STATE_GENERIC_READ

Если я перейду vb в розыск (D3D12_RESOURCE_STATE_COPY_DEST) Вместо этого я получаю сообщение об ошибке:

D3D12 ОШИБКА: ID3D12CommandList :: ResourceBarrier: некоторые кучи
ограничено определенными состояниями D3D12_RESOURCE_STATES и не может быть
изменилось. D3D12_HEAP_TYPE_UPLOAD требует
D3D12_RESOURCE_STATE_GENERIC_READ. D3D12_HEAP_TYPE_READBACK требует
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 государство (ссылка на сайт). Вам нужно создать буфер по умолчанию с D3D12_RESOURCE_STATE_COPY_DEST государство. Затем после сопоставления кучи загрузки на процессоре вы можете скопировать содержимое буфера загрузки в буфер по умолчанию на gpu с помощью ID3D12GraphicsCommandList :: CopyBufferRegion () метод. Не забудьте перевести буфер по умолчанию в работоспособное состояние после и убедитесь, что куча загрузки все еще существует в тот момент, когда gpu выполнил копирование.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector