rhi: Expose HDR output info in a saner way

Don't bother with exposing the IDXGIOutput6. Instead, report the values,
just the ones that matter for tonemapping or transfer functions in a
cross-platform way that's also prepared for Metal's different way of doing
things.

Change-Id: I28c7b6144f8267a9d3d44eff1e40697fb543385f
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
Laszlo Agocs 2022-01-02 20:21:46 +01:00
parent abe802cd00
commit 8efe2d54b7
5 changed files with 73 additions and 49 deletions

View File

@ -4465,18 +4465,37 @@ QRhiResource::Type QRhiSwapChain::resourceType() const
Regardless of the return value, calling destroy() is always safe.
*/
/*!
\return a pointer to a backend-specific QRhiNativeHandles subclass, such as
QRhiD3D11SwapChainNativeHandles. The returned value is \nullptr when
exposing the underlying native resources is not supported by the backend.
\sa QRhiD3D11SwapChainNativeHandles
*/
const QRhiNativeHandles *QRhiSwapChain::nativeHandles()
QRhiSwapChainHdrInfo QRhiSwapChain::hdrInfo()
{
return nullptr;
QRhiSwapChainHdrInfo info;
info.isHardCodedDefaults = true;
info.limitsType = QRhiSwapChainHdrInfo::LuminanceInNits;
info.limits.luminanceInNits.minLuminance = 0.0f;
info.limits.luminanceInNits.maxLuminance = 1000.0f;
return info;
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QRhiSwapChainHdrInfo &info)
{
QDebugStateSaver saver(dbg);
dbg.nospace() << "QRhiSwapChainHdrInfo(" << (info.isHardCodedDefaults ? "with hard-coded defaults" : "queried from system");
switch (info.limitsType) {
case QRhiSwapChainHdrInfo::LuminanceInNits:
dbg.nospace() << " minLuminance=" << info.limits.luminanceInNits.minLuminance
<< " maxLuminance=" << info.limits.luminanceInNits.maxLuminance;
break;
case QRhiSwapChainHdrInfo::ColorComponentValue:
dbg.nospace() << " maxColorComponentValue=" << info.limits.colorComponentValue.maxColorComponentValue;
break;
default:
break;
}
dbg.nospace() << ')';
return dbg;
}
#endif
/*!
\class QRhiComputePipeline
\internal

View File

@ -1313,6 +1313,31 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::Flags)
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::ColorMask)
Q_DECLARE_TYPEINFO(QRhiGraphicsPipeline::TargetBlend, Q_RELOCATABLE_TYPE);
struct QRhiSwapChainHdrInfo
{
bool isHardCodedDefaults;
enum LimitsType {
LuminanceInNits,
ColorComponentValue
};
LimitsType limitsType;
union {
struct {
float minLuminance;
float maxLuminance;
} luminanceInNits;
struct {
float maxColorComponentValue;
} colorComponentValue;
} limits;
};
Q_DECLARE_TYPEINFO(QRhiSwapChainHdrInfo, Q_RELOCATABLE_TYPE);
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiSwapChainHdrInfo &);
#endif
class Q_GUI_EXPORT QRhiSwapChain : public QRhiResource
{
public:
@ -1360,8 +1385,7 @@ public:
virtual bool isFormatSupported(Format f) = 0;
virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
virtual bool createOrResize() = 0;
virtual const QRhiNativeHandles *nativeHandles();
virtual QRhiSwapChainHdrInfo hdrInfo();
protected:
QRhiSwapChain(QRhiImplementation *rhi);

View File

@ -115,18 +115,6 @@ QT_BEGIN_NAMESPACE
\c{ID3D11Device *} and \c{ID3D11DeviceContext *}.
*/
/*!
\class QRhiD3D11SwapChainNativeHandles
\internal
\inmodule QtGui
\brief Exposes D3D/DXGI specific data for a swapchain
dxgiOutput6 is the IDXGIOutput6* for the swapchain's current output, if
supported, null otherwise. The current output is determined based on the
position of the swapchain's associated window at the time of calling
QRhiSwapChain::createOrResize().
*/
// help mingw with its ancient sdk headers
#ifndef DXGI_ADAPTER_FLAG_SOFTWARE
#define DXGI_ADAPTER_FLAG_SOFTWARE 2
@ -4376,11 +4364,6 @@ void QD3D11SwapChain::destroy()
swapChain->Release();
swapChain = nullptr;
if (output6) {
output6->Release();
output6 = nullptr;
}
QRHI_RES_RHI(QRhiD3D11);
if (rhiD)
rhiD->unregisterResource(this);
@ -4458,6 +4441,22 @@ bool QD3D11SwapChain::isFormatSupported(Format f)
return false;
}
QRhiSwapChainHdrInfo QD3D11SwapChain::hdrInfo()
{
QRhiSwapChainHdrInfo info = QRhiSwapChain::hdrInfo();
if (m_format != QRhiSwapChain::SDR && m_window) {
QRHI_RES_RHI(QRhiD3D11);
DXGI_OUTPUT_DESC1 hdrOutputDesc;
if (outputDesc1ForWindow(m_window, rhiD->activeAdapter, &hdrOutputDesc)) {
info.isHardCodedDefaults = false;
info.limitsType = QRhiSwapChainHdrInfo::LuminanceInNits;
info.limits.luminanceInNits.minLuminance = hdrOutputDesc.MinLuminance;
info.limits.luminanceInNits.maxLuminance = hdrOutputDesc.MaxLuminance;
}
}
return info;
}
QRhiRenderPassDescriptor *QD3D11SwapChain::newCompatibleRenderPassDescriptor()
{
return new QD3D11RenderPassDescriptor(m_rhi);
@ -4546,13 +4545,9 @@ bool QD3D11SwapChain::createOrResize()
HRESULT hr;
if (useFlipDiscard) {
DXGI_COLOR_SPACE_TYPE hdrColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; // SDR
if (output6) {
output6->Release();
output6 = nullptr;
}
if (output6ForWindow(m_window, rhiD->activeAdapter, &output6) && m_format != SDR) {
DXGI_OUTPUT_DESC1 hdrOutputDesc;
if (outputDesc1ForWindow(m_window, rhiD->activeAdapter, &hdrOutputDesc) && m_format != SDR) {
// https://docs.microsoft.com/en-us/windows/win32/direct3darticles/high-dynamic-range
output6->GetDesc1(&hdrOutputDesc);
if (hdrOutputDesc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) {
switch (m_format) {
case HDRExtendedSrgbLinear:
@ -4767,12 +4762,6 @@ bool QD3D11SwapChain::createOrResize()
return true;
}
const QRhiNativeHandles *QD3D11SwapChain::nativeHandles()
{
nativeHandlesStruct.dxgiOutput6 = output6;
return &nativeHandlesStruct;
}
void QRhiD3D11::DeviceCurse::initResources()
{
framesLeft = framesToActivate;

View File

@ -76,11 +76,6 @@ struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles
qint32 adapterLuidHigh = 0;
};
struct Q_GUI_EXPORT QRhiD3D11SwapChainNativeHandles : public QRhiNativeHandles
{
void *dxgiOutput6 = nullptr;
};
QT_END_NAMESPACE
#endif

View File

@ -560,10 +560,10 @@ struct QD3D11SwapChain : public QRhiSwapChain
QSize surfacePixelSize() override;
bool isFormatSupported(Format f) override;
QRhiSwapChainHdrInfo hdrInfo() override;
QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
bool createOrResize() override;
const QRhiNativeHandles *nativeHandles() override;
void releaseBuffers();
bool newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI_SAMPLE_DESC sampleDesc,
@ -589,9 +589,6 @@ struct QD3D11SwapChain : public QRhiSwapChain
ID3D11Query *timestampDisjointQuery[BUFFER_COUNT];
ID3D11Query *timestampQuery[BUFFER_COUNT * 2];
UINT swapInterval = 1;
IDXGIOutput6 *output6 = nullptr;
DXGI_OUTPUT_DESC1 hdrOutputDesc;
QRhiD3D11SwapChainNativeHandles nativeHandlesStruct;
};
class QRhiD3D11 : public QRhiImplementation