Fixed VAO cache.
This commit is contained in:
parent
b1cb4de638
commit
e866a7b2e3
@ -720,6 +720,8 @@ namespace bgfx
|
|||||||
{
|
{
|
||||||
GL_CHECK(glUseProgram(0) );
|
GL_CHECK(glUseProgram(0) );
|
||||||
GL_CHECK(glDeleteProgram(m_id) );
|
GL_CHECK(glDeleteProgram(m_id) );
|
||||||
|
|
||||||
|
m_vcref.invalidate(s_renderCtx.m_vaoCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::init()
|
void Program::init()
|
||||||
@ -917,6 +919,22 @@ namespace bgfx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IndexBuffer::destroy()
|
||||||
|
{
|
||||||
|
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
|
||||||
|
GL_CHECK(glDeleteBuffers(1, &m_id) );
|
||||||
|
|
||||||
|
m_vcref.invalidate(s_renderCtx.m_vaoCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VertexBuffer::destroy()
|
||||||
|
{
|
||||||
|
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
||||||
|
GL_CHECK(glDeleteBuffers(1, &m_id) );
|
||||||
|
|
||||||
|
m_vcref.invalidate(s_renderCtx.m_vaoCache);
|
||||||
|
}
|
||||||
|
|
||||||
static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _pixels)
|
static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _pixels)
|
||||||
{
|
{
|
||||||
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||||
@ -1829,7 +1847,7 @@ namespace bgfx
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !BGFX_CONFIG_RENDERER_OPENGLES3
|
#if !BGFX_CONFIG_RENDERER_OPENGLES3
|
||||||
if (NULL != glVertexAttribDivisor
|
if (false && NULL != glVertexAttribDivisor
|
||||||
&& NULL != glDrawArraysInstanced
|
&& NULL != glDrawArraysInstanced
|
||||||
&& NULL != glDrawElementsInstanced)
|
&& NULL != glDrawElementsInstanced)
|
||||||
{
|
{
|
||||||
@ -1995,6 +2013,13 @@ namespace bgfx
|
|||||||
|
|
||||||
void Context::rendererSubmit()
|
void Context::rendererSubmit()
|
||||||
{
|
{
|
||||||
|
if (s_renderCtx.m_vaoSupport)
|
||||||
|
{
|
||||||
|
GL_CHECK(glBindVertexArray(0) );
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
|
||||||
|
|
||||||
s_renderCtx.updateResolution(m_render->m_resolution);
|
s_renderCtx.updateResolution(m_render->m_resolution);
|
||||||
|
|
||||||
int64_t elapsed = -bx::getHPCounter();
|
int64_t elapsed = -bx::getHPCounter();
|
||||||
@ -2041,8 +2066,7 @@ namespace bgfx
|
|||||||
GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
|
GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
|
||||||
uint32_t primNumVerts = 3;
|
uint32_t primNumVerts = 3;
|
||||||
uint32_t baseVertex = 0;
|
uint32_t baseVertex = 0;
|
||||||
|
GLuint currentVao = 0;
|
||||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
|
|
||||||
|
|
||||||
uint32_t statsNumPrimsSubmitted = 0;
|
uint32_t statsNumPrimsSubmitted = 0;
|
||||||
uint32_t statsNumIndices = 0;
|
uint32_t statsNumIndices = 0;
|
||||||
@ -2504,19 +2528,22 @@ namespace bgfx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_renderCtx.m_vaoSupport)
|
if (s_renderCtx.m_vaoSupport
|
||||||
|
&& 0 == state.m_startVertex
|
||||||
|
&& 0 == state.m_instanceDataOffset)
|
||||||
{
|
{
|
||||||
if (programChanged
|
if (programChanged
|
||||||
|| currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx
|
|| currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx
|
||||||
|| baseVertex != state.m_startVertex
|
|| currentState.m_indexBuffer.idx != state.m_indexBuffer.idx
|
||||||
|| currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
|
|| currentState.m_instanceDataBuffer.idx != state.m_instanceDataBuffer.idx)
|
||||||
{
|
{
|
||||||
uint64_t hash = (uint64_t(state.m_vertexBuffer.idx)<<48)
|
bx::HashMurmur2A murmur;
|
||||||
| (uint64_t(state.m_indexBuffer.idx)<<32)
|
murmur.begin();
|
||||||
| (uint64_t(state.m_instanceDataBuffer.idx)<<16)
|
murmur.add(state.m_vertexBuffer.idx);
|
||||||
| programIdx
|
murmur.add(state.m_indexBuffer.idx);
|
||||||
;
|
murmur.add(state.m_instanceDataBuffer.idx);
|
||||||
hash ^= state.m_startVertex;
|
murmur.add(programIdx);
|
||||||
|
uint32_t hash = murmur.end();
|
||||||
|
|
||||||
currentState.m_vertexBuffer = state.m_vertexBuffer;
|
currentState.m_vertexBuffer = state.m_vertexBuffer;
|
||||||
currentState.m_indexBuffer = state.m_indexBuffer;
|
currentState.m_indexBuffer = state.m_indexBuffer;
|
||||||
@ -2525,25 +2552,32 @@ namespace bgfx
|
|||||||
GLuint id = s_renderCtx.m_vaoCache.find(hash);
|
GLuint id = s_renderCtx.m_vaoCache.find(hash);
|
||||||
if (UINT32_MAX != id)
|
if (UINT32_MAX != id)
|
||||||
{
|
{
|
||||||
|
currentVao = id;
|
||||||
GL_CHECK(glBindVertexArray(id) );
|
GL_CHECK(glBindVertexArray(id) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id = s_renderCtx.m_vaoCache.add(hash);
|
id = s_renderCtx.m_vaoCache.add(hash);
|
||||||
|
currentVao = id;
|
||||||
GL_CHECK(glBindVertexArray(id) );
|
GL_CHECK(glBindVertexArray(id) );
|
||||||
|
|
||||||
|
Program& program = s_renderCtx.m_program[programIdx];
|
||||||
|
program.add(hash);
|
||||||
|
|
||||||
if (invalidHandle != state.m_vertexBuffer.idx)
|
if (invalidHandle != state.m_vertexBuffer.idx)
|
||||||
{
|
{
|
||||||
VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
|
VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
|
||||||
|
vb.add(hash);
|
||||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
|
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
|
||||||
|
|
||||||
uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
|
uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
|
||||||
const Program& program = s_renderCtx.m_program[programIdx];
|
|
||||||
program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
|
program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
|
||||||
|
|
||||||
if (invalidHandle != state.m_instanceDataBuffer.idx)
|
if (invalidHandle != state.m_instanceDataBuffer.idx)
|
||||||
{
|
{
|
||||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
|
VertexBuffer& instanceVb = s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx];
|
||||||
|
instanceVb.add(hash);
|
||||||
|
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, instanceVb.m_id) );
|
||||||
program.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
|
program.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2555,6 +2589,7 @@ namespace bgfx
|
|||||||
if (invalidHandle != state.m_indexBuffer.idx)
|
if (invalidHandle != state.m_indexBuffer.idx)
|
||||||
{
|
{
|
||||||
IndexBuffer& ib = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx];
|
IndexBuffer& ib = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx];
|
||||||
|
ib.add(hash);
|
||||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
|
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2566,6 +2601,16 @@ namespace bgfx
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (s_renderCtx.m_vaoSupport
|
||||||
|
&& 0 != currentVao)
|
||||||
|
{
|
||||||
|
GL_CHECK(glBindVertexArray(0) );
|
||||||
|
currentState.m_vertexBuffer.idx = invalidHandle;
|
||||||
|
currentState.m_indexBuffer.idx = invalidHandle;
|
||||||
|
bindAttribs = true;
|
||||||
|
currentVao = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (programChanged
|
if (programChanged
|
||||||
|| currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx)
|
|| currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +178,8 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
|
|||||||
# define glClearDepth glClearDepthf
|
# define glClearDepth glClearDepthf
|
||||||
#endif // !BGFX_CONFIG_RENDERER_OPENGL
|
#endif // !BGFX_CONFIG_RENDERER_OPENGL
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace bgfx
|
namespace bgfx
|
||||||
{
|
{
|
||||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORBGFXPROC)(GLuint _index, GLuint _divisor);
|
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORBGFXPROC)(GLuint _index, GLuint _divisor);
|
||||||
@ -229,6 +231,82 @@ namespace bgfx
|
|||||||
|
|
||||||
class ConstantBuffer;
|
class ConstantBuffer;
|
||||||
|
|
||||||
|
class VaoCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLuint add(uint32_t _hash)
|
||||||
|
{
|
||||||
|
invalidate(_hash);
|
||||||
|
|
||||||
|
GLuint arrayId;
|
||||||
|
GL_CHECK(glGenVertexArrays(1, &arrayId) );
|
||||||
|
|
||||||
|
m_hashMap.insert(stl::make_pair(_hash, arrayId) );
|
||||||
|
|
||||||
|
return arrayId;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint find(uint32_t _hash)
|
||||||
|
{
|
||||||
|
HashMap::iterator it = m_hashMap.find(_hash);
|
||||||
|
if (it != m_hashMap.end() )
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate(uint32_t _hash)
|
||||||
|
{
|
||||||
|
GL_CHECK(glBindVertexArray(0) );
|
||||||
|
|
||||||
|
HashMap::iterator it = m_hashMap.find(_hash);
|
||||||
|
if (it != m_hashMap.end() )
|
||||||
|
{
|
||||||
|
GL_CHECK(glDeleteVertexArrays(1, &it->second) );
|
||||||
|
m_hashMap.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
GL_CHECK(glBindVertexArray(0) );
|
||||||
|
|
||||||
|
for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
GL_CHECK(glDeleteVertexArrays(1, &it->second) );
|
||||||
|
}
|
||||||
|
m_hashMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef stl::unordered_map<uint32_t, GLuint> HashMap;
|
||||||
|
HashMap m_hashMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VaoCacheRef
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void add(uint32_t _hash)
|
||||||
|
{
|
||||||
|
m_vaoSet.insert(_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate(VaoCache& _vaoCache)
|
||||||
|
{
|
||||||
|
for (VaoSet::iterator it = m_vaoSet.begin(), itEnd = m_vaoSet.end(); it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
_vaoCache.invalidate(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vaoSet.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef stl::set<uint32_t> VaoSet;
|
||||||
|
VaoSet m_vaoSet;
|
||||||
|
};
|
||||||
|
|
||||||
struct IndexBuffer
|
struct IndexBuffer
|
||||||
{
|
{
|
||||||
void create(uint32_t _size, void* _data)
|
void create(uint32_t _size, void* _data)
|
||||||
@ -257,14 +335,16 @@ namespace bgfx
|
|||||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
|
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy()
|
void destroy();
|
||||||
|
|
||||||
|
void add(uint32_t _hash)
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
m_vcref.add(_hash);
|
||||||
glDeleteBuffers(1, &m_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint m_id;
|
GLuint m_id;
|
||||||
uint32_t m_size;
|
uint32_t m_size;
|
||||||
|
VaoCacheRef m_vcref;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexBuffer
|
struct VertexBuffer
|
||||||
@ -296,65 +376,17 @@ namespace bgfx
|
|||||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy()
|
void destroy();
|
||||||
|
|
||||||
|
void add(uint32_t _hash)
|
||||||
{
|
{
|
||||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
m_vcref.add(_hash);
|
||||||
GL_CHECK(glDeleteBuffers(1, &m_id) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint m_id;
|
GLuint m_id;
|
||||||
uint32_t m_size;
|
uint32_t m_size;
|
||||||
VertexDeclHandle m_decl;
|
VertexDeclHandle m_decl;
|
||||||
};
|
VaoCacheRef m_vcref;
|
||||||
|
|
||||||
class VaoCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GLuint add(uint64_t _hash)
|
|
||||||
{
|
|
||||||
invalidate(_hash);
|
|
||||||
|
|
||||||
GLuint arrayId;
|
|
||||||
GL_CHECK(glGenVertexArrays(1, &arrayId) );
|
|
||||||
|
|
||||||
m_hashMap.insert(stl::make_pair(_hash, arrayId) );
|
|
||||||
|
|
||||||
return arrayId;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint find(uint64_t _hash)
|
|
||||||
{
|
|
||||||
HashMap::iterator it = m_hashMap.find(_hash);
|
|
||||||
if (it != m_hashMap.end() )
|
|
||||||
{
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalidate(uint64_t _hash)
|
|
||||||
{
|
|
||||||
HashMap::iterator it = m_hashMap.find(_hash);
|
|
||||||
if (it != m_hashMap.end() )
|
|
||||||
{
|
|
||||||
GL_CHECK(glDeleteVertexArrays(1, &it->second) );
|
|
||||||
m_hashMap.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalidate()
|
|
||||||
{
|
|
||||||
for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
|
|
||||||
{
|
|
||||||
GL_CHECK(glDeleteVertexArrays(1, &it->second) );
|
|
||||||
}
|
|
||||||
m_hashMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef stl::unordered_map<uint64_t, GLuint> HashMap;
|
|
||||||
HashMap m_hashMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture
|
struct Texture
|
||||||
@ -456,6 +488,11 @@ namespace bgfx
|
|||||||
m_constantBuffer->commit();
|
m_constantBuffer->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add(uint32_t _hash)
|
||||||
|
{
|
||||||
|
m_vcref.add(_hash);
|
||||||
|
}
|
||||||
|
|
||||||
GLuint m_id;
|
GLuint m_id;
|
||||||
|
|
||||||
uint8_t m_used[Attrib::Count+1]; // dense
|
uint8_t m_used[Attrib::Count+1]; // dense
|
||||||
@ -468,6 +505,7 @@ namespace bgfx
|
|||||||
ConstantBuffer* m_constantBuffer;
|
ConstantBuffer* m_constantBuffer;
|
||||||
PredefinedUniform m_predefined[PredefinedUniform::Count];
|
PredefinedUniform m_predefined[PredefinedUniform::Count];
|
||||||
uint8_t m_numPredefined;
|
uint8_t m_numPredefined;
|
||||||
|
VaoCacheRef m_vcref;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||||
|
Loading…
Reference in New Issue
Block a user