From ee7129982f5a4462de046f19f89fda6992ec542a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 11 Jan 2024 22:59:26 +0100 Subject: [PATCH] fix some oversights in vertex buffer binding cache now buffers are only bound if needed --- BBGE/VertexBuffer.cpp | 94 ++++++++++++++++++++++--------------------- BBGE/VertexBuffer.h | 12 +++--- 2 files changed, 56 insertions(+), 50 deletions(-) diff --git a/BBGE/VertexBuffer.cpp b/BBGE/VertexBuffer.cpp index d2b5213..dc28df9 100644 --- a/BBGE/VertexBuffer.cpp +++ b/BBGE/VertexBuffer.cpp @@ -6,9 +6,8 @@ bool DynamicGPUBuffer::_HasARB = false; -static unsigned s_lastVertexBuffer = 0; -static unsigned s_lastIndexBuffer = 0; -static void *s_lastHostPtr = NULL; +static unsigned s_lastBuffer[GPUBUF_BINDING_MASK + 1]; // index via (usage & GPUBUF_BINDING_MASK) +static void *s_lastPtr = NULL; static BufDataType s_lastDataType = BufDataType(-1); static unsigned s_lastState = 0; // StateBits @@ -33,13 +32,14 @@ void DynamicGPUBuffer::StaticInit() DynamicGPUBuffer::DynamicGPUBuffer(unsigned usage) : _bufid(0) - , _binding((usage & GPUBUF_INDEXBUF) ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB) + , _gl_binding((usage & GPUBUF_INDEXBUF) ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB) , _size(0) , _h_cap(0) , _h_data(NULL) , _d_cap(0) , _d_map(NULL) - , _usage(toGlUsage(usage)) + , _gl_usage(toGlUsage(usage)) + , _usage(usage) , _datatype(BufDataType(-1)) { } @@ -51,8 +51,8 @@ DynamicGPUBuffer::~DynamicGPUBuffer() void* DynamicGPUBuffer::_allocBytes(size_t bytes) { - if(s_lastHostPtr == _h_data) - s_lastHostPtr = NULL; + if(s_lastPtr == _h_data) + s_lastPtr = NULL; void *p = realloc(_h_data, bytes); if(p) @@ -83,12 +83,18 @@ void* DynamicGPUBuffer::beginWrite(BufDataType type, size_t newsize, unsigned ac if(_HasARB) { - glBindBufferARB(_binding, _ensureDBuf()); + const unsigned id = _ensureDBuf(); + unsigned& last = s_lastBuffer[_usage & GPUBUF_BINDING_MASK]; + if(id != last) + { + last = id; + glBindBufferARB(_gl_binding, id); + } if(!(access & GPUACCESS_HOSTCOPY)) { _d_cap = newsize; - glBufferDataARB(_binding, newsize, NULL, _usage); // orphan buffer - void *p = glMapBufferARB(_binding, GL_WRITE_ONLY_ARB); + glBufferDataARB(_gl_binding, newsize, NULL, _gl_usage); // orphan buffer + void *p = glMapBufferARB(_gl_binding, GL_WRITE_ONLY_ARB); _d_map = p; if(p) return p; @@ -116,7 +122,7 @@ bool DynamicGPUBuffer::_commitWrite(size_t used) if(_d_map) { assert(used <= _d_cap); - bool ok = glUnmapBufferARB(_binding); // can fail + bool ok = glUnmapBufferARB(_gl_binding); // can fail if(ok) _d_map = NULL; return ok; @@ -126,11 +132,11 @@ bool DynamicGPUBuffer::_commitWrite(size_t used) assert(_h_data); assert(used <= _h_cap); if(used <= _d_cap) - glBufferSubDataARB(_binding, 0, used, _h_data); // update existing buffer + glBufferSubDataARB(_gl_binding, 0, used, _h_data); // update existing buffer else { _d_cap = used; - glBufferDataARB(_binding, used, _h_data, _usage); // alloc new buffer + glBufferDataARB(_gl_binding, used, _h_data, _gl_usage); // alloc new buffer } } // else nothing to do @@ -145,8 +151,14 @@ void DynamicGPUBuffer::upload(BufDataType type, const void* data, size_t size) if(_HasARB) { - glBindBufferARB(_binding, _ensureDBuf()); - glBufferDataARB(_binding, size, data, _usage); + const unsigned id = _ensureDBuf(); + unsigned& last = s_lastBuffer[_usage & GPUBUF_BINDING_MASK]; + if(id != last) + { + last = id; + glBindBufferARB(_gl_binding, id); + } + glBufferDataARB(_gl_binding, size, data, _gl_usage); } else memcpy(_ensureBytes(size), data, size); @@ -173,30 +185,22 @@ void DynamicGPUBuffer::apply(BufDataType usetype) const const unsigned bufid = this->_bufid; - void *p; - if(bufid) - { - p = NULL; - //if(bufid != s_lastVertexBuffer) - // glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufid); - } - else - { - p = (void*)this->_h_data; - //assert(p != s_lastHostPtr); // check that it's no redundant state change - //if(p == s_lastHostPtr && usetype == s_lastDataType) // don't need to check for datatype since that's const for the buffer with that ptr - // return; - } + void *p = bufid ? NULL : (void*)this->_h_data; assert(bufid || p); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufid); + if(bufid != s_lastBuffer[GPUBUF_VERTEXBUF]) + { + s_lastBuffer[GPUBUF_VERTEXBUF] = bufid; + glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufid); + } + else if(p == s_lastPtr && usetype == s_lastDataType) + return; - //if(bufid == s_lastVertexBuffer && usetype == s_lastDataType && p == s_lastHostPtr) - // return; + // --- something is different compared to last time, setup pointers --- s_lastDataType = usetype; - s_lastVertexBuffer = bufid; + s_lastPtr = p; unsigned u = usetype; // always want unsigned shifts assert((u & 0xf) < Countof(s_gltype)); @@ -242,16 +246,16 @@ unsigned DynamicGPUBuffer::_ensureDBuf() void DynamicGPUBuffer::dropBuffer() { - if(s_lastHostPtr == _h_data) - s_lastHostPtr = NULL; + if(s_lastPtr == _h_data) + s_lastPtr = NULL; free(_h_data); _h_data = NULL; if(_bufid) { - if(s_lastVertexBuffer == _bufid) - s_lastVertexBuffer = 0; - if(s_lastIndexBuffer == _bufid) - s_lastIndexBuffer = 0; + if(s_lastBuffer[GPUBUF_VERTEXBUF] == _bufid) + s_lastBuffer[GPUBUF_VERTEXBUF] = 0; + if(s_lastBuffer[GPUBUF_INDEXBUF] == _bufid) + s_lastBuffer[GPUBUF_INDEXBUF] = 0; glDeleteBuffersARB(1, &_bufid); _bufid = 0; @@ -268,17 +272,17 @@ void DynamicGPUBuffer::dropBuffer() void DynamicGPUBuffer::drawElements(unsigned glmode, size_t n, size_t first) const { - assert(_binding == GL_ELEMENT_ARRAY_BUFFER_ARB); + assert(_gl_binding == GL_ELEMENT_ARRAY_BUFFER_ARB); assert(s_gltype[_datatype & 0xf] == GL_SHORT); //assert(getBoundBuffer(GL_ARRAY_BUFFER_BINDING)); // FIXME: this assert is wrong if indices are on the host - unsigned id = _bufid; + const unsigned id = _bufid; - //if(s_lastIndexBuffer != id) - //{ - // s_lastIndexBuffer = id; + if(s_lastBuffer[GPUBUF_INDEXBUF] != id) + { + s_lastBuffer[GPUBUF_INDEXBUF] = id; glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, id); - //} + } const unsigned short *p = (unsigned short*)(id ? NULL : _h_data); assert(p || id); diff --git a/BBGE/VertexBuffer.h b/BBGE/VertexBuffer.h index c56cb56..ed39d32 100644 --- a/BBGE/VertexBuffer.h +++ b/BBGE/VertexBuffer.h @@ -7,12 +7,13 @@ struct TexCoordBox; enum BufUsage { - // usage - GPUBUF_DYNAMIC = 0x00, - GPUBUF_STATIC = 0x01, // binding point GPUBUF_VERTEXBUF = 0x00, - GPUBUF_INDEXBUF = 0x02 + GPUBUF_INDEXBUF = 0x01, + GPUBUF_BINDING_MASK = 0x01, + // usage + GPUBUF_DYNAMIC = 0x00, + GPUBUF_STATIC = 0x10 }; enum BufDataType @@ -87,12 +88,13 @@ private: bool _commitWrite(size_t used); unsigned _bufid; - unsigned _binding; + unsigned _gl_binding; size_t _size; size_t _h_cap; void *_h_data; size_t _d_cap; void *_d_map; + const unsigned _gl_usage; const unsigned _usage; BufDataType _datatype;