mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-13 00:26:00 +00:00
Residency 3: Track Resource Heap Usages
Track what heaps are required to be resident upon command list submission. Bug: dawn:193 Change-Id: Icefe5aed047140f401d51018937c5364b3ed7c4f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16382 Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
421684f943
commit
0338b7ae19
@ -20,6 +20,7 @@
|
|||||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||||
#include "dawn_native/d3d12/D3D12Error.h"
|
#include "dawn_native/d3d12/D3D12Error.h"
|
||||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||||
|
#include "dawn_native/d3d12/HeapD3D12.h"
|
||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
@ -127,6 +128,29 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return mResourceAllocation.GetD3D12Resource();
|
return mResourceAllocation.GetD3D12Resource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
||||||
|
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
||||||
|
// cause subsequent errors.
|
||||||
|
bool Buffer::TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
|
wgpu::BufferUsage newUsage) {
|
||||||
|
// Track the underlying heap to ensure residency.
|
||||||
|
Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap());
|
||||||
|
commandContext->TrackHeapUsage(heap, GetDevice()->GetPendingCommandSerial());
|
||||||
|
|
||||||
|
// Return the resource barrier.
|
||||||
|
return TransitionUsageAndGetResourceBarrier(commandContext, barrier, newUsage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
|
wgpu::BufferUsage newUsage) {
|
||||||
|
D3D12_RESOURCE_BARRIER barrier;
|
||||||
|
|
||||||
|
if (TrackUsageAndGetResourceBarrier(commandContext, &barrier, newUsage)) {
|
||||||
|
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
||||||
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
||||||
// cause subsequent errors.
|
// cause subsequent errors.
|
||||||
@ -202,15 +226,6 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::TransitionUsageNow(CommandRecordingContext* commandContext,
|
|
||||||
wgpu::BufferUsage usage) {
|
|
||||||
D3D12_RESOURCE_BARRIER barrier;
|
|
||||||
|
|
||||||
if (TransitionUsageAndGetResourceBarrier(commandContext, &barrier, usage)) {
|
|
||||||
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS Buffer::GetVA() const {
|
D3D12_GPU_VIRTUAL_ADDRESS Buffer::GetVA() const {
|
||||||
return mResourceAllocation.GetGPUPointer();
|
return mResourceAllocation.GetGPUPointer();
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,12 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
ComPtr<ID3D12Resource> GetD3D12Resource() const;
|
ComPtr<ID3D12Resource> GetD3D12Resource() const;
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
|
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
|
||||||
void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);
|
void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);
|
||||||
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
|
||||||
|
bool TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
D3D12_RESOURCE_BARRIER* barrier,
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
wgpu::BufferUsage newUsage);
|
wgpu::BufferUsage newUsage);
|
||||||
void TransitionUsageNow(CommandRecordingContext* commandContext, wgpu::BufferUsage usage);
|
void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
|
wgpu::BufferUsage newUsage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Dawn API
|
// Dawn API
|
||||||
@ -51,6 +53,10 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
bool IsMapWritable() const override;
|
bool IsMapWritable() const override;
|
||||||
virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||||
|
|
||||||
|
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
|
wgpu::BufferUsage newUsage);
|
||||||
|
|
||||||
ResourceHeapAllocation mResourceAllocation;
|
ResourceHeapAllocation mResourceAllocation;
|
||||||
bool mFixedResourceState = false;
|
bool mFixedResourceState = false;
|
||||||
wgpu::BufferUsage mLastUsage = wgpu::BufferUsage::None;
|
wgpu::BufferUsage mLastUsage = wgpu::BufferUsage::None;
|
||||||
|
@ -131,7 +131,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
switch (bindingType) {
|
switch (bindingType) {
|
||||||
case wgpu::BindingType::StorageBuffer:
|
case wgpu::BindingType::StorageBuffer:
|
||||||
ToBackend(mBuffers[index][binding])
|
ToBackend(mBuffers[index][binding])
|
||||||
->TransitionUsageNow(commandContext,
|
->TrackUsageAndTransitionNow(commandContext,
|
||||||
wgpu::BufferUsage::Storage);
|
wgpu::BufferUsage::Storage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -431,9 +431,9 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
Texture* resolveTexture = ToBackend(resolveTarget->GetTexture());
|
Texture* resolveTexture = ToBackend(resolveTarget->GetTexture());
|
||||||
|
|
||||||
// Transition the usages of the color attachment and resolve target.
|
// Transition the usages of the color attachment and resolve target.
|
||||||
colorTexture->TransitionUsageNow(commandContext,
|
colorTexture->TrackUsageAndTransitionNow(commandContext,
|
||||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
|
D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
|
||||||
resolveTexture->TransitionUsageNow(commandContext,
|
resolveTexture->TrackUsageAndTransitionNow(commandContext,
|
||||||
D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
||||||
|
|
||||||
// Do MSAA resolve with ResolveSubResource().
|
// Do MSAA resolve with ResolveSubResource().
|
||||||
@ -469,7 +469,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
bindingTracker.SetID3D12DescriptorHeaps(commandList);
|
bindingTracker.SetID3D12DescriptorHeaps(commandList);
|
||||||
|
|
||||||
// Records the necessary barriers for the resource usage pre-computed by the frontend
|
// Records the necessary barriers for the resource usage pre-computed by the frontend
|
||||||
auto TransitionForPass = [](CommandRecordingContext* commandContext,
|
auto PrepareResourcesForSubmission = [](CommandRecordingContext* commandContext,
|
||||||
const PassResourceUsage& usages) -> bool {
|
const PassResourceUsage& usages) -> bool {
|
||||||
std::vector<D3D12_RESOURCE_BARRIER> barriers;
|
std::vector<D3D12_RESOURCE_BARRIER> barriers;
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
for (size_t i = 0; i < usages.buffers.size(); ++i) {
|
for (size_t i = 0; i < usages.buffers.size(); ++i) {
|
||||||
D3D12_RESOURCE_BARRIER barrier;
|
D3D12_RESOURCE_BARRIER barrier;
|
||||||
if (ToBackend(usages.buffers[i])
|
if (ToBackend(usages.buffers[i])
|
||||||
->TransitionUsageAndGetResourceBarrier(commandContext, &barrier,
|
->TrackUsageAndGetResourceBarrier(commandContext, &barrier,
|
||||||
usages.bufferUsages[i])) {
|
usages.bufferUsages[i])) {
|
||||||
barriers.push_back(barrier);
|
barriers.push_back(barrier);
|
||||||
}
|
}
|
||||||
@ -504,7 +504,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
for (size_t i = 0; i < usages.textures.size(); ++i) {
|
for (size_t i = 0; i < usages.textures.size(); ++i) {
|
||||||
D3D12_RESOURCE_BARRIER barrier;
|
D3D12_RESOURCE_BARRIER barrier;
|
||||||
if (ToBackend(usages.textures[i])
|
if (ToBackend(usages.textures[i])
|
||||||
->TransitionUsageAndGetResourceBarrier(commandContext, &barrier,
|
->TrackUsageAndGetResourceBarrier(commandContext, &barrier,
|
||||||
usages.textureUsages[i])) {
|
usages.textureUsages[i])) {
|
||||||
barriers.push_back(barrier);
|
barriers.push_back(barrier);
|
||||||
}
|
}
|
||||||
@ -528,7 +528,8 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
case Command::BeginComputePass: {
|
case Command::BeginComputePass: {
|
||||||
mCommands.NextCommand<BeginComputePassCmd>();
|
mCommands.NextCommand<BeginComputePassCmd>();
|
||||||
|
|
||||||
TransitionForPass(commandContext, passResourceUsages[nextPassNumber]);
|
PrepareResourcesForSubmission(commandContext,
|
||||||
|
passResourceUsages[nextPassNumber]);
|
||||||
bindingTracker.SetInComputePass(true);
|
bindingTracker.SetInComputePass(true);
|
||||||
DAWN_TRY(RecordComputePass(commandContext, &bindingTracker));
|
DAWN_TRY(RecordComputePass(commandContext, &bindingTracker));
|
||||||
|
|
||||||
@ -539,8 +540,8 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
BeginRenderPassCmd* beginRenderPassCmd =
|
BeginRenderPassCmd* beginRenderPassCmd =
|
||||||
mCommands.NextCommand<BeginRenderPassCmd>();
|
mCommands.NextCommand<BeginRenderPassCmd>();
|
||||||
|
|
||||||
const bool passHasUAV =
|
const bool passHasUAV = PrepareResourcesForSubmission(
|
||||||
TransitionForPass(commandContext, passResourceUsages[nextPassNumber]);
|
commandContext, passResourceUsages[nextPassNumber]);
|
||||||
bindingTracker.SetInComputePass(false);
|
bindingTracker.SetInComputePass(false);
|
||||||
|
|
||||||
LazyClearRenderPassAttachments(beginRenderPassCmd);
|
LazyClearRenderPassAttachments(beginRenderPassCmd);
|
||||||
@ -555,8 +556,10 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
Buffer* srcBuffer = ToBackend(copy->source.Get());
|
Buffer* srcBuffer = ToBackend(copy->source.Get());
|
||||||
Buffer* dstBuffer = ToBackend(copy->destination.Get());
|
Buffer* dstBuffer = ToBackend(copy->destination.Get());
|
||||||
|
|
||||||
srcBuffer->TransitionUsageNow(commandContext, wgpu::BufferUsage::CopySrc);
|
srcBuffer->TrackUsageAndTransitionNow(commandContext,
|
||||||
dstBuffer->TransitionUsageNow(commandContext, wgpu::BufferUsage::CopyDst);
|
wgpu::BufferUsage::CopySrc);
|
||||||
|
dstBuffer->TrackUsageAndTransitionNow(commandContext,
|
||||||
|
wgpu::BufferUsage::CopyDst);
|
||||||
|
|
||||||
commandList->CopyBufferRegion(
|
commandList->CopyBufferRegion(
|
||||||
dstBuffer->GetD3D12Resource().Get(), copy->destinationOffset,
|
dstBuffer->GetD3D12Resource().Get(), copy->destinationOffset,
|
||||||
@ -578,8 +581,9 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
copy->destination.arrayLayer, 1);
|
copy->destination.arrayLayer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->TransitionUsageNow(commandContext, wgpu::BufferUsage::CopySrc);
|
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopySrc);
|
||||||
texture->TransitionUsageNow(commandContext, wgpu::TextureUsage::CopyDst);
|
texture->TrackUsageAndTransitionNow(commandContext,
|
||||||
|
wgpu::TextureUsage::CopyDst);
|
||||||
|
|
||||||
auto copySplit = ComputeTextureCopySplit(
|
auto copySplit = ComputeTextureCopySplit(
|
||||||
copy->destination.origin, copy->copySize, texture->GetFormat(),
|
copy->destination.origin, copy->copySize, texture->GetFormat(),
|
||||||
@ -613,8 +617,9 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
texture->EnsureSubresourceContentInitialized(
|
texture->EnsureSubresourceContentInitialized(
|
||||||
commandContext, copy->source.mipLevel, 1, copy->source.arrayLayer, 1);
|
commandContext, copy->source.mipLevel, 1, copy->source.arrayLayer, 1);
|
||||||
|
|
||||||
texture->TransitionUsageNow(commandContext, wgpu::TextureUsage::CopySrc);
|
texture->TrackUsageAndTransitionNow(commandContext,
|
||||||
buffer->TransitionUsageNow(commandContext, wgpu::BufferUsage::CopyDst);
|
wgpu::TextureUsage::CopySrc);
|
||||||
|
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst);
|
||||||
|
|
||||||
TextureCopySplit copySplit = ComputeTextureCopySplit(
|
TextureCopySplit copySplit = ComputeTextureCopySplit(
|
||||||
copy->source.origin, copy->copySize, texture->GetFormat(),
|
copy->source.origin, copy->copySize, texture->GetFormat(),
|
||||||
@ -660,8 +665,9 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
commandContext, copy->destination.mipLevel, 1,
|
commandContext, copy->destination.mipLevel, 1,
|
||||||
copy->destination.arrayLayer, 1);
|
copy->destination.arrayLayer, 1);
|
||||||
}
|
}
|
||||||
source->TransitionUsageNow(commandContext, wgpu::TextureUsage::CopySrc);
|
source->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc);
|
||||||
destination->TransitionUsageNow(commandContext, wgpu::TextureUsage::CopyDst);
|
destination->TrackUsageAndTransitionNow(commandContext,
|
||||||
|
wgpu::TextureUsage::CopyDst);
|
||||||
|
|
||||||
if (CanUseCopyResource(source->GetNumMipLevels(), source->GetSize(),
|
if (CanUseCopyResource(source->GetNumMipLevels(), source->GetSize(),
|
||||||
destination->GetSize(), copy->copySize)) {
|
destination->GetSize(), copy->copySize)) {
|
||||||
@ -811,8 +817,8 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
Texture* resolveDestinationTexture =
|
Texture* resolveDestinationTexture =
|
||||||
ToBackend(resolveDestinationView->GetTexture());
|
ToBackend(resolveDestinationView->GetTexture());
|
||||||
|
|
||||||
resolveDestinationTexture->TransitionUsageNow(commandContext,
|
resolveDestinationTexture->TrackUsageAndTransitionNow(
|
||||||
D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
commandContext, D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
||||||
|
|
||||||
renderPassBuilder->SetRenderTargetEndingAccessResolve(i, attachmentInfo.storeOp,
|
renderPassBuilder->SetRenderTargetEndingAccessResolve(i, attachmentInfo.storeOp,
|
||||||
view, resolveDestinationView);
|
view, resolveDestinationView);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||||
#include "dawn_native/d3d12/CommandAllocatorManager.h"
|
#include "dawn_native/d3d12/CommandAllocatorManager.h"
|
||||||
#include "dawn_native/d3d12/D3D12Error.h"
|
#include "dawn_native/d3d12/D3D12Error.h"
|
||||||
|
#include "dawn_native/d3d12/HeapD3D12.h"
|
||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
// common state right before command list submission. TransitionUsageNow itself ensures
|
// common state right before command list submission. TransitionUsageNow itself ensures
|
||||||
// no unnecessary transitions happen if the resources is already in the common state.
|
// no unnecessary transitions happen if the resources is already in the common state.
|
||||||
for (Texture* texture : mSharedTextures) {
|
for (Texture* texture : mSharedTextures) {
|
||||||
texture->TransitionUsageNow(this, D3D12_RESOURCE_STATE_COMMON);
|
texture->TrackUsageAndTransitionNow(this, D3D12_RESOURCE_STATE_COMMON);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError error =
|
MaybeError error =
|
||||||
@ -73,10 +74,20 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
mIsOpen = false;
|
mIsOpen = false;
|
||||||
mSharedTextures.clear();
|
mSharedTextures.clear();
|
||||||
|
mHeapsPendingUsage.clear();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandRecordingContext::TrackHeapUsage(Heap* heap, Serial serial) {
|
||||||
|
// Before tracking the heap, check the last serial it was recorded on to ensure we aren't
|
||||||
|
// tracking it more than once.
|
||||||
|
if (heap->GetLastUsage() < serial) {
|
||||||
|
heap->SetLastUsage(serial);
|
||||||
|
mHeapsPendingUsage.push_back(heap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ID3D12GraphicsCommandList* CommandRecordingContext::GetCommandList() const {
|
ID3D12GraphicsCommandList* CommandRecordingContext::GetCommandList() const {
|
||||||
ASSERT(mD3d12CommandList != nullptr);
|
ASSERT(mD3d12CommandList != nullptr);
|
||||||
ASSERT(IsOpen());
|
ASSERT(IsOpen());
|
||||||
@ -96,6 +107,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
mD3d12CommandList4.Reset();
|
mD3d12CommandList4.Reset();
|
||||||
mIsOpen = false;
|
mIsOpen = false;
|
||||||
mSharedTextures.clear();
|
mSharedTextures.clear();
|
||||||
|
mHeapsPendingUsage.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandRecordingContext::IsOpen() const {
|
bool CommandRecordingContext::IsOpen() const {
|
||||||
|
@ -37,11 +37,14 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
MaybeError ExecuteCommandList(ID3D12CommandQueue* d3d12CommandQueue);
|
MaybeError ExecuteCommandList(ID3D12CommandQueue* d3d12CommandQueue);
|
||||||
|
|
||||||
|
void TrackHeapUsage(Heap* heap, Serial serial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ComPtr<ID3D12GraphicsCommandList> mD3d12CommandList;
|
ComPtr<ID3D12GraphicsCommandList> mD3d12CommandList;
|
||||||
ComPtr<ID3D12GraphicsCommandList4> mD3d12CommandList4;
|
ComPtr<ID3D12GraphicsCommandList4> mD3d12CommandList4;
|
||||||
bool mIsOpen = false;
|
bool mIsOpen = false;
|
||||||
std::set<Texture*> mSharedTextures;
|
std::set<Texture*> mSharedTextures;
|
||||||
|
std::vector<Heap*> mHeapsPendingUsage;
|
||||||
};
|
};
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
||||||
|
@ -290,12 +290,14 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
CommandRecordingContext* commandRecordingContext;
|
CommandRecordingContext* commandRecordingContext;
|
||||||
DAWN_TRY_ASSIGN(commandRecordingContext, GetPendingCommandContext());
|
DAWN_TRY_ASSIGN(commandRecordingContext, GetPendingCommandContext());
|
||||||
|
|
||||||
ToBackend(destination)
|
Buffer* dstBuffer = ToBackend(destination);
|
||||||
->TransitionUsageNow(commandRecordingContext, wgpu::BufferUsage::CopyDst);
|
StagingBuffer* srcBuffer = ToBackend(source);
|
||||||
|
dstBuffer->TrackUsageAndTransitionNow(commandRecordingContext, wgpu::BufferUsage::CopyDst);
|
||||||
|
srcBuffer->TrackUsage(commandRecordingContext);
|
||||||
|
|
||||||
commandRecordingContext->GetCommandList()->CopyBufferRegion(
|
commandRecordingContext->GetCommandList()->CopyBufferRegion(
|
||||||
ToBackend(destination)->GetD3D12Resource().Get(), destinationOffset,
|
dstBuffer->GetD3D12Resource().Get(), destinationOffset, srcBuffer->GetResource(),
|
||||||
ToBackend(source)->GetResource(), sourceOffset, size);
|
sourceOffset, size);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,14 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return mD3d12Pageable;
|
return mD3d12Pageable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Serial Heap::GetLastUsage() const {
|
||||||
|
return mLastUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Heap::SetLastUsage(Serial serial) {
|
||||||
|
mLastUsage = serial;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t Heap::GetSize() const {
|
uint64_t Heap::GetSize() const {
|
||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#ifndef DAWNNATIVE_D3D12_HEAPD3D12_H_
|
#ifndef DAWNNATIVE_D3D12_HEAPD3D12_H_
|
||||||
#define DAWNNATIVE_D3D12_HEAPD3D12_H_
|
#define DAWNNATIVE_D3D12_HEAPD3D12_H_
|
||||||
|
|
||||||
|
#include "common/Serial.h"
|
||||||
#include "dawn_native/ResourceHeap.h"
|
#include "dawn_native/ResourceHeap.h"
|
||||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||||
|
|
||||||
@ -28,10 +29,17 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
ComPtr<ID3D12Heap> GetD3D12Heap() const;
|
ComPtr<ID3D12Heap> GetD3D12Heap() const;
|
||||||
ComPtr<ID3D12Pageable> GetD3D12Pageable() const;
|
ComPtr<ID3D12Pageable> GetD3D12Pageable() const;
|
||||||
|
|
||||||
|
// We set mLastRecordingSerial to denote the serial this heap was last recorded to be used.
|
||||||
|
// We must check this serial against the current serial when recording heap usages to ensure
|
||||||
|
// we do not process residency for this heap multiple times.
|
||||||
|
Serial GetLastUsage() const;
|
||||||
|
void SetLastUsage(Serial serial);
|
||||||
|
|
||||||
uint64_t GetSize() const;
|
uint64_t GetSize() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ComPtr<ID3D12Pageable> mD3d12Pageable;
|
ComPtr<ID3D12Pageable> mD3d12Pageable;
|
||||||
|
Serial mLastUsage = 0;
|
||||||
uint64_t mSize = 0;
|
uint64_t mSize = 0;
|
||||||
};
|
};
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "dawn_native/d3d12/StagingBufferD3D12.h"
|
#include "dawn_native/d3d12/StagingBufferD3D12.h"
|
||||||
#include "dawn_native/d3d12/D3D12Error.h"
|
#include "dawn_native/d3d12/D3D12Error.h"
|
||||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||||
|
#include "dawn_native/d3d12/HeapD3D12.h"
|
||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
@ -60,4 +61,9 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return mUploadHeap.GetD3D12Resource().Get();
|
return mUploadHeap.GetD3D12Resource().Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StagingBuffer::TrackUsage(CommandRecordingContext* commandContext) {
|
||||||
|
// Track the underlying heap to ensure residency.
|
||||||
|
Heap* heap = ToBackend(mUploadHeap.GetResourceHeap());
|
||||||
|
commandContext->TrackHeapUsage(heap, mDevice->GetPendingCommandSerial());
|
||||||
|
}
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
|
class CommandRecordingContext;
|
||||||
class Device;
|
class Device;
|
||||||
|
|
||||||
class StagingBuffer : public StagingBufferBase {
|
class StagingBuffer : public StagingBufferBase {
|
||||||
@ -32,6 +33,8 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
MaybeError Initialize() override;
|
MaybeError Initialize() override;
|
||||||
|
|
||||||
|
void TrackUsage(CommandRecordingContext* commandContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device* mDevice;
|
Device* mDevice;
|
||||||
ResourceHeapAllocation mUploadHeap;
|
ResourceHeapAllocation mUploadHeap;
|
||||||
|
@ -55,7 +55,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
|
DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
|
||||||
|
|
||||||
// Perform the necessary transition for the texture to be presented.
|
// Perform the necessary transition for the texture to be presented.
|
||||||
ToBackend(texture)->TransitionUsageNow(commandContext, mTextureUsage);
|
ToBackend(texture)->TrackUsageAndTransitionNow(commandContext, mTextureUsage);
|
||||||
|
|
||||||
DAWN_TRY(device->ExecutePendingCommandContext());
|
DAWN_TRY(device->ExecutePendingCommandContext());
|
||||||
|
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
#include "dawn_native/DynamicUploader.h"
|
#include "dawn_native/DynamicUploader.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/d3d12/BufferD3D12.h"
|
#include "dawn_native/d3d12/BufferD3D12.h"
|
||||||
|
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||||
#include "dawn_native/d3d12/D3D12Error.h"
|
#include "dawn_native/d3d12/D3D12Error.h"
|
||||||
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
|
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
|
||||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||||
|
#include "dawn_native/d3d12/HeapD3D12.h"
|
||||||
#include "dawn_native/d3d12/ResourceAllocatorManagerD3D12.h"
|
#include "dawn_native/d3d12/ResourceAllocatorManagerD3D12.h"
|
||||||
#include "dawn_native/d3d12/StagingBufferD3D12.h"
|
#include "dawn_native/d3d12/StagingBufferD3D12.h"
|
||||||
#include "dawn_native/d3d12/TextureCopySplitter.h"
|
#include "dawn_native/d3d12/TextureCopySplitter.h"
|
||||||
@ -417,13 +419,47 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
||||||
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
||||||
// cause subsequent errors.
|
// cause subsequent errors.
|
||||||
bool Texture::TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
bool Texture::TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
D3D12_RESOURCE_BARRIER* barrier,
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
wgpu::TextureUsage newUsage) {
|
wgpu::TextureUsage newUsage) {
|
||||||
return TransitionUsageAndGetResourceBarrier(commandContext, barrier,
|
return TrackUsageAndGetResourceBarrier(commandContext, barrier,
|
||||||
D3D12TextureUsage(newUsage, GetFormat()));
|
D3D12TextureUsage(newUsage, GetFormat()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
||||||
|
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
||||||
|
// cause subsequent errors.
|
||||||
|
bool Texture::TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
|
D3D12_RESOURCE_STATES newState) {
|
||||||
|
if (mResourceAllocation.GetInfo().mMethod != AllocationMethod::kExternal) {
|
||||||
|
// Track the underlying heap to ensure residency.
|
||||||
|
Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap());
|
||||||
|
commandContext->TrackHeapUsage(heap, GetDevice()->GetPendingCommandSerial());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the resource barrier.
|
||||||
|
return TransitionUsageAndGetResourceBarrier(commandContext, barrier, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
|
wgpu::TextureUsage usage) {
|
||||||
|
D3D12_RESOURCE_BARRIER barrier;
|
||||||
|
|
||||||
|
if (TrackUsageAndGetResourceBarrier(commandContext, &barrier, usage)) {
|
||||||
|
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_STATES newState) {
|
||||||
|
D3D12_RESOURCE_BARRIER barrier;
|
||||||
|
|
||||||
|
if (TrackUsageAndGetResourceBarrier(commandContext, &barrier, newState)) {
|
||||||
|
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
||||||
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
// ResourceBarrier call. Failing to do so will cause the tracked state to become invalid and can
|
||||||
// cause subsequent errors.
|
// cause subsequent errors.
|
||||||
@ -502,20 +538,6 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::TransitionUsageNow(CommandRecordingContext* commandContext,
|
|
||||||
wgpu::TextureUsage usage) {
|
|
||||||
TransitionUsageNow(commandContext, D3D12TextureUsage(usage, GetFormat()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::TransitionUsageNow(CommandRecordingContext* commandContext,
|
|
||||||
D3D12_RESOURCE_STATES newState) {
|
|
||||||
D3D12_RESOURCE_BARRIER barrier;
|
|
||||||
|
|
||||||
if (TransitionUsageAndGetResourceBarrier(commandContext, &barrier, newState)) {
|
|
||||||
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t baseMipLevel,
|
D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t baseMipLevel,
|
||||||
uint32_t baseArrayLayer,
|
uint32_t baseArrayLayer,
|
||||||
uint32_t layerCount) const {
|
uint32_t layerCount) const {
|
||||||
@ -583,7 +605,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
if (GetFormat().isRenderable) {
|
if (GetFormat().isRenderable) {
|
||||||
if (GetFormat().HasDepthOrStencil()) {
|
if (GetFormat().HasDepthOrStencil()) {
|
||||||
TransitionUsageNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||||
DescriptorHeapHandle dsvHeap;
|
DescriptorHeapHandle dsvHeap;
|
||||||
DAWN_TRY_ASSIGN(dsvHeap, descriptorHeapAllocator->AllocateCPUHeap(
|
DAWN_TRY_ASSIGN(dsvHeap, descriptorHeapAllocator->AllocateCPUHeap(
|
||||||
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1));
|
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1));
|
||||||
@ -603,7 +625,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
commandList->ClearDepthStencilView(dsvHandle, clearFlags, fClearColor, clearColor,
|
commandList->ClearDepthStencilView(dsvHandle, clearFlags, fClearColor, clearColor,
|
||||||
0, nullptr);
|
0, nullptr);
|
||||||
} else {
|
} else {
|
||||||
TransitionUsageNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||||
DescriptorHeapHandle rtvHeap;
|
DescriptorHeapHandle rtvHeap;
|
||||||
DAWN_TRY_ASSIGN(rtvHeap, descriptorHeapAllocator->AllocateCPUHeap(
|
DAWN_TRY_ASSIGN(rtvHeap, descriptorHeapAllocator->AllocateCPUHeap(
|
||||||
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1));
|
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1));
|
||||||
@ -637,7 +659,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
uploader->Allocate(bufferSize, device->GetPendingCommandSerial()));
|
uploader->Allocate(bufferSize, device->GetPendingCommandSerial()));
|
||||||
memset(uploadHandle.mappedBuffer, clearColor, bufferSize);
|
memset(uploadHandle.mappedBuffer, clearColor, bufferSize);
|
||||||
|
|
||||||
TransitionUsageNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST);
|
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||||
|
|
||||||
// compute d3d12 texture copy locations for texture and buffer
|
// compute d3d12 texture copy locations for texture and buffer
|
||||||
Extent3D copySize = {GetSize().width, GetSize().height, 1};
|
Extent3D copySize = {GetSize().width, GetSize().height, 1};
|
||||||
|
@ -48,12 +48,6 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
DXGI_FORMAT GetD3D12Format() const;
|
DXGI_FORMAT GetD3D12Format() const;
|
||||||
ID3D12Resource* GetD3D12Resource() const;
|
ID3D12Resource* GetD3D12Resource() const;
|
||||||
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
|
||||||
D3D12_RESOURCE_BARRIER* barrier,
|
|
||||||
wgpu::TextureUsage newUsage);
|
|
||||||
void TransitionUsageNow(CommandRecordingContext* commandContext, wgpu::TextureUsage usage);
|
|
||||||
void TransitionUsageNow(CommandRecordingContext* commandContext,
|
|
||||||
D3D12_RESOURCE_STATES newState);
|
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t baseMipLevel,
|
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t baseMipLevel,
|
||||||
uint32_t baseArrayLayer,
|
uint32_t baseArrayLayer,
|
||||||
@ -65,6 +59,14 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
uint32_t baseArrayLayer,
|
uint32_t baseArrayLayer,
|
||||||
uint32_t layerCount);
|
uint32_t layerCount);
|
||||||
|
|
||||||
|
bool TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
|
wgpu::TextureUsage newUsage);
|
||||||
|
void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
|
wgpu::TextureUsage usage);
|
||||||
|
void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_STATES newState);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using TextureBase::TextureBase;
|
using TextureBase::TextureBase;
|
||||||
|
|
||||||
@ -84,6 +86,9 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
UINT16 GetDepthOrArraySize();
|
UINT16 GetDepthOrArraySize();
|
||||||
|
|
||||||
|
bool TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
|
D3D12_RESOURCE_STATES newState);
|
||||||
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||||
D3D12_RESOURCE_BARRIER* barrier,
|
D3D12_RESOURCE_BARRIER* barrier,
|
||||||
D3D12_RESOURCE_STATES newState);
|
D3D12_RESOURCE_STATES newState);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user