mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-05-10 19:13:44 +00:00
fix some oversights in vertex buffer binding cache
now buffers are only bound if needed
This commit is contained in:
parent
5dccefffc0
commit
ee7129982f
2 changed files with 56 additions and 50 deletions
|
@ -6,9 +6,8 @@
|
||||||
|
|
||||||
bool DynamicGPUBuffer::_HasARB = false;
|
bool DynamicGPUBuffer::_HasARB = false;
|
||||||
|
|
||||||
static unsigned s_lastVertexBuffer = 0;
|
static unsigned s_lastBuffer[GPUBUF_BINDING_MASK + 1]; // index via (usage & GPUBUF_BINDING_MASK)
|
||||||
static unsigned s_lastIndexBuffer = 0;
|
static void *s_lastPtr = NULL;
|
||||||
static void *s_lastHostPtr = NULL;
|
|
||||||
static BufDataType s_lastDataType = BufDataType(-1);
|
static BufDataType s_lastDataType = BufDataType(-1);
|
||||||
static unsigned s_lastState = 0; // StateBits
|
static unsigned s_lastState = 0; // StateBits
|
||||||
|
|
||||||
|
@ -33,13 +32,14 @@ void DynamicGPUBuffer::StaticInit()
|
||||||
|
|
||||||
DynamicGPUBuffer::DynamicGPUBuffer(unsigned usage)
|
DynamicGPUBuffer::DynamicGPUBuffer(unsigned usage)
|
||||||
: _bufid(0)
|
: _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)
|
, _size(0)
|
||||||
, _h_cap(0)
|
, _h_cap(0)
|
||||||
, _h_data(NULL)
|
, _h_data(NULL)
|
||||||
, _d_cap(0)
|
, _d_cap(0)
|
||||||
, _d_map(NULL)
|
, _d_map(NULL)
|
||||||
, _usage(toGlUsage(usage))
|
, _gl_usage(toGlUsage(usage))
|
||||||
|
, _usage(usage)
|
||||||
, _datatype(BufDataType(-1))
|
, _datatype(BufDataType(-1))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ DynamicGPUBuffer::~DynamicGPUBuffer()
|
||||||
|
|
||||||
void* DynamicGPUBuffer::_allocBytes(size_t bytes)
|
void* DynamicGPUBuffer::_allocBytes(size_t bytes)
|
||||||
{
|
{
|
||||||
if(s_lastHostPtr == _h_data)
|
if(s_lastPtr == _h_data)
|
||||||
s_lastHostPtr = NULL;
|
s_lastPtr = NULL;
|
||||||
|
|
||||||
void *p = realloc(_h_data, bytes);
|
void *p = realloc(_h_data, bytes);
|
||||||
if(p)
|
if(p)
|
||||||
|
@ -83,12 +83,18 @@ void* DynamicGPUBuffer::beginWrite(BufDataType type, size_t newsize, unsigned ac
|
||||||
|
|
||||||
if(_HasARB)
|
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))
|
if(!(access & GPUACCESS_HOSTCOPY))
|
||||||
{
|
{
|
||||||
_d_cap = newsize;
|
_d_cap = newsize;
|
||||||
glBufferDataARB(_binding, newsize, NULL, _usage); // orphan buffer
|
glBufferDataARB(_gl_binding, newsize, NULL, _gl_usage); // orphan buffer
|
||||||
void *p = glMapBufferARB(_binding, GL_WRITE_ONLY_ARB);
|
void *p = glMapBufferARB(_gl_binding, GL_WRITE_ONLY_ARB);
|
||||||
_d_map = p;
|
_d_map = p;
|
||||||
if(p)
|
if(p)
|
||||||
return p;
|
return p;
|
||||||
|
@ -116,7 +122,7 @@ bool DynamicGPUBuffer::_commitWrite(size_t used)
|
||||||
if(_d_map)
|
if(_d_map)
|
||||||
{
|
{
|
||||||
assert(used <= _d_cap);
|
assert(used <= _d_cap);
|
||||||
bool ok = glUnmapBufferARB(_binding); // can fail
|
bool ok = glUnmapBufferARB(_gl_binding); // can fail
|
||||||
if(ok)
|
if(ok)
|
||||||
_d_map = NULL;
|
_d_map = NULL;
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -126,11 +132,11 @@ bool DynamicGPUBuffer::_commitWrite(size_t used)
|
||||||
assert(_h_data);
|
assert(_h_data);
|
||||||
assert(used <= _h_cap);
|
assert(used <= _h_cap);
|
||||||
if(used <= _d_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
|
else
|
||||||
{
|
{
|
||||||
_d_cap = used;
|
_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
|
// else nothing to do
|
||||||
|
@ -145,8 +151,14 @@ void DynamicGPUBuffer::upload(BufDataType type, const void* data, size_t size)
|
||||||
|
|
||||||
if(_HasARB)
|
if(_HasARB)
|
||||||
{
|
{
|
||||||
glBindBufferARB(_binding, _ensureDBuf());
|
const unsigned id = _ensureDBuf();
|
||||||
glBufferDataARB(_binding, size, data, _usage);
|
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
|
else
|
||||||
memcpy(_ensureBytes(size), data, size);
|
memcpy(_ensureBytes(size), data, size);
|
||||||
|
@ -173,30 +185,22 @@ void DynamicGPUBuffer::apply(BufDataType usetype) const
|
||||||
|
|
||||||
const unsigned bufid = this->_bufid;
|
const unsigned bufid = this->_bufid;
|
||||||
|
|
||||||
void *p;
|
void *p = bufid ? NULL : (void*)this->_h_data;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(bufid || p);
|
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)
|
// --- something is different compared to last time, setup pointers ---
|
||||||
// return;
|
|
||||||
|
|
||||||
s_lastDataType = usetype;
|
s_lastDataType = usetype;
|
||||||
s_lastVertexBuffer = bufid;
|
s_lastPtr = p;
|
||||||
|
|
||||||
unsigned u = usetype; // always want unsigned shifts
|
unsigned u = usetype; // always want unsigned shifts
|
||||||
assert((u & 0xf) < Countof(s_gltype));
|
assert((u & 0xf) < Countof(s_gltype));
|
||||||
|
@ -242,16 +246,16 @@ unsigned DynamicGPUBuffer::_ensureDBuf()
|
||||||
|
|
||||||
void DynamicGPUBuffer::dropBuffer()
|
void DynamicGPUBuffer::dropBuffer()
|
||||||
{
|
{
|
||||||
if(s_lastHostPtr == _h_data)
|
if(s_lastPtr == _h_data)
|
||||||
s_lastHostPtr = NULL;
|
s_lastPtr = NULL;
|
||||||
free(_h_data);
|
free(_h_data);
|
||||||
_h_data = NULL;
|
_h_data = NULL;
|
||||||
if(_bufid)
|
if(_bufid)
|
||||||
{
|
{
|
||||||
if(s_lastVertexBuffer == _bufid)
|
if(s_lastBuffer[GPUBUF_VERTEXBUF] == _bufid)
|
||||||
s_lastVertexBuffer = 0;
|
s_lastBuffer[GPUBUF_VERTEXBUF] = 0;
|
||||||
if(s_lastIndexBuffer == _bufid)
|
if(s_lastBuffer[GPUBUF_INDEXBUF] == _bufid)
|
||||||
s_lastIndexBuffer = 0;
|
s_lastBuffer[GPUBUF_INDEXBUF] = 0;
|
||||||
|
|
||||||
glDeleteBuffersARB(1, &_bufid);
|
glDeleteBuffersARB(1, &_bufid);
|
||||||
_bufid = 0;
|
_bufid = 0;
|
||||||
|
@ -268,17 +272,17 @@ void DynamicGPUBuffer::dropBuffer()
|
||||||
|
|
||||||
void DynamicGPUBuffer::drawElements(unsigned glmode, size_t n, size_t first) const
|
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(s_gltype[_datatype & 0xf] == GL_SHORT);
|
||||||
//assert(getBoundBuffer(GL_ARRAY_BUFFER_BINDING)); // FIXME: this assert is wrong if indices are on the host
|
//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)
|
if(s_lastBuffer[GPUBUF_INDEXBUF] != id)
|
||||||
//{
|
{
|
||||||
// s_lastIndexBuffer = id;
|
s_lastBuffer[GPUBUF_INDEXBUF] = id;
|
||||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, id);
|
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, id);
|
||||||
//}
|
}
|
||||||
|
|
||||||
const unsigned short *p = (unsigned short*)(id ? NULL : _h_data);
|
const unsigned short *p = (unsigned short*)(id ? NULL : _h_data);
|
||||||
assert(p || id);
|
assert(p || id);
|
||||||
|
|
|
@ -7,12 +7,13 @@ struct TexCoordBox;
|
||||||
|
|
||||||
enum BufUsage
|
enum BufUsage
|
||||||
{
|
{
|
||||||
// usage
|
|
||||||
GPUBUF_DYNAMIC = 0x00,
|
|
||||||
GPUBUF_STATIC = 0x01,
|
|
||||||
// binding point
|
// binding point
|
||||||
GPUBUF_VERTEXBUF = 0x00,
|
GPUBUF_VERTEXBUF = 0x00,
|
||||||
GPUBUF_INDEXBUF = 0x02
|
GPUBUF_INDEXBUF = 0x01,
|
||||||
|
GPUBUF_BINDING_MASK = 0x01,
|
||||||
|
// usage
|
||||||
|
GPUBUF_DYNAMIC = 0x00,
|
||||||
|
GPUBUF_STATIC = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BufDataType
|
enum BufDataType
|
||||||
|
@ -87,12 +88,13 @@ private:
|
||||||
bool _commitWrite(size_t used);
|
bool _commitWrite(size_t used);
|
||||||
|
|
||||||
unsigned _bufid;
|
unsigned _bufid;
|
||||||
unsigned _binding;
|
unsigned _gl_binding;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
size_t _h_cap;
|
size_t _h_cap;
|
||||||
void *_h_data;
|
void *_h_data;
|
||||||
size_t _d_cap;
|
size_t _d_cap;
|
||||||
void *_d_map;
|
void *_d_map;
|
||||||
|
const unsigned _gl_usage;
|
||||||
const unsigned _usage;
|
const unsigned _usage;
|
||||||
BufDataType _datatype;
|
BufDataType _datatype;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue