dawn-cmake/src/tests/perf_tests/BufferUploadPerf.cpp
Bryan Bernhart 3debb26a9e Limit heap growth when uploading with SetSubData.
Removes unbounded heap growth by capping the heap
size to 4MB and falling back to direct allocation for larger
requests.

BUG=dawn:239

Change-Id: I9ae660809e3c0c539fbcfbee4afcf6fb1f466355
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12720
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
2019-10-29 22:49:43 +00:00

154 lines
5.0 KiB
C++

// 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 "tests/perf_tests/DawnPerfTest.h"
#include "tests/ParamGenerator.h"
#include "utils/WGPUHelpers.h"
namespace {
constexpr unsigned int kNumIterations = 50;
enum class UploadMethod {
SetSubData,
CreateBufferMapped,
};
// Perf delta exists between ranges [0, 1MB] vs [1MB, MAX_SIZE).
// These are sample buffer sizes within each range.
enum class UploadSize {
BufferSize_1KB = 1 * 1024,
BufferSize_64KB = 64 * 1024,
BufferSize_1MB = 1 * 1024 * 1024,
BufferSize_4MB = 4 * 1024 * 1024,
BufferSize_16MB = 16 * 1024 * 1024,
};
struct BufferUploadParams : DawnTestParam {
BufferUploadParams(const DawnTestParam& param,
UploadMethod uploadMethod,
UploadSize uploadSize)
: DawnTestParam(param), uploadMethod(uploadMethod), uploadSize(uploadSize) {
}
UploadMethod uploadMethod;
UploadSize uploadSize;
};
std::ostream& operator<<(std::ostream& ostream, const BufferUploadParams& param) {
ostream << static_cast<const DawnTestParam&>(param);
switch (param.uploadMethod) {
case UploadMethod::SetSubData:
ostream << "_SetSubData";
break;
case UploadMethod::CreateBufferMapped:
ostream << "_CreateBufferMapped";
break;
}
switch (param.uploadSize) {
case UploadSize::BufferSize_1KB:
ostream << "_BufferSize_1KB";
break;
case UploadSize::BufferSize_64KB:
ostream << "_BufferSize_64KB";
break;
case UploadSize::BufferSize_1MB:
ostream << "_BufferSize_1MB";
break;
case UploadSize::BufferSize_4MB:
ostream << "_BufferSize_4MB";
break;
case UploadSize::BufferSize_16MB:
ostream << "_BufferSize_16MB";
break;
}
return ostream;
}
} // namespace
// Test uploading |kBufferSize| bytes of data |kNumIterations| times.
class BufferUploadPerf : public DawnPerfTestWithParams<BufferUploadParams> {
public:
BufferUploadPerf()
: DawnPerfTestWithParams(kNumIterations, 1),
data(static_cast<size_t>(GetParam().uploadSize)) {
}
~BufferUploadPerf() override = default;
void TestSetUp() override;
private:
void Step() override;
wgpu::Buffer dst;
std::vector<uint8_t> data;
};
void BufferUploadPerf::TestSetUp() {
DawnPerfTestWithParams<BufferUploadParams>::TestSetUp();
wgpu::BufferDescriptor desc = {};
desc.size = data.size();
desc.usage = wgpu::BufferUsage::CopyDst;
dst = device.CreateBuffer(&desc);
}
void BufferUploadPerf::Step() {
switch (GetParam().uploadMethod) {
case UploadMethod::SetSubData: {
for (unsigned int i = 0; i < kNumIterations; ++i) {
dst.SetSubData(0, data.size(), data.data());
}
// Make sure all SetSubData's are flushed.
queue.Submit(0, nullptr);
} break;
case UploadMethod::CreateBufferMapped: {
wgpu::BufferDescriptor desc = {};
desc.size = data.size();
desc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::MapWrite;
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
for (unsigned int i = 0; i < kNumIterations; ++i) {
auto result = device.CreateBufferMapped(&desc);
memcpy(result.data, data.data(), data.size());
result.buffer.Unmap();
encoder.CopyBufferToBuffer(result.buffer, 0, dst, 0, data.size());
}
wgpu::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands);
} break;
}
}
TEST_P(BufferUploadPerf, Run) {
RunTest();
}
DAWN_INSTANTIATE_PERF_TEST_SUITE_P(BufferUploadPerf,
{D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend},
{UploadMethod::SetSubData, UploadMethod::CreateBufferMapped},
{UploadSize::BufferSize_1KB, UploadSize::BufferSize_64KB,
UploadSize::BufferSize_1MB, UploadSize::BufferSize_4MB,
UploadSize::BufferSize_16MB});