Proper dynamic buffer sync

This commit is contained in:
Jack Andersen 2015-11-29 16:37:46 -10:00
parent 5843840411
commit 66c2cbdf14
1 changed files with 60 additions and 56 deletions

View File

@ -5,6 +5,7 @@
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <array>
#include <LogVisor/LogVisor.hpp> #include <LogVisor/LogVisor.hpp>
@ -79,9 +80,9 @@ public:
void* map(size_t sz); void* map(size_t sz);
void unmap(); void unmap();
void bindVertex() const; void bindVertex(int b) const;
void bindIndex() const; void bindIndex(int b) const;
void bindUniform(size_t idx) const; void bindUniform(size_t idx, int b) const;
}; };
IGraphicsBufferS* IGraphicsBufferS*
@ -445,13 +446,13 @@ IShaderPipeline* GLDataFactory::newShaderPipeline
struct GLVertexFormat : IVertexFormat struct GLVertexFormat : IVertexFormat
{ {
GLCommandQueue* m_q; GLCommandQueue* m_q;
GLuint m_vao = 0; GLuint m_vao[3] = {};
size_t m_elementCount; size_t m_elementCount;
std::unique_ptr<VertexElementDescriptor[]> m_elements; std::unique_ptr<VertexElementDescriptor[]> m_elements;
GLVertexFormat(GLCommandQueue* q, size_t elementCount, GLVertexFormat(GLCommandQueue* q, size_t elementCount,
const VertexElementDescriptor* elements); const VertexElementDescriptor* elements);
~GLVertexFormat(); ~GLVertexFormat();
void bind() const {glBindVertexArray(m_vao);} void bind(int idx) const {glBindVertexArray(m_vao[idx]);}
}; };
struct GLShaderDataBinding : IShaderDataBinding struct GLShaderDataBinding : IShaderDataBinding
@ -478,15 +479,15 @@ struct GLShaderDataBinding : IShaderDataBinding
for (size_t i=0 ; i<texCount ; ++i) for (size_t i=0 ; i<texCount ; ++i)
m_texs[i] = texs[i]; m_texs[i] = texs[i];
} }
void bind() const void bind(int b) const
{ {
GLuint prog = m_pipeline->bind(); GLuint prog = m_pipeline->bind();
m_vtxFormat->bind(); m_vtxFormat->bind(b);
for (size_t i=0 ; i<m_ubufCount ; ++i) for (size_t i=0 ; i<m_ubufCount ; ++i)
{ {
IGraphicsBuffer* ubuf = m_ubufs[i]; IGraphicsBuffer* ubuf = m_ubufs[i];
if (ubuf->dynamic()) if (ubuf->dynamic())
static_cast<GLGraphicsBufferD*>(ubuf)->bindUniform(i); static_cast<GLGraphicsBufferD*>(ubuf)->bindUniform(i, b);
else else
static_cast<GLGraphicsBufferS*>(ubuf)->bindUniform(i); static_cast<GLGraphicsBufferS*>(ubuf)->bindUniform(i);
glUniformBlockBinding(prog, m_pipeline->m_uniLocs.at(i), i); glUniformBlockBinding(prog, m_pipeline->m_uniLocs.at(i), i);
@ -668,13 +669,13 @@ struct GLCommandQueue : IGraphicsCommandQueue
/* These members are locked for multithreaded access */ /* These members are locked for multithreaded access */
std::vector<RenderTextureResize> m_pendingResizes; std::vector<RenderTextureResize> m_pendingResizes;
std::vector<GLVertexFormat*> m_pendingFmtAdds; std::vector<GLVertexFormat*> m_pendingFmtAdds;
std::vector<GLuint> m_pendingFmtDels; std::vector<std::array<GLuint, 3>> m_pendingFmtDels;
std::vector<GLTextureR*> m_pendingFboAdds; std::vector<GLTextureR*> m_pendingFboAdds;
std::vector<GLuint> m_pendingFboDels; std::vector<GLuint> m_pendingFboDels;
static void ConfigureVertexFormat(GLVertexFormat* fmt) static void ConfigureVertexFormat(GLVertexFormat* fmt)
{ {
glGenVertexArrays(1, &fmt->m_vao); glGenVertexArrays(3, fmt->m_vao);
size_t stride = 0; size_t stride = 0;
size_t instStride = 0; size_t instStride = 0;
@ -687,9 +688,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
stride += SEMANTIC_SIZE_TABLE[int(desc->semantic & VertexSemantic::SemanticMask)]; stride += SEMANTIC_SIZE_TABLE[int(desc->semantic & VertexSemantic::SemanticMask)];
} }
for (int b=0 ; b<3 ; ++b)
{
size_t offset = 0; size_t offset = 0;
size_t instOffset = 0; size_t instOffset = 0;
glBindVertexArray(fmt->m_vao); glBindVertexArray(fmt->m_vao[b]);
const IGraphicsBuffer* lastVBO = nullptr; const IGraphicsBuffer* lastVBO = nullptr;
const IGraphicsBuffer* lastEBO = nullptr; const IGraphicsBuffer* lastEBO = nullptr;
for (size_t i=0 ; i<fmt->m_elementCount ; ++i) for (size_t i=0 ; i<fmt->m_elementCount ; ++i)
@ -699,7 +702,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
{ {
lastVBO = desc->vertBuffer; lastVBO = desc->vertBuffer;
if (lastVBO->dynamic()) if (lastVBO->dynamic())
static_cast<const GLGraphicsBufferD*>(lastVBO)->bindVertex(); static_cast<const GLGraphicsBufferD*>(lastVBO)->bindVertex(b);
else else
static_cast<const GLGraphicsBufferS*>(lastVBO)->bindVertex(); static_cast<const GLGraphicsBufferS*>(lastVBO)->bindVertex();
} }
@ -707,7 +710,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
{ {
lastEBO = desc->indexBuffer; lastEBO = desc->indexBuffer;
if (lastEBO->dynamic()) if (lastEBO->dynamic())
static_cast<const GLGraphicsBufferD*>(lastEBO)->bindIndex(); static_cast<const GLGraphicsBufferD*>(lastEBO)->bindIndex(b);
else else
static_cast<const GLGraphicsBufferS*>(lastEBO)->bindIndex(); static_cast<const GLGraphicsBufferS*>(lastEBO)->bindIndex();
} }
@ -728,6 +731,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
} }
} }
} }
}
static void ConfigureFBO(GLTextureR* tex) static void ConfigureFBO(GLTextureR* tex)
{ {
@ -772,8 +776,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
if (self->m_pendingFmtDels.size()) if (self->m_pendingFmtDels.size())
{ {
for (GLuint fmt : self->m_pendingFmtDels) for (const auto& fmt : self->m_pendingFmtDels)
glDeleteVertexArrays(1, &fmt); glDeleteVertexArrays(3, fmt.data());
self->m_pendingFmtDels.clear(); self->m_pendingFmtDels.clear();
} }
@ -798,7 +802,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
switch (cmd.m_op) switch (cmd.m_op)
{ {
case Command::Op::SetShaderDataBinding: case Command::Op::SetShaderDataBinding:
static_cast<const GLShaderDataBinding*>(cmd.binding)->bind(); static_cast<const GLShaderDataBinding*>(cmd.binding)->bind(self->m_drawBuf);
break; break;
case Command::Op::SetRenderTarget: case Command::Op::SetRenderTarget:
{ {
@ -1006,7 +1010,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
void delVertexFormat(GLVertexFormat* fmt) void delVertexFormat(GLVertexFormat* fmt)
{ {
std::unique_lock<std::mutex> lk(m_mt); std::unique_lock<std::mutex> lk(m_mt);
m_pendingFmtDels.push_back(fmt->m_vao); m_pendingFmtDels.push_back({fmt->m_vao[0], fmt->m_vao[1], fmt->m_vao[2]});
} }
void addFBO(GLTextureR* tex) void addFBO(GLTextureR* tex)
@ -1058,12 +1062,12 @@ void GLGraphicsBufferD::unmap()
free(m_mappedBuf); free(m_mappedBuf);
m_mappedBuf = nullptr; m_mappedBuf = nullptr;
} }
void GLGraphicsBufferD::bindVertex() const void GLGraphicsBufferD::bindVertex(int b) const
{glBindBuffer(GL_ARRAY_BUFFER, m_bufs[m_q->m_drawBuf]);} {glBindBuffer(GL_ARRAY_BUFFER, m_bufs[b]);}
void GLGraphicsBufferD::bindIndex() const void GLGraphicsBufferD::bindIndex(int b) const
{glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufs[m_q->m_drawBuf]);} {glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufs[b]);}
void GLGraphicsBufferD::bindUniform(size_t idx) const void GLGraphicsBufferD::bindUniform(size_t idx, int b) const
{glBindBufferBase(GL_UNIFORM_BUFFER, idx, m_bufs[m_q->m_drawBuf]);} {glBindBufferBase(GL_UNIFORM_BUFFER, idx, m_bufs[b]);}
IGraphicsBufferD* IGraphicsBufferD*
GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count) GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)