Commit 2f6d6a84 authored by Laszlo Agocs's avatar Laszlo Agocs

gl: Add support for depth textures

parent 7188859e
......@@ -1310,13 +1310,13 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
enqueueResourceUpdates(cb, resourceUpdates);
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
bool needsColorClear = true;
bool needsDsClear = true;
bool wantsColorClear = true;
bool wantsDsClear = true;
QD3D11RenderTargetData *rtD = rtData(rt);
if (rt->type() == QRhiRenderTarget::RtTexture) {
QD3D11TextureRenderTarget *rtTex = QRHI_RES(QD3D11TextureRenderTarget, rt);
needsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
needsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
wantsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
wantsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
}
cbD->currentTarget = rt;
......@@ -1330,9 +1330,9 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
clearCmd.cmd = QD3D11CommandBuffer::Command::Clear;
clearCmd.args.clear.rt = rt;
clearCmd.args.clear.mask = 0;
if (rtD->colorAttCount && needsColorClear)
if (rtD->colorAttCount && wantsColorClear)
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Color;
if (rtD->dsAttCount && needsDsClear)
if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
const QVector4D rgba = colorClearValue.rgba();
......
......@@ -180,6 +180,14 @@ QT_BEGIN_NAMESPACE
#define GL_RGBA16F 0x881A
#endif
#ifndef GL_DEPTH_COMPONENT16
#define GL_DEPTH_COMPONENT16 0x81A5
#endif
#ifndef GL_DEPTH_COMPONENT32F
#define GL_DEPTH_COMPONENT32F 0x8CAC
#endif
#ifndef GL_PRIMITIVE_RESTART_FIXED_INDEX
#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
#endif
......@@ -314,11 +322,10 @@ bool QRhiGles2::create(QRhi::Flags flags)
caps.bgraExternalFormat = f->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat);
caps.bgraInternalFormat = caps.bgraExternalFormat && actualFormat.renderableType() == QSurfaceFormat::OpenGLES;
caps.r8Format = f->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats);
caps.r16Format = f->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats);
caps.floatFormats = actualFormat.version() >= qMakePair(3, 0);
caps.depthTexture = actualFormat.version() >= qMakePair(3, 0);
caps.srgbCapableDefaultFramebuffer = f->hasOpenGLExtension(QOpenGLExtensions::SRGBFrameBuffer);
......@@ -467,7 +474,7 @@ bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture
case QRhiTexture::D16:
Q_FALLTHROUGH();
case QRhiTexture::D32:
return false;
return caps.depthTexture;
case QRhiTexture::BGRA8:
return caps.bgraExternalFormat;
......@@ -1767,8 +1774,8 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
enqueueResourceUpdates(cb, resourceUpdates);
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
bool needsColorClear = true;
bool needsDsClear = true;
bool wantsColorClear = true;
bool wantsDsClear = true;
QGles2RenderTargetData *rtD = nullptr;
QGles2CommandBuffer::Command fbCmd;
fbCmd.cmd = QGles2CommandBuffer::Command::BindFramebuffer;
......@@ -1781,8 +1788,8 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
{
QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, rt);
rtD = &rtTex->d;
needsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
needsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
wantsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
wantsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer;
}
break;
......@@ -1795,13 +1802,12 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
cbD->currentTarget = rt;
Q_ASSERT(rtD->attCount == 1 || rtD->attCount == 2);
QGles2CommandBuffer::Command clearCmd;
clearCmd.cmd = QGles2CommandBuffer::Command::Clear;
clearCmd.args.clear.mask = 0;
if (rtD->attCount > 0 && needsColorClear)
if (rtD->colorAttCount && wantsColorClear)
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
if (rtD->attCount > 1 && needsDsClear)
if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
const QVector4D rgba = colorClearValue.rgba();
......@@ -1822,8 +1828,9 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
if (cbD->currentTarget->type() == QRhiRenderTarget::RtTexture) {
QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, cbD->currentTarget);
// handle only 1 color attachment and only (msaa) renderbuffer
const QVector<QRhiColorAttachment> colorAttachments = rtTex->m_desc.colorAttachments();
if (!colorAttachments.isEmpty()) {
// handle only 1 color attachment and only (msaa) renderbuffer
const QRhiColorAttachment &colorAtt(colorAttachments[0]);
if (colorAtt.resolveTexture()) {
Q_ASSERT(colorAtt.renderBuffer());
......@@ -1839,13 +1846,15 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
cmd.args.blitFromRb.w = size.width();
cmd.args.blitFromRb.h = size.height();
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : colorTexD->target;
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
: colorTexD->target;
cmd.args.blitFromRb.target = faceTargetBase + colorAtt.resolveLayer();
cmd.args.blitFromRb.texture = colorTexD->texture;
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
cbD->commands.append(cmd);
}
}
}
cbD->currentTarget = nullptr;
......@@ -2090,6 +2099,16 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize)
glformat = GL_RGBA;
gltype = GL_FLOAT;
break;
case QRhiTexture::D16:
glintformat = GL_DEPTH_COMPONENT16;
glformat = GL_DEPTH_COMPONENT;
gltype = GL_UNSIGNED_SHORT;
break;
case QRhiTexture::D32:
glintformat = GL_DEPTH_COMPONENT32F;
glformat = GL_DEPTH_COMPONENT;
gltype = GL_FLOAT;
break;
default:
Q_UNREACHABLE();
glintformat = GL_RGBA;
......@@ -2283,12 +2302,13 @@ bool QGles2TextureRenderTarget::build()
release();
const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
Q_ASSERT(!colorAttachments.isEmpty());
Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture());
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 (m_desc.depthTexture())
if (m_desc.depthTexture() && !rhiD->caps.depthTexture)
qWarning("QGles2TextureRenderTarget: Depth texture is not supported and will be ignored");
if (!rhiD->ensureContext())
......@@ -2297,14 +2317,11 @@ bool QGles2TextureRenderTarget::build()
rhiD->f->glGenFramebuffers(1, &framebuffer);
rhiD->f->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
if (!colorAttachments.isEmpty()) {
const QRhiColorAttachment &colorAtt(colorAttachments.constFirst());
QRhiTexture *texture = colorAtt.texture();
QRhiRenderBuffer *renderBuffer = colorAtt.renderBuffer();
Q_ASSERT(texture || renderBuffer);
d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
d.attCount = 1;
if (texture) {
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
Q_ASSERT(texD->texture && texD->specified);
......@@ -2318,15 +2335,28 @@ bool QGles2TextureRenderTarget::build()
d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples;
}
d.dpr = 1;
d.colorAttCount = 1;
} else {
d.colorAttCount = 0;
}
if (hasDepthStencil) {
if (m_desc.depthStencilBuffer()) {
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, m_desc.depthStencilBuffer());
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbD->renderbuffer);
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbD->renderbuffer);
d.attCount += 1;
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);
} else {
QGles2Texture *depthTexD = QRHI_RES(QGles2Texture, m_desc.depthTexture());
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexD->texture, 0);
}
d.dsAttCount = 1;
} else {
d.dsAttCount = 0;
}
d.dpr = 1;
d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
GLenum status = rhiD->f->glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_NO_ERROR && status != GL_FRAMEBUFFER_COMPLETE) {
qWarning("Framebuffer incomplete: 0x%x", status);
......@@ -2600,7 +2630,8 @@ bool QGles2SwapChain::buildOrResize()
rt.d.pixelSize = pixelSize;
rt.d.dpr = m_window->devicePixelRatio();
rt.d.sampleCount = qBound(1, m_sampleCount, 64);
rt.d.attCount = m_depthStencil ? 2 : 1;
rt.d.colorAttCount = 1;
rt.d.dsAttCount = m_depthStencil ? 1 : 0;
rt.d.srgbUpdateAndBlend = m_flags.testFlag(QRhiSwapChain::sRGB);
frameCount = 0;
......
......@@ -132,7 +132,8 @@ struct QGles2RenderTargetData
QSize pixelSize;
float dpr = 1;
int sampleCount = 1;
int attCount = 0;
int colorAttCount = 0;
int dsAttCount = 0;
bool srgbUpdateAndBlend = false;
};
......@@ -562,6 +563,7 @@ public:
r8Format(false),
r16Format(false),
floatFormats(false),
depthTexture(false),
srgbCapableDefaultFramebuffer(false)
{ }
int maxTextureSize;
......@@ -576,6 +578,7 @@ public:
uint r8Format : 1;
uint r16Format : 1;
uint floatFormats : 1;
uint depthTexture : 1;
uint srgbCapableDefaultFramebuffer : 1;
} caps;
bool inFrame = false;
......
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