We have a WPF application that some of our users remote in and use. The Application is not extremely graphic intensive, but we are seeing a lot of lagging / unresponsiveness over RDP when the application is doing rendering.
We can replicate the issue over RDP, but not when running locally. From this we think there are two approaches:
- Part of the issue is the amount of data that has to be rendered after certain UI events (there will be some code optimizations to hopefully address it to some extent)
- When running over RDP the WPF app is using full software rendering as opposed to GPU acceleration
Is there a way with Win10 and WPF over RDP to force hardware acceleration and GPU rendering?
Below is some of the system specs and observations from what we have tried. Our assumption at this point is that it is just not possible with RDP and Win10, but I would love to be proved wrong.
First, the way we are validating the how the WPF application is using .NETs RenderCapability.Tier
enum.
0: No graphics hardware acceleration is available for the application on the device. All graphics features use software acceleration. The DirectX version level is less than version 9.0.
1: Most of the graphics features of WPF will use hardware acceleration if the necessary system resources are available and have not been exhausted. This corresponds to a DirectX version that is greater than or equal to 9.0.
2: Most of the graphics features of WPF will use hardware acceleration provided the necessary system resources have not been exhausted. This corresponds to a DirectX version that is greater than or equal to 9.0.
We have tried variations of the following registry and GPO settings
Registry Settings
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics\DisableHWAcceleration
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Terminal Services\AVCHardwareEncodePreferred
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Terminal Services\fEnableVirtualizedGraphics
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Terminal Services\MaxCompressionLevel
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Terminal Services\VisualExperiencePolicy
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Terminal Services\VGOptimization_CaptureFrameRate
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Terminal Services\VGOptimization_CompressionRatio
GPO
Windows Components/Remote Desktop Services/Remote Desktop Session Host/Remote Session Environment
Configure H.264/AVC hardware encoding for Remote Desktop Connections
Prioritize H.264/AVC 444 graphics mode for Remote Desktop Connections
Use hardware graphics adapters for all Remote Desktop Services sessions
Regardless of the combination, we have found that over RDP our application is always in full software render, but with same configuration if we run locally it uses Tier 2 graphics acceleration.
Example of an RDP run:
Example of a local run:
Shell code to get above information:
public MainWindow()
{
InitializeComponent();
int displayTier = (RenderCapability.Tier >> 16);
bool shader1HardwareSupported = RenderCapability.IsPixelShaderVersionSupported(1, 0);
bool shader2HardwareSupported = RenderCapability.IsPixelShaderVersionSupported(2, 0);
bool shader1SoftwareSupported = RenderCapability.IsPixelShaderVersionSupportedInSoftware(1, 0);
bool shader2SoftwareSupported = RenderCapability.IsPixelShaderVersionSupportedInSoftware(2, 0);
StringBuilder sbMessage = new StringBuilder($"WPF Tier = {displayTier + Environment.NewLine}");
sbMessage.Append($"Hardware PixelShader Version 1.0 Support: {shader1HardwareSupported + Environment.NewLine}");
sbMessage.Append($"Hardware PixelShader Version 2.0 Support: {shader2HardwareSupported + Environment.NewLine}");
sbMessage.Append($"Software PixelShader Version 1.0 Support: {shader1SoftwareSupported + Environment.NewLine}");
sbMessage.Append($"Software PixelShader Version 2.0 Support: {shader2SoftwareSupported + Environment.NewLine}");
ManagementClass c = new ManagementClass("Win32_VideoController");
foreach (ManagementObject o in c.GetInstances())
{
sbMessage.Append($"GPU Name: {o["Name"] + Environment.NewLine}");
sbMessage.Append($"AdapterRam: {o["AdapterRam"] + Environment.NewLine}");
sbMessage.Append($"DeviceID: {o["DeviceID"] + Environment.NewLine}");
sbMessage.Append($"AdapterDACType: {o["AdapterDACType"] + Environment.NewLine}");
sbMessage.Append($"InstalledDisplayDrivers: {o["InstalledDisplayDrivers"] + Environment.NewLine}");
sbMessage.Append($"DriverVersion: {o["DriverVersion"] + Environment.NewLine}");
sbMessage.Append($"VideoProcessor: {o["VideoProcessor"] + Environment.NewLine}");
sbMessage.Append($"VideoArchitecture: {o["VideoArchitecture"] + Environment.NewLine}");
sbMessage.Append($"VideoMemoryType: {o["VideoMemoryType"] + Environment.NewLine}");
}
MessageBox.Show(sbMessage.ToString());
}
Some environment settings. Let me know if there are more you need
Client OS: Windows 10
Remote OS: Windows 10
Remoting Software: RDP
.NET Target Framework: 4.5.2 (persists on 4.7.1 as well)