@@ -46,33 +46,6 @@ public class HUDWindow : LayeredWindow
4646 // Set to distance from top-left corner to place text.
4747 const int TextOffset = 10 ;
4848
49- readonly int ProcessorCount = System . Environment . ProcessorCount ;
50-
51- readonly Version Windows10 = new Version ( 10 , 0 ) ;
52- const int PerformanceCounterUpdateTimeS = 10 ;
53- float PerformanceCounterElapsedTimeS = PerformanceCounterUpdateTimeS ;
54-
55- readonly PerformanceCounter CLRMemoryAllocatedBytesPerSecCounter ; // \.NET CLR Memory(*)\Allocated Bytes/sec
56- float CLRMemoryAllocatedBytesPerSec ;
57-
58- readonly PerformanceCounter CPUMemoryPrivateCounter ; // \Process(*)\Private Bytes
59- readonly PerformanceCounter CPUMemoryWorkingSetCounter ; // \Process(*)\Working Set
60- readonly PerformanceCounter CPUMemoryWorkingSetPrivateCounter ; // \Process(*)\Working Set - Private
61- readonly PerformanceCounter CPUMemoryVirtualCounter ; // \Process(*)\Virtual Bytes
62-
63- float CPUMemoryPrivate ;
64- float CPUMemoryWorkingSet ;
65- float CPUMemoryWorkingSetPrivate ;
66- float CPUMemoryVirtual ;
67-
68- readonly List < PerformanceCounter > GPUMemoryCommittedCounters = new List < PerformanceCounter > ( ) ; // \GPU Process Memory(*)\Total Committed
69- readonly List < PerformanceCounter > GPUMemoryDedicatedCounters = new List < PerformanceCounter > ( ) ; // \GPU Process Memory(*)\Dedicated Usage
70- readonly List < PerformanceCounter > GPUMemorySharedCounters = new List < PerformanceCounter > ( ) ; // \GPU Process Memory(*)\Shared Usage
71-
72- float GPUMemoryCommitted ;
73- float GPUMemoryDedicated ;
74- float GPUMemoryShared ;
75-
7649 readonly Viewer Viewer ;
7750 readonly Action < TableData > [ ] TextPages ;
7851 readonly WindowTextFont TextFont ;
@@ -102,86 +75,14 @@ public class HUDWindow : LayeredWindow
10275 HUDGraphMesh DebugGraphProcessLoader ;
10376 HUDGraphMesh DebugGraphProcessSound ;
10477
78+ HostProcess Host => Viewer . Game . HostProcess ;
79+
10580 public HUDWindow ( WindowManager owner )
10681 : base ( owner , TextOffset , TextOffset , "HUD" )
10782 {
10883 Viewer = owner . Viewer ;
10984 LastTextPage = LocomotivePage ;
11085
111- ProcessHandle = OpenProcess ( 0x410 /* PROCESS_QUERY_INFORMATION | PROCESS_VM_READ */ , false , Process . GetCurrentProcess ( ) . Id ) ;
112- ProcessMemoryCounters = new PROCESS_MEMORY_COUNTERS ( ) { Size = 40 } ;
113- ProcessVirtualAddressLimit = GetVirtualAddressLimit ( ) ;
114-
115- var processId = Process . GetCurrentProcess ( ) . Id ;
116- try
117- {
118- var counterDotNetClrMemory = new PerformanceCounterCategory ( ".NET CLR Memory" ) ;
119- foreach ( InstanceData instance in counterDotNetClrMemory . ReadCategory ( ) [ "Process ID" ] . Values )
120- {
121- if ( instance . RawValue == processId )
122- {
123- var process = instance . InstanceName ;
124- CLRMemoryAllocatedBytesPerSecCounter = new PerformanceCounter ( ".NET CLR Memory" , "Allocated Bytes/sec" , process ) ;
125- Trace . TraceInformation ( $ "Found Microsoft .NET Framework performance counter { process } ") ;
126- break ;
127- }
128- }
129- }
130- catch ( Exception error )
131- {
132- Trace . WriteLine ( error ) ;
133- Trace . TraceWarning ( "Unable to access Microsoft .NET Framework performance counters. This may be resolved by following the instructions at http://support.microsoft.com/kb/300956" ) ;
134- }
135-
136- try
137- {
138- var counterProcess = new PerformanceCounterCategory ( "Process" ) ;
139- foreach ( InstanceData instance in counterProcess . ReadCategory ( ) [ "ID Process" ] . Values )
140- {
141- if ( instance . RawValue == processId )
142- {
143- var process = instance . InstanceName ;
144- CPUMemoryPrivateCounter = new PerformanceCounter ( "Process" , "Private Bytes" , process ) ;
145- CPUMemoryWorkingSetCounter = new PerformanceCounter ( "Process" , "Working Set" , process ) ;
146- CPUMemoryWorkingSetPrivateCounter = new PerformanceCounter ( "Process" , "Working Set - Private" , process ) ;
147- CPUMemoryVirtualCounter = new PerformanceCounter ( "Process" , "Virtual Bytes" , process ) ;
148- Trace . TraceInformation ( $ "Found Windows Process performance counter { process } ") ;
149- break ;
150- }
151- }
152- }
153- catch ( Exception error )
154- {
155- Trace . WriteLine ( error ) ;
156- Trace . TraceWarning ( "Unable to access Windows Process performance counters. This may be resolved by following the instructions at http://support.microsoft.com/kb/300956" ) ;
157- }
158-
159- if ( Environment . OSVersion . Platform == PlatformID . Win32NT && Environment . OSVersion . Version >= Windows10 )
160- {
161- try
162- {
163- var instancePrefix = $ "pid_{ Process . GetCurrentProcess ( ) . Id } _";
164- var counterProcess = new PerformanceCounterCategory ( "GPU Process Memory" ) ;
165- foreach ( var process in counterProcess . GetInstanceNames ( ) )
166- {
167- if ( process . StartsWith ( instancePrefix ) )
168- {
169- GPUMemoryCommittedCounters . Add ( new PerformanceCounter ( "GPU Process Memory" , "Total Committed" , process ) ) ;
170- GPUMemoryDedicatedCounters . Add ( new PerformanceCounter ( "GPU Process Memory" , "Dedicated Usage" , process ) ) ;
171- GPUMemorySharedCounters . Add ( new PerformanceCounter ( "GPU Process Memory" , "Shared Usage" , process ) ) ;
172- Trace . TraceInformation ( $ "Found Windows GPU Process Memory performance counter { process } ") ;
173- }
174- }
175- }
176- catch ( Exception error )
177- {
178- Trace . WriteLine ( error ) ;
179- Trace . TraceWarning ( "Unable to access Windows GPU Process Memory performance counters. This may be resolved by following the instructions at http://support.microsoft.com/kb/300956" ) ;
180- }
181- }
182-
183- Debug . Assert ( GC . MaxGeneration == 2 , "Runtime is expected to have a MaxGeneration of 2." ) ;
184-
18586 var textPages = new List < Action < TableData > > ( ) ;
18687 textPages . Add ( TextPageCommon ) ;
18788 textPages . Add ( TextPageConsistInfo ) ;
@@ -211,7 +112,7 @@ public HUDWindow(WindowManager owner)
211112 ForceGraphNumOfSubsteps = ForceGraphs . Add ( Viewer . Catalog . GetString ( "Num of substeps" ) , "0" , "50" , Color . Blue , 25 ) ;
212113
213114 DebugGraphs = new HUDGraphSet ( Viewer , HUDGraphMaterial ) ;
214- DebugGraphMemory = DebugGraphs . Add ( Viewer . Catalog . GetString ( "Memory" ) , "0GB" , String . Format ( "{0:F0}GB" , ( float ) ProcessVirtualAddressLimit / 1024 / 1024 / 1024 ) , Color . Orange , 50 ) ;
115+ DebugGraphMemory = DebugGraphs . Add ( Viewer . Catalog . GetString ( "Memory" ) , "0GB" , String . Format ( "{0:F0}GB" , ( float ) Host . CPUMemoryVirtualLimit / 1024 / 1024 / 1024 ) , Color . Orange , 50 ) ;
215116 DebugGraphGCs = DebugGraphs . Add ( Viewer . Catalog . GetString ( "GCs" ) , "0" , "2" , Color . Magenta , 20 ) ; // Multiple of 4
216117 DebugGraphFrameTime = DebugGraphs . Add ( Viewer . Catalog . GetString ( "Frame time" ) , "0.0s" , "0.1s" , Color . LightGreen , 50 ) ;
217118 DebugGraphProcessRender = DebugGraphs . Add ( Viewer . Catalog . GetString ( "Render process" ) , "0%" , "100%" , Color . Red , 20 ) ;
@@ -332,7 +233,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime, bo
332233 if ( Visible && TextPages [ TextPage ] == TextPageDebugInfo )
333234 {
334235 var gcCounts = new [ ] { GC . CollectionCount ( 0 ) , GC . CollectionCount ( 1 ) , GC . CollectionCount ( 2 ) } ;
335- DebugGraphMemory . AddSample ( ( float ) GetWorkingSetSize ( ) / ProcessVirtualAddressLimit ) ;
236+ DebugGraphMemory . AddSample ( ( float ) Host . CPUMemoryWorkingSet / Host . CPUMemoryVirtualLimit ) ;
336237 DebugGraphGCs . AddSample ( gcCounts [ 2 ] > lastGCCounts [ 2 ] ? 1.0f : gcCounts [ 1 ] > lastGCCounts [ 1 ] ? 0.5f : gcCounts [ 0 ] > lastGCCounts [ 0 ] ? 0.25f : 0 ) ;
337238 DebugGraphFrameTime . AddSample ( Viewer . RenderProcess . FrameTime . Value * 10 ) ;
338239 DebugGraphProcessRender . AddSample ( Viewer . RenderProcess . Profiler . Wall . Value / 100 ) ;
@@ -348,13 +249,6 @@ public override void PrepareFrame(ElapsedTime elapsedTime, bool updateFull)
348249 {
349250 base . PrepareFrame ( elapsedTime , updateFull ) ;
350251
351- PerformanceCounterElapsedTimeS += elapsedTime . RealSeconds ;
352- if ( PerformanceCounterElapsedTimeS >= PerformanceCounterUpdateTimeS )
353- {
354- UpdatePerformanceCounters ( ) ;
355- PerformanceCounterElapsedTimeS = 0 ;
356- }
357-
358252 if ( updateFull )
359253 {
360254 var table = new TableData ( ) { Cells = new string [ TextTable . Cells . GetLength ( 0 ) , TextTable . Cells . GetLength ( 1 ) ] } ;
@@ -1437,11 +1331,11 @@ void TextPageDebugInfo(TableData table)
14371331
14381332 TableAddLabelValue ( table , Viewer . Catalog . GetString ( "Logging enabled" ) , Viewer . Settings . DataLogger ? Viewer . Catalog . GetString ( "Yes" ) : Viewer . Catalog . GetString ( "No" ) ) ;
14391333 TableAddLabelValue ( table , Viewer . Catalog . GetString ( "Build" ) , VersionInfo . Build ) ;
1440- TableAddLabelValue ( table , Viewer . Catalog . GetString ( "CPU" ) , Viewer . Catalog . GetStringFmt ( "{0:F0}% ({1})" , ( Viewer . RenderProcess . Profiler . CPU . SmoothedValue + Viewer . UpdaterProcess . Profiler . CPU . SmoothedValue + Viewer . LoaderProcess . Profiler . CPU . SmoothedValue + Viewer . SoundProcess . Profiler . CPU . SmoothedValue ) / ProcessorCount , Viewer . Catalog . GetPluralStringFmt ( "{0} logical processor" , "{0} logical processors" , ProcessorCount ) ) ) ;
1334+ TableAddLabelValue ( table , Viewer . Catalog . GetString ( "CPU" ) , Viewer . Catalog . GetStringFmt ( "{0:F0}% ({1})" , ( Viewer . RenderProcess . Profiler . CPU . SmoothedValue + Viewer . UpdaterProcess . Profiler . CPU . SmoothedValue + Viewer . LoaderProcess . Profiler . CPU . SmoothedValue + Viewer . SoundProcess . Profiler . CPU . SmoothedValue ) / Host . ProcessorCount , Viewer . Catalog . GetPluralStringFmt ( "{0} logical processor" , "{0} logical processors" , Host . ProcessorCount ) ) ) ;
14411335 TableAddLabelValue ( table , Viewer . Catalog . GetString ( "GPU" ) , Viewer . Catalog . GetStringFmt ( "{0:F0} FPS (50th/95th/99th percentiles {1:F1} / {2:F1} / {3:F1} ms, DirectX feature level >= {4})" , Viewer . RenderProcess . FrameRate . SmoothedValue , Viewer . RenderProcess . FrameTime . SmoothedP50 * 1000 , Viewer . RenderProcess . FrameTime . SmoothedP95 * 1000 , Viewer . RenderProcess . FrameTime . SmoothedP99 * 1000 , Viewer . Settings . DirectXFeatureLevel ) ) ;
1442- TableAddLabelValue ( table , Viewer . Catalog . GetString ( "Memory" ) , Viewer . Catalog . GetStringFmt ( "{3}, {4}, {5}, {6} ({7:F0} kB/frame allocated, {0:F0}/{1:F0}/{2:F0} GCs)" , GC . CollectionCount ( 0 ) , GC . CollectionCount ( 1 ) , GC . CollectionCount ( 2 ) , Viewer . TextureManager . GetStatus ( ) , Viewer . MaterialManager . GetStatus ( ) , Viewer . ShapeManager . GetStatus ( ) , Viewer . World . Terrain . GetStatus ( ) , CLRMemoryAllocatedBytesPerSec / Viewer . RenderProcess . FrameRate . SmoothedValue / 1024 ) ) ;
1443- if ( CPUMemoryPrivate > 0 ) TableAddLabelValue ( table , Viewer . Catalog . GetString ( "CPU Memory" ) , Viewer . Catalog . GetStringFmt ( "{0:F0} MB private, {1:F0} MB working set, {2:F0} MB private working set, {3:F0} MB managed, {4:F0} MB virtual" , CPUMemoryPrivate / 1024 / 1024 , CPUMemoryWorkingSet / 1024 / 1024 , CPUMemoryWorkingSetPrivate / 1024 / 1024 , GC . GetTotalMemory ( false ) / 1024 / 1024 , CPUMemoryVirtual / 1024 / 1024 ) ) ;
1444- if ( GPUMemoryCommitted > 0 ) TableAddLabelValue ( table , Viewer . Catalog . GetString ( "GPU Memory" ) , Viewer . Catalog . GetStringFmt ( "{0:F0} MB committed, {1:F0} MB dedicated, {2:F0} MB shared" , GPUMemoryCommitted / 1024 / 1024 , GPUMemoryDedicated / 1024 / 1024 , GPUMemoryShared / 1024 / 1024 ) ) ;
1336+ TableAddLabelValue ( table , Viewer . Catalog . GetString ( "Memory" ) , Viewer . Catalog . GetStringFmt ( "{3}, {4}, {5}, {6} ({7:F0} kB/frame allocated, {0:F0}/{1:F0}/{2:F0} GCs)" , GC . CollectionCount ( 0 ) , GC . CollectionCount ( 1 ) , GC . CollectionCount ( 2 ) , Viewer . TextureManager . GetStatus ( ) , Viewer . MaterialManager . GetStatus ( ) , Viewer . ShapeManager . GetStatus ( ) , Viewer . World . Terrain . GetStatus ( ) , Host . CLRMemoryAllocatedBytesPerSec / Viewer . RenderProcess . FrameRate . SmoothedValue / 1024 ) ) ;
1337+ if ( Host . CPUMemoryPrivate > 0 ) TableAddLabelValue ( table , Viewer . Catalog . GetString ( "CPU Memory" ) , Viewer . Catalog . GetStringFmt ( "{0:F0} MB private, {1:F0} MB working set, {2:F0} MB private working set, {3:F0} MB managed, {4:F0} MB virtual" , Host . CPUMemoryPrivate / 1024 / 1024 , Host . CPUMemoryWorkingSet / 1024 / 1024 , Host . CPUMemoryWorkingSetPrivate / 1024 / 1024 , GC . GetTotalMemory ( false ) / 1024 / 1024 , Host . CPUMemoryVirtual / 1024 / 1024 ) ) ;
1338+ if ( Host . GPUMemoryCommitted > 0 ) TableAddLabelValue ( table , Viewer . Catalog . GetString ( "GPU Memory" ) , Viewer . Catalog . GetStringFmt ( "{0:F0} MB committed, {1:F0} MB dedicated, {2:F0} MB shared" , Host . GPUMemoryCommitted / 1024 / 1024 , Host . GPUMemoryDedicated / 1024 / 1024 , Host . GPUMemoryShared / 1024 / 1024 ) ) ;
14451339 TableAddLabelValue ( table , Viewer . Catalog . GetString ( "Adapter" ) , Viewer . Catalog . GetStringFmt ( "{0} ({1:F0} MB)" , Viewer . AdapterDescription , Viewer . AdapterMemory / 1024 / 1024 ) ) ;
14461340 if ( Viewer . Settings . DynamicShadows )
14471341 {
@@ -1467,78 +1361,6 @@ static void TextPageHeading(TableData table, string name)
14671361 TableAddLine ( table ) ;
14681362 TableAddLine ( table , name ) ;
14691363 }
1470-
1471- #region Native code
1472- [ StructLayout ( LayoutKind . Sequential , Size = 64 ) ]
1473- public class MEMORYSTATUSEX
1474- {
1475- public uint Size ;
1476- public uint MemoryLoad ;
1477- public ulong TotalPhysical ;
1478- public ulong AvailablePhysical ;
1479- public ulong TotalPageFile ;
1480- public ulong AvailablePageFile ;
1481- public ulong TotalVirtual ;
1482- public ulong AvailableVirtual ;
1483- public ulong AvailableExtendedVirtual ;
1484- }
1485-
1486- [ StructLayout ( LayoutKind . Sequential , Size = 40 ) ]
1487- struct PROCESS_MEMORY_COUNTERS
1488- {
1489- public int Size ;
1490- public int PageFaultCount ;
1491- public int PeakWorkingSetSize ;
1492- public int WorkingSetSize ;
1493- public int QuotaPeakPagedPoolUsage ;
1494- public int QuotaPagedPoolUsage ;
1495- public int QuotaPeakNonPagedPoolUsage ;
1496- public int QuotaNonPagedPoolUsage ;
1497- public int PagefileUsage ;
1498- public int PeakPagefileUsage ;
1499- }
1500-
1501- [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
1502- static extern bool GlobalMemoryStatusEx ( [ In , Out ] MEMORYSTATUSEX buffer ) ;
1503-
1504- [ DllImport ( "psapi.dll" , SetLastError = true ) ]
1505- static extern bool GetProcessMemoryInfo ( IntPtr hProcess , out PROCESS_MEMORY_COUNTERS counters , int size ) ;
1506-
1507- [ DllImport ( "kernel32.dll" ) ]
1508- static extern IntPtr OpenProcess ( int dwDesiredAccess , [ MarshalAs ( UnmanagedType . Bool ) ] bool bInheritHandle , int dwProcessId ) ;
1509-
1510- readonly IntPtr ProcessHandle ;
1511- PROCESS_MEMORY_COUNTERS ProcessMemoryCounters ;
1512- readonly ulong ProcessVirtualAddressLimit ;
1513- #endregion
1514-
1515- public ulong GetWorkingSetSize ( )
1516- {
1517- // Get memory usage (working set).
1518- GetProcessMemoryInfo ( ProcessHandle , out ProcessMemoryCounters , ProcessMemoryCounters . Size ) ;
1519- return ( ulong ) ProcessMemoryCounters . WorkingSetSize ;
1520- }
1521-
1522- public ulong GetVirtualAddressLimit ( )
1523- {
1524- var buffer = new MEMORYSTATUSEX { Size = 64 } ;
1525- GlobalMemoryStatusEx ( buffer ) ;
1526- return Math . Min ( buffer . TotalVirtual , buffer . TotalPhysical ) ;
1527- }
1528-
1529- void UpdatePerformanceCounters ( )
1530- {
1531- // Only update CLRMemoryAllocatedBytesPerSec with non-zero values
1532- var clrMemoryAllocatedBytesPerSec = CLRMemoryAllocatedBytesPerSecCounter ? . NextValue ( ) ?? 0 ;
1533- if ( clrMemoryAllocatedBytesPerSec >= 1 ) CLRMemoryAllocatedBytesPerSec = clrMemoryAllocatedBytesPerSec ;
1534- CPUMemoryPrivate = CPUMemoryPrivateCounter ? . NextValue ( ) ?? 0 ;
1535- CPUMemoryWorkingSet = CPUMemoryWorkingSetCounter ? . NextValue ( ) ?? 0 ;
1536- CPUMemoryWorkingSetPrivate = CPUMemoryWorkingSetPrivateCounter ? . NextValue ( ) ?? 0 ;
1537- CPUMemoryVirtual = CPUMemoryVirtualCounter ? . NextValue ( ) ?? 0 ;
1538- GPUMemoryCommitted = GPUMemoryCommittedCounters . Sum ( counter => counter . NextValue ( ) ) ;
1539- GPUMemoryDedicated = GPUMemoryDedicatedCounters . Sum ( counter => counter . NextValue ( ) ) ;
1540- GPUMemoryShared = GPUMemorySharedCounters . Sum ( counter => counter . NextValue ( ) ) ;
1541- }
15421364 }
15431365
15441366 public class HUDGraphSet
0 commit comments