diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 83666f1141..6c4c787a65 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -7064,10 +7064,14 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const (same as SDR/sRGB) and linear colors. Conversion to the display's native color space (such as, HDR10) is performed by the windowing system. On Windows this is the canonical color space of the system compositor, and is - the recommended format for HDR swapchains in general. + the recommended format for HDR swapchains in general on desktop platforms. \value HDR10 10-bit unsigned int RGB or BGR with 2 bit alpha, high dynamic range, HDR10 (Rec. 2020) color space with an ST2084 PQ transfer function. + + \value HDRExtendedDisplayP3Linear 16-bit float RGBA, high dynamic range, + extended linear Display P3 color space. The primary choice for HDR on + platforms such as iOS and VisionOS. */ /*! diff --git a/src/gui/rhi/qrhi.h b/src/gui/rhi/qrhi.h index 2a4c16b881..c1d3e951ea 100644 --- a/src/gui/rhi/qrhi.h +++ b/src/gui/rhi/qrhi.h @@ -1532,7 +1532,8 @@ public: enum Format { SDR, HDRExtendedSrgbLinear, - HDR10 + HDR10, + HDRExtendedDisplayP3Linear }; enum StereoTargetBuffer { diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 95a954fab5..cf209c0975 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -6180,6 +6180,11 @@ bool QMetalSwapChain::isFormatSupported(Format f) return hdrInfo().limits.colorComponentValue.maxPotentialColorComponentValue > 1.0f; else return false; + } else if (f == HDRExtendedDisplayP3Linear) { + if (@available(macOS 11.0, iOS 14.0, *)) + return hdrInfo().limits.colorComponentValue.maxPotentialColorComponentValue > 1.0f; + else + return false; } return f == SDR; } @@ -6215,7 +6220,7 @@ void QMetalSwapChain::chooseFormats() QRHI_RES_RHI(QRhiMetal); samples = rhiD->effectiveSampleCount(m_sampleCount); // pick a format that is allowed for CAMetalLayer.pixelFormat - if (m_format == HDRExtendedSrgbLinear) { + if (m_format == HDRExtendedSrgbLinear || m_format == HDRExtendedDisplayP3Linear) { d->colorFormat = MTLPixelFormatRGBA16Float; d->rhiColorFormat = QRhiTexture::RGBA16F; return; @@ -6268,6 +6273,11 @@ bool QMetalSwapChain::createOrResize() d->layer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB); d->layer.wantsExtendedDynamicRangeContent = YES; } + } else if (m_format == HDRExtendedDisplayP3Linear) { + if (@available(macOS 11.0, iOS 14.0, *)) { + d->layer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearDisplayP3); + d->layer.wantsExtendedDynamicRangeContent = YES; + } } if (m_flags.testFlag(UsedAsTransferSource)) diff --git a/tests/manual/rhi/hdr/hdr.cpp b/tests/manual/rhi/hdr/hdr.cpp index ab51b7a8e8..52f03bcb10 100644 --- a/tests/manual/rhi/hdr/hdr.cpp +++ b/tests/manual/rhi/hdr/hdr.cpp @@ -188,6 +188,9 @@ void preInit() if (args.contains("scrgb")) { d.usingHDRWindow = true; swapchainFormat = QRhiSwapChain::HDRExtendedSrgbLinear; + } else if (args.contains("p3")) { + d.usingHDRWindow = true; + swapchainFormat = QRhiSwapChain::HDRExtendedDisplayP3Linear; } else if (args.contains("sdr")) { d.usingHDRWindow = false; swapchainFormat = QRhiSwapChain::SDR; @@ -365,9 +368,15 @@ void Window::customGui() ImGui::Begin("HDR test"); if (d.usingHDRWindow) { - ImGui::Text("The window is now scRGB (extended *linear* sRGB) + FP16 color buffer,\n" - "the ImGui UI and the green background are considered SDR content,\n" - "the cube is using a HDR texture."); + if (swapchainFormat == QRhiSwapChain::HDRExtendedDisplayP3Linear) { + ImGui::Text("The window is now Extended Linear Display P3 + FP16 color buffer,\n" + "the ImGui UI and the green background are considered SDR content,\n" + "the cube is using a HDR texture."); + } else { + ImGui::Text("The window is now scRGB (Extended Linear sRGB) + FP16 color buffer,\n" + "the ImGui UI and the green background are considered SDR content,\n" + "the cube is using a HDR texture."); + } ImGui::Checkbox("Adjust SDR content", &d.adjustSDR); addTip("Multiplies fragment colors for non-HDR content with sdr_white_level / 80. " "Not relevant with macOS (due to EDR being display-referred).");