From 49182a0d5776dbab5125a534bc756b970d77bcf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 19 Nov 2024 13:12:24 +0100 Subject: [PATCH] visionOS: Adapt the rhi setViewport function to work with rate maps When shading rate maps are used we shouldn't use the target's pixel size to set the viewport, as the target's pixel size is likely to different then the "output" size. Instead we get the viewport size from Metal's screenSize function. The rendered content should then be correctly scaled to the output size by the rate map. Pick-to: 6.8 Task-number: QTBUG-129733 Change-Id: I1c53ded0a700eb860cd3bf08fc12a0404c2e6ffa Reviewed-by: Andy Nichols --- src/gui/rhi/qrhimetal.mm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index fc69b6eb4e8..36cfd633a9e 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -1862,7 +1862,21 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) { QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass); - const QSize outputSize = cbD->currentTarget->pixelSize(); + QSize outputSize = cbD->currentTarget->pixelSize(); + + // If we have a shading rate map check and use the output size as given by the "screenSize" + // call. This is important for the viewport to be correct when using a shading rate map, as + // the pixel size of the target will likely be smaller then what will be rendered to the output. + // This is specifically needed for visionOS. + if (cbD->currentTarget->resourceType() == QRhiResource::TextureRenderTarget) { + QRhiTextureRenderTarget *rt = static_cast(cbD->currentTarget); + if (QRhiShadingRateMap *srm = rt->description().shadingRateMap()) { + if (id rateMap = QRHI_RES(QMetalShadingRateMap, srm)->d->rateMap) { + auto screenSize = [rateMap screenSize]; + outputSize = QSize(screenSize.width, screenSize.height); + } + } + } // x,y is top-left in MTLViewportRect but bottom-left in QRhiViewport float x, y, w, h;