Commit 5d5209c6 authored by Laszlo Agocs's avatar Laszlo Agocs

gl: add support for multiple color attachments

...when running on gles 3.0+ or gl.
parent 73881112
......@@ -1461,10 +1461,22 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
cmd.args.bindShaderResources.dynamicOffsetCount);
break;
case QGles2CommandBuffer::Command::BindFramebuffer:
if (cmd.args.bindFramebuffer.fbo)
if (cmd.args.bindFramebuffer.fbo) {
f->glBindFramebuffer(GL_FRAMEBUFFER, cmd.args.bindFramebuffer.fbo);
else
if (caps.maxDrawBuffers > 1) {
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
QVarLengthArray<GLenum, 8> bufs;
for (int i = 0; i < colorAttCount; ++i)
bufs.append(GL_COLOR_ATTACHMENT0 + i);
f->glDrawBuffers(colorAttCount, bufs.constData());
}
} else {
f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
if (caps.maxDrawBuffers > 1) {
GLenum bufs = GL_BACK;
f->glDrawBuffers(1, &bufs);
}
}
if (caps.srgbCapableDefaultFramebuffer) {
if (cmd.args.bindFramebuffer.srgb)
f->glEnable(GL_FRAMEBUFFER_SRGB);
......@@ -1795,6 +1807,7 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
case QRhiRenderTarget::RtRef:
rtD = &QRHI_RES(QGles2ReferenceRenderTarget, rt)->d;
fbCmd.args.bindFramebuffer.fbo = 0;
fbCmd.args.bindFramebuffer.colorAttCount = 1;
break;
case QRhiRenderTarget::RtTexture:
{
......@@ -1803,6 +1816,7 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
wantsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
wantsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer;
fbCmd.args.bindFramebuffer.colorAttCount = rtD->colorAttCount;
}
break;
default:
......@@ -2318,8 +2332,9 @@ bool QGles2TextureRenderTarget::build()
Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture());
const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();
if (colorAttachments.count() > 1)
qWarning("QGles2TextureRenderTarget: Multiple color attachments are not supported");
if (colorAttachments.count() > rhiD->caps.maxDrawBuffers)
qWarning("QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)",
colorAttachments.count(), rhiD->caps.maxDrawBuffers);
if (m_desc.depthTexture() && !rhiD->caps.depthTexture)
qWarning("QGles2TextureRenderTarget: Depth texture is not supported and will be ignored");
......@@ -2329,8 +2344,9 @@ bool QGles2TextureRenderTarget::build()
rhiD->f->glGenFramebuffers(1, &framebuffer);
rhiD->f->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
if (!colorAttachments.isEmpty()) {
const QRhiColorAttachment &colorAtt(colorAttachments.constFirst());
d.colorAttCount = colorAttachments.count();
for (int i = 0; i < d.colorAttCount; ++i) {
const QRhiColorAttachment &colorAtt(colorAttachments[i]);
QRhiTexture *texture = colorAtt.texture();
QRhiRenderBuffer *renderBuffer = colorAtt.renderBuffer();
Q_ASSERT(texture || renderBuffer);
......@@ -2338,18 +2354,19 @@ bool QGles2TextureRenderTarget::build()
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
Q_ASSERT(texD->texture && texD->specified);
const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, faceTargetBase + colorAtt.layer(), texD->texture, colorAtt.level());
d.pixelSize = texD->pixelSize();
d.sampleCount = 1;
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, faceTargetBase + colorAtt.layer(), texD->texture, colorAtt.level());
if (i == 0) {
d.pixelSize = texD->pixelSize();
d.sampleCount = 1;
}
} else if (renderBuffer) {
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbD->renderbuffer);
d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples;
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, rbD->renderbuffer);
if (i == 0) {
d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples;
}
}
d.colorAttCount = 1;
} else {
d.colorAttCount = 0;
}
if (hasDepthStencil) {
......@@ -2357,9 +2374,17 @@ bool QGles2TextureRenderTarget::build()
QGles2RenderBuffer *depthRbD = QRHI_RES(QGles2RenderBuffer, m_desc.depthStencilBuffer());
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbD->renderbuffer);
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRbD->renderbuffer);
if (d.colorAttCount == 0) {
d.pixelSize = depthRbD->pixelSize();
d.sampleCount = depthRbD->samples;
}
} else {
QGles2Texture *depthTexD = QRHI_RES(QGles2Texture, m_desc.depthTexture());
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexD->texture, 0);
if (d.colorAttCount == 0) {
d.pixelSize = depthTexD->pixelSize();
d.sampleCount = 1;
}
}
d.dsAttCount = 1;
} else {
......
......@@ -315,6 +315,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
struct {
GLuint fbo;
bool srgb;
int colorAttCount;
} bindFramebuffer;
struct {
GLenum target;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment