summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhi_p.h
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-12-31 14:39:53 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2022-01-03 14:35:13 +0100
commit5ae238f90fb31ac216f83c0290737bbbec8ff565 (patch)
treee2211c4ddafce12b8ff5b527ca6708346a8320e2 /src/gui/rhi/qrhi_p.h
parent8e2f101a6bf6c59e707b2747d6df76e8e221e319 (diff)
rhi: Add the basics for HDR swapchains
...backed by support in the backends for D3D11 and Vulkan. Expose only what works in practice: scRGB with RGBA16F and HDR10 with RGB10A2 (or A2BGRA10 etc.). For general use, e.g. to render 2D/3D content, scRGB (i.e. extended sRGB linear) should be chosen because that is a linear space. On Windows with a HDR10 display (and an NVIDIA card) both of these are known to work, as long as Use HDR is enabled in the Settings for the display on which the window is created. When requesting a HDR format and it is not supported, we will fall back to the default SDR RGBA8/BGRA8 format. However, the behavior seems to be a bit weird with Vulkan and NVIDIA at least when there is a HDR display but Use HDR is set to Off: this seems to enable HDR mode for the lifetime of the window (with the usual set of black screens while switching over the entire display). Not sure why the driver does this. With D3D/DXGI, with fewer abstractions in the way, we can check upfront properly, so that will nicely fall back to the defaults regardless of why HDR is not available. Support can also be checked in advance via QRhiSwapChain::isFormatSupported() as long as the QWindow is available. (though with Vulkan, as said above, this also seems to ignore the Use HDR setting of Windows) Complications, such as moving a window from one screen to another, are currently not known how they behave. To be seen how this is handled by the Windows compositor. (from 1903 and up it is said to be able to automatically downconvert scRGB to SDR so perhaps moving from a HDR to a non-HDR screen would work - remains to be seen if this needs something more involved) When it comes to other platforms and potential future support: - based on its docs Android 8+ may support scRGB with Vulkan as-is on a suitable device/display, as long as the application declares android:colorMode="wideColorGamut" in the manifest. - for Metal the layer can be made EDR enabled and then e.g. MTLPixelFormatRGBA16Float/kCGColorSpaceExtendedLinearSRGB should work. However, this won't be added unless we can test it. - Linux is unknown. If one needs access to display specific values such as the min/max luminance when implementing tonemapping or a transfer function, that needs platform/API specific approaches, and sadly the kind of data exposed seems to vary, potentially making it difficult to maintain a single cross-platform logic. With D3D one can get the DXGI_OUTPUT_DESC1 from the IDXGIOutput6. This has the min/max luminances in nits and a bunch of other things. For convenience the output object is now exposed from the swapchain's nativeHandles() whenever the D3D backend is used at run time. For Metal one would presumably access maximumExtendedDynamicRangeColorComponentValue and co. in the NSScreen. Elsewhere one needs to rely on platform/winsys specific approaches, if there are any. Remains to be seen longer term if/how this needs/can be better supported. Change-Id: I2e61a0e062282d4bfdfba39655941c0f9a795112 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhi_p.h')
-rw-r--r--src/gui/rhi/qrhi_p.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 5344046841..7a3bfff0c7 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1327,6 +1327,12 @@ public:
};
Q_DECLARE_FLAGS(Flags, Flag)
+ enum Format {
+ SDR,
+ HDRExtendedSrgbLinear,
+ HDR10
+ };
+
QRhiResource::Type resourceType() const override;
QWindow *window() const { return m_window; }
@@ -1335,6 +1341,9 @@ public:
Flags flags() const { return m_flags; }
void setFlags(Flags f) { m_flags = f; }
+ Format format() const { return m_format; }
+ void setFormat(Format f) { m_format = f; }
+
QRhiRenderBuffer *depthStencil() const { return m_depthStencil; }
void setDepthStencil(QRhiRenderBuffer *ds) { m_depthStencil = ds; }
@@ -1349,13 +1358,17 @@ public:
virtual QRhiCommandBuffer *currentFrameCommandBuffer() = 0;
virtual QRhiRenderTarget *currentFrameRenderTarget() = 0;
virtual QSize surfacePixelSize() = 0;
+ virtual bool isFormatSupported(Format f) = 0;
virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
virtual bool createOrResize() = 0;
+ virtual const QRhiNativeHandles *nativeHandles();
+
protected:
QRhiSwapChain(QRhiImplementation *rhi);
QWindow *m_window = nullptr;
Flags m_flags;
+ Format m_format = SDR;
QRhiRenderBuffer *m_depthStencil = nullptr;
int m_sampleCount = 1;
QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;