Residency Bug: Always Attempt To Evict To Under Budget

In the case that a previous submit to the GPU required Dawn to exceed
the residency budget, Dawn must attempt to get back under budget the
next time EnsureCanMakeResident is called. This CL fixes a bug where we
only evicted the current size needed to be resident, which would
incorrectly raise the budget when a submit to the GPU required us to
exceed the budget.

Bug: dawn:193
Change-Id: I04649056e9eecce1fc6b5759c889b52a4f1b4594
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/19440
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Brandon Jones <brandon1.jones@intel.com>
This commit is contained in:
Brandon Jones 2020-04-16 23:52:23 +00:00 committed by Commit Bot service account
parent 3aa5be9749
commit 82ae680ccc
2 changed files with 28 additions and 2 deletions

View File

@ -171,9 +171,10 @@ namespace dawn_native { namespace d3d12 {
} }
std::vector<ID3D12Pageable*> resourcesToEvict; std::vector<ID3D12Pageable*> resourcesToEvict;
uint64_t sizeNeededToBeUnderBudget =
memoryUsageAfterMakeResident - mVideoMemoryInfo.dawnBudget;
uint64_t sizeEvicted = 0; uint64_t sizeEvicted = 0;
while (sizeEvicted < sizeToMakeResident) { while (sizeEvicted < sizeNeededToBeUnderBudget) {
Heap* heap; Heap* heap;
DAWN_TRY_ASSIGN(heap, RemoveSingleEntryFromLRU()); DAWN_TRY_ASSIGN(heap, RemoveSingleEntryFromLRU());

View File

@ -276,4 +276,29 @@ TEST_P(D3D12ResidencyTests, AsyncMappedBufferWrite) {
EXPECT_FALSE(CheckIfBufferIsResident(buffer)); EXPECT_FALSE(CheckIfBufferIsResident(buffer));
} }
// Check that overcommitting in a single submit works, then make sure the budget is enforced after.
TEST_P(D3D12ResidencyTests, OvercommitInASingleSubmit) {
// Create enough buffers to exceed the budget
constexpr uint32_t numberOfBuffersToOvercommit = 5;
std::vector<wgpu::Buffer> bufferSet1 = AllocateBuffers(
kDirectlyAllocatedResourceSize,
(kRestrictedBudgetSize / kDirectlyAllocatedResourceSize) + numberOfBuffersToOvercommit);
// Touch the buffers, which creates an overcommitted command list.
TouchBuffers(0, bufferSet1.size(), bufferSet1);
// Ensure that all of these buffers are resident, even though we're exceeding the budget.
for (uint32_t i = 0; i < bufferSet1.size(); i++) {
EXPECT_TRUE(CheckIfBufferIsResident(bufferSet1[i]));
}
// Allocate another set of buffers that exceeds the budget.
std::vector<wgpu::Buffer> bufferSet2 = AllocateBuffers(
kDirectlyAllocatedResourceSize,
(kRestrictedBudgetSize / kDirectlyAllocatedResourceSize) + numberOfBuffersToOvercommit);
// Ensure the first <numberOfBuffersToOvercommit> buffers in the second buffer set were evicted,
// since they shouldn't fit in the budget.
for (uint32_t i = 0; i < numberOfBuffersToOvercommit; i++) {
EXPECT_FALSE(CheckIfBufferIsResident(bufferSet2[i]));
}
}
DAWN_INSTANTIATE_TEST(D3D12ResidencyTests, D3D12Backend()); DAWN_INSTANTIATE_TEST(D3D12ResidencyTests, D3D12Backend());