From 94e5b8c03b9e435462f621868d3e51af6cff5cbe Mon Sep 17 00:00:00 2001 From: SweetId <2630750+SweetId@users.noreply.github.com> Date: Tue, 9 Aug 2022 21:41:14 +0100 Subject: [PATCH] rework drawcalls building --- src/NazaraImgui/NazaraImgui.cpp | 84 +++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/src/NazaraImgui/NazaraImgui.cpp b/src/NazaraImgui/NazaraImgui.cpp index 309689e..41121c5 100644 --- a/src/NazaraImgui/NazaraImgui.cpp +++ b/src/NazaraImgui/NazaraImgui.cpp @@ -568,40 +568,66 @@ namespace Nz auto renderDevice = Nz::Graphics::Instance()->GetRenderDevice(); + struct DrawCall + { + size_t vertex_offset, indice_offset; + std::vector cmdBuffer; + }; + + std::vector drawCalls; + + // first pass over cmd lists to prepare buffers + std::vector vertices; + std::vector indices; for (int n = 0; n < drawData->CmdListsCount; ++n) { const ImDrawList* cmd_list = drawData->CmdLists[n]; - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - std::vector vertices; - vertices.reserve(cmd_list->VtxBuffer.size()); + DrawCall drawCall; + drawCall.vertex_offset = vertices.size(); + drawCall.indice_offset = indices.size(); + + vertices.reserve(vertices.size() + cmd_list->VtxBuffer.size()); for (auto& vertex : cmd_list->VtxBuffer) vertices.push_back({ ToNzVec3(vertex.pos), ToNzColor(vertex.col), ToNzVec2(vertex.uv) }); - size_t size = vertices.size() * sizeof(Nz::VertexStruct_XYZ_Color_UV); - auto vertexBuffer = renderDevice->InstantiateBuffer(Nz::BufferType::Vertex, size, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic, vertices.data()); - auto indexBuffer = renderDevice->InstantiateBuffer(Nz::BufferType::Index, cmd_list->IdxBuffer.size() * sizeof(ImWchar), Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic, idx_buffer); + indices.reserve(indices.size() + cmd_list->IdxBuffer.size()); + for (auto indice : cmd_list->IdxBuffer) + indices.push_back(drawCall.vertex_offset + indice); - auto* windowRT = window.GetRenderTarget(); - - std::vector cmdBuffer; - cmdBuffer.reserve(cmd_list->CmdBuffer.size()); for (auto& cmd : cmd_list->CmdBuffer) - cmdBuffer.push_back(cmd); + drawCall.cmdBuffer.push_back(cmd); - frame.Execute([this, windowRT, &frame, fb_width, fb_height, cmdBuffer, vertexBuffer, indexBuffer](Nz::CommandBufferBuilder& builder) { - builder.BeginDebugRegion("ImGui", Nz::Color::Green); + drawCalls.push_back(std::move(drawCall)); + } + + + // now that we have macro buffers, allocate them on gpu + size_t size = vertices.size() * sizeof(Nz::VertexStruct_XYZ_Color_UV); + auto vertexBuffer = renderDevice->InstantiateBuffer(Nz::BufferType::Vertex, size, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic, vertices.data()); + size = indices.size() * sizeof(uint16_t); + auto indexBuffer = renderDevice->InstantiateBuffer(Nz::BufferType::Index, size, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic, indices.data()); + + // freeing memory now, no need to keep buffers on CPU + vertices.clear(); + indices.clear(); + + auto* windowRT = window.GetRenderTarget(); + + frame.Execute([this, windowRT, &frame, fb_width, fb_height, drawCalls, vertexBuffer, indexBuffer](Nz::CommandBufferBuilder& builder) { + builder.BeginDebugRegion("ImGui", Nz::Color::Green); + { + Nz::Recti renderRect(0, 0, fb_width, fb_height); + + builder.BeginRenderPass(windowRT->GetFramebuffer(frame.GetFramebufferIndex()), windowRT->GetRenderPass(), renderRect); { - Nz::Recti renderRect(0, 0, fb_width, fb_height); + builder.SetViewport(Nz::Recti{ 0, 0, fb_width, fb_height }); + builder.BindIndexBuffer(*indexBuffer, Nz::IndexType::U16); + builder.BindVertexBuffer(0, *vertexBuffer); - Nz::CommandBufferBuilder::ClearValues clearValues[2]; - clearValues[0].color = Nz::Color::Black; - clearValues[1].depth = 1.f; - clearValues[1].stencil = 0; - - builder.BeginRenderPass(windowRT->GetFramebuffer(frame.GetFramebufferIndex()), windowRT->GetRenderPass(), renderRect, { clearValues[0], clearValues[1] }); + for (auto& drawCall : drawCalls) { - Nz::UInt64 indexOffset = 0; - for (auto& cmd : cmdBuffer) + Nz::UInt64 indexOffset = drawCall.indice_offset; + for (auto& cmd : drawCall.cmdBuffer) { if (!cmd.UserCallback) { @@ -635,22 +661,18 @@ namespace Nz builder.BindShaderBinding(0, *m_untexturedPipeline.uboShaderBinding); } - builder.SetViewport(Nz::Recti{ 0, 0, fb_width, fb_height }); builder.SetScissor(Nz::Recti{ int(rect.x), int(rect.y), int(rect.z - rect.x), int(rect.w - rect.y) });// Nz::Recti{ int(rect.x), int(fb_height - rect.w), int(rect.z - rect.x), int(rect.w - rect.y) }); - builder.BindIndexBuffer(*indexBuffer, Nz::IndexType::U16, indexOffset * sizeof(ImWchar)); - builder.BindVertexBuffer(0, *vertexBuffer); - - builder.DrawIndexed(count); + builder.DrawIndexed(count, 1, indexOffset); } indexOffset += cmd.ElemCount; } } - builder.EndRenderPass(); } - builder.EndDebugRegion(); - }, Nz::QueueType::Graphics); - } + builder.EndRenderPass(); + } + builder.EndDebugRegion(); + }, Nz::QueueType::Graphics); } }