mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 23:56:16 +00:00
Non-Local Residency 2: Implement Non-Local Management Logic
Implements logic for managing the NON_LOCAL memory segment for UPLOAD and READBACK heaps on Non-UMA devices. Bug: dawn:193 Change-Id: I2426bf6b5f7a7ccd4420f830f344379af9faf73c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/19901 Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Brandon Jones <brandon1.jones@intel.com>
This commit is contained in:
committed by
Commit Bot service account
parent
409cf67207
commit
635239faf8
@@ -26,6 +26,12 @@ constexpr uint32_t kDirectlyAllocatedResourceSize = 5000000; // 5MB
|
||||
constexpr uint32_t kSuballocatedResourceSize = 1000000; // 1MB
|
||||
constexpr uint32_t kSourceBufferSize = 4; // 4B
|
||||
|
||||
constexpr wgpu::BufferUsage kMapReadBufferUsage =
|
||||
wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
|
||||
constexpr wgpu::BufferUsage kMapWriteBufferUsage =
|
||||
wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::MapWrite;
|
||||
constexpr wgpu::BufferUsage kNonMappableBufferUsage = wgpu::BufferUsage::CopyDst;
|
||||
|
||||
class D3D12ResidencyTests : public DawnTest {
|
||||
protected:
|
||||
void TestSetUp() override {
|
||||
@@ -43,11 +49,13 @@ class D3D12ResidencyTests : public DawnTest {
|
||||
utils::CreateBufferFromData(device, &one, sizeof(one), wgpu::BufferUsage::CopySrc);
|
||||
}
|
||||
|
||||
std::vector<wgpu::Buffer> AllocateBuffers(uint32_t bufferSize, uint32_t numberOfBuffers) {
|
||||
std::vector<wgpu::Buffer> AllocateBuffers(uint32_t bufferSize,
|
||||
uint32_t numberOfBuffers,
|
||||
wgpu::BufferUsage usage) {
|
||||
std::vector<wgpu::Buffer> buffers;
|
||||
|
||||
for (uint64_t i = 0; i < numberOfBuffers; i++) {
|
||||
buffers.push_back(CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst));
|
||||
buffers.push_back(CreateBuffer(bufferSize, usage));
|
||||
}
|
||||
|
||||
return buffers;
|
||||
@@ -121,7 +129,8 @@ class D3D12ResidencyTests : public DawnTest {
|
||||
TEST_P(D3D12ResidencyTests, OvercommitSmallResources) {
|
||||
// Create suballocated buffers to fill half the budget.
|
||||
std::vector<wgpu::Buffer> bufferSet1 = AllocateBuffers(
|
||||
kSuballocatedResourceSize, ((kRestrictedBudgetSize / 2) / kSuballocatedResourceSize));
|
||||
kSuballocatedResourceSize, ((kRestrictedBudgetSize / 2) / kSuballocatedResourceSize),
|
||||
kNonMappableBufferUsage);
|
||||
|
||||
// Check that all the buffers allocated are resident. Also make sure they were suballocated
|
||||
// internally.
|
||||
@@ -133,7 +142,8 @@ TEST_P(D3D12ResidencyTests, OvercommitSmallResources) {
|
||||
|
||||
// Create enough directly-allocated buffers to use the entire budget.
|
||||
std::vector<wgpu::Buffer> bufferSet2 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize);
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize,
|
||||
kNonMappableBufferUsage);
|
||||
|
||||
// Check that everything in bufferSet1 is now evicted.
|
||||
for (uint32_t i = 0; i < bufferSet1.size(); i++) {
|
||||
@@ -157,9 +167,9 @@ TEST_P(D3D12ResidencyTests, OvercommitSmallResources) {
|
||||
// correctly.
|
||||
TEST_P(D3D12ResidencyTests, OvercommitLargeResources) {
|
||||
// Create directly-allocated buffers to fill half the budget.
|
||||
std::vector<wgpu::Buffer> bufferSet1 =
|
||||
AllocateBuffers(kDirectlyAllocatedResourceSize,
|
||||
((kRestrictedBudgetSize / 2) / kDirectlyAllocatedResourceSize));
|
||||
std::vector<wgpu::Buffer> bufferSet1 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize,
|
||||
((kRestrictedBudgetSize / 2) / kDirectlyAllocatedResourceSize), kNonMappableBufferUsage);
|
||||
|
||||
// Check that all the allocated buffers are resident. Also make sure they were directly
|
||||
// allocated internally.
|
||||
@@ -170,7 +180,8 @@ TEST_P(D3D12ResidencyTests, OvercommitLargeResources) {
|
||||
|
||||
// Create enough directly-allocated buffers to use the entire budget.
|
||||
std::vector<wgpu::Buffer> bufferSet2 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize);
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize,
|
||||
kNonMappableBufferUsage);
|
||||
|
||||
// Check that everything in bufferSet1 is now evicted.
|
||||
for (uint32_t i = 0; i < bufferSet1.size(); i++) {
|
||||
@@ -191,12 +202,8 @@ TEST_P(D3D12ResidencyTests, OvercommitLargeResources) {
|
||||
|
||||
// Check that calling MapReadAsync makes the buffer resident and keeps it locked resident.
|
||||
TEST_P(D3D12ResidencyTests, AsyncMappedBufferRead) {
|
||||
// Dawn currently only manages LOCAL_MEMORY. Mappable buffers exist in NON_LOCAL_MEMORY on
|
||||
// discrete devices.
|
||||
DAWN_SKIP_TEST_IF(!IsUMA());
|
||||
|
||||
// Create a mappable buffer.
|
||||
wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst);
|
||||
wgpu::Buffer buffer = CreateBuffer(4, kMapReadBufferUsage);
|
||||
|
||||
uint32_t data = 12345;
|
||||
buffer.SetSubData(0, sizeof(uint32_t), &data);
|
||||
@@ -206,7 +213,8 @@ TEST_P(D3D12ResidencyTests, AsyncMappedBufferRead) {
|
||||
|
||||
// Create and touch enough buffers to use the entire budget.
|
||||
std::vector<wgpu::Buffer> bufferSet = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize);
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize,
|
||||
kMapReadBufferUsage);
|
||||
TouchBuffers(0, bufferSet.size(), bufferSet);
|
||||
|
||||
// The mappable buffer should have been evicted.
|
||||
@@ -229,25 +237,23 @@ TEST_P(D3D12ResidencyTests, AsyncMappedBufferRead) {
|
||||
// This should evict the mappable buffer.
|
||||
buffer.Unmap();
|
||||
std::vector<wgpu::Buffer> bufferSet2 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize);
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize,
|
||||
kMapReadBufferUsage);
|
||||
TouchBuffers(0, bufferSet2.size(), bufferSet2);
|
||||
EXPECT_FALSE(CheckIfBufferIsResident(buffer));
|
||||
}
|
||||
|
||||
// Check that calling MapWriteAsync makes the buffer resident and keeps it locked resident.
|
||||
TEST_P(D3D12ResidencyTests, AsyncMappedBufferWrite) {
|
||||
// Dawn currently only manages LOCAL_MEMORY. Mappable buffers exist in NON_LOCAL_MEMORY on
|
||||
// discrete devices.
|
||||
DAWN_SKIP_TEST_IF(!IsUMA());
|
||||
|
||||
// Create a mappable buffer.
|
||||
wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc);
|
||||
wgpu::Buffer buffer = CreateBuffer(4, kMapWriteBufferUsage);
|
||||
// The mappable buffer should be resident.
|
||||
EXPECT_TRUE(CheckIfBufferIsResident(buffer));
|
||||
|
||||
// Create and touch enough buffers to use the entire budget.
|
||||
std::vector<wgpu::Buffer> bufferSet1 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize);
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize,
|
||||
kMapReadBufferUsage);
|
||||
TouchBuffers(0, bufferSet1.size(), bufferSet1);
|
||||
|
||||
// The mappable buffer should have been evicted.
|
||||
@@ -270,7 +276,8 @@ TEST_P(D3D12ResidencyTests, AsyncMappedBufferWrite) {
|
||||
// This should evict the mappable buffer.
|
||||
buffer.Unmap();
|
||||
std::vector<wgpu::Buffer> bufferSet2 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize);
|
||||
kDirectlyAllocatedResourceSize, kRestrictedBudgetSize / kDirectlyAllocatedResourceSize,
|
||||
kMapReadBufferUsage);
|
||||
TouchBuffers(0, bufferSet2.size(), bufferSet2);
|
||||
EXPECT_FALSE(CheckIfBufferIsResident(buffer));
|
||||
}
|
||||
@@ -281,7 +288,8 @@ TEST_P(D3D12ResidencyTests, OvercommitInASingleSubmit) {
|
||||
constexpr uint32_t numberOfBuffersToOvercommit = 5;
|
||||
std::vector<wgpu::Buffer> bufferSet1 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize,
|
||||
(kRestrictedBudgetSize / kDirectlyAllocatedResourceSize) + numberOfBuffersToOvercommit);
|
||||
(kRestrictedBudgetSize / kDirectlyAllocatedResourceSize) + numberOfBuffersToOvercommit,
|
||||
kNonMappableBufferUsage);
|
||||
// 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.
|
||||
@@ -292,7 +300,8 @@ TEST_P(D3D12ResidencyTests, OvercommitInASingleSubmit) {
|
||||
// Allocate another set of buffers that exceeds the budget.
|
||||
std::vector<wgpu::Buffer> bufferSet2 = AllocateBuffers(
|
||||
kDirectlyAllocatedResourceSize,
|
||||
(kRestrictedBudgetSize / kDirectlyAllocatedResourceSize) + numberOfBuffersToOvercommit);
|
||||
(kRestrictedBudgetSize / kDirectlyAllocatedResourceSize) + numberOfBuffersToOvercommit,
|
||||
kNonMappableBufferUsage);
|
||||
// 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++) {
|
||||
|
||||
Reference in New Issue
Block a user