summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/rhi')
-rw-r--r--src/gui/rhi/qrhi.cpp20
-rw-r--r--src/gui/rhi/qrhi.h4
-rw-r--r--src/gui/rhi/qrhid3d11.cpp2
-rw-r--r--src/gui/rhi/qrhid3d12.cpp2
-rw-r--r--src/gui/rhi/qrhigles2.cpp22
-rw-r--r--src/gui/rhi/qrhigles2_p.h3
-rw-r--r--src/gui/rhi/qrhimetal.mm8
-rw-r--r--src/gui/rhi/qrhimetal_p.h1
-rw-r--r--src/gui/rhi/qrhivulkan.cpp4
-rw-r--r--src/gui/rhi/qrhivulkan_p.h1
10 files changed, 64 insertions, 3 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 62b7ab6efb0..5590f2fb431 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -7186,6 +7186,26 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
*/
/*!
+ \fn bool QRhiGraphicsPipeline::hasDepthClamp() const
+ \return true if depth clamp is enabled.
+
+ \since 6.11
+ */
+
+/*!
+ \fn void QRhiGraphicsPipeline::setDepthClamp(bool enable)
+
+ Enables depth clamping when \a enable is true. When depth clamping is
+ enabled, primitives that would otherwise be clipped by the near or far
+ clip plane are rasterized and their depth values are clamped to the
+ depth range. When disabled (the default), such primitives are clipped.
+
+ \note This setting is ignored on OpenGL ES.
+
+ \since 6.11
+ */
+
+/*!
\fn QRhiGraphicsPipeline::CompareOp QRhiGraphicsPipeline::depthOp() const
\return the depth comparison function.
*/
diff --git a/src/gui/rhi/qrhi.h b/src/gui/rhi/qrhi.h
index b5a3f7b43be..5ee2a9acd13 100644
--- a/src/gui/rhi/qrhi.h
+++ b/src/gui/rhi/qrhi.h
@@ -1453,6 +1453,9 @@ public:
bool hasDepthWrite() const { return m_depthWrite; }
void setDepthWrite(bool enable) { m_depthWrite = enable; }
+ bool hasDepthClamp() const { return m_depthClamp; }
+ void setDepthClamp(bool enable) { m_depthClamp = enable; }
+
CompareOp depthOp() const { return m_depthOp; }
void setDepthOp(CompareOp op) { m_depthOp = op; }
@@ -1524,6 +1527,7 @@ protected:
QVarLengthArray<TargetBlend, 8> m_targetBlends;
bool m_depthTest = false;
bool m_depthWrite = false;
+ bool m_depthClamp = false;
CompareOp m_depthOp = Less;
bool m_stencilTest = false;
StencilOpState m_stencilFront;
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index a5f860e7724..1441be24043 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -4673,7 +4673,7 @@ bool QD3D11GraphicsPipeline::create()
rastDesc.FrontCounterClockwise = m_frontFace == CCW;
rastDesc.DepthBias = m_depthBias;
rastDesc.SlopeScaledDepthBias = m_slopeScaledDepthBias;
- rastDesc.DepthClipEnable = true;
+ rastDesc.DepthClipEnable = m_depthClamp ? FALSE : TRUE;
rastDesc.ScissorEnable = m_flags.testFlag(UsesScissor);
rastDesc.MultisampleEnable = rhiD->effectiveSampleDesc(m_sampleCount).Count > 1;
HRESULT hr = rhiD->dev->CreateRasterizerState(&rastDesc, &rastState);
diff --git a/src/gui/rhi/qrhid3d12.cpp b/src/gui/rhi/qrhid3d12.cpp
index 4f09b3c136b..b68b65b1063 100644
--- a/src/gui/rhi/qrhid3d12.cpp
+++ b/src/gui/rhi/qrhid3d12.cpp
@@ -6263,7 +6263,7 @@ bool QD3D12GraphicsPipeline::create()
stream.rasterizerState.object.FrontCounterClockwise = m_frontFace == CCW;
stream.rasterizerState.object.DepthBias = m_depthBias;
stream.rasterizerState.object.SlopeScaledDepthBias = m_slopeScaledDepthBias;
- stream.rasterizerState.object.DepthClipEnable = TRUE;
+ stream.rasterizerState.object.DepthClipEnable = m_depthClamp ? FALSE : TRUE;
stream.rasterizerState.object.MultisampleEnable = sampleDesc.Count > 1;
stream.depthStencilState.object.DepthEnable = m_depthTest;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 15f5cd8f7e8..1308d4362e5 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -585,6 +585,10 @@ QT_BEGIN_NAMESPACE
#define GL_PROGRAM 0x82E2
#endif
+#ifndef GL_DEPTH_CLAMP
+#define GL_DEPTH_CLAMP 0x864F
+#endif
+
/*!
Constructs a new QRhiGles2InitParams.
@@ -998,6 +1002,13 @@ bool QRhiGles2::create(QRhi::Flags flags)
}
if (caps.gles)
+ caps.depthClamp = false;
+ else
+ caps.depthClamp = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2); // Desktop 3.2
+ if (!caps.depthClamp)
+ caps.depthClamp = ctx->hasExtension("GL_EXT_depth_clamp") || ctx->hasExtension("GL_ARB_depth_clamp");
+
+ if (caps.gles)
caps.textureCompareMode = caps.ctxMajor >= 3; // ES 3.0
else
caps.textureCompareMode = true;
@@ -3959,6 +3970,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
break;
case QGles2CommandBuffer::Command::InvalidateFramebuffer:
if (caps.gles && caps.ctxMajor >= 3) {
+ f->glBindFramebuffer(GL_FRAMEBUFFER, cmd.args.invalidateFramebuffer.fbo);
f->glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER,
cmd.args.invalidateFramebuffer.attCount,
cmd.args.invalidateFramebuffer.att);
@@ -4095,6 +4107,15 @@ void QRhiGles2::executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2Grap
f->glDepthMask(depthWrite);
}
+ const bool depthClamp = psD->m_depthClamp;
+ if (caps.depthClamp && (forceUpdate || depthClamp != state.depthClamp)) {
+ state.depthClamp = depthClamp;
+ if (depthClamp)
+ f->glEnable(GL_DEPTH_CLAMP);
+ else
+ f->glDisable(GL_DEPTH_CLAMP);
+ }
+
const GLenum depthFunc = toGlCompareOp(psD->m_depthOp);
if (forceUpdate || depthFunc != state.depthFunc) {
state.depthFunc = depthFunc;
@@ -4881,6 +4902,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (mayDiscardDepthStencil) {
QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::InvalidateFramebuffer;
+ cmd.args.invalidateFramebuffer.fbo = rtTex->framebuffer;
if (caps.needsDepthStencilCombinedAttach) {
cmd.args.invalidateFramebuffer.attCount = 1;
cmd.args.invalidateFramebuffer.att[0] = GL_DEPTH_STENCIL_ATTACHMENT;
diff --git a/src/gui/rhi/qrhigles2_p.h b/src/gui/rhi/qrhigles2_p.h
index 725e71a3665..70dd96a8dc7 100644
--- a/src/gui/rhi/qrhigles2_p.h
+++ b/src/gui/rhi/qrhigles2_p.h
@@ -547,6 +547,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
GLbitfield barriers;
} barrier;
struct {
+ GLuint fbo;
int attCount;
GLenum att[3];
} invalidateFramebuffer;
@@ -592,6 +593,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
} blend[16];
bool depthTest;
bool depthWrite;
+ bool depthClamp;
GLenum depthFunc;
bool stencilTest;
GLuint stencilReadMask;
@@ -1074,6 +1076,7 @@ public:
uint baseVertex : 1;
uint compute : 1;
uint textureCompareMode : 1;
+ uint depthClamp : 1;
uint properMapBuffer : 1;
uint nonBaseLevelFramebufferTexture : 1;
uint texelFetch : 1;
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index c3f1031b44b..7fa05f69232 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -403,6 +403,7 @@ struct QMetalGraphicsPipelineData
MTLWinding winding;
MTLCullMode cullMode;
MTLTriangleFillMode triangleFillMode;
+ MTLDepthClipMode depthClipMode;
float depthBias;
float slopeScaledDepthBias;
QMetalShader vs;
@@ -1477,7 +1478,6 @@ void QMetalGraphicsPipeline::makeActiveForCurrentRenderPassEncoder(QMetalCommand
[cbD->d->currentRenderPassEncoder setDepthStencilState: d->ds];
cbD->d->currentDepthStencilState = d->ds;
}
-
if (cbD->currentCullMode == -1 || d->cullMode != uint(cbD->currentCullMode)) {
[cbD->d->currentRenderPassEncoder setCullMode: d->cullMode];
cbD->currentCullMode = int(d->cullMode);
@@ -1486,6 +1486,10 @@ void QMetalGraphicsPipeline::makeActiveForCurrentRenderPassEncoder(QMetalCommand
[cbD->d->currentRenderPassEncoder setTriangleFillMode: d->triangleFillMode];
cbD->currentTriangleFillMode = int(d->triangleFillMode);
}
+ if (cbD->currentDepthClipMode == -1 || d->depthClipMode != uint(cbD->currentDepthClipMode)) {
+ [cbD->d->currentRenderPassEncoder setDepthClipMode: d->depthClipMode];
+ cbD->currentDepthClipMode = int(d->depthClipMode);
+ }
if (cbD->currentFrontFaceWinding == -1 || d->winding != uint(cbD->currentFrontFaceWinding)) {
[cbD->d->currentRenderPassEncoder setFrontFacingWinding: d->winding];
cbD->currentFrontFaceWinding = int(d->winding);
@@ -5035,6 +5039,7 @@ void QMetalGraphicsPipeline::mapStates()
d->winding = m_frontFace == CCW ? MTLWindingCounterClockwise : MTLWindingClockwise;
d->cullMode = toMetalCullMode(m_cullMode);
d->triangleFillMode = toMetalTriangleFillMode(m_polygonMode);
+ d->depthClipMode = m_depthClamp ? MTLDepthClipModeClamp : MTLDepthClipModeClip;
d->depthBias = float(m_depthBias);
d->slopeScaledDepthBias = m_slopeScaledDepthBias;
}
@@ -6257,6 +6262,7 @@ void QMetalCommandBuffer::resetPerPassCachedState()
currentIndexFormat = QRhiCommandBuffer::IndexUInt16;
currentCullMode = -1;
currentTriangleFillMode = -1;
+ currentDepthClipMode = -1;
currentFrontFaceWinding = -1;
currentDepthBiasValues = { 0.0f, 0.0f };
diff --git a/src/gui/rhi/qrhimetal_p.h b/src/gui/rhi/qrhimetal_p.h
index 7c19ae9e767..6649a6cd304 100644
--- a/src/gui/rhi/qrhimetal_p.h
+++ b/src/gui/rhi/qrhimetal_p.h
@@ -299,6 +299,7 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
QRhiCommandBuffer::IndexFormat currentIndexFormat;
int currentCullMode;
int currentTriangleFillMode;
+ int currentDepthClipMode;
int currentFrontFaceWinding;
std::pair<float, float> currentDepthBiasValues;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index c5167a6e7de..481ffd57b5d 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -949,6 +949,8 @@ bool QRhiVulkan::create(QRhi::Flags flags)
// elsewhere states that the minimum bufferOffset is 4...
texbufAlign = qMax<VkDeviceSize>(4, physDevProperties.limits.optimalBufferCopyOffsetAlignment);
+ caps.depthClamp = physDevFeatures.depthClamp;
+
caps.wideLines = physDevFeatures.wideLines;
caps.texture3DSliceAs2D = caps.apiVersion >= QVersionNumber(1, 1);
@@ -8402,6 +8404,8 @@ bool QVkGraphicsPipeline::create()
VkPipelineRasterizationStateCreateInfo rastInfo = {};
rastInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+ if (m_depthClamp && rhiD->caps.depthClamp)
+ rastInfo.depthClampEnable = m_depthClamp;
rastInfo.cullMode = toVkCullMode(m_cullMode);
rastInfo.frontFace = toVkFrontFace(m_frontFace);
if (m_depthBias != 0 || !qFuzzyIsNull(m_slopeScaledDepthBias)) {
diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h
index d141a84c5fb..1e9318513fd 100644
--- a/src/gui/rhi/qrhivulkan_p.h
+++ b/src/gui/rhi/qrhivulkan_p.h
@@ -936,6 +936,7 @@ public:
struct {
bool compute = false;
+ bool depthClamp = false;
bool wideLines = false;
bool debugUtils = false;
bool vertexAttribDivisor = false;