aurora: Use multiple staging buffers & map at end of frame

This commit is contained in:
Luke Street 2022-03-16 02:05:56 -04:00
parent 73348d8d9f
commit 788f57cb52
2 changed files with 29 additions and 15 deletions

View File

@ -211,7 +211,7 @@ wgpu::Buffer g_uniformBuffer;
wgpu::Buffer g_indexBuffer;
wgpu::Buffer g_storageBuffer;
size_t g_staticStorageLastSize = 0;
static wgpu::Buffer g_stagingBuffer;
static std::array<wgpu::Buffer, 2> g_stagingBuffers;
static ShaderState g_state;
static PipelineRef g_currentPipeline;
@ -405,8 +405,11 @@ void initialize() {
"Shared Index Buffer");
createBuffer(g_storageBuffer, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst, StorageBufferSize,
"Shared Storage Buffer");
createBuffer(g_stagingBuffer, wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, StagingBufferSize,
"Staging Buffer");
createBuffer(g_stagingBuffers[0], wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, StagingBufferSize,
"Staging Buffer 1");
createBuffer(g_stagingBuffers[1], wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, StagingBufferSize,
"Staging Buffer 2");
map_staging_buffer();
g_state.moviePlayer = movie_player::construct_state();
g_state.coloredQuad = colored_quad::construct_state();
@ -429,31 +432,39 @@ void shutdown() {
g_uniformBuffer = {};
g_indexBuffer = {};
g_storageBuffer = {};
g_stagingBuffer = {};
g_stagingBuffers.fill({});
g_state = {};
}
void begin_frame() {
bool bufferMapped = false;
size_t bufferOffset = 0;
const auto mapBuffer = [&](ByteBuffer& buf, uint64_t size) {
buf = ByteBuffer{static_cast<u8*>(g_stagingBuffer.GetMappedRange(bufferOffset, size)), size};
bufferOffset += size;
};
g_stagingBuffer.MapAsync(
static size_t currentStagingBuffer = 0;
static bool bufferMapped = false;
void map_staging_buffer() {
bufferMapped = false;
g_stagingBuffers[currentStagingBuffer].MapAsync(
wgpu::MapMode::Write, 0, StagingBufferSize,
[](WGPUBufferMapAsyncStatus status, void* userdata) {
if (status != WGPUBufferMapAsyncStatus_Success) {
if (status == WGPUBufferMapAsyncStatus_DestroyedBeforeCallback) {
return;
} else if (status != WGPUBufferMapAsyncStatus_Success) {
Log.report(logvisor::Fatal, FMT_STRING("Buffer mapping failed: {}"), status);
unreachable();
}
*static_cast<bool*>(userdata) = true;
},
&bufferMapped);
}
void begin_frame() {
while (!bufferMapped) {
g_device.Tick();
}
size_t bufferOffset = 0;
auto& stagingBuf = g_stagingBuffers[currentStagingBuffer];
const auto mapBuffer = [&](ByteBuffer& buf, uint64_t size) {
buf = ByteBuffer{static_cast<u8*>(stagingBuf.GetMappedRange(bufferOffset, size)), size};
bufferOffset += size;
};
mapBuffer(g_verts, VertexBufferSize);
mapBuffer(g_uniforms, UniformBufferSize);
mapBuffer(g_indices, IndexBufferSize);
@ -465,16 +476,18 @@ void end_frame(const wgpu::CommandEncoder& cmd) {
const auto writeBuffer = [&](ByteBuffer& buf, wgpu::Buffer& out, uint64_t size, std::string_view label) {
const auto writeSize = buf.size(); // Only need to copy this many bytes
if (writeSize > 0) {
cmd.CopyBufferToBuffer(g_stagingBuffer, bufferOffset, out, 0, writeSize);
cmd.CopyBufferToBuffer(g_stagingBuffers[currentStagingBuffer], bufferOffset, out, 0, writeSize);
buf.clear();
}
bufferOffset += size;
};
g_stagingBuffer.Unmap();
g_stagingBuffers[currentStagingBuffer].Unmap();
writeBuffer(g_verts, g_vertexBuffer, VertexBufferSize, "Vertex");
writeBuffer(g_uniforms, g_uniformBuffer, UniformBufferSize, "Uniform");
writeBuffer(g_indices, g_indexBuffer, IndexBufferSize, "Index");
writeBuffer(g_storage, g_storageBuffer, StorageBufferSize, "Storage");
currentStagingBuffer = (currentStagingBuffer + 1) % g_stagingBuffers.size();
map_staging_buffer();
}
void render(const wgpu::RenderPassEncoder& pass) {

View File

@ -174,6 +174,7 @@ void shutdown();
void begin_frame();
void end_frame(const wgpu::CommandEncoder& cmd);
void render(const wgpu::RenderPassEncoder& pass);
void map_staging_buffer();
Range push_verts(const uint8_t* data, size_t length);
template <typename T>