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, ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz); const void* data, size_t sz);
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); 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); 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 GLGraphicsBufferD>> m_DBufs;
std::vector<std::unique_ptr<class GLTextureS>> m_STexs; std::vector<std::unique_ptr<class GLTextureS>> m_STexs;
std::vector<std::unique_ptr<class GLTextureD>> m_DTexs; 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; std::vector<std::unique_ptr<struct GLVertexFormat>> m_VFmts;
}; };
@ -130,8 +131,7 @@ class GLTextureD : public ITextureD
friend class GLDataFactory; friend class GLDataFactory;
friend struct GLCommandQueue; friend struct GLCommandQueue;
struct GLCommandQueue* m_q; struct GLCommandQueue* m_q;
GLuint m_texs[2]; GLuint m_texs[3];
GLuint m_fbo = 0;
void* m_mappedBuf = nullptr; void* m_mappedBuf = nullptr;
size_t m_mappedSize = 0; size_t m_mappedSize = 0;
size_t m_width = 0; size_t m_width = 0;
@ -140,26 +140,28 @@ class GLTextureD : public ITextureD
public: public:
~GLTextureD(); ~GLTextureD();
void load(const void* data, size_t sz) void load(const void* data, size_t sz);
{ void* map(size_t sz);
glBindTexture(GL_TEXTURE_2D, m_texs[0]); void unmap();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
} void bind(size_t idx) const;
void* map(size_t sz) };
{
if (m_mappedBuf) class GLTextureR : public ITextureR
free(m_mappedBuf); {
m_mappedBuf = malloc(sz); friend class GLDataFactory;
m_mappedSize = sz; friend struct GLCommandQueue;
return m_mappedBuf; struct GLCommandQueue* m_q;
} GLuint m_texs[2];
void unmap() GLuint m_fbo = 0;
{ void* m_mappedBuf = nullptr;
glBindTexture(GL_TEXTURE_2D, m_texs[0]); size_t m_mappedSize = 0;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_mappedBuf); size_t m_width = 0;
free(m_mappedBuf); size_t m_height = 0;
m_mappedBuf = nullptr; 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 void bind(size_t idx) const
{ {
@ -401,9 +403,9 @@ struct GLShaderDataBinding : IShaderDataBinding
} }
for (size_t i=0 ; i<m_texCount ; ++i) 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); 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); static_cast<GLTextureS*>(m_texs[i])->bind(i);
} }
} }
@ -509,7 +511,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
union union
{ {
const IShaderDataBinding* binding; const IShaderDataBinding* binding;
const ITextureD* target; const ITextureR* target;
const ITextureR* source;
SWindowRect rect; SWindowRect rect;
float rgba[4]; float rgba[4];
GLbitfield flags; GLbitfield flags;
@ -539,7 +542,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
/* These members are locked for multithreaded access */ /* These members are locked for multithreaded access */
std::vector<GLVertexFormat*> m_pendingFmtAdds; std::vector<GLVertexFormat*> m_pendingFmtAdds;
std::vector<GLuint> m_pendingFmtDels; std::vector<GLuint> m_pendingFmtDels;
std::vector<GLTextureD*> 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)
@ -583,7 +586,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
} }
} }
static void ConfigureFBO(GLTextureD* tex) static void ConfigureFBO(GLTextureR* tex)
{ {
glGenFramebuffers(1, &tex->m_fbo); glGenFramebuffers(1, &tex->m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo);
@ -621,7 +624,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
self->m_pendingFmtDels.clear(); self->m_pendingFmtDels.clear();
if (self->m_pendingFboAdds.size()) if (self->m_pendingFboAdds.size())
for (GLTextureD* tex : self->m_pendingFboAdds) for (GLTextureR* tex : self->m_pendingFboAdds)
ConfigureFBO(tex); ConfigureFBO(tex);
self->m_pendingFboAdds.clear(); self->m_pendingFboAdds.clear();
@ -641,8 +644,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
break; break;
case Command::OpSetRenderTarget: case Command::OpSetRenderTarget:
{ {
const GLTextureD* tex = static_cast<const GLTextureD*>(cmd.target); const GLTextureR* tex = static_cast<const GLTextureR*>(cmd.target);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo); if (!tex)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
else
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_fbo);
break; break;
} }
case Command::OpSetViewport: case Command::OpSetViewport:
@ -671,8 +677,18 @@ struct GLCommandQueue : IGraphicsCommandQueue
glDrawElementsInstanced(prim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount); glDrawElementsInstanced(prim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount);
break; break;
case Command::OpPresent: 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(); self->m_parent->present();
break; break;
}
default: break; default: break;
} }
} }
@ -702,16 +718,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.emplace_back(Command::OpSetShaderDataBinding); cmds.emplace_back(Command::OpSetShaderDataBinding);
cmds.back().binding = binding; cmds.back().binding = binding;
} }
void setRenderTarget(ITextureD* target)
void setRenderTarget(ITextureR* target)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpSetRenderTarget); cmds.emplace_back(Command::OpSetRenderTarget);
cmds.back().target = target; cmds.back().target = target;
} }
void setRenderTarget(IWindow* target)
{
/* TODO: Do */
}
void setViewport(const SWindowRect& rect) void setViewport(const SWindowRect& rect)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -728,6 +742,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().rgba[2] = rgba[2]; cmds.back().rgba[2] = rgba[2];
cmds.back().rgba[3] = rgba[3]; cmds.back().rgba[3] = rgba[3];
} }
void clearTarget(bool render=true, bool depth=true) void clearTarget(bool render=true, bool depth=true)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -748,6 +763,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
else if (prim == PrimitiveTriStrips) else if (prim == PrimitiveTriStrips)
cmds.back().prim = GL_TRIANGLE_STRIP; cmds.back().prim = GL_TRIANGLE_STRIP;
} }
void draw(size_t start, size_t count) void draw(size_t start, size_t count)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -755,6 +771,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().start = start; cmds.back().start = start;
cmds.back().count = count; cmds.back().count = count;
} }
void drawIndexed(size_t start, size_t count) void drawIndexed(size_t start, size_t count)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -762,6 +779,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().start = start; cmds.back().start = start;
cmds.back().count = count; cmds.back().count = count;
} }
void drawInstances(size_t start, size_t count, size_t instCount) void drawInstances(size_t start, size_t count, size_t instCount)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -770,6 +788,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().count = count; cmds.back().count = count;
cmds.back().instCount = instCount; cmds.back().instCount = instCount;
} }
void drawInstancesIndexed(size_t start, size_t count, size_t instCount) void drawInstancesIndexed(size_t start, size_t count, size_t instCount)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
@ -779,10 +798,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().instCount = instCount; cmds.back().instCount = instCount;
} }
void present() void resolveDisplay(ITextureR* source)
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpPresent); cmds.emplace_back(Command::OpPresent);
cmds.back().source = source;
} }
void addVertexFormat(GLVertexFormat* fmt) void addVertexFormat(GLVertexFormat* fmt)
@ -797,13 +817,13 @@ struct GLCommandQueue : IGraphicsCommandQueue
m_pendingFmtDels.push_back(fmt->m_vao); m_pendingFmtDels.push_back(fmt->m_vao);
} }
void addFBO(GLTextureD* tex) void addFBO(GLTextureR* tex)
{ {
std::unique_lock<std::mutex> lk(m_mt); std::unique_lock<std::mutex> lk(m_mt);
m_pendingFboAdds.push_back(tex); m_pendingFboAdds.push_back(tex);
} }
void delFBO(GLTextureD* tex) void delFBO(GLTextureR* tex)
{ {
std::unique_lock<std::mutex> lk(m_mt); std::unique_lock<std::mutex> lk(m_mt);
m_pendingFboDels.push_back(tex->m_fbo); 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) 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; glGenTextures(3, m_texs);
m_height = height;
glGenTextures(2, m_texs);
glBindTexture(GL_TEXTURE_2D, m_texs[0]); glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[1]); 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); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
m_q->addFBO(this); 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* ITextureD*
GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) 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; 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, GLVertexFormat::GLVertexFormat(GLCommandQueue* q, size_t elementCount,
const VertexElementDescriptor* elements) const VertexElementDescriptor* elements)
: m_q(q), : 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 #ifdef GL_VERSION_3_3
static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT); 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) static GLboolean _glewInit_GL_VERSION_3_3 (GLEW_CONTEXT_ARG_DEF_INIT)
{ {
GLboolean r = GL_FALSE; GLboolean r = GL_FALSE;
r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r; r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r;
_glewInit_GL_ARB_vertex_array_object(); _glewInit_GL_ARB_vertex_array_object();
_glewInit_GL_ARB_framebuffer_object();
return r; return r;
} }

View File

@ -343,9 +343,9 @@ public:
m_loadCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, ContextAttribs); m_loadCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_glxCtx, True, ContextAttribs);
if (!m_loadCtx) if (!m_loadCtx)
Log.report(LogVisor::FatalError, "unable to make load GLX context"); 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(); return getDataFactory();
} }

View File

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