Bring back global lithium pools
why? cause sorting around the global driver pool would basically use more cpu power then just copy data sequences into the right order And sorting data references costs 0 performance at all
This commit is contained in:
@@ -52,6 +52,7 @@ set(PD_SOURCES
|
|||||||
source/lithium/drawlist.cpp
|
source/lithium/drawlist.cpp
|
||||||
source/lithium/font.cpp
|
source/lithium/font.cpp
|
||||||
source/lithium/math.cpp
|
source/lithium/math.cpp
|
||||||
|
source/lithium/pools.cpp
|
||||||
|
|
||||||
# UI7
|
# UI7
|
||||||
source/ui7/io.cpp
|
source/ui7/io.cpp
|
||||||
|
|||||||
+50
-12
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#include <pd/core/mat.hpp>
|
#include <pd/core/mat.hpp>
|
||||||
#include <pd/drivers/interface.hpp>
|
#include <pd/drivers/interface.hpp>
|
||||||
#include <pd/lithium/command.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
|
#include <pd/lithium/pools.hpp>
|
||||||
#include <pd/lithium/texture.hpp>
|
#include <pd/lithium/texture.hpp>
|
||||||
|
|
||||||
using PDGfxBackendFlags = PD::u32;
|
using PDGfxBackendFlags = PD::u32;
|
||||||
@@ -37,7 +38,7 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
virtual void DeleteTexture(const Li::Texture& tex) {}
|
virtual void DeleteTexture(const Li::Texture& tex) {}
|
||||||
virtual void Draw(const Pool<Li::Command>& commands) {}
|
virtual void Draw(const Li::Drawlist& commands) {}
|
||||||
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
||||||
PDGfxBackendFlags GetFlags() { return Flags; }
|
PDGfxBackendFlags GetFlags() { return Flags; }
|
||||||
|
|
||||||
@@ -110,28 +111,67 @@ class GfxDriverBase : public GfxDriver {
|
|||||||
pWhite = LoadTexture(img, 16, 16);
|
pWhite = LoadTexture(img, 16, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(const Pool<Li::Command>& commands) override {
|
void Draw(const Li::Drawlist& dl) override {
|
||||||
|
const auto& commands = dl.Data();
|
||||||
|
if (commands.size() == 0) return;
|
||||||
pCountCommands += commands.size();
|
pCountCommands += commands.size();
|
||||||
size_t index = 0;
|
|
||||||
|
size_t vtotal = dl.GetNumVertices();
|
||||||
|
size_t itotal = dl.GetNumIndices();
|
||||||
|
|
||||||
|
size_t start_vtx = pVtxPool.size();
|
||||||
|
pVtxPool.Allocate(vtotal);
|
||||||
|
CurrentVertex += vtotal;
|
||||||
|
|
||||||
|
size_t start_idx = pIdxPool.size();
|
||||||
|
pIdxPool.Allocate(itotal);
|
||||||
|
CurrentIndex += itotal;
|
||||||
|
|
||||||
|
size_t current_vtx = start_vtx;
|
||||||
|
size_t current_idx = start_idx;
|
||||||
|
|
||||||
|
const auto& vpool = Li::GetVertexPool();
|
||||||
|
const auto& ipool = Li::GetIndexPool();
|
||||||
|
/** Build Pools */
|
||||||
|
for (size_t i = 0; i < commands.size(); i++) {
|
||||||
|
const auto& cmd = commands[i];
|
||||||
|
if (cmd.VertexCount > 0) {
|
||||||
|
std::memcpy(pVtxPool.begin() + current_vtx,
|
||||||
|
vpool.begin() + cmd.FirstVertex,
|
||||||
|
cmd.VertexCount * sizeof(Li::Vertex));
|
||||||
|
}
|
||||||
|
for (size_t idx = 0; idx < cmd.IndexCount; idx++) {
|
||||||
|
u16 local_idx = ipool[cmd.FirstIndex + idx];
|
||||||
|
pIdxPool[current_idx + idx] = static_cast<u16>(current_vtx + local_idx);
|
||||||
|
}
|
||||||
|
current_vtx += cmd.VertexCount;
|
||||||
|
current_idx += cmd.IndexCount;
|
||||||
|
}
|
||||||
|
|
||||||
UploadPools();
|
UploadPools();
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
size_t ioff = start_idx;
|
||||||
|
|
||||||
while (index < commands.size()) {
|
while (index < commands.size()) {
|
||||||
CurrentTex = commands[index].Tex;
|
CurrentTex = commands[index].Tex;
|
||||||
CurrentTexIsSDF = commands[index].SDF;
|
CurrentTexIsSDF = commands[index].SDF;
|
||||||
if (!CurrentTex) {
|
if (!CurrentTex) {
|
||||||
CurrentTex = pWhite.GetID();
|
CurrentTex = pWhite.GetID();
|
||||||
}
|
}
|
||||||
size_t startidx = commands[index].FirstIndex;
|
|
||||||
size_t num_indices = 0;
|
size_t num_indices = 0;
|
||||||
while (index < commands.size() &&
|
while (index < commands.size() &&
|
||||||
CurrentTexIsSDF == commands[index].SDF &&
|
CurrentTexIsSDF == commands[index].SDF &&
|
||||||
(CurrentTex == commands[index].Tex ||
|
(CurrentTex == commands[index].Tex ||
|
||||||
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0)) &&
|
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0))) {
|
||||||
commands[index].FirstIndex == startidx + num_indices) {
|
|
||||||
num_indices += commands[index].IndexCount;
|
num_indices += commands[index].IndexCount;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
Submit(num_indices, startidx);
|
if (num_indices > 0) {
|
||||||
pCountDrawcalls++;
|
Submit(num_indices, ioff);
|
||||||
|
ioff += num_indices;
|
||||||
|
pCountDrawcalls++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +251,7 @@ class PD_API Gfx {
|
|||||||
static void SetViewPort(const ivec2& vp) { driver->SetViewPort(vp); }
|
static void SetViewPort(const ivec2& vp) { driver->SetViewPort(vp); }
|
||||||
static void SetViewPort(int w, int h) { driver->SetViewPort(w, h); }
|
static void SetViewPort(int w, int h) { driver->SetViewPort(w, h); }
|
||||||
static void Reset() { driver->Reset(); }
|
static void Reset() { driver->Reset(); }
|
||||||
static void Draw(const Pool<Li::Command>& commands) {
|
static void Draw(const Li::Drawlist& dl) { driver->Draw(dl); }
|
||||||
driver->Draw(commands);
|
|
||||||
}
|
|
||||||
static Li::Texture LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
static Li::Texture LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
int h,
|
int h,
|
||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
|
|||||||
@@ -4,4 +4,5 @@
|
|||||||
#include <pd/lithium/drawlist.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
#include <pd/lithium/font.hpp>
|
#include <pd/lithium/font.hpp>
|
||||||
#include <pd/lithium/math.hpp>
|
#include <pd/lithium/math.hpp>
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/pools.hpp>
|
||||||
|
#include <pd/lithium/vertex.hpp>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/lithium/vertex.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Li {
|
||||||
|
PD_API PD::Pool<Vertex>& GetVertexPool();
|
||||||
|
PD_API PD::Pool<u16>& GetIndexPool();
|
||||||
|
PD_API void ResetPools();
|
||||||
|
} // namespace Li
|
||||||
|
} // namespace PD
|
||||||
+42
-14
@@ -1,23 +1,48 @@
|
|||||||
#include <pd/drivers/gfx.hpp>
|
#include <pd/drivers/gfx.hpp>
|
||||||
#include <pd/lithium/command.hpp>
|
#include <pd/lithium/command.hpp>
|
||||||
|
#include <pd/lithium/pools.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
|
|
||||||
void Command::Reserve(size_t vtx, size_t idx) {
|
void Command::Reserve(size_t vtx, size_t idx) {
|
||||||
|
auto& vpool = GetVertexPool();
|
||||||
|
auto& ipool = GetIndexPool();
|
||||||
if (VertexCountMax == 0) {
|
if (VertexCountMax == 0) {
|
||||||
FirstVertex = Gfx::AllocateVertices(vtx, (PD::ptr)this);
|
FirstVertex = vpool.size();
|
||||||
|
vpool.Allocate(vtx);
|
||||||
VertexCountMax = vtx;
|
VertexCountMax = vtx;
|
||||||
} else {
|
} else {
|
||||||
Gfx::ExpandVertices(vtx, (PD::ptr)this);
|
if (vpool.size() == FirstVertex + VertexCountMax) {
|
||||||
VertexCountMax += vtx;
|
vpool.Allocate(vtx);
|
||||||
|
VertexCountMax += vtx;
|
||||||
|
} else {
|
||||||
|
size_t tmp = FirstVertex;
|
||||||
|
FirstVertex = vpool.size();
|
||||||
|
vpool.Allocate(VertexCountMax + vtx);
|
||||||
|
for (size_t i = 0; i < VertexCount; i++) {
|
||||||
|
vpool[FirstVertex + i] = vpool[tmp + i];
|
||||||
|
}
|
||||||
|
VertexCountMax += vtx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (IndexCountMax == 0) {
|
if (IndexCountMax == 0) {
|
||||||
FirstIndex = Gfx::AllocateIndices(idx, (PD::ptr)this);
|
FirstIndex = ipool.size();
|
||||||
|
ipool.Allocate(idx);
|
||||||
IndexCountMax = idx;
|
IndexCountMax = idx;
|
||||||
} else {
|
} else {
|
||||||
Gfx::ExpandIndices(idx, (PD::ptr)this);
|
if (ipool.size() == FirstIndex + IndexCountMax) {
|
||||||
IndexCountMax += idx;
|
ipool.Allocate(idx);
|
||||||
|
IndexCountMax += idx;
|
||||||
|
} else {
|
||||||
|
size_t tmp = FirstIndex;
|
||||||
|
FirstIndex = ipool.size();
|
||||||
|
ipool.Allocate(IndexCountMax + idx);
|
||||||
|
for (size_t i = 0; i < IndexCount; i++) {
|
||||||
|
ipool[FirstIndex + i] = ipool[tmp + i];
|
||||||
|
}
|
||||||
|
IndexCountMax += idx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,22 +59,25 @@ void Command::Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Command& Command::Add(const Vertex& vtx) {
|
Command& Command::Add(const Vertex& vtx) {
|
||||||
if (VertexCount <= VertexCountMax)
|
if (VertexCount < VertexCountMax) {
|
||||||
Gfx::PutVertex(FirstVertex + VertexCount++, vtx, (PD::ptr)this);
|
GetVertexPool()[FirstVertex + VertexCount++] = vtx;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Command& Command::Add(u16 idx) {
|
Command& Command::Add(u16 idx) {
|
||||||
if (IndexCount <= IndexCountMax)
|
if (IndexCount < IndexCountMax) {
|
||||||
Gfx::PutIndex(FirstIndex + IndexCount++, FirstVertex + VertexCount + idx,
|
GetIndexPool()[FirstIndex + IndexCount++] =
|
||||||
(PD::ptr)this);
|
static_cast<u16>(VertexCount + idx);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Command& Command::Add(u16 a, u16 b, u16 c) {
|
Command& Command::Add(u16 a, u16 b, u16 c) {
|
||||||
if (IndexCount + 3 <= IndexCountMax) {
|
if (IndexCount + 3 <= IndexCountMax) {
|
||||||
|
auto& ip = GetIndexPool();
|
||||||
size_t idx = FirstIndex + IndexCount;
|
size_t idx = FirstIndex + IndexCount;
|
||||||
Gfx::PutIndex(idx + 0, FirstVertex + VertexCount + a, (PD::ptr)this);
|
ip[idx + 0] = static_cast<u16>(VertexCount + a);
|
||||||
Gfx::PutIndex(idx + 1, FirstVertex + VertexCount + b, (PD::ptr)this);
|
ip[idx + 1] = static_cast<u16>(VertexCount + b);
|
||||||
Gfx::PutIndex(idx + 2, FirstVertex + VertexCount + c, (PD::ptr)this);
|
ip[idx + 2] = static_cast<u16>(VertexCount + c);
|
||||||
IndexCount += 3;
|
IndexCount += 3;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <pd/drivers/gfx.hpp>
|
#include <pd/drivers/gfx.hpp>
|
||||||
#include <pd/lithium/drawlist.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
@@ -19,19 +20,26 @@ PD_API void Drawlist::Copy(Drawlist& other) {
|
|||||||
pCommands.AppendCopy(other.pCommands);
|
pCommands.AppendCopy(other.pCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Optimize() {}
|
PD_API void Drawlist::Optimize() {
|
||||||
|
if (pCommands.size() <= 1) return;
|
||||||
|
std::stable_sort(pCommands.begin(), pCommands.end(),
|
||||||
|
[](const Command& a, const Command& b) {
|
||||||
|
if (a.Layer != b.Layer) return a.Layer < b.Layer;
|
||||||
|
if (a.SDF != b.SDF) return a.SDF < b.SDF;
|
||||||
|
return a.Tex < b.Tex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Clear() {
|
PD_API void Drawlist::Clear() {
|
||||||
UnbindTexture();
|
UnbindTexture();
|
||||||
pPath.ResetFast();
|
pPath.ResetFast();
|
||||||
pVertices.ResetFast();
|
pCommands.NoReset();
|
||||||
pIndices.ResetFast();
|
|
||||||
pCommands.ResetFast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Command Allocation */
|
/** Command Allocation */
|
||||||
PD_API Command& Drawlist::NewCommand() {
|
PD_API Command& Drawlist::NewCommand() {
|
||||||
auto cmd = pCommands.Allocate(1);
|
auto cmd = pCommands.Allocate(1);
|
||||||
|
cmd->Reset();
|
||||||
cmd->Tex = pCurrentTexture.GetID();
|
cmd->Tex = pCurrentTexture.GetID();
|
||||||
return *cmd;
|
return *cmd;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include <pd/lithium/pools.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Li {
|
||||||
|
static PD::Pool<Vertex> gVertexPool;
|
||||||
|
static PD::Pool<u16> gIndexPool;
|
||||||
|
|
||||||
|
PD_API PD::Pool<Vertex>& GetVertexPool() { return gVertexPool; }
|
||||||
|
PD_API PD::Pool<u16>& GetIndexPool() { return gIndexPool; }
|
||||||
|
|
||||||
|
PD_API void ResetPools() {
|
||||||
|
gVertexPool.NoReset();
|
||||||
|
gIndexPool.NoReset();
|
||||||
|
}
|
||||||
|
} // namespace Li
|
||||||
|
} // namespace PD
|
||||||
@@ -217,6 +217,7 @@ int main(int argc, char** argv) {
|
|||||||
PD::TT::Beg("MainRaw");
|
PD::TT::Beg("MainRaw");
|
||||||
PD::Hid::Update();
|
PD::Hid::Update();
|
||||||
PD::Gfx::NewFrame();
|
PD::Gfx::NewFrame();
|
||||||
|
PD::Li::ResetPools();
|
||||||
// app.Update(pOs->GetViewport(), pList);
|
// app.Update(pOs->GetViewport(), pList);
|
||||||
pList.SetFontscale(0.7);
|
pList.SetFontscale(0.7);
|
||||||
if (PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::CPLeft |
|
if (PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::CPLeft |
|
||||||
@@ -297,7 +298,6 @@ int main(int argc, char** argv) {
|
|||||||
"#ff00ff");
|
"#ff00ff");
|
||||||
}
|
}
|
||||||
pList.SetFont(&font);
|
pList.SetFont(&font);
|
||||||
#ifndef __3DS__
|
|
||||||
PD::TT::Beg("BuildUI7Menus");
|
PD::TT::Beg("BuildUI7Menus");
|
||||||
if (auto m = ui7.BeginMenu("Test")) {
|
if (auto m = ui7.BeginMenu("Test")) {
|
||||||
m->Label("Hello World!");
|
m->Label("Hello World!");
|
||||||
@@ -318,11 +318,10 @@ int main(int argc, char** argv) {
|
|||||||
PD::TT::Beg("UI7::Context::Update");
|
PD::TT::Beg("UI7::Context::Update");
|
||||||
ui7.Update();
|
ui7.Update();
|
||||||
PD::TT::End("UI7::Context::Update");
|
PD::TT::End("UI7::Context::Update");
|
||||||
#endif
|
|
||||||
PD::Gfx::Reset();
|
PD::Gfx::Reset();
|
||||||
PD::TT::Beg("PD::Gfx::Draw");
|
PD::TT::Beg("PD::Gfx::Draw");
|
||||||
PD::Gfx::Draw(pList);
|
|
||||||
PD::Gfx::Draw(ui7.GetDrawData());
|
PD::Gfx::Draw(ui7.GetDrawData());
|
||||||
|
PD::Gfx::Draw(pList);
|
||||||
PD::TT::End("PD::Gfx::Draw");
|
PD::TT::End("PD::Gfx::Draw");
|
||||||
pList.Clear();
|
pList.Clear();
|
||||||
PD::TT::End("MainRaw");
|
PD::TT::End("MainRaw");
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ void HorizonCtr::Init() {
|
|||||||
romfsInit();
|
romfsInit();
|
||||||
osSetSpeedupEnable(true);
|
osSetSpeedupEnable(true);
|
||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
consoleInit(GFX_BOTTOM, nullptr);
|
// consoleInit(GFX_BOTTOM, nullptr);
|
||||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||||
impl->Top =
|
impl->Top =
|
||||||
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||||
@@ -63,12 +63,12 @@ bool HorizonCtr::Mainloop() {
|
|||||||
pViewPort = ivec2(400, 240);
|
pViewPort = ivec2(400, 240);
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
bool _kill = hidKeysUp() & KEY_START;
|
bool _kill = hidKeysUp() & KEY_START;
|
||||||
|
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||||
return aptMainLoop() && !_kill;
|
return aptMainLoop() && !_kill;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizonCtr::ClearViewPort() {
|
void HorizonCtr::ClearViewPort() {
|
||||||
PD::Gfx::SetViewPort(pViewPort);
|
PD::Gfx::SetViewPort(pViewPort);
|
||||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
|
||||||
C3D_FrameDrawOn(impl->Top);
|
C3D_FrameDrawOn(impl->Top);
|
||||||
C3D_RenderTargetClear(impl->Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
|
C3D_RenderTargetClear(impl->Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user