1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-06 17:41:04 +00:00

Replace data structure for HW buffer book-keeping

before
  time in endScene ÷ num hw buf ________________  199x   0.128
after
  time in endScene ÷ num hw buf ________________  199x   0.057
This commit is contained in:
sfan5 2024-12-28 14:39:54 +01:00
parent a2058f7f3a
commit 40afc84597
4 changed files with 46 additions and 40 deletions

View file

@ -218,7 +218,7 @@ bool CNullDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u
bool CNullDriver::endScene() bool CNullDriver::endScene()
{ {
FPSCounter.registerFrame(os::Timer::getRealTime()); FPSCounter.registerFrame(os::Timer::getRealTime());
updateAllHardwareBuffers(); expireHardwareBuffers();
updateAllOcclusionQueries(); updateAllOcclusionQueries();
return true; return true;
} }
@ -1141,25 +1141,28 @@ CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IIndexBuffer
return createHardwareBuffer(ib); // no hardware links, and mesh wants one, create it return createHardwareBuffer(ib); // no hardware links, and mesh wants one, create it
} }
//! Update all hardware buffers, remove unused ones void CNullDriver::registerHardwareBuffer(SHWBufferLink *HWBuffer)
void CNullDriver::updateAllHardwareBuffers()
{ {
// FIXME: this method can take a lot of time just doing the refcount _IRR_DEBUG_BREAK_IF(!HWBuffer)
// checks and iteration (too much pointer chasing?) for HWBuffer->ListPosition = HWBufferList.size();
// large buffer counts (e.g. 50000) HWBufferList.push_back(HWBuffer);
}
auto it = HWBufferList.begin(); void CNullDriver::expireHardwareBuffers()
while (it != HWBufferList.end()) { {
SHWBufferLink *Link = *it; for (size_t i = 0; i < HWBufferList.size(); ) {
++it; auto *Link = HWBufferList[i];
if (Link->IsVertex) { bool del;
if (!Link->VertexBuffer || Link->VertexBuffer->getReferenceCount() == 1) if (Link->IsVertex)
deleteHardwareBuffer(Link); del = !Link->VertexBuffer || Link->VertexBuffer->getReferenceCount() == 1;
} else { else
if (!Link->IndexBuffer || Link->IndexBuffer->getReferenceCount() == 1) del = !Link->IndexBuffer || Link->IndexBuffer->getReferenceCount() == 1;
deleteHardwareBuffer(Link); // deleting can reorder, so don't advance in list
} if (del)
deleteHardwareBuffer(Link);
else
i++;
} }
FrameStats.HWBuffersActive = HWBufferList.size(); FrameStats.HWBuffersActive = HWBufferList.size();
@ -1169,7 +1172,16 @@ void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer)
{ {
if (!HWBuffer) if (!HWBuffer)
return; return;
HWBufferList.erase(HWBuffer->listPosition); const size_t pos = HWBuffer->ListPosition;
_IRR_DEBUG_BREAK_IF(HWBufferList.at(pos) != HWBuffer)
if (HWBufferList.size() < 2 || pos == HWBufferList.size() - 1) {
HWBufferList.erase(HWBufferList.begin() + pos);
} else {
// swap with last
std::swap(HWBufferList[pos], HWBufferList.back());
HWBufferList.pop_back();
HWBufferList[pos]->ListPosition = pos;
}
delete HWBuffer; delete HWBuffer;
} }

View file

@ -17,7 +17,6 @@
#include "S3DVertex.h" #include "S3DVertex.h"
#include "SVertexIndex.h" #include "SVertexIndex.h"
#include "SExposedVideoData.h" #include "SExposedVideoData.h"
#include <list>
namespace irr namespace irr
{ {
@ -293,7 +292,7 @@ protected:
struct SHWBufferLink struct SHWBufferLink
{ {
SHWBufferLink(const scene::IVertexBuffer *vb) : SHWBufferLink(const scene::IVertexBuffer *vb) :
VertexBuffer(vb), ChangedID(0), IsVertex(true) VertexBuffer(vb), IsVertex(true)
{ {
if (VertexBuffer) { if (VertexBuffer) {
VertexBuffer->grab(); VertexBuffer->grab();
@ -301,7 +300,7 @@ protected:
} }
} }
SHWBufferLink(const scene::IIndexBuffer *ib) : SHWBufferLink(const scene::IIndexBuffer *ib) :
IndexBuffer(ib), ChangedID(0), IsVertex(false) IndexBuffer(ib), IsVertex(false)
{ {
if (IndexBuffer) { if (IndexBuffer) {
IndexBuffer->grab(); IndexBuffer->grab();
@ -324,9 +323,9 @@ protected:
const scene::IVertexBuffer *VertexBuffer; const scene::IVertexBuffer *VertexBuffer;
const scene::IIndexBuffer *IndexBuffer; const scene::IIndexBuffer *IndexBuffer;
}; };
u32 ChangedID; size_t ListPosition = static_cast<size_t>(-1);
u32 ChangedID = 0;
bool IsVertex; bool IsVertex;
std::list<SHWBufferLink*>::iterator listPosition;
}; };
//! Gets hardware buffer link from a vertex buffer (may create or update buffer) //! Gets hardware buffer link from a vertex buffer (may create or update buffer)
@ -361,8 +360,8 @@ public:
//! Remove all hardware buffers //! Remove all hardware buffers
void removeAllHardwareBuffers() override; void removeAllHardwareBuffers() override;
//! Update all hardware buffers, remove unused ones //! Run garbage-collection on all HW buffers
virtual void updateAllHardwareBuffers(); void expireHardwareBuffers();
//! is vbo recommended? //! is vbo recommended?
virtual bool isHardwareBufferRecommend(const scene::IVertexBuffer *mb); virtual bool isHardwareBufferRecommend(const scene::IVertexBuffer *mb);
@ -582,6 +581,9 @@ protected:
//! deletes all material renderers //! deletes all material renderers
void deleteMaterialRenders(); void deleteMaterialRenders();
// adds a created hardware buffer to the relevant data structure
void registerHardwareBuffer(SHWBufferLink *HWBuffer);
// prints renderer version // prints renderer version
void printVersion(); void printVersion();
@ -705,7 +707,7 @@ protected:
core::array<video::IImageWriter *> SurfaceWriter; core::array<video::IImageWriter *> SurfaceWriter;
core::array<SMaterialRenderer> MaterialRenderers; core::array<SMaterialRenderer> MaterialRenderers;
std::list<SHWBufferLink *> HWBufferList; std::vector<SHWBufferLink *> HWBufferList;
io::IFileSystem *FileSystem; io::IFileSystem *FileSystem;

View file

@ -430,9 +430,7 @@ COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::I
return 0; return 0;
SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(vb); SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(vb);
registerHardwareBuffer(HWBuffer);
// add to map
HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);
if (!updateVertexHardwareBuffer(HWBuffer)) { if (!updateVertexHardwareBuffer(HWBuffer)) {
deleteHardwareBuffer(HWBuffer); deleteHardwareBuffer(HWBuffer);
@ -453,9 +451,7 @@ COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::I
return 0; return 0;
SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(ib); SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(ib);
registerHardwareBuffer(HWBuffer);
// add to map
HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);
if (!updateIndexHardwareBuffer(HWBuffer)) { if (!updateIndexHardwareBuffer(HWBuffer)) {
deleteHardwareBuffer(HWBuffer); deleteHardwareBuffer(HWBuffer);

View file

@ -566,10 +566,8 @@ COpenGL3DriverBase::SHWBufferLink *COpenGL3DriverBase::createHardwareBuffer(cons
if (!vb || vb->getHardwareMappingHint() == scene::EHM_NEVER) if (!vb || vb->getHardwareMappingHint() == scene::EHM_NEVER)
return 0; return 0;
SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(vb); auto *HWBuffer = new SHWBufferLink_opengl(vb);
registerHardwareBuffer(HWBuffer);
// add to map
HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);
if (!updateVertexHardwareBuffer(HWBuffer)) { if (!updateVertexHardwareBuffer(HWBuffer)) {
deleteHardwareBuffer(HWBuffer); deleteHardwareBuffer(HWBuffer);
@ -584,10 +582,8 @@ COpenGL3DriverBase::SHWBufferLink *COpenGL3DriverBase::createHardwareBuffer(cons
if (!ib || ib->getHardwareMappingHint() == scene::EHM_NEVER) if (!ib || ib->getHardwareMappingHint() == scene::EHM_NEVER)
return 0; return 0;
SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(ib); auto *HWBuffer = new SHWBufferLink_opengl(ib);
registerHardwareBuffer(HWBuffer);
// add to map
HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);
if (!updateIndexHardwareBuffer(HWBuffer)) { if (!updateIndexHardwareBuffer(HWBuffer)) {
deleteHardwareBuffer(HWBuffer); deleteHardwareBuffer(HWBuffer);