mirror of https://github.com/AxioDL/metaforce.git
aurora: Use staging buffer for mapping
This commit is contained in:
parent
efd14dcaf2
commit
c01152e23a
|
@ -293,6 +293,7 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv)
|
||||||
.label = "Redraw encoder",
|
.label = "Redraw encoder",
|
||||||
};
|
};
|
||||||
auto encoder = g_device.CreateCommandEncoder(&encoderDescriptor);
|
auto encoder = g_device.CreateCommandEncoder(&encoderDescriptor);
|
||||||
|
gfx::end_frame(encoder);
|
||||||
{
|
{
|
||||||
const std::array attachments{
|
const std::array attachments{
|
||||||
wgpu::RenderPassColorAttachment{
|
wgpu::RenderPassColorAttachment{
|
||||||
|
@ -324,7 +325,7 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv)
|
||||||
.depthStencilAttachment = &depthStencilAttachment,
|
.depthStencilAttachment = &depthStencilAttachment,
|
||||||
};
|
};
|
||||||
auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
|
auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
|
||||||
gfx::end_frame(pass);
|
gfx::render(pass);
|
||||||
pass.End();
|
pass.End();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,8 @@ constexpr uint64_t VertexBufferSize = 5242880; // 5mb
|
||||||
constexpr uint64_t IndexBufferSize = 2097152; // 2mb
|
constexpr uint64_t IndexBufferSize = 2097152; // 2mb
|
||||||
constexpr uint64_t StorageBufferSize = 134217728; // 128mb
|
constexpr uint64_t StorageBufferSize = 134217728; // 128mb
|
||||||
|
|
||||||
|
constexpr uint64_t StagingBufferSize = UniformBufferSize + VertexBufferSize + IndexBufferSize + StorageBufferSize;
|
||||||
|
|
||||||
struct ShaderState {
|
struct ShaderState {
|
||||||
movie_player::State moviePlayer;
|
movie_player::State moviePlayer;
|
||||||
colored_quad::State coloredQuad;
|
colored_quad::State coloredQuad;
|
||||||
|
@ -209,6 +211,7 @@ wgpu::Buffer g_uniformBuffer;
|
||||||
wgpu::Buffer g_indexBuffer;
|
wgpu::Buffer g_indexBuffer;
|
||||||
wgpu::Buffer g_storageBuffer;
|
wgpu::Buffer g_storageBuffer;
|
||||||
size_t g_staticStorageLastSize = 0;
|
size_t g_staticStorageLastSize = 0;
|
||||||
|
static wgpu::Buffer g_stagingBuffer;
|
||||||
|
|
||||||
static ShaderState g_state;
|
static ShaderState g_state;
|
||||||
static PipelineRef g_currentPipeline;
|
static PipelineRef g_currentPipeline;
|
||||||
|
@ -389,15 +392,21 @@ void initialize() {
|
||||||
const auto createBuffer = [](wgpu::Buffer& out, wgpu::BufferUsage usage, uint64_t size, const char* label) {
|
const auto createBuffer = [](wgpu::Buffer& out, wgpu::BufferUsage usage, uint64_t size, const char* label) {
|
||||||
const wgpu::BufferDescriptor descriptor{
|
const wgpu::BufferDescriptor descriptor{
|
||||||
.label = label,
|
.label = label,
|
||||||
.usage = usage | wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapWrite,
|
.usage = usage,
|
||||||
.size = size,
|
.size = size,
|
||||||
};
|
};
|
||||||
out = g_device.CreateBuffer(&descriptor);
|
out = g_device.CreateBuffer(&descriptor);
|
||||||
};
|
};
|
||||||
createBuffer(g_uniformBuffer, wgpu::BufferUsage::Uniform, UniformBufferSize, "Shared Uniform Buffer");
|
createBuffer(g_uniformBuffer, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst, UniformBufferSize,
|
||||||
createBuffer(g_vertexBuffer, wgpu::BufferUsage::Vertex, VertexBufferSize, "Shared Vertex Buffer");
|
"Shared Uniform Buffer");
|
||||||
createBuffer(g_indexBuffer, wgpu::BufferUsage::Index, IndexBufferSize, "Shared Index Buffer");
|
createBuffer(g_vertexBuffer, wgpu::BufferUsage::Vertex | wgpu::BufferUsage::CopyDst, VertexBufferSize,
|
||||||
createBuffer(g_storageBuffer, wgpu::BufferUsage::Storage, StorageBufferSize, "Shared Storage Buffer");
|
"Shared Vertex Buffer");
|
||||||
|
createBuffer(g_indexBuffer, wgpu::BufferUsage::Index | wgpu::BufferUsage::CopyDst, IndexBufferSize,
|
||||||
|
"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");
|
||||||
|
|
||||||
g_state.moviePlayer = movie_player::construct_state();
|
g_state.moviePlayer = movie_player::construct_state();
|
||||||
g_state.coloredQuad = colored_quad::construct_state();
|
g_state.coloredQuad = colored_quad::construct_state();
|
||||||
|
@ -420,61 +429,55 @@ void shutdown() {
|
||||||
g_uniformBuffer = {};
|
g_uniformBuffer = {};
|
||||||
g_indexBuffer = {};
|
g_indexBuffer = {};
|
||||||
g_storageBuffer = {};
|
g_storageBuffer = {};
|
||||||
|
g_stagingBuffer = {};
|
||||||
|
|
||||||
g_state = {};
|
g_state = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin_frame() {
|
void begin_frame() {
|
||||||
int mappedBuffers = 0, totalBuffers = 0;
|
bool bufferMapped = false;
|
||||||
const auto mapBuffer = [&](ByteBuffer& buf, wgpu::Buffer& out, uint64_t size) {
|
size_t bufferOffset = 0;
|
||||||
struct MapCallbackData {
|
const auto mapBuffer = [&](ByteBuffer& buf, uint64_t size) {
|
||||||
ByteBuffer& buf;
|
buf = ByteBuffer{static_cast<u8*>(g_stagingBuffer.GetMappedRange(bufferOffset, size)), size};
|
||||||
wgpu::Buffer& out;
|
bufferOffset += size;
|
||||||
uint64_t size;
|
|
||||||
int& mappedBuffers;
|
|
||||||
};
|
|
||||||
auto* data = new MapCallbackData{
|
|
||||||
.buf = buf,
|
|
||||||
.out = out,
|
|
||||||
.size = size,
|
|
||||||
.mappedBuffers = mappedBuffers,
|
|
||||||
};
|
|
||||||
out.MapAsync(
|
|
||||||
wgpu::MapMode::Write, 0, size,
|
|
||||||
[](WGPUBufferMapAsyncStatus status, void* userdata) {
|
|
||||||
if (status != WGPUBufferMapAsyncStatus_Success) {
|
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Buffer mapping failed: {}"), status);
|
|
||||||
unreachable();
|
|
||||||
}
|
|
||||||
auto* data = static_cast<MapCallbackData*>(userdata);
|
|
||||||
data->buf = ByteBuffer{static_cast<uint8_t*>(data->out.GetMappedRange(0, data->size)), data->size};
|
|
||||||
++data->mappedBuffers;
|
|
||||||
delete data;
|
|
||||||
},
|
|
||||||
data);
|
|
||||||
++totalBuffers;
|
|
||||||
};
|
};
|
||||||
mapBuffer(g_verts, g_vertexBuffer, VertexBufferSize);
|
g_stagingBuffer.MapAsync(
|
||||||
mapBuffer(g_uniforms, g_uniformBuffer, UniformBufferSize);
|
wgpu::MapMode::Write, 0, StagingBufferSize,
|
||||||
mapBuffer(g_indices, g_indexBuffer, IndexBufferSize);
|
[](WGPUBufferMapAsyncStatus status, void* userdata) {
|
||||||
mapBuffer(g_storage, g_storageBuffer, StorageBufferSize);
|
if (status != WGPUBufferMapAsyncStatus_Success) {
|
||||||
while (mappedBuffers < totalBuffers) {
|
Log.report(logvisor::Fatal, FMT_STRING("Buffer mapping failed: {}"), status);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
*static_cast<bool*>(userdata) = true;
|
||||||
|
},
|
||||||
|
&bufferMapped);
|
||||||
|
while (!bufferMapped) {
|
||||||
g_device.Tick();
|
g_device.Tick();
|
||||||
}
|
}
|
||||||
|
mapBuffer(g_verts, VertexBufferSize);
|
||||||
|
mapBuffer(g_uniforms, UniformBufferSize);
|
||||||
|
mapBuffer(g_indices, IndexBufferSize);
|
||||||
|
mapBuffer(g_storage, StorageBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_frame(const wgpu::RenderPassEncoder& pass) {
|
void end_frame(const wgpu::CommandEncoder& cmd) {
|
||||||
const auto writeBuffer = [](ByteBuffer& buf, wgpu::Buffer& out, std::string_view label) {
|
uint64_t bufferOffset = 0;
|
||||||
const auto size = buf.size();
|
const auto writeBuffer = [&](ByteBuffer& buf, wgpu::Buffer& out, uint64_t size, std::string_view label) {
|
||||||
// Log.report(logvisor::Info, FMT_STRING("{} buffer usage: {}"), label, size);
|
const auto writeSize = buf.size(); // Only need to copy this many bytes
|
||||||
buf.clear();
|
if (writeSize > 0) {
|
||||||
out.Unmap();
|
cmd.CopyBufferToBuffer(g_stagingBuffer, bufferOffset, out, 0, writeSize);
|
||||||
|
buf.clear();
|
||||||
|
}
|
||||||
|
bufferOffset += size;
|
||||||
};
|
};
|
||||||
writeBuffer(g_verts, g_vertexBuffer, "Vertex");
|
g_stagingBuffer.Unmap();
|
||||||
writeBuffer(g_uniforms, g_uniformBuffer, "Uniform");
|
writeBuffer(g_verts, g_vertexBuffer, VertexBufferSize, "Vertex");
|
||||||
writeBuffer(g_indices, g_indexBuffer, "Index");
|
writeBuffer(g_uniforms, g_uniformBuffer, UniformBufferSize, "Uniform");
|
||||||
writeBuffer(g_storage, g_storageBuffer, "Storage");
|
writeBuffer(g_indices, g_indexBuffer, IndexBufferSize, "Index");
|
||||||
|
writeBuffer(g_storage, g_storageBuffer, StorageBufferSize, "Storage");
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(const wgpu::RenderPassEncoder& pass) {
|
||||||
g_currentPipeline = UINT64_MAX;
|
g_currentPipeline = UINT64_MAX;
|
||||||
|
|
||||||
for (const auto& cmd : g_commands) {
|
for (const auto& cmd : g_commands) {
|
||||||
|
|
|
@ -172,7 +172,8 @@ void initialize();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
void begin_frame();
|
void begin_frame();
|
||||||
void end_frame(const wgpu::RenderPassEncoder& pass);
|
void end_frame(const wgpu::CommandEncoder& cmd);
|
||||||
|
void render(const wgpu::RenderPassEncoder& pass);
|
||||||
|
|
||||||
Range push_verts(const uint8_t* data, size_t length);
|
Range push_verts(const uint8_t* data, size_t length);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
Loading…
Reference in New Issue