rework drawcalls building
This commit is contained in:
parent
afc12c44f8
commit
94e5b8c03b
|
|
@ -568,40 +568,66 @@ namespace Nz
|
||||||
|
|
||||||
auto renderDevice = Nz::Graphics::Instance()->GetRenderDevice();
|
auto renderDevice = Nz::Graphics::Instance()->GetRenderDevice();
|
||||||
|
|
||||||
|
struct DrawCall
|
||||||
|
{
|
||||||
|
size_t vertex_offset, indice_offset;
|
||||||
|
std::vector<ImDrawCmd> cmdBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<DrawCall> drawCalls;
|
||||||
|
|
||||||
|
// first pass over cmd lists to prepare buffers
|
||||||
|
std::vector<Nz::VertexStruct_XYZ_Color_UV> vertices;
|
||||||
|
std::vector<uint16_t> indices;
|
||||||
for (int n = 0; n < drawData->CmdListsCount; ++n) {
|
for (int n = 0; n < drawData->CmdListsCount; ++n) {
|
||||||
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
||||||
const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
|
|
||||||
|
|
||||||
std::vector<Nz::VertexStruct_XYZ_Color_UV> vertices;
|
DrawCall drawCall;
|
||||||
vertices.reserve(cmd_list->VtxBuffer.size());
|
drawCall.vertex_offset = vertices.size();
|
||||||
|
drawCall.indice_offset = indices.size();
|
||||||
|
|
||||||
|
vertices.reserve(vertices.size() + cmd_list->VtxBuffer.size());
|
||||||
for (auto& vertex : cmd_list->VtxBuffer)
|
for (auto& vertex : cmd_list->VtxBuffer)
|
||||||
vertices.push_back({ ToNzVec3(vertex.pos), ToNzColor(vertex.col), ToNzVec2(vertex.uv) });
|
vertices.push_back({ ToNzVec3(vertex.pos), ToNzColor(vertex.col), ToNzVec2(vertex.uv) });
|
||||||
|
|
||||||
size_t size = vertices.size() * sizeof(Nz::VertexStruct_XYZ_Color_UV);
|
indices.reserve(indices.size() + cmd_list->IdxBuffer.size());
|
||||||
auto vertexBuffer = renderDevice->InstantiateBuffer(Nz::BufferType::Vertex, size, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic, vertices.data());
|
for (auto indice : cmd_list->IdxBuffer)
|
||||||
auto indexBuffer = renderDevice->InstantiateBuffer(Nz::BufferType::Index, cmd_list->IdxBuffer.size() * sizeof(ImWchar), Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic, idx_buffer);
|
indices.push_back(drawCall.vertex_offset + indice);
|
||||||
|
|
||||||
auto* windowRT = window.GetRenderTarget();
|
|
||||||
|
|
||||||
std::vector<ImDrawCmd> cmdBuffer;
|
|
||||||
cmdBuffer.reserve(cmd_list->CmdBuffer.size());
|
|
||||||
for (auto& cmd : cmd_list->CmdBuffer)
|
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) {
|
drawCalls.push_back(std::move(drawCall));
|
||||||
builder.BeginDebugRegion("ImGui", Nz::Color::Green);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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];
|
for (auto& drawCall : drawCalls)
|
||||||
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] });
|
|
||||||
{
|
{
|
||||||
Nz::UInt64 indexOffset = 0;
|
Nz::UInt64 indexOffset = drawCall.indice_offset;
|
||||||
for (auto& cmd : cmdBuffer)
|
for (auto& cmd : drawCall.cmdBuffer)
|
||||||
{
|
{
|
||||||
if (!cmd.UserCallback)
|
if (!cmd.UserCallback)
|
||||||
{
|
{
|
||||||
|
|
@ -635,22 +661,18 @@ namespace Nz
|
||||||
builder.BindShaderBinding(0, *m_untexturedPipeline.uboShaderBinding);
|
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.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.DrawIndexed(count, 1, indexOffset);
|
||||||
builder.BindVertexBuffer(0, *vertexBuffer);
|
|
||||||
|
|
||||||
builder.DrawIndexed(count);
|
|
||||||
}
|
}
|
||||||
indexOffset += cmd.ElemCount;
|
indexOffset += cmd.ElemCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
builder.EndRenderPass();
|
|
||||||
}
|
}
|
||||||
builder.EndDebugRegion();
|
builder.EndRenderPass();
|
||||||
}, Nz::QueueType::Graphics);
|
}
|
||||||
}
|
builder.EndDebugRegion();
|
||||||
|
}, Nz::QueueType::Graphics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue