OpenGL API sync

This commit is contained in:
Jack Andersen 2015-11-03 15:02:05 -10:00
parent 7367c9a952
commit 30898c6549
5 changed files with 125 additions and 49 deletions

View File

@ -29,6 +29,7 @@ public:
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz);
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);

View File

@ -19,6 +19,7 @@ struct GLData : IGraphicsData
std::vector<std::unique_ptr<class GLGraphicsBufferD>> m_DBufs;
std::vector<std::unique_ptr<class GLTextureS>> m_STexs;
std::vector<std::unique_ptr<class GLTextureD>> m_DTexs;
std::vector<std::unique_ptr<class GLTextureR>> m_RTexs;
std::vector<std::unique_ptr<struct GLVertexFormat>> m_VFmts;
};
@ -130,8 +131,7 @@ class GLTextureD : public ITextureD
friend class GLDataFactory;
friend struct GLCommandQueue;
struct GLCommandQueue* m_q;
GLuint m_texs[2];
GLuint m_fbo = 0;
GLuint m_texs[3];
void* m_mappedBuf = nullptr;
size_t m_mappedSize = 0;
size_t m_width = 0;
@ -140,26 +140,28 @@ class GLTextureD : public ITextureD
public:
~GLTextureD();
void load(const void* data, size_t sz)
{
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
void* map(size_t sz)
{
if (m_mappedBuf)
free(m_mappedBuf);
m_mappedBuf = malloc(sz);
m_mappedSize = sz;
return m_mappedBuf;
}
void unmap()
{
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_mappedBuf);
free(m_mappedBuf);
m_mappedBuf = nullptr;
}
void load(const void* data, size_t sz);
void* map(size_t sz);
void unmap();
void bind(size_t idx) const;
};
class GLTextureR : public ITextureR
{
friend class GLDataFactory;
friend struct GLCommandQueue;
struct GLCommandQueue* m_q;
GLuint m_texs[2];
GLuint m_fbo = 0;
void* m_mappedBuf = nullptr;
size_t m_mappedSize = 0;
size_t m_width = 0;
size_t m_height = 0;
size_t m_samples = 0;
GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t samples);
public:
~GLTextureR();
void bind(size_t idx) const
{
@ -401,9 +403,9 @@ struct GLShaderDataBinding : IShaderDataBinding
}
for (size_t i=0 ; i<m_texCount ; ++i)
{
if (m_texs[i]->dynamic())
if (m_texs[i]->type() == ITexture::TextureDynamic)
static_cast<GLTextureD*>(m_texs[i])->bind(i);
else
else if (m_texs[i]->type() == ITexture::TextureStatic)
static_cast<GLTextureS*>(m_texs[i])->bind(i);
}
}
@ -509,7 +511,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
union
{
const IShaderDataBinding* binding;
const ITextureD* target;
const ITextureR* target;
const ITextureR* source;
SWindowRect rect;
float rgba[4];
GLbitfield flags;
@ -539,7 +542,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
/* These members are locked for multithreaded access */
std::vector<GLVertexFormat*> m_pendingFmtAdds;
std::vector<GLuint> m_pendingFmtDels;
std::vector<GLTextureD*> m_pendingFboAdds;
std::vector<GLTextureR*> m_pendingFboAdds;
std::vector<GLuint> m_pendingFboDels;
static void ConfigureVertexFormat(GLVertexFormat* fmt)
@ -583,7 +586,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
}
}
static void ConfigureFBO(GLTextureD* tex)
static void ConfigureFBO(GLTextureR* tex)
{
glGenFramebuffers(1, &tex->m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo);
@ -621,7 +624,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
self->m_pendingFmtDels.clear();
if (self->m_pendingFboAdds.size())
for (GLTextureD* tex : self->m_pendingFboAdds)
for (GLTextureR* tex : self->m_pendingFboAdds)
ConfigureFBO(tex);
self->m_pendingFboAdds.clear();
@ -641,8 +644,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
break;
case Command::OpSetRenderTarget:
{
const GLTextureD* tex = static_cast<const GLTextureD*>(cmd.target);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo);
const GLTextureR* tex = static_cast<const GLTextureR*>(cmd.target);
if (!tex)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
else
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo);
break;
}
case Command::OpSetViewport:
@ -671,8 +677,18 @@ struct GLCommandQueue : IGraphicsCommandQueue
glDrawElementsInstanced(prim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount);
break;
case Command::OpPresent:
{
const GLTextureR* tex = static_cast<const GLTextureR*>(cmd.source);
if (tex)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, tex->m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, tex->m_width, tex->m_height, 0, 0,
tex->m_width, tex->m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
self->m_parent->present();
break;
}
default: break;
}
}
@ -702,16 +718,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.emplace_back(Command::OpSetShaderDataBinding);
cmds.back().binding = binding;
}
void setRenderTarget(ITextureD* target)
void setRenderTarget(ITextureR* target)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpSetRenderTarget);
cmds.back().target = target;
}
void setRenderTarget(IWindow* target)
{
/* TODO: Do */
}
void setViewport(const SWindowRect& rect)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -728,6 +742,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().rgba[2] = rgba[2];
cmds.back().rgba[3] = rgba[3];
}
void clearTarget(bool render=true, bool depth=true)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -748,6 +763,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
else if (prim == PrimitiveTriStrips)
cmds.back().prim = GL_TRIANGLE_STRIP;
}
void draw(size_t start, size_t count)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -755,6 +771,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().start = start;
cmds.back().count = count;
}
void drawIndexed(size_t start, size_t count)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -762,6 +779,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().start = start;
cmds.back().count = count;
}
void drawInstances(size_t start, size_t count, size_t instCount)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -770,6 +788,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().count = count;
cmds.back().instCount = instCount;
}
void drawInstancesIndexed(size_t start, size_t count, size_t instCount)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -779,10 +798,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().instCount = instCount;
}
void present()
void resolveDisplay(ITextureR* source)
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpPresent);
cmds.back().source = source;
}
void addVertexFormat(GLVertexFormat* fmt)
@ -797,13 +817,13 @@ struct GLCommandQueue : IGraphicsCommandQueue
m_pendingFmtDels.push_back(fmt->m_vao);
}
void addFBO(GLTextureD* tex)
void addFBO(GLTextureR* tex)
{
std::unique_lock<std::mutex> lk(m_mt);
m_pendingFboAdds.push_back(tex);
}
void delFBO(GLTextureD* tex)
void delFBO(GLTextureR* tex)
{
std::unique_lock<std::mutex> lk(m_mt);
m_pendingFboDels.push_back(tex->m_fbo);
@ -863,18 +883,44 @@ GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
}
GLTextureD::GLTextureD(GLCommandQueue* q, size_t width, size_t height, TextureFormat fmt)
: m_q(q)
: m_q(q), m_width(width), m_height(height)
{
m_width = width;
m_height = height;
glGenTextures(2, m_texs);
glGenTextures(3, m_texs);
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
m_q->addFBO(this);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
GLTextureD::~GLTextureD() {glDeleteTextures(3, m_texs);}
void GLTextureD::load(const void* data, size_t sz)
{
glBindTexture(GL_TEXTURE_2D, m_texs[m_q->m_fillBuf]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
void* GLTextureD::map(size_t sz)
{
if (m_mappedBuf)
free(m_mappedBuf);
m_mappedBuf = malloc(sz);
m_mappedSize = sz;
return m_mappedBuf;
}
void GLTextureD::unmap()
{
glBindTexture(GL_TEXTURE_2D, m_texs[m_q->m_fillBuf]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_mappedBuf);
free(m_mappedBuf);
m_mappedBuf = nullptr;
}
void GLTextureD::bind(size_t idx) const
{
glActiveTexture(GL_TEXTURE0 + idx);
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
}
GLTextureD::~GLTextureD() {glDeleteTextures(2, m_texs); m_q->delFBO(this);}
ITextureD*
GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
@ -885,6 +931,27 @@ GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
return retval;
}
GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t samples)
: m_q(q), m_width(width), m_height(height), m_samples(samples)
{
glGenTextures(2, m_texs);
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
m_q->addFBO(this);
}
GLTextureR::~GLTextureR() {glDeleteTextures(2, m_texs); m_q->delFBO(this);}
ITextureR*
GLDataFactory::newRenderTexture(size_t width, size_t height, size_t samples)
{
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue());
GLTextureR* retval = new GLTextureR(q, width, height, samples);
static_cast<GLData*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval;
}
GLVertexFormat::GLVertexFormat(GLCommandQueue* q, size_t elementCount,
const VertexElementDescriptor* elements)
: m_q(q),

View File

@ -3948,12 +3948,14 @@ static GLboolean _glewInit_GL_VERSION_3_2 (GLEW_CONTEXT_ARG_DEF_INIT)
#ifdef GL_VERSION_3_3
static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT);
static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT);
static GLboolean _glewInit_GL_VERSION_3_3 (GLEW_CONTEXT_ARG_DEF_INIT)
{
GLboolean r = GL_FALSE;
r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r;
_glewInit_GL_ARB_vertex_array_object();
_glewInit_GL_ARB_framebuffer_object();
return r;
}

View File

@ -343,9 +343,9 @@ public:
m_loadCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, ContextAttribs);
if (!m_loadCtx)
Log.report(LogVisor::FatalError, "unable to make load GLX context");
if (!glXMakeContextCurrent(m_xDisp, m_glxWindow, m_glxWindow, m_loadCtx))
Log.report(LogVisor::FatalError, "unable to make load GLX context current");
}
if (!glXMakeContextCurrent(m_xDisp, m_glxWindow, m_glxWindow, m_loadCtx))
Log.report(LogVisor::FatalError, "unable to make load GLX context current");
return getDataFactory();
}

View File

@ -285,14 +285,20 @@ struct TestApplicationCallback : IApplicationCallback
devFinder.startScanning();
IGraphicsCommandQueue* gfxQ = mainWindow->getCommandQueue();
IGraphicsDataFactory* gfxF = mainWindow->getDataFactory();
ITextureR* renderTarget = gfxF->newRenderTexture(640, 480, 1);
gfxF->commit();
std::thread loaderThread(LoaderProc, this);
size_t frameIdx = 0;
size_t lastCheck = 0;
gfxQ->setViewport({{0, 0}, {640, 480}});
while (running)
{
mainWindow->waitForRetrace();
gfxQ->setRenderTarget(renderTarget);
gfxQ->setViewport({{0, 0}, {640, 480}});
float rgba[] = {sinf(frameIdx / 60.0), cosf(frameIdx / 60.0), 0.0, 1.0};
gfxQ->setClearColor(rgba);
gfxQ->clearTarget();
@ -302,7 +308,7 @@ struct TestApplicationCallback : IApplicationCallback
gfxQ->setShaderDataBinding(m_binding);
gfxQ->draw(0, 4);
}
gfxQ->present();
gfxQ->resolveDisplay(renderTarget);
gfxQ->execute();
//fprintf(stderr, "%zu\n", frameIdx);