Add CommandRecordingContext to D3D12
This change refactors D3D12 backend to have CommandRecordingContext CommandRecordingContext allows us to, in a future, add additional data to the context such as textures that need to be acquired and released before command lists are executed. The Device's pending command list and the command list which resides in the Queue object were converted to use CommandRecordingContext. Bug=dawn:234 Change-Id: Ic13a229fc1f15895ef71117ce638c942de224743 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11940 Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
d285525d4a
commit
8bde031abe
2
BUILD.gn
2
BUILD.gn
|
@ -254,6 +254,8 @@ source_set("libdawn_native_sources") {
|
|||
"src/dawn_native/d3d12/CommandAllocatorManager.h",
|
||||
"src/dawn_native/d3d12/CommandBufferD3D12.cpp",
|
||||
"src/dawn_native/d3d12/CommandBufferD3D12.h",
|
||||
"src/dawn_native/d3d12/CommandRecordingContext.cpp",
|
||||
"src/dawn_native/d3d12/CommandRecordingContext.h",
|
||||
"src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.cpp",
|
||||
"src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.h",
|
||||
"src/dawn_native/d3d12/ComputePipelineD3D12.cpp",
|
||||
|
|
|
@ -104,6 +104,12 @@ namespace dawn_native {
|
|||
return mPointee;
|
||||
}
|
||||
|
||||
T* Detach() {
|
||||
T* pointee = mPointee;
|
||||
mPointee = nullptr;
|
||||
return pointee;
|
||||
}
|
||||
|
||||
private:
|
||||
void Reference() const {
|
||||
if (mPointee != nullptr) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "common/Math.h"
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
@ -130,7 +131,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
// 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::TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
bool Buffer::TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_BARRIER* barrier,
|
||||
dawn::BufferUsage newUsage) {
|
||||
// Resources in upload and readback heaps must be kept in the COPY_SOURCE/DEST state
|
||||
if (mFixedResourceState) {
|
||||
|
@ -187,12 +189,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Buffer::TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void Buffer::TransitionUsageNow(CommandRecordingContext* commandContext,
|
||||
dawn::BufferUsage usage) {
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
|
||||
if (TransitionUsageAndGetResourceBarrier(&barrier, usage)) {
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
if (TransitionUsageAndGetResourceBarrier(commandContext, &barrier, usage)) {
|
||||
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
class CommandRecordingContext;
|
||||
class Device;
|
||||
|
||||
class Buffer : public BufferBase {
|
||||
|
@ -36,10 +37,10 @@ namespace dawn_native { namespace d3d12 {
|
|||
ComPtr<ID3D12Resource> GetD3D12Resource() const;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
|
||||
void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);
|
||||
bool TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_BARRIER* barrier,
|
||||
dawn::BufferUsage newUsage);
|
||||
void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
dawn::BufferUsage usage);
|
||||
void TransitionUsageNow(CommandRecordingContext* commandContext, dawn::BufferUsage usage);
|
||||
|
||||
private:
|
||||
// Dawn API
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "dawn_native/d3d12/BindGroupD3D12.h"
|
||||
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/BufferD3D12.h"
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/ComputePipelineD3D12.h"
|
||||
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
|
@ -502,7 +503,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return {};
|
||||
}
|
||||
|
||||
void ResolveMultisampledRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void ResolveMultisampledRenderPass(CommandRecordingContext* commandContext,
|
||||
BeginRenderPassCmd* renderPass) {
|
||||
ASSERT(renderPass != nullptr);
|
||||
|
||||
|
@ -519,8 +520,10 @@ namespace dawn_native { namespace d3d12 {
|
|||
Texture* resolveTexture = ToBackend(resolveTarget->GetTexture());
|
||||
|
||||
// Transition the usages of the color attachment and resolve target.
|
||||
colorTexture->TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
|
||||
resolveTexture->TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
||||
colorTexture->TransitionUsageNow(commandContext,
|
||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
|
||||
resolveTexture->TransitionUsageNow(commandContext,
|
||||
D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
||||
|
||||
// Do MSAA resolve with ResolveSubResource().
|
||||
ID3D12Resource* colorTextureHandle = colorTexture->GetD3D12Resource();
|
||||
|
@ -528,7 +531,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
const uint32_t resolveTextureSubresourceIndex = resolveTexture->GetSubresourceIndex(
|
||||
resolveTarget->GetBaseMipLevel(), resolveTarget->GetBaseArrayLayer());
|
||||
constexpr uint32_t kColorTextureSubresourceIndex = 0;
|
||||
commandList->ResolveSubresource(
|
||||
commandContext->GetCommandList()->ResolveSubresource(
|
||||
resolveTextureHandle, resolveTextureSubresourceIndex, colorTextureHandle,
|
||||
kColorTextureSubresourceIndex, colorTexture->GetD3D12Format());
|
||||
}
|
||||
|
@ -545,12 +548,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
FreeCommands(&mCommands);
|
||||
}
|
||||
|
||||
MaybeError CommandBuffer::RecordCommands(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
MaybeError CommandBuffer::RecordCommands(CommandRecordingContext* commandContext,
|
||||
uint32_t indexInSubmit) {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
BindGroupStateTracker bindingTracker(device);
|
||||
RenderPassDescriptorHeapTracker renderPassTracker(device);
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
|
||||
|
||||
// Precompute the allocation of bindgroups in descriptor heaps
|
||||
// TODO(cwallez@chromium.org): Iterating over all the commands here is inefficient. We
|
||||
// should have a system where commands and descriptors are recorded in parallel then the
|
||||
|
@ -563,14 +568,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
|
||||
// Records the necessary barriers for the resource usage pre-computed by the frontend
|
||||
auto TransitionForPass = [](ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
auto TransitionForPass = [](CommandRecordingContext* commandContext,
|
||||
const PassResourceUsage& usages) {
|
||||
std::vector<D3D12_RESOURCE_BARRIER> barriers;
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
|
||||
|
||||
for (size_t i = 0; i < usages.buffers.size(); ++i) {
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
if (ToBackend(usages.buffers[i])
|
||||
->TransitionUsageAndGetResourceBarrier(&barrier, usages.bufferUsages[i])) {
|
||||
->TransitionUsageAndGetResourceBarrier(commandContext, &barrier,
|
||||
usages.bufferUsages[i])) {
|
||||
barriers.push_back(barrier);
|
||||
}
|
||||
}
|
||||
|
@ -581,15 +589,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
// cleared during record render pass if the texture subresource has not been
|
||||
// initialized before the render pass.
|
||||
if (!(usages.textureUsages[i] & dawn::TextureUsage::OutputAttachment)) {
|
||||
texture->EnsureSubresourceContentInitialized(
|
||||
commandList, 0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers());
|
||||
texture->EnsureSubresourceContentInitialized(commandContext, 0,
|
||||
texture->GetNumMipLevels(), 0,
|
||||
texture->GetArrayLayers());
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < usages.textures.size(); ++i) {
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
if (ToBackend(usages.textures[i])
|
||||
->TransitionUsageAndGetResourceBarrier(&barrier, usages.textureUsages[i])) {
|
||||
->TransitionUsageAndGetResourceBarrier(commandContext, &barrier,
|
||||
usages.textureUsages[i])) {
|
||||
barriers.push_back(barrier);
|
||||
}
|
||||
}
|
||||
|
@ -608,7 +618,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::BeginComputePass: {
|
||||
mCommands.NextCommand<BeginComputePassCmd>();
|
||||
|
||||
TransitionForPass(commandList, passResourceUsages[nextPassNumber]);
|
||||
TransitionForPass(commandContext, passResourceUsages[nextPassNumber]);
|
||||
bindingTracker.SetInComputePass(true);
|
||||
RecordComputePass(commandList, &bindingTracker);
|
||||
|
||||
|
@ -619,9 +629,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
BeginRenderPassCmd* beginRenderPassCmd =
|
||||
mCommands.NextCommand<BeginRenderPassCmd>();
|
||||
|
||||
TransitionForPass(commandList, passResourceUsages[nextPassNumber]);
|
||||
TransitionForPass(commandContext, passResourceUsages[nextPassNumber]);
|
||||
bindingTracker.SetInComputePass(false);
|
||||
RecordRenderPass(commandList, &bindingTracker, &renderPassTracker,
|
||||
RecordRenderPass(commandContext, &bindingTracker, &renderPassTracker,
|
||||
beginRenderPassCmd);
|
||||
|
||||
nextPassNumber++;
|
||||
|
@ -632,8 +642,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
Buffer* srcBuffer = ToBackend(copy->source.Get());
|
||||
Buffer* dstBuffer = ToBackend(copy->destination.Get());
|
||||
|
||||
srcBuffer->TransitionUsageNow(commandList, dawn::BufferUsage::CopySrc);
|
||||
dstBuffer->TransitionUsageNow(commandList, dawn::BufferUsage::CopyDst);
|
||||
srcBuffer->TransitionUsageNow(commandContext, dawn::BufferUsage::CopySrc);
|
||||
dstBuffer->TransitionUsageNow(commandContext, dawn::BufferUsage::CopyDst);
|
||||
|
||||
commandList->CopyBufferRegion(
|
||||
dstBuffer->GetD3D12Resource().Get(), copy->destinationOffset,
|
||||
|
@ -651,12 +661,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
true, copy->destination.mipLevel, 1, copy->destination.arrayLayer, 1);
|
||||
} else {
|
||||
texture->EnsureSubresourceContentInitialized(
|
||||
commandList, copy->destination.mipLevel, 1,
|
||||
commandContext, copy->destination.mipLevel, 1,
|
||||
copy->destination.arrayLayer, 1);
|
||||
}
|
||||
|
||||
buffer->TransitionUsageNow(commandList, dawn::BufferUsage::CopySrc);
|
||||
texture->TransitionUsageNow(commandList, dawn::TextureUsage::CopyDst);
|
||||
buffer->TransitionUsageNow(commandContext, dawn::BufferUsage::CopySrc);
|
||||
texture->TransitionUsageNow(commandContext, dawn::TextureUsage::CopyDst);
|
||||
|
||||
auto copySplit = ComputeTextureCopySplit(
|
||||
copy->destination.origin, copy->copySize, texture->GetFormat(),
|
||||
|
@ -687,11 +697,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
Texture* texture = ToBackend(copy->source.texture.Get());
|
||||
Buffer* buffer = ToBackend(copy->destination.buffer.Get());
|
||||
|
||||
texture->EnsureSubresourceContentInitialized(commandList, copy->source.mipLevel,
|
||||
1, copy->source.arrayLayer, 1);
|
||||
texture->EnsureSubresourceContentInitialized(
|
||||
commandContext, copy->source.mipLevel, 1, copy->source.arrayLayer, 1);
|
||||
|
||||
texture->TransitionUsageNow(commandList, dawn::TextureUsage::CopySrc);
|
||||
buffer->TransitionUsageNow(commandList, dawn::BufferUsage::CopyDst);
|
||||
texture->TransitionUsageNow(commandContext, dawn::TextureUsage::CopySrc);
|
||||
buffer->TransitionUsageNow(commandContext, dawn::BufferUsage::CopyDst);
|
||||
|
||||
TextureCopySplit copySplit = ComputeTextureCopySplit(
|
||||
copy->source.origin, copy->copySize, texture->GetFormat(),
|
||||
|
@ -726,19 +736,19 @@ namespace dawn_native { namespace d3d12 {
|
|||
Texture* source = ToBackend(copy->source.texture.Get());
|
||||
Texture* destination = ToBackend(copy->destination.texture.Get());
|
||||
|
||||
source->EnsureSubresourceContentInitialized(commandList, copy->source.mipLevel,
|
||||
1, copy->source.arrayLayer, 1);
|
||||
source->EnsureSubresourceContentInitialized(
|
||||
commandContext, copy->source.mipLevel, 1, copy->source.arrayLayer, 1);
|
||||
if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
|
||||
copy->destination.mipLevel)) {
|
||||
destination->SetIsSubresourceContentInitialized(
|
||||
true, copy->destination.mipLevel, 1, copy->destination.arrayLayer, 1);
|
||||
} else {
|
||||
destination->EnsureSubresourceContentInitialized(
|
||||
commandList, copy->destination.mipLevel, 1,
|
||||
commandContext, copy->destination.mipLevel, 1,
|
||||
copy->destination.arrayLayer, 1);
|
||||
}
|
||||
source->TransitionUsageNow(commandList, dawn::TextureUsage::CopySrc);
|
||||
destination->TransitionUsageNow(commandList, dawn::TextureUsage::CopyDst);
|
||||
source->TransitionUsageNow(commandContext, dawn::TextureUsage::CopySrc);
|
||||
destination->TransitionUsageNow(commandContext, dawn::TextureUsage::CopyDst);
|
||||
|
||||
if (CanUseCopyResource(source->GetNumMipLevels(), source->GetSize(),
|
||||
destination->GetSize(), copy->copySize)) {
|
||||
|
@ -771,7 +781,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return {};
|
||||
}
|
||||
|
||||
void CommandBuffer::RecordComputePass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void CommandBuffer::RecordComputePass(ID3D12GraphicsCommandList* commandList,
|
||||
BindGroupStateTracker* bindingTracker) {
|
||||
PipelineLayout* lastLayout = nullptr;
|
||||
|
||||
|
@ -781,14 +791,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::Dispatch: {
|
||||
DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
|
||||
|
||||
bindingTracker->Apply(commandList.Get());
|
||||
bindingTracker->Apply(commandList);
|
||||
commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
|
||||
} break;
|
||||
|
||||
case Command::DispatchIndirect: {
|
||||
DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>();
|
||||
|
||||
bindingTracker->Apply(commandList.Get());
|
||||
bindingTracker->Apply(commandList);
|
||||
Buffer* buffer = ToBackend(dispatch->indirectBuffer.Get());
|
||||
ComPtr<ID3D12CommandSignature> signature =
|
||||
ToBackend(GetDevice())->GetDispatchIndirectSignature();
|
||||
|
@ -837,7 +847,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
||||
ToBackend(GetDevice())
|
||||
->GetFunctions()
|
||||
->pixSetMarkerOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
||||
->pixSetMarkerOnCommandList(commandList, kPIXBlackColor, label);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -847,7 +857,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
||||
ToBackend(GetDevice())
|
||||
->GetFunctions()
|
||||
->pixEndEventOnCommandList(commandList.Get());
|
||||
->pixEndEventOnCommandList(commandList);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -860,7 +870,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
||||
ToBackend(GetDevice())
|
||||
->GetFunctions()
|
||||
->pixBeginEventOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
||||
->pixBeginEventOnCommandList(commandList, kPIXBlackColor, label);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -869,11 +879,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
}
|
||||
|
||||
void CommandBuffer::RecordRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void CommandBuffer::RecordRenderPass(CommandRecordingContext* commandContext,
|
||||
BindGroupStateTracker* bindingTracker,
|
||||
RenderPassDescriptorHeapTracker* renderPassTracker,
|
||||
BeginRenderPassCmd* renderPass) {
|
||||
OMSetRenderTargetArgs args = renderPassTracker->GetSubpassOMSetRenderTargetArgs(renderPass);
|
||||
ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
|
||||
|
||||
// Clear framebuffer attachments as needed and transition to render target
|
||||
{
|
||||
|
@ -1012,8 +1023,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::Draw: {
|
||||
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||
|
||||
bindingTracker->Apply(commandList.Get());
|
||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||
bindingTracker->Apply(commandList);
|
||||
vertexBufferTracker.Apply(commandList, lastPipeline);
|
||||
commandList->DrawInstanced(draw->vertexCount, draw->instanceCount,
|
||||
draw->firstVertex, draw->firstInstance);
|
||||
} break;
|
||||
|
@ -1021,9 +1032,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::DrawIndexed: {
|
||||
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||
|
||||
bindingTracker->Apply(commandList.Get());
|
||||
indexBufferTracker.Apply(commandList.Get());
|
||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||
bindingTracker->Apply(commandList);
|
||||
indexBufferTracker.Apply(commandList);
|
||||
vertexBufferTracker.Apply(commandList, lastPipeline);
|
||||
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
||||
draw->firstIndex, draw->baseVertex,
|
||||
draw->firstInstance);
|
||||
|
@ -1032,8 +1043,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::DrawIndirect: {
|
||||
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||
|
||||
bindingTracker->Apply(commandList.Get());
|
||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||
bindingTracker->Apply(commandList);
|
||||
vertexBufferTracker.Apply(commandList, lastPipeline);
|
||||
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||
ComPtr<ID3D12CommandSignature> signature =
|
||||
ToBackend(GetDevice())->GetDrawIndirectSignature();
|
||||
|
@ -1045,9 +1056,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::DrawIndexedIndirect: {
|
||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||
|
||||
bindingTracker->Apply(commandList.Get());
|
||||
indexBufferTracker.Apply(commandList.Get());
|
||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||
bindingTracker->Apply(commandList);
|
||||
indexBufferTracker.Apply(commandList);
|
||||
vertexBufferTracker.Apply(commandList, lastPipeline);
|
||||
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||
ComPtr<ID3D12CommandSignature> signature =
|
||||
ToBackend(GetDevice())->GetDrawIndexedIndirectSignature();
|
||||
|
@ -1065,7 +1076,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
||||
ToBackend(GetDevice())
|
||||
->GetFunctions()
|
||||
->pixSetMarkerOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
||||
->pixSetMarkerOnCommandList(commandList, kPIXBlackColor, label);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -1075,7 +1086,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
||||
ToBackend(GetDevice())
|
||||
->GetFunctions()
|
||||
->pixEndEventOnCommandList(commandList.Get());
|
||||
->pixEndEventOnCommandList(commandList);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -1088,7 +1099,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
||||
ToBackend(GetDevice())
|
||||
->GetFunctions()
|
||||
->pixBeginEventOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
||||
->pixBeginEventOnCommandList(commandList, kPIXBlackColor, label);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -1149,7 +1160,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
// TODO(brandon1.jones@intel.com): avoid calling this function and enable MSAA
|
||||
// resolve in D3D12 render pass on the platforms that support this feature.
|
||||
if (renderPass->attachmentState->GetSampleCount() > 1) {
|
||||
ResolveMultisampledRenderPass(commandList, renderPass);
|
||||
ResolveMultisampledRenderPass(commandContext, renderPass);
|
||||
}
|
||||
return;
|
||||
} break;
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace dawn_native {
|
|||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
class BindGroupStateTracker;
|
||||
class CommandRecordingContext;
|
||||
class Device;
|
||||
class RenderPassDescriptorHeapTracker;
|
||||
class RenderPipeline;
|
||||
|
@ -41,13 +42,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor);
|
||||
~CommandBuffer();
|
||||
|
||||
MaybeError RecordCommands(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
uint32_t indexInSubmit);
|
||||
MaybeError RecordCommands(CommandRecordingContext* commandContext, uint32_t indexInSubmit);
|
||||
|
||||
private:
|
||||
void RecordComputePass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void RecordComputePass(ID3D12GraphicsCommandList* commandList,
|
||||
BindGroupStateTracker* bindingTracker);
|
||||
void RecordRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void RecordRenderPass(CommandRecordingContext* commandContext,
|
||||
BindGroupStateTracker* bindingTracker,
|
||||
RenderPassDescriptorHeapTracker* renderPassTracker,
|
||||
BeginRenderPassCmd* renderPass);
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/CommandAllocatorManager.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
MaybeError CommandRecordingContext::Open(ID3D12Device* d3d12Device,
|
||||
CommandAllocatorManager* commandAllocationManager) {
|
||||
ASSERT(!IsOpen());
|
||||
if (mD3d12CommandList != nullptr) {
|
||||
const HRESULT hr = mD3d12CommandList->Reset(
|
||||
commandAllocationManager->ReserveCommandAllocator().Get(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
mD3d12CommandList.Reset();
|
||||
return DAWN_DEVICE_LOST_ERROR("Error resetting command list.");
|
||||
}
|
||||
} else {
|
||||
ComPtr<ID3D12GraphicsCommandList> d3d12GraphicsCommandList;
|
||||
const HRESULT hr = d3d12Device->CreateCommandList(
|
||||
0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
commandAllocationManager->ReserveCommandAllocator().Get(), nullptr,
|
||||
IID_PPV_ARGS(&d3d12GraphicsCommandList));
|
||||
if (FAILED(hr)) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Error creating a direct command list.");
|
||||
}
|
||||
mD3d12CommandList = std::move(d3d12GraphicsCommandList);
|
||||
}
|
||||
|
||||
mIsOpen = true;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<ID3D12GraphicsCommandList*> CommandRecordingContext::Close() {
|
||||
ASSERT(IsOpen());
|
||||
mIsOpen = false;
|
||||
const HRESULT hr = mD3d12CommandList->Close();
|
||||
if (FAILED(hr)) {
|
||||
mD3d12CommandList.Reset();
|
||||
return DAWN_DEVICE_LOST_ERROR("Error closing pending command list.");
|
||||
}
|
||||
return mD3d12CommandList.Get();
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* CommandRecordingContext::GetCommandList() const {
|
||||
ASSERT(mD3d12CommandList != nullptr);
|
||||
ASSERT(IsOpen());
|
||||
return mD3d12CommandList.Get();
|
||||
}
|
||||
|
||||
void CommandRecordingContext::Release() {
|
||||
mD3d12CommandList.Reset();
|
||||
mIsOpen = false;
|
||||
}
|
||||
|
||||
bool CommandRecordingContext::IsOpen() const {
|
||||
return mIsOpen;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef DAWNNATIVE_D3D12_COMMANDRECORDINGCONTEXT_H_
|
||||
#define DAWNNATIVE_D3D12_COMMANDRECORDINGCONTEXT_H_
|
||||
|
||||
#include "dawn_native/Error.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
class CommandAllocatorManager;
|
||||
|
||||
class CommandRecordingContext {
|
||||
public:
|
||||
MaybeError Open(ID3D12Device* d3d12Device,
|
||||
CommandAllocatorManager* commandAllocationManager);
|
||||
ResultOrError<ID3D12GraphicsCommandList*> Close();
|
||||
ID3D12GraphicsCommandList* GetCommandList() const;
|
||||
void Release();
|
||||
bool IsOpen() const;
|
||||
|
||||
private:
|
||||
ComPtr<ID3D12GraphicsCommandList> mD3d12CommandList;
|
||||
bool mIsOpen = false;
|
||||
};
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
#endif // DAWNNATIVE_D3D12_COMMANDRECORDINGCONTEXT_H_
|
|
@ -101,11 +101,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
Device::~Device() {
|
||||
// Immediately forget about all pending commands
|
||||
if (mPendingCommands.open) {
|
||||
mPendingCommands.commandList->Close();
|
||||
mPendingCommands.open = false;
|
||||
mPendingCommands.commandList = nullptr;
|
||||
}
|
||||
mPendingCommands.Release();
|
||||
|
||||
NextSerial();
|
||||
WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing
|
||||
|
||||
|
@ -133,7 +130,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
||||
|
||||
ASSERT(mUsedComObjectRefs.Empty());
|
||||
ASSERT(mPendingCommands.commandList == nullptr);
|
||||
ASSERT(!mPendingCommands.IsOpen());
|
||||
}
|
||||
|
||||
ComPtr<ID3D12Device> Device::GetD3D12Device() const {
|
||||
|
@ -176,27 +173,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
return mResourceAllocator.get();
|
||||
}
|
||||
|
||||
void Device::OpenCommandList(ComPtr<ID3D12GraphicsCommandList>* commandList) {
|
||||
ComPtr<ID3D12GraphicsCommandList>& cmdList = *commandList;
|
||||
if (!cmdList) {
|
||||
ASSERT_SUCCESS(mD3d12Device->CreateCommandList(
|
||||
0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
mCommandAllocatorManager->ReserveCommandAllocator().Get(), nullptr,
|
||||
IID_PPV_ARGS(&cmdList)));
|
||||
} else {
|
||||
ASSERT_SUCCESS(
|
||||
cmdList->Reset(mCommandAllocatorManager->ReserveCommandAllocator().Get(), nullptr));
|
||||
}
|
||||
CommandAllocatorManager* Device::GetCommandAllocatorManager() const {
|
||||
return mCommandAllocatorManager.get();
|
||||
}
|
||||
|
||||
ComPtr<ID3D12GraphicsCommandList> Device::GetPendingCommandList() {
|
||||
ResultOrError<CommandRecordingContext*> Device::GetPendingCommandContext() {
|
||||
// Callers of GetPendingCommandList do so to record commands. Only reserve a command
|
||||
// allocator when it is needed so we don't submit empty command lists
|
||||
if (!mPendingCommands.open) {
|
||||
OpenCommandList(&mPendingCommands.commandList);
|
||||
mPendingCommands.open = true;
|
||||
if (!mPendingCommands.IsOpen()) {
|
||||
DAWN_TRY(mPendingCommands.Open(mD3d12Device.Get(), mCommandAllocatorManager.get()));
|
||||
}
|
||||
return mPendingCommands.commandList;
|
||||
return &mPendingCommands;
|
||||
}
|
||||
|
||||
Serial Device::GetCompletedCommandSerial() const {
|
||||
|
@ -224,7 +211,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
|
||||
mMapRequestTracker->Tick(mCompletedSerial);
|
||||
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
||||
DAWN_TRY(ExecuteCommandList(nullptr));
|
||||
DAWN_TRY(ExecuteCommandContext(nullptr));
|
||||
NextSerial();
|
||||
|
||||
return {};
|
||||
|
@ -247,27 +234,23 @@ namespace dawn_native { namespace d3d12 {
|
|||
mUsedComObjectRefs.Enqueue(object, GetPendingCommandSerial());
|
||||
}
|
||||
|
||||
MaybeError Device::ExecuteCommandList(ID3D12CommandList* d3d12CommandList) {
|
||||
MaybeError Device::ExecuteCommandContext(CommandRecordingContext* commandContext) {
|
||||
UINT numLists = 0;
|
||||
std::array<ID3D12CommandList*, 2> d3d12CommandLists;
|
||||
|
||||
// If there are pending commands, prepend them to ExecuteCommandLists
|
||||
if (mPendingCommands.open) {
|
||||
const HRESULT hr = mPendingCommands.commandList->Close();
|
||||
if (FAILED(hr)) {
|
||||
mPendingCommands.open = false;
|
||||
mPendingCommands.commandList.Reset();
|
||||
return DAWN_DEVICE_LOST_ERROR("Error closing pending command list.");
|
||||
}
|
||||
mPendingCommands.open = false;
|
||||
d3d12CommandLists[numLists++] = mPendingCommands.commandList.Get();
|
||||
if (mPendingCommands.IsOpen()) {
|
||||
ID3D12GraphicsCommandList* d3d12CommandList;
|
||||
DAWN_TRY_ASSIGN(d3d12CommandList, mPendingCommands.Close());
|
||||
d3d12CommandLists[numLists++] = d3d12CommandList;
|
||||
}
|
||||
if (d3d12CommandList != nullptr) {
|
||||
if (commandContext != nullptr) {
|
||||
ID3D12GraphicsCommandList* d3d12CommandList;
|
||||
DAWN_TRY_ASSIGN(d3d12CommandList, commandContext->Close());
|
||||
d3d12CommandLists[numLists++] = d3d12CommandList;
|
||||
}
|
||||
if (numLists > 0) {
|
||||
mCommandQueue->ExecuteCommandLists(numLists, d3d12CommandLists.data());
|
||||
mPendingCommands.commandList.Reset();
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -317,7 +300,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return new SwapChain(this, descriptor);
|
||||
}
|
||||
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
|
||||
return new Texture(this, descriptor);
|
||||
return Texture::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl(
|
||||
TextureBase* texture,
|
||||
|
@ -337,10 +320,13 @@ namespace dawn_native { namespace d3d12 {
|
|||
BufferBase* destination,
|
||||
uint64_t destinationOffset,
|
||||
uint64_t size) {
|
||||
ToBackend(destination)
|
||||
->TransitionUsageNow(GetPendingCommandList(), dawn::BufferUsage::CopyDst);
|
||||
CommandRecordingContext* commandRecordingContext;
|
||||
DAWN_TRY_ASSIGN(commandRecordingContext, GetPendingCommandContext());
|
||||
|
||||
GetPendingCommandList()->CopyBufferRegion(
|
||||
ToBackend(destination)
|
||||
->TransitionUsageNow(commandRecordingContext, dawn::BufferUsage::CopyDst);
|
||||
|
||||
commandRecordingContext->GetCommandList()->CopyBufferRegion(
|
||||
ToBackend(destination)->GetD3D12Resource().Get(), destinationOffset,
|
||||
ToBackend(source)->GetResource(), sourceOffset, size);
|
||||
|
||||
|
@ -381,6 +367,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return new Texture(this, descriptor, d3d12Resource.Get());
|
||||
return new Texture(this, descriptor, std::move(d3d12Resource));
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
#include "common/SerialQueue.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/Forward.h"
|
||||
#include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -65,12 +65,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
DescriptorHeapAllocator* GetDescriptorHeapAllocator() const;
|
||||
MapRequestTracker* GetMapRequestTracker() const;
|
||||
ResourceAllocator* GetResourceAllocator() const;
|
||||
CommandAllocatorManager* GetCommandAllocatorManager() const;
|
||||
|
||||
const PlatformFunctions* GetFunctions() const;
|
||||
ComPtr<IDXGIFactory4> GetFactory() const;
|
||||
|
||||
void OpenCommandList(ComPtr<ID3D12GraphicsCommandList>* commandList);
|
||||
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
|
||||
ResultOrError<CommandRecordingContext*> GetPendingCommandContext();
|
||||
Serial GetPendingCommandSerial() const override;
|
||||
|
||||
void NextSerial();
|
||||
|
@ -78,7 +78,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
void ReferenceUntilUnused(ComPtr<IUnknown> object);
|
||||
|
||||
MaybeError ExecuteCommandList(ID3D12CommandList* d3d12CommandList);
|
||||
MaybeError ExecuteCommandContext(CommandRecordingContext* commandContext);
|
||||
|
||||
ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
|
||||
MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
|
||||
|
@ -132,10 +132,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
ComPtr<ID3D12CommandSignature> mDrawIndirectSignature;
|
||||
ComPtr<ID3D12CommandSignature> mDrawIndexedIndirectSignature;
|
||||
|
||||
struct PendingCommandList {
|
||||
ComPtr<ID3D12GraphicsCommandList> commandList;
|
||||
bool open = false;
|
||||
} mPendingCommands;
|
||||
CommandRecordingContext mPendingCommands;
|
||||
|
||||
SerialQueue<ComPtr<IUnknown>> mUsedComObjectRefs;
|
||||
|
||||
|
|
|
@ -27,13 +27,13 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
device->Tick();
|
||||
|
||||
device->OpenCommandList(&mCommandList);
|
||||
DAWN_TRY(mCommandContext.Open(device->GetD3D12Device().Get(),
|
||||
device->GetCommandAllocatorManager()));
|
||||
for (uint32_t i = 0; i < commandCount; ++i) {
|
||||
DAWN_TRY(ToBackend(commands[i])->RecordCommands(mCommandList, i));
|
||||
DAWN_TRY(ToBackend(commands[i])->RecordCommands(&mCommandContext, i));
|
||||
}
|
||||
ASSERT_SUCCESS(mCommandList->Close());
|
||||
|
||||
DAWN_TRY(device->ExecuteCommandList(mCommandList.Get()));
|
||||
DAWN_TRY(device->ExecuteCommandContext(&mCommandContext));
|
||||
|
||||
device->NextSerial();
|
||||
return {};
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "dawn_native/Queue.h"
|
||||
|
||||
#include "dawn_native/d3d12/CommandRecordingContext.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
@ -31,7 +32,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
private:
|
||||
MaybeError SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) override;
|
||||
|
||||
ComPtr<ID3D12GraphicsCommandList> mCommandList;
|
||||
CommandRecordingContext mCommandContext;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -51,10 +51,13 @@ namespace dawn_native { namespace d3d12 {
|
|||
MaybeError SwapChain::OnBeforePresent(TextureBase* texture) {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
// Perform the necessary transition for the texture to be presented.
|
||||
ToBackend(texture)->TransitionUsageNow(device->GetPendingCommandList(), mTextureUsage);
|
||||
CommandRecordingContext* commandContext;
|
||||
DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
|
||||
|
||||
DAWN_TRY(device->ExecuteCommandList(nullptr));
|
||||
// Perform the necessary transition for the texture to be presented.
|
||||
ToBackend(texture)->TransitionUsageNow(commandContext, mTextureUsage);
|
||||
|
||||
DAWN_TRY(device->ExecuteCommandContext(nullptr));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -270,8 +270,18 @@ namespace dawn_native { namespace d3d12 {
|
|||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<TextureBase*> Texture::Create(Device* device,
|
||||
const TextureDescriptor* descriptor) {
|
||||
Ref<Texture> dawnTexture = AcquireRef(new Texture(device, descriptor));
|
||||
DAWN_TRY(dawnTexture->InitializeAsInternalTexture());
|
||||
return dawnTexture.Detach();
|
||||
}
|
||||
|
||||
Texture::Texture(Device* device, const TextureDescriptor* descriptor)
|
||||
: TextureBase(device, descriptor, TextureState::OwnedInternal) {
|
||||
}
|
||||
|
||||
MaybeError Texture::InitializeAsInternalTexture() {
|
||||
D3D12_RESOURCE_DESC resourceDescriptor;
|
||||
resourceDescriptor.Dimension = D3D12TextureDimension(GetDimension());
|
||||
resourceDescriptor.Alignment = 0;
|
||||
|
@ -283,7 +293,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
resourceDescriptor.DepthOrArraySize = GetDepthOrArraySize();
|
||||
resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
|
||||
resourceDescriptor.Format = D3D12TextureFormat(GetFormat().format);
|
||||
resourceDescriptor.SampleDesc.Count = descriptor->sampleCount;
|
||||
resourceDescriptor.SampleDesc.Count = GetSampleCount();
|
||||
// TODO(bryan.bernhart@intel.com): investigate how to specify standard MSAA sample pattern.
|
||||
resourceDescriptor.SampleDesc.Quality = 0;
|
||||
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
|
@ -295,18 +305,25 @@ namespace dawn_native { namespace d3d12 {
|
|||
->Allocate(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor,
|
||||
D3D12_RESOURCE_STATE_COMMON);
|
||||
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
|
||||
device->ConsumedError(ClearTexture(device->GetPendingCommandList(), 0,
|
||||
GetNumMipLevels(), 0, GetArrayLayers(),
|
||||
TextureBase::ClearValue::NonZero));
|
||||
CommandRecordingContext* commandContext;
|
||||
DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
|
||||
|
||||
DAWN_TRY(ClearTexture(commandContext, 0, GetNumMipLevels(), 0, GetArrayLayers(),
|
||||
TextureBase::ClearValue::NonZero));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// With this constructor, the lifetime of the ID3D12Resource is externally managed.
|
||||
Texture::Texture(Device* device,
|
||||
const TextureDescriptor* descriptor,
|
||||
ID3D12Resource* nativeTexture)
|
||||
: TextureBase(device, descriptor, TextureState::OwnedExternal), mResource(nativeTexture) {
|
||||
ComPtr<ID3D12Resource> nativeTexture)
|
||||
: TextureBase(device, descriptor, TextureState::OwnedExternal),
|
||||
mResource(std::move(nativeTexture)) {
|
||||
SetIsSubresourceContentInitialized(true, 0, descriptor->mipLevelCount, 0,
|
||||
descriptor->arrayLayerCount);
|
||||
}
|
||||
|
@ -341,16 +358,18 @@ namespace dawn_native { namespace d3d12 {
|
|||
// 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::TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
bool Texture::TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_BARRIER* barrier,
|
||||
dawn::TextureUsage newUsage) {
|
||||
return TransitionUsageAndGetResourceBarrier(barrier,
|
||||
return TransitionUsageAndGetResourceBarrier(commandContext, barrier,
|
||||
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::TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
bool Texture::TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_BARRIER* barrier,
|
||||
D3D12_RESOURCE_STATES newState) {
|
||||
// Avoid transitioning the texture when it isn't needed.
|
||||
// TODO(cwallez@chromium.org): Need some form of UAV barriers at some point.
|
||||
|
@ -417,17 +436,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Texture::TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void Texture::TransitionUsageNow(CommandRecordingContext* commandContext,
|
||||
dawn::TextureUsage usage) {
|
||||
TransitionUsageNow(commandList, D3D12TextureUsage(usage, GetFormat()));
|
||||
TransitionUsageNow(commandContext, D3D12TextureUsage(usage, GetFormat()));
|
||||
}
|
||||
|
||||
void Texture::TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void Texture::TransitionUsageNow(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_STATES newState) {
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
|
||||
if (TransitionUsageAndGetResourceBarrier(&barrier, newState)) {
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
if (TransitionUsageAndGetResourceBarrier(commandContext, &barrier, newState)) {
|
||||
commandContext->GetCommandList()->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,7 +494,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return dsvDesc;
|
||||
}
|
||||
|
||||
MaybeError Texture::ClearTexture(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
|
||||
uint32_t baseMipLevel,
|
||||
uint32_t levelCount,
|
||||
uint32_t baseArrayLayer,
|
||||
|
@ -488,12 +507,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
return {};
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
|
||||
|
||||
Device* device = ToBackend(GetDevice());
|
||||
DescriptorHeapAllocator* descriptorHeapAllocator = device->GetDescriptorHeapAllocator();
|
||||
uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1;
|
||||
if (GetFormat().isRenderable) {
|
||||
if (GetFormat().HasDepthOrStencil()) {
|
||||
TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||
TransitionUsageNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||
DescriptorHeapHandle dsvHeap;
|
||||
DAWN_TRY_ASSIGN(dsvHeap, descriptorHeapAllocator->AllocateCPUHeap(
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1));
|
||||
|
@ -513,7 +534,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
commandList->ClearDepthStencilView(dsvHandle, clearFlags, clearColor, clearColor, 0,
|
||||
nullptr);
|
||||
} else {
|
||||
TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
TransitionUsageNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
DescriptorHeapHandle rtvHeap;
|
||||
DAWN_TRY_ASSIGN(rtvHeap, descriptorHeapAllocator->AllocateCPUHeap(
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1));
|
||||
|
@ -548,7 +569,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
reinterpret_cast<uint32_t*>(uploadHandle.mappedBuffer + bufferSize),
|
||||
clearColor);
|
||||
|
||||
TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
TransitionUsageNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
// compute d3d12 texture copy locations for texture and buffer
|
||||
Extent3D copySize = {GetSize().width, GetSize().height, 1};
|
||||
|
@ -586,7 +607,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return {};
|
||||
}
|
||||
|
||||
void Texture::EnsureSubresourceContentInitialized(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext,
|
||||
uint32_t baseMipLevel,
|
||||
uint32_t levelCount,
|
||||
uint32_t baseArrayLayer,
|
||||
|
@ -598,7 +619,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
layerCount)) {
|
||||
// If subresource has not been initialized, clear it to black as it could contain
|
||||
// dirty bits from recycled memory
|
||||
GetDevice()->ConsumedError(ClearTexture(commandList, baseMipLevel, levelCount,
|
||||
GetDevice()->ConsumedError(ClearTexture(commandContext, baseMipLevel, levelCount,
|
||||
baseArrayLayer, layerCount,
|
||||
TextureBase::ClearValue::Zero));
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
class CommandRecordingContext;
|
||||
class Device;
|
||||
|
||||
DXGI_FORMAT D3D12TextureFormat(dawn::TextureFormat format);
|
||||
|
@ -31,33 +32,39 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
class Texture : public TextureBase {
|
||||
public:
|
||||
Texture(Device* device, const TextureDescriptor* descriptor);
|
||||
Texture(Device* device, const TextureDescriptor* descriptor, ID3D12Resource* nativeTexture);
|
||||
static ResultOrError<TextureBase*> Create(Device* device,
|
||||
const TextureDescriptor* descriptor);
|
||||
Texture(Device* device,
|
||||
const TextureDescriptor* descriptor,
|
||||
ComPtr<ID3D12Resource> nativeTexture);
|
||||
~Texture();
|
||||
|
||||
DXGI_FORMAT GetD3D12Format() const;
|
||||
ID3D12Resource* GetD3D12Resource() const;
|
||||
bool TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_BARRIER* barrier,
|
||||
dawn::TextureUsage newUsage);
|
||||
void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
dawn::TextureUsage usage);
|
||||
void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void TransitionUsageNow(CommandRecordingContext* commandContext, dawn::TextureUsage usage);
|
||||
void TransitionUsageNow(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_STATES newState);
|
||||
|
||||
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t baseMipLevel,
|
||||
uint32_t baseArrayLayer,
|
||||
uint32_t layerCount) const;
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor(uint32_t baseMipLevel) const;
|
||||
void EnsureSubresourceContentInitialized(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
void EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext,
|
||||
uint32_t baseMipLevel,
|
||||
uint32_t levelCount,
|
||||
uint32_t baseArrayLayer,
|
||||
uint32_t layerCount);
|
||||
|
||||
private:
|
||||
Texture(Device* device, const TextureDescriptor* descriptor);
|
||||
MaybeError InitializeAsInternalTexture();
|
||||
|
||||
// Dawn API
|
||||
void DestroyImpl() override;
|
||||
MaybeError ClearTexture(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
MaybeError ClearTexture(CommandRecordingContext* commandContext,
|
||||
uint32_t baseMipLevel,
|
||||
uint32_t levelCount,
|
||||
uint32_t baseArrayLayer,
|
||||
|
@ -66,7 +73,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
UINT16 GetDepthOrArraySize();
|
||||
|
||||
bool TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
|
||||
D3D12_RESOURCE_BARRIER* barrier,
|
||||
D3D12_RESOURCE_STATES newState);
|
||||
|
||||
ComPtr<ID3D12Resource> mResource;
|
||||
|
|
Loading…
Reference in New Issue