mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-18 22:50:57 +00:00
Remove the previous frame rendered fence
- Waiting on this fence prior to rendering introduces pipeline bubbles which can impact rendering performance on low-end GPUs - Pacer simply waiting to release the previous frame until after the current frame is rendered already means any decoder stall should be very short
This commit is contained in:
@@ -107,7 +107,6 @@ D3D11VARenderer::~D3D11VARenderer()
|
|||||||
m_OverlayBlendState.Reset();
|
m_OverlayBlendState.Reset();
|
||||||
m_VideoBlendState.Reset();
|
m_VideoBlendState.Reset();
|
||||||
|
|
||||||
m_PreviousFrameRenderedFence.Reset();
|
|
||||||
m_DecodeD2RFence.Reset();
|
m_DecodeD2RFence.Reset();
|
||||||
m_DecodeR2DFence.Reset();
|
m_DecodeR2DFence.Reset();
|
||||||
m_RenderD2RFence.Reset();
|
m_RenderD2RFence.Reset();
|
||||||
@@ -363,30 +362,6 @@ bool D3D11VARenderer::createDeviceByAdapterIndex(int adapterIndex, bool* adapter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_FenceType != SupportedFenceType::None) {
|
|
||||||
// If this GPU supports monitored fences, use one to wait until the previous frame
|
|
||||||
// has finished rendering before starting on the next one. This reduces latency by
|
|
||||||
// avoiding stalling during rendering after we've already grabbed the next frame
|
|
||||||
// to render, and also avoids stalling the decoder by releasing a surface back to
|
|
||||||
// the pool before we've finished reading from it (causing a stall if the decoder
|
|
||||||
// tries to write again).
|
|
||||||
if (m_FenceType == SupportedFenceType::Monitored) {
|
|
||||||
m_PreviousFrameRenderedFenceValue = 0;
|
|
||||||
hr = m_RenderDevice->CreateFence(m_PreviousFrameRenderedFenceValue,
|
|
||||||
D3D11_FENCE_FLAG_NONE,
|
|
||||||
IID_PPV_ARGS(&m_PreviousFrameRenderedFence));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"ID3D11Device5::CreateFence() failed: %x",
|
|
||||||
hr);
|
|
||||||
// Non-fatal
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an auto-reset event for our fence to signal
|
|
||||||
m_PreviousFrameRenderedEvent.Attach(CreateEvent(NULL, FALSE, TRUE, NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils::getEnvironmentVariableOverride("D3D11VA_FORCE_BIND", &m_BindDecoderOutputTextures)) {
|
if (Utils::getEnvironmentVariableOverride("D3D11VA_FORCE_BIND", &m_BindDecoderOutputTextures)) {
|
||||||
@@ -1071,16 +1046,6 @@ void D3D11VARenderer::renderVideo(AVFrame* frame)
|
|||||||
unlockContext(this);
|
unlockContext(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger our fence to signal after this video frame has been rendered
|
|
||||||
if (m_PreviousFrameRenderedFence) {
|
|
||||||
ComPtr<ID3D11DeviceContext4> deviceContext4;
|
|
||||||
if (SUCCEEDED(m_RenderDeviceContext.As(&deviceContext4))) {
|
|
||||||
if (SUCCEEDED(deviceContext4->Signal(m_PreviousFrameRenderedFence.Get(), m_PreviousFrameRenderedFenceValue + 1))) {
|
|
||||||
m_PreviousFrameRenderedFenceValue++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function must NOT use any DXGI or ID3D11DeviceContext methods
|
// This function must NOT use any DXGI or ID3D11DeviceContext methods
|
||||||
@@ -1302,32 +1267,6 @@ bool D3D11VARenderer::notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO stateInfo)
|
|||||||
return stateInfo->stateChangeFlags == 0;
|
return stateInfo->stateChangeFlags == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11VARenderer::waitToRender()
|
|
||||||
{
|
|
||||||
if (m_PreviousFrameRenderedFence && m_PreviousFrameRenderedEvent.IsValid()) {
|
|
||||||
SDL_assert(m_FenceType == SupportedFenceType::Monitored);
|
|
||||||
|
|
||||||
// Check if the GPU is already finished
|
|
||||||
if (m_PreviousFrameRenderedFence->GetCompletedValue() < m_PreviousFrameRenderedFenceValue) {
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
hr = m_PreviousFrameRenderedFence->SetEventOnCompletion(m_PreviousFrameRenderedFenceValue, m_PreviousFrameRenderedEvent.Get());
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
// If we don't wake within 2 seconds, something is probably wrong
|
|
||||||
if (WaitForSingleObject(m_PreviousFrameRenderedEvent.Get(), 2000) != WAIT_OBJECT_0) {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Failed to wait on fence event!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"ID3D11Fence::SetEventOnCompletion() failed: %x",
|
|
||||||
hr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool D3D11VARenderer::checkDecoderSupport(IDXGIAdapter* adapter)
|
bool D3D11VARenderer::checkDecoderSupport(IDXGIAdapter* adapter)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ public:
|
|||||||
virtual void renderFrame(AVFrame* frame) override;
|
virtual void renderFrame(AVFrame* frame) override;
|
||||||
virtual void notifyOverlayUpdated(Overlay::OverlayType) override;
|
virtual void notifyOverlayUpdated(Overlay::OverlayType) override;
|
||||||
virtual bool notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO stateInfo) override;
|
virtual bool notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO stateInfo) override;
|
||||||
virtual void waitToRender() override;
|
|
||||||
virtual int getRendererAttributes() override;
|
virtual int getRendererAttributes() override;
|
||||||
virtual int getDecoderCapabilities() override;
|
virtual int getDecoderCapabilities() override;
|
||||||
virtual InitFailureReason getInitFailureReason() override;
|
virtual InitFailureReason getInitFailureReason() override;
|
||||||
@@ -79,9 +78,6 @@ private:
|
|||||||
Microsoft::WRL::ComPtr<ID3D11BlendState> m_OverlayBlendState;
|
Microsoft::WRL::ComPtr<ID3D11BlendState> m_OverlayBlendState;
|
||||||
|
|
||||||
SupportedFenceType m_FenceType;
|
SupportedFenceType m_FenceType;
|
||||||
Microsoft::WRL::ComPtr<ID3D11Fence> m_PreviousFrameRenderedFence;
|
|
||||||
Microsoft::WRL::Wrappers::Event m_PreviousFrameRenderedEvent;
|
|
||||||
UINT64 m_PreviousFrameRenderedFenceValue;
|
|
||||||
Microsoft::WRL::ComPtr<ID3D11Fence> m_DecodeD2RFence, m_RenderD2RFence;
|
Microsoft::WRL::ComPtr<ID3D11Fence> m_DecodeD2RFence, m_RenderD2RFence;
|
||||||
Microsoft::WRL::ComPtr<ID3D11Fence> m_DecodeR2DFence, m_RenderR2DFence;
|
Microsoft::WRL::ComPtr<ID3D11Fence> m_DecodeR2DFence, m_RenderR2DFence;
|
||||||
UINT64 m_DecodeRenderSyncFenceValue;
|
UINT64 m_DecodeRenderSyncFenceValue;
|
||||||
|
|||||||
Reference in New Issue
Block a user