mirror of https://github.com/AxioDL/metaforce.git
aurora: Use multiple staging buffers & map at end of frame
This commit is contained in:
parent
73348d8d9f
commit
788f57cb52
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue