From d46ad528727772362b710d68c27d963db81235c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Wed, 19 Oct 2022 09:04:54 +0300 Subject: QRhi: Allow negative viewport origin Do not bound viewport rect to surface size, only scirror rect. Modifying the viewport will move the view origin changing the way the scene gets rendered. Pick-to: 6.4 Task-number: QTBUG-106082 Change-Id: I105516bd460af87727d0e73f580b8cf6b748d87f Reviewed-by: Qt CI Bot Reviewed-by: Laszlo Agocs --- src/gui/rhi/qrhi_p_p.h | 41 +++++++++++++++++++++++++---------------- src/gui/rhi/qrhid3d11.cpp | 4 ++-- src/gui/rhi/qrhimetal.mm | 5 +++-- src/gui/rhi/qrhivulkan.cpp | 5 +++-- 4 files changed, 33 insertions(+), 22 deletions(-) (limited to 'src/gui/rhi') diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 7ac0184a16..446403f9b7 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -245,7 +245,13 @@ private: friend class QRhiResourceUpdateBatchPrivate; }; -template +enum QRhiTargetRectBoundMode +{ + UnBounded, + Bounded +}; + +template bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array &r, T *x, T *y, T *w, T *h) { @@ -256,7 +262,7 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array(0, inputWidth - widthOffset) : 0; - *h = *y < outputHeight ? qMax(0, inputHeight - heightOffset) : 0; - - *x = qBound(0, *x, outputWidth - 1); - *y = qBound(0, *y, outputHeight - 1); - - if (*x + *w > outputWidth) - *w = qMax(0, outputWidth - *x); - if (*y + *h > outputHeight) - *h = qMax(0, outputHeight - *y); - + *w = inputWidth; + *h = inputHeight; + + if (boundingMode == Bounded) { + const T widthOffset = *x < 0 ? -*x : 0; + const T heightOffset = *y < 0 ? -*y : 0; + *w = *x < outputWidth ? qMax(0, inputWidth - widthOffset) : 0; + *h = *y < outputHeight ? qMax(0, inputHeight - heightOffset) : 0; + + *x = qBound(0, *x, outputWidth - 1); + *y = qBound(0, *y, outputHeight - 1); + + if (*x + *w > outputWidth) + *w = qMax(0, outputWidth - *x); + if (*y + *h > outputHeight) + *h = qMax(0, outputHeight - *y); + } return true; } diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 3ef1fa394e..da7089edf9 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -1084,7 +1084,7 @@ void QRhiD3D11::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) // d3d expects top-left, QRhiViewport is bottom-left float x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) return; QD3D11CommandBuffer::Command &cmd(cbD->commands.get()); @@ -1106,7 +1106,7 @@ void QRhiD3D11::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) // d3d expects top-left, QRhiScissor is bottom-left int x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) return; QD3D11CommandBuffer::Command &cmd(cbD->commands.get()); diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 31364761a2..5b18ff3e96 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -1643,7 +1643,7 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) // x,y is top-left in MTLViewportRect but bottom-left in QRhiViewport float x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) return; MTLViewport vp; @@ -1659,6 +1659,7 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) if (cbD->currentGraphicsPipeline && !cbD->currentGraphicsPipeline->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) { MTLScissorRect s; + qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h); s.x = NSUInteger(x); s.y = NSUInteger(y); s.width = NSUInteger(w); @@ -1676,7 +1677,7 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) // x,y is top-left in MTLScissorRect but bottom-left in QRhiScissor int x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) return; MTLScissorRect s; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 05a67e82de..832db33631 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4927,7 +4927,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport // x,y is top-left in VkViewport but bottom-left in QRhiViewport float x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) return; QVkCommandBuffer::Command &cmd(cbD->commands.get()); @@ -4951,6 +4951,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport ->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) { QVkCommandBuffer::Command &cmd(cbD->commands.get()); VkRect2D *s = &cmd.args.setScissor.scissor; + qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h); s->offset.x = int32_t(x); s->offset.y = int32_t(y); s->extent.width = uint32_t(w); @@ -4973,7 +4974,7 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) // x,y is top-left in VkRect2D but bottom-left in QRhiScissor int x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) return; QVkCommandBuffer::Command &cmd(cbD->commands.get()); -- cgit v1.2.3