Direct2d with WPF over RDP

╄→尐↘猪︶ㄣ 提交于 2021-01-27 17:45:16

问题


I'm developing a C# application which uses SharpDx to render a map with Direct2d. This map get displayed with the D3DImage on a WPF host. On a local machine everything works fine but when I try to connect via Remote Desktop, the D3DImage loses its Backbuffer and the rendered image can't be displayed with WPF.

I tried to enable the software fallback when I bind the Backbuffer. The result is that the application manages to render one image and then loses the backbuffer again. I also tried to enable hardware acceleration on remote desktop connections with gpedit but nothing changed.

    public void SetBackBuffer(D3D11.Texture2D texture)
    {
      using (var device = CreateDevice(NativeMethods.GetDesktopWindow()))
      {
        using (var texture9 = GetSharedSurface(device, texture))
        {
          this.surface = texture9.GetSurfaceLevel(0);
        }
      }

      this.Lock();
      this.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface.NativePointer, true);
      this.Unlock();
    }

    private static D3D9.Texture GetSharedSurface(D3D9.Device device, D3D11.Texture2D texture)
    {
      using (var surface = texture.QueryInterface<DXGI.Resource>())
      {
        IntPtr handle = surface.SharedHandle;

        return new D3D9.Texture(
          device,
          texture.Description.Width,
          texture.Description.Height,
          1,
          D3D9.Usage.RenderTarget,
          D3D9.Format.A8R8G8B8, // D3DFMT_A8R8G8B8
          D3D9.Pool.Default,  // D3DPOOL_DEFAULT
          ref handle);
      }
    }

    private static D3D9.DeviceEx CreateDevice(IntPtr handle)
    {
      using (var d3D9Ex = new D3D9.Direct3DEx())
      {
        var present = new D3D9.PresentParameters
        {
          Windowed = true,
          SwapEffect = D3D9.SwapEffect.Discard,
          DeviceWindowHandle = handle,
          PresentationInterval = D3D9.PresentInterval.Immediate,
        };

        const D3D9.CreateFlags CreateFlags = D3D9.CreateFlags.HardwareVertexProcessing | D3D9.CreateFlags.Multithreaded | D3D9.CreateFlags.FpuPreserve;

        return new D3D9.DeviceEx(
          d3D9Ex,
          0, // D3DADAPTER_DEFAULT
          D3D9.DeviceType.Hardware, // D3DDEVTYPE_HAL
          handle,
          CreateFlags,
          present);
      }
    }

Edit When I disable hardware acceleration with HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avolon.Graphics/DisableHWAcceleration, I get the same issue on a local machine without RDP.

Edit2 I tried to create a Reference or a Warp Device with Direct11. But after a bit of research it turns out that both software devices do not support SharedSurfaces which I am using to create the WPF image.


回答1:


So I found a solution for my problem:

First of all you have to enable the software fallback when you bind the BackBuffer to your D3DImage. My problem was that after one frame I received the IsFrontBufferAvailableChanged event, IsFrontBufferAvailable turned to false and I stopped rendering. But on software rendering you can ignore those things.

Here is a github issue which helped me fix it: https://github.com/Sascha-L/WPF-MediaKit/issues/3



来源:https://stackoverflow.com/questions/56849171/direct2d-with-wpf-over-rdp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!