D3D12: Avoid re-binding sampler tables.

Skip re-binding samplers since sampler heap
allocations are cached and the pipeline would
redundantly get set every draw. This is
particularly important for draw heavy scenarios.

After the change:
+3% in RendererPerfTest/1.* via SkiaDawn
+100% for Forest Demo FPS (55ms vs 28ms)

BUG=dawn:479

Change-Id: I93cbca4e365d6ff89ec86fc15eaccf70b49ea916
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24161
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
This commit is contained in:
Bryan Bernhart 2020-07-07 23:32:52 +00:00 committed by Commit Bot service account
parent a0b4571546
commit 7622be0544
1 changed files with 26 additions and 4 deletions

View File

@ -83,6 +83,8 @@ namespace dawn_native { namespace d3d12 {
} // anonymous namespace } // anonymous namespace
class BindGroupStateTracker : public BindGroupAndStorageBarrierTrackerBase<false, uint64_t> { class BindGroupStateTracker : public BindGroupAndStorageBarrierTrackerBase<false, uint64_t> {
using Base = BindGroupAndStorageBarrierTrackerBase;
public: public:
BindGroupStateTracker(Device* device) BindGroupStateTracker(Device* device)
: BindGroupAndStorageBarrierTrackerBase(), : BindGroupAndStorageBarrierTrackerBase(),
@ -95,6 +97,17 @@ namespace dawn_native { namespace d3d12 {
mInCompute = inCompute_; mInCompute = inCompute_;
} }
void OnSetPipeline(PipelineBase* pipeline) {
// Invalidate the root sampler tables previously set in the root signature.
// This is because changing the pipeline layout also changes the root signature.
const PipelineLayout* pipelineLayout = ToBackend(pipeline->GetLayout());
if (mLastAppliedPipelineLayout != pipelineLayout) {
mBoundRootSamplerTables = {};
}
Base::OnSetPipeline(pipeline);
}
MaybeError Apply(CommandRecordingContext* commandContext) { MaybeError Apply(CommandRecordingContext* commandContext) {
// Bindgroups are allocated in shader-visible descriptor heaps which are managed by a // Bindgroups are allocated in shader-visible descriptor heaps which are managed by a
// ringbuffer. There can be a single shader-visible descriptor heap of each type bound // ringbuffer. There can be a single shader-visible descriptor heap of each type bound
@ -309,10 +322,16 @@ namespace dawn_native { namespace d3d12 {
uint32_t parameterIndex = pipelineLayout->GetSamplerRootParameterIndex(index); uint32_t parameterIndex = pipelineLayout->GetSamplerRootParameterIndex(index);
const D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor = const D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor =
group->GetBaseSamplerDescriptor(); group->GetBaseSamplerDescriptor();
if (mInCompute) { // Check if the group requires its sampler table to be set in the pipeline.
commandList->SetComputeRootDescriptorTable(parameterIndex, baseDescriptor); // This because sampler heap allocations could be cached and use the same table.
} else { if (mBoundRootSamplerTables[index].ptr != baseDescriptor.ptr) {
commandList->SetGraphicsRootDescriptorTable(parameterIndex, baseDescriptor); if (mInCompute) {
commandList->SetComputeRootDescriptorTable(parameterIndex, baseDescriptor);
} else {
commandList->SetGraphicsRootDescriptorTable(parameterIndex, baseDescriptor);
}
mBoundRootSamplerTables[index] = baseDescriptor;
} }
} }
} }
@ -321,6 +340,9 @@ namespace dawn_native { namespace d3d12 {
bool mInCompute = false; bool mInCompute = false;
ityp::array<BindGroupIndex, D3D12_GPU_DESCRIPTOR_HANDLE, kMaxBindGroups>
mBoundRootSamplerTables = {};
ShaderVisibleDescriptorAllocator* mViewAllocator; ShaderVisibleDescriptorAllocator* mViewAllocator;
ShaderVisibleDescriptorAllocator* mSamplerAllocator; ShaderVisibleDescriptorAllocator* mSamplerAllocator;
}; };