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 <andy.nichols@qt.io>
This commit is contained in:
Christian Strømme 2024-11-19 13:12:24 +01:00
parent da367d0bff
commit 49182a0d57

View File

@ -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<QRhiTextureRenderTarget *>(cbD->currentTarget);
if (QRhiShadingRateMap *srm = rt->description().shadingRateMap()) {
if (id<MTLRasterizationRateMap> 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;