rhi: d3d12: Also default to max frame latency 2
Follow what's been done in the D3D11 backend. Slightly different logic here and there due to always having the newer interfaces available, but does the same thing. Use QT_D3D_MAX_FRAME_LATENCY to override the default 2. [ChangeLog][RHI] The D3D12 backend creates swapchains from now on with DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT by default, with a max frame latency of 2. Task-number: QTBUG-127267 Change-Id: I4d0361ab546a1c0041592389f8954281f588b0ba Reviewed-by: Andy Nichols <andy.nichols@qt.io> (cherry picked from commit 91cae3f9cc9cb97eab69e39d405000f2fd1e533a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
9200606068
commit
1e6950fd77
@ -223,6 +223,11 @@ bool QRhiD3D12::create(QRhi::Flags flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (qEnvironmentVariableIsSet("QT_D3D_MAX_FRAME_LATENCY"))
|
||||
maxFrameLatency = UINT(qMax(0, qEnvironmentVariableIntValue("QT_D3D_MAX_FRAME_LATENCY")));
|
||||
if (maxFrameLatency != 0)
|
||||
qCDebug(QRHI_LOG_INFO, "Using frame latency waitable object with max frame latency %u", maxFrameLatency);
|
||||
|
||||
supportsAllowTearing = false;
|
||||
IDXGIFactory5 *factory5 = nullptr;
|
||||
if (SUCCEEDED(dxgiFactory->QueryInterface(__uuidof(IDXGIFactory5), reinterpret_cast<void **>(&factory5)))) {
|
||||
@ -1527,6 +1532,9 @@ QRhi::FrameOpResult QRhiD3D12::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
|
||||
for (QD3D12SwapChain *sc : std::as_const(swapchains))
|
||||
sc->waitCommandCompletionForFrameSlot(currentFrameSlot); // note: swapChainD->currentFrameSlot, not sc's
|
||||
|
||||
if (swapChainD->frameLatencyWaitableObject)
|
||||
WaitForSingleObjectEx(swapChainD->frameLatencyWaitableObject, 1000, true);
|
||||
|
||||
HRESULT hr = cmdAllocators[currentFrameSlot]->Reset();
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to reset command allocator: %s",
|
||||
@ -6122,6 +6130,11 @@ void QD3D12SwapChain::destroy()
|
||||
dcompTarget = nullptr;
|
||||
}
|
||||
|
||||
if (frameLatencyWaitableObject) {
|
||||
CloseHandle(frameLatencyWaitableObject);
|
||||
frameLatencyWaitableObject = nullptr;
|
||||
}
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D12);
|
||||
if (rhiD) {
|
||||
rhiD->swapchains.remove(this);
|
||||
@ -6338,6 +6351,14 @@ bool QD3D12SwapChain::createOrResize()
|
||||
if (swapInterval == 0 && rhiD->supportsAllowTearing)
|
||||
swapChainFlags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
|
||||
// maxFrameLatency 0 means no waitable object usage.
|
||||
// Ignore it also when NoVSync is on, and when using WARP.
|
||||
const bool useFrameLatencyWaitableObject = rhiD->maxFrameLatency != 0
|
||||
&& swapInterval != 0
|
||||
&& rhiD->driverInfoStruct.deviceType != QRhiDriverInfo::CpuDevice;
|
||||
if (useFrameLatencyWaitableObject)
|
||||
swapChainFlags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
|
||||
|
||||
if (!swapChain) {
|
||||
chooseFormats();
|
||||
|
||||
@ -6394,6 +6415,10 @@ bool QD3D12SwapChain::createOrResize()
|
||||
qPrintable(QSystemError::windowsComString(hr)));
|
||||
}
|
||||
}
|
||||
if (useFrameLatencyWaitableObject) {
|
||||
swapChain->SetMaximumFrameLatency(rhiD->maxFrameLatency);
|
||||
frameLatencyWaitableObject = swapChain->GetFrameLatencyWaitableObject();
|
||||
}
|
||||
if (dcompVisual) {
|
||||
hr = dcompVisual->SetContent(swapChain);
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
@ -1044,6 +1044,7 @@ struct QD3D12SwapChain : public QRhiSwapChain
|
||||
QD3D12SwapChainRenderTarget rtWrapper;
|
||||
QD3D12SwapChainRenderTarget rtWrapperRight;
|
||||
QD3D12CommandBuffer cbWrapper;
|
||||
HANDLE frameLatencyWaitableObject = nullptr;
|
||||
|
||||
struct FrameResources {
|
||||
ID3D12Fence *fence = nullptr;
|
||||
@ -1194,6 +1195,7 @@ public:
|
||||
void bindShaderVisibleHeaps(QD3D12CommandBuffer *cbD);
|
||||
|
||||
bool debugLayer = false;
|
||||
UINT maxFrameLatency = 2; // 1-3, use 2 to keep CPU-GPU parallelism while reducing lag compared to tripple buffering
|
||||
ID3D12Device2 *dev = nullptr;
|
||||
D3D_FEATURE_LEVEL minimumFeatureLevel = D3D_FEATURE_LEVEL(0);
|
||||
LUID adapterLuid = {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user