mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-11-12 22:47:15 +00:00
Wait on a dummy fence before using textures shared with the decoder
This commit is contained in:
parent
302dca6c0c
commit
8b50eea485
2 changed files with 67 additions and 2 deletions
|
@ -109,6 +109,8 @@ D3D11VARenderer::~D3D11VARenderer()
|
||||||
|
|
||||||
SDL_DestroyMutex(m_ContextLock);
|
SDL_DestroyMutex(m_ContextLock);
|
||||||
|
|
||||||
|
m_DecodeFence.Reset();
|
||||||
|
|
||||||
m_VideoVertexBuffer.Reset();
|
m_VideoVertexBuffer.Reset();
|
||||||
for (auto& shader : m_VideoPixelShaders) {
|
for (auto& shader : m_VideoPixelShaders) {
|
||||||
shader.Reset();
|
shader.Reset();
|
||||||
|
@ -244,6 +246,26 @@ bool D3D11VARenderer::createDeviceByAdapterIndex(int adapterIndex, bool* adapter
|
||||||
m_DevicesWithFL11Support++;
|
m_DevicesWithFL11Support++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check which fence types are supported by this GPU
|
||||||
|
{
|
||||||
|
m_FenceType = SupportedFenceType::None;
|
||||||
|
|
||||||
|
ComPtr<IDXGIAdapter4> adapter4;
|
||||||
|
if (SUCCEEDED(adapter.As(&adapter4))) {
|
||||||
|
DXGI_ADAPTER_DESC3 desc3;
|
||||||
|
if (SUCCEEDED(adapter4->GetDesc3(&desc3))) {
|
||||||
|
if (desc3.Flags & DXGI_ADAPTER_FLAG3_SUPPORT_MONITORED_FENCES) {
|
||||||
|
// Monitored fences must be used when they are supported
|
||||||
|
m_FenceType = SupportedFenceType::Monitored;
|
||||||
|
}
|
||||||
|
else if (desc3.Flags & DXGI_ADAPTER_FLAG3_SUPPORT_NON_MONITORED_FENCES) {
|
||||||
|
// Non-monitored fences must only be used when monitored fences are unsupported
|
||||||
|
m_FenceType = SupportedFenceType::NonMonitored;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!checkDecoderSupport(adapter.Get())) {
|
if (!checkDecoderSupport(adapter.Get())) {
|
||||||
m_DeviceContext.Reset();
|
m_DeviceContext.Reset();
|
||||||
m_Device.Reset();
|
m_Device.Reset();
|
||||||
|
@ -565,6 +587,20 @@ void D3D11VARenderer::renderFrame(AVFrame* frame)
|
||||||
// access from inside FFmpeg's decoding code
|
// access from inside FFmpeg's decoding code
|
||||||
lockContext(this);
|
lockContext(this);
|
||||||
|
|
||||||
|
// Ensure decoding operations have completed using a dummy fence.
|
||||||
|
// This is not necessary on modern GPU drivers, but it is required
|
||||||
|
// on some older GPU drivers that don't properly synchronize the
|
||||||
|
// video engine with 3D operations.
|
||||||
|
if (m_BindDecoderOutputTextures && m_DecodeFence) {
|
||||||
|
ComPtr<ID3D11DeviceContext4> deviceContext4;
|
||||||
|
if (SUCCEEDED(m_DeviceContext.As(&deviceContext4))) {
|
||||||
|
auto desiredFenceValue = m_DecodeFence->GetCompletedValue() + 1;
|
||||||
|
if (SUCCEEDED(deviceContext4->Signal(m_DecodeFence.Get(), desiredFenceValue))) {
|
||||||
|
deviceContext4->Wait(m_DecodeFence.Get(), desiredFenceValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clear the back buffer
|
// Clear the back buffer
|
||||||
const float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
const float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
m_DeviceContext->ClearRenderTargetView(m_RenderTargetView.Get(), clearColor);
|
m_DeviceContext->ClearRenderTargetView(m_RenderTargetView.Get(), clearColor);
|
||||||
|
@ -1457,6 +1493,27 @@ bool D3D11VARenderer::setupRenderingResources()
|
||||||
m_DeviceContext->RSSetViewports(1, &viewport);
|
m_DeviceContext->RSSetViewports(1, &viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create our decoding fence if the GPU supports fences
|
||||||
|
if (m_FenceType != SupportedFenceType::None) {
|
||||||
|
ComPtr<ID3D11Device5> device5;
|
||||||
|
if (SUCCEEDED(m_Device.As(&device5))) {
|
||||||
|
hr = device5->CreateFence(0,
|
||||||
|
m_FenceType == SupportedFenceType::Monitored ?
|
||||||
|
D3D11_FENCE_FLAG_NONE : D3D11_FENCE_FLAG_NON_MONITORED,
|
||||||
|
IID_PPV_ARGS(&m_DecodeFence));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
// Non-fatal
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"ID3D11Device5::CreateFence() failed: %x",
|
||||||
|
hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"ID3D11Device5::CreateFence() not available until Windows 10 1703");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
#include <d3d11_1.h>
|
#include <d3d11_4.h>
|
||||||
#include <dxgi1_5.h>
|
#include <dxgi1_6.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavutil/hwcontext_d3d11va.h>
|
#include <libavutil/hwcontext_d3d11va.h>
|
||||||
|
@ -53,11 +53,19 @@ private:
|
||||||
int m_DevicesWithFL11Support;
|
int m_DevicesWithFL11Support;
|
||||||
int m_DevicesWithCodecSupport;
|
int m_DevicesWithCodecSupport;
|
||||||
|
|
||||||
|
enum class SupportedFenceType {
|
||||||
|
None,
|
||||||
|
NonMonitored,
|
||||||
|
Monitored,
|
||||||
|
};
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<IDXGIFactory5> m_Factory;
|
Microsoft::WRL::ComPtr<IDXGIFactory5> m_Factory;
|
||||||
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
|
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
|
||||||
Microsoft::WRL::ComPtr<IDXGISwapChain4> m_SwapChain;
|
Microsoft::WRL::ComPtr<IDXGISwapChain4> m_SwapChain;
|
||||||
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
|
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
|
||||||
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_RenderTargetView;
|
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_RenderTargetView;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Fence> m_DecodeFence;
|
||||||
|
SupportedFenceType m_FenceType;
|
||||||
SDL_mutex* m_ContextLock;
|
SDL_mutex* m_ContextLock;
|
||||||
bool m_BindDecoderOutputTextures;
|
bool m_BindDecoderOutputTextures;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue