gl_engine: enable msaa resolve in GLRenderPass

* use GLRenderBuffer in color and stencil attachment, also use x4 sample
  count by default.
* add msaa resolve logical at the end of a ComposeTask, so the normal
  color texture can get the final rendering result.
This commit is contained in:
RuiwenTang 2024-03-08 11:41:21 +08:00 committed by Sergii Liebodkin
parent 8146a6ef25
commit 68f7e4c245
4 changed files with 59 additions and 22 deletions

View file

@ -48,6 +48,22 @@ void GlRenderTarget::init(GLint resolveId)
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mFbo)); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mFbo));
GL_CHECK(glGenRenderbuffers(1, &mColorBuffer));
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, mColorBuffer));
GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, mWidth, mHeight));
GL_CHECK(glGenRenderbuffers(1, &mStencilBuffer));
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, mStencilBuffer));
GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_STENCIL_INDEX8, mWidth, mHeight));
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0));
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorBuffer));
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBuffer));
// resolve target
GL_CHECK(glGenTextures(1, &mColorTex)); GL_CHECK(glGenTextures(1, &mColorTex));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, mColorTex)); GL_CHECK(glBindTexture(GL_TEXTURE_2D, mColorTex));
@ -60,16 +76,9 @@ void GlRenderTarget::init(GLint resolveId)
GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0)); GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
GL_CHECK(glGenRenderbuffers(1, &mStencilBuffer)); GL_CHECK(glGenFramebuffers(1, &mResolveFbo));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mResolveFbo));
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, mStencilBuffer));
GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight));
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0));
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTex, 0)); GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTex, 0));
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBuffer));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, resolveId)); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, resolveId));
} }

View file

@ -40,14 +40,20 @@ public:
void init(GLint resolveId); void init(GLint resolveId);
GLuint getFboId() { return mFbo; } GLuint getFboId() { return mFbo; }
GLuint getResolveFboId() { return mResolveFbo; }
GLuint getColorTexture() { return mColorTex; } GLuint getColorTexture() { return mColorTex; }
uint32_t getWidth() const { return mWidth; }
uint32_t getHeight() const { return mHeight; }
private: private:
uint32_t mWidth = 0; uint32_t mWidth = 0;
uint32_t mHeight = 0; uint32_t mHeight = 0;
GLuint mFbo = 0; GLuint mFbo = 0;
GLuint mColorTex = 0; GLuint mColorBuffer = 0;
GLuint mStencilBuffer = 0; GLuint mStencilBuffer = 0;
GLuint mResolveFbo = 0;
GLuint mColorTex = 0;
}; };
class GlRenderPass class GlRenderPass
@ -66,7 +72,7 @@ public:
template <class T> template <class T>
T* endRenderPass(GlProgram* program, GLuint targetFbo) { T* endRenderPass(GlProgram* program, GLuint targetFbo) {
return new T(program, targetFbo, mFbo->getFboId(), std::move(mTasks)); return new T(program, targetFbo, mFbo, std::move(mTasks));
} }
private: private:
GlRenderTarget* mFbo; GlRenderTarget* mFbo;

View file

@ -22,6 +22,7 @@
#include "tvgGlRenderTask.h" #include "tvgGlRenderTask.h"
#include "tvgGlProgram.h" #include "tvgGlProgram.h"
#include "tvgGlRenderPass.h"
/************************************************************************/ /************************************************************************/
/* External Class Implementation */ /* External Class Implementation */
@ -131,8 +132,8 @@ void GlStencilCoverTask::run()
GL_CHECK(glDisable(GL_STENCIL_TEST)); GL_CHECK(glDisable(GL_STENCIL_TEST));
} }
GlComposeTask::GlComposeTask(GlProgram* program, GLuint target, GLuint selfFbo, Array<GlRenderTask*>&& tasks) GlComposeTask::GlComposeTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks)
:GlRenderTask(program) ,mTargetFbo(target), mSelfFbo(selfFbo), mTasks() :GlRenderTask(program) ,mTargetFbo(target), mFbo(fbo), mTasks()
{ {
mTasks.push(tasks); mTasks.push(tasks);
tasks.clear(); tasks.clear();
@ -165,10 +166,23 @@ void GlComposeTask::run()
GLenum stencil_attachment = GL_STENCIL_ATTACHMENT; GLenum stencil_attachment = GL_STENCIL_ATTACHMENT;
GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &stencil_attachment)); GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &stencil_attachment));
onResolve();
} }
GlBlitTask::GlBlitTask(GlProgram* program, GLuint target, GLuint compose, Array<GlRenderTask*>&& tasks) GLuint GlComposeTask::getSelfFbo() { return mFbo->getFboId(); }
: GlComposeTask(program, target, compose, std::move(tasks))
GLuint GlComposeTask::getResolveFboId() { return mFbo->getResolveFboId(); }
void GlComposeTask::onResolve() {
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, getSelfFbo()));
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getResolveFboId()));
GL_CHECK(glBlitFramebuffer(0, 0, mFbo->getWidth(), mFbo->getHeight(), 0, 0, mFbo->getWidth(), mFbo->getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST));
}
GlBlitTask::GlBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks)
: GlComposeTask(program, target, fbo, std::move(tasks))
{ {
} }
@ -189,8 +203,8 @@ void GlBlitTask::run()
GL_CHECK(glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST)); GL_CHECK(glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST));
} }
GlDrawBlitTask::GlDrawBlitTask(GlProgram* program, GLuint target, GLuint compose, Array<GlRenderTask*>&& tasks) GlDrawBlitTask::GlDrawBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks)
: GlComposeTask(program, target, compose, std::move(tasks)) : GlComposeTask(program, target, fbo, std::move(tasks))
{ {
} }

View file

@ -110,10 +110,12 @@ private:
GlRenderTask* mCoverTask; GlRenderTask* mCoverTask;
}; };
class GlRenderTarget;
class GlComposeTask : public GlRenderTask class GlComposeTask : public GlRenderTask
{ {
public: public:
GlComposeTask(GlProgram* program, GLuint target, GLuint selfFbo, Array<GlRenderTask*>&& tasks); GlComposeTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks);
~GlComposeTask() override; ~GlComposeTask() override;
void run() override; void run() override;
@ -123,24 +125,30 @@ public:
protected: protected:
GLuint getTargetFbo() { return mTargetFbo; } GLuint getTargetFbo() { return mTargetFbo; }
GLuint getSelfFbo() { return mSelfFbo; } GLuint getSelfFbo();
GLuint getResolveFboId();
virtual void onResolve();
private: private:
GLuint mTargetFbo; GLuint mTargetFbo;
GLuint mSelfFbo; GlRenderTarget* mFbo;
Array<GlRenderTask*> mTasks; Array<GlRenderTask*> mTasks;
}; };
class GlBlitTask : public GlComposeTask class GlBlitTask : public GlComposeTask
{ {
public: public:
GlBlitTask(GlProgram*, GLuint target, GLuint compose, Array<GlRenderTask*>&& tasks); GlBlitTask(GlProgram*, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks);
~GlBlitTask() override = default; ~GlBlitTask() override = default;
void setSize(uint32_t width, uint32_t height); void setSize(uint32_t width, uint32_t height);
void run() override; void run() override;
protected:
void onResolve() override {}
private: private:
uint32_t mWidth = 0; uint32_t mWidth = 0;
uint32_t mHeight = 0; uint32_t mHeight = 0;
@ -149,7 +157,7 @@ private:
class GlDrawBlitTask : public GlComposeTask class GlDrawBlitTask : public GlComposeTask
{ {
public: public:
GlDrawBlitTask(GlProgram*, GLuint target, GLuint compose, Array<GlRenderTask*>&& tasks); GlDrawBlitTask(GlProgram*, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks);
~GlDrawBlitTask() override = default; ~GlDrawBlitTask() override = default;
void run() override; void run() override;