@@ -36,6 +36,7 @@ Thread t3;
36
36
Thread t4;
37
37
Thread t6;
38
38
Thread t7;
39
+ Thread t5;
39
40
const uint64_t systemtickfrequency = 19200000 ;
40
41
bool threadexit = false ;
41
42
bool threadexit2 = false ;
@@ -130,8 +131,38 @@ double Rotation_Duty = 0;
130
131
// GPU Usage
131
132
FieldDescriptor fd = 0 ;
132
133
uint32_t GPU_Load_u = 0 ;
134
+ bool GPULoadPerFrame = true ;
133
135
134
136
// NX-FPS
137
+
138
+ struct resolutionCalls {
139
+ uint16_t width;
140
+ uint16_t height;
141
+ uint16_t calls;
142
+ };
143
+
144
+ struct NxFpsSharedBlock {
145
+ uint32_t MAGIC;
146
+ uint8_t FPS;
147
+ float FPSavg;
148
+ bool pluginActive;
149
+ uint8_t FPSlocked;
150
+ uint8_t FPSmode;
151
+ uint8_t ZeroSync;
152
+ uint8_t patchApplied;
153
+ uint8_t API;
154
+ uint32_t FPSticks[10 ];
155
+ uint8_t Buffers;
156
+ uint8_t SetBuffers;
157
+ uint8_t ActiveBuffers;
158
+ uint8_t SetActiveBuffers;
159
+ uint8_t displaySync;
160
+ resolutionCalls renderCalls[8 ];
161
+ resolutionCalls viewportCalls[8 ];
162
+ bool forceOriginalRefreshRate;
163
+ } NX_PACKED;
164
+
165
+ NxFpsSharedBlock* NxFps = 0 ;
135
166
bool GameRunning = false ;
136
167
bool check = true ;
137
168
bool SaltySD = false ;
@@ -144,22 +175,8 @@ float FPSmin = 254;
144
175
float FPSmax = 0 ;
145
176
SharedMemory _sharedmemory = {};
146
177
bool SharedMemoryUsed = false ;
147
- uint32_t * MAGIC_shared = 0 ;
148
- uint8_t * FPS_shared = 0 ;
149
- uint8_t * API_shared = 0 ;
150
- float * FPSavg_shared = 0 ;
151
- bool * pluginActive = 0 ;
152
- uint32_t * FPSticks_shared = 0 ;
153
178
Handle remoteSharedMemory = 1 ;
154
179
155
- struct resolutionCalls {
156
- uint16_t width;
157
- uint16_t height;
158
- uint16_t calls;
159
- };
160
- resolutionCalls* renderCalls_shared = 0 ;
161
- resolutionCalls* viewportCalls_shared = 0 ;
162
-
163
180
// Read real freqs from sys-clk sysmodule
164
181
uint32_t realCPU_Hz = 0 ;
165
182
uint32_t realGPU_Hz = 0 ;
@@ -212,16 +229,17 @@ void LoadSharedMemory() {
212
229
else FPS = 1234 ;
213
230
}
214
231
215
- ptrdiff_t searchSharedMemoryBlock (uintptr_t base) {
232
+ void searchSharedMemoryBlock (uintptr_t base) {
216
233
ptrdiff_t search_offset = 0 ;
217
234
while (search_offset < 0x1000 ) {
218
- MAGIC_shared = (uint32_t *)(base + search_offset);
219
- if (*MAGIC_shared == 0x465053 ) {
220
- return search_offset ;
235
+ NxFps = (NxFpsSharedBlock *)(base + search_offset);
236
+ if (NxFps -> MAGIC == 0x465053 ) {
237
+ return ;
221
238
}
222
239
else search_offset += 4 ;
223
240
}
224
- return -1 ;
241
+ NxFps = 0 ;
242
+ return ;
225
243
}
226
244
227
245
// Check if SaltyNX is working
@@ -252,29 +270,22 @@ void CheckIfGameRunning(void*) {
252
270
if (!check && R_FAILED (pmdmntGetApplicationProcessId (&PID))) {
253
271
GameRunning = false ;
254
272
if (SharedMemoryUsed) {
255
- *MAGIC_shared = 0 ;
256
- * pluginActive = false ;
257
- *FPS_shared = 0 ;
258
- *FPSavg_shared = 0.0 ;
273
+ (NxFps -> MAGIC) = 0 ;
274
+ (NxFps -> pluginActive) = false ;
275
+ (NxFps -> FPS) = 0 ;
276
+ (NxFps -> FPSavg) = 0.0 ;
259
277
FPS = 254 ;
260
278
FPSavg = 254.0 ;
261
279
}
262
280
check = true ;
263
281
}
264
282
else if (!GameRunning && SharedMemoryUsed) {
265
283
uintptr_t base = (uintptr_t )shmemGetAddr (&_sharedmemory);
266
- ptrdiff_t rel_offset = searchSharedMemoryBlock (base);
267
- if (rel_offset > -1 ) {
268
- FPS_shared = (uint8_t *)(base + rel_offset + 4 );
269
- FPSavg_shared = (float *)(base + rel_offset + 5 );
270
- pluginActive = (bool *)(base + rel_offset + 9 );
271
- API_shared = (uint8_t *)(base + rel_offset + 14 );
272
- FPSticks_shared = (uint32_t *)(base + rel_offset + 15 );
273
- renderCalls_shared = (resolutionCalls*)(base + rel_offset + 60 );
274
- viewportCalls_shared = (resolutionCalls*)(base + rel_offset + 60 + (sizeof (resolutionCalls) * 8 ));
275
- *pluginActive = false ;
284
+ searchSharedMemoryBlock (base);
285
+ if (NxFps) {
286
+ (NxFps -> pluginActive) = false ;
276
287
svcSleepThread (100'000'000 );
277
- if (* pluginActive) {
288
+ if ((NxFps -> pluginActive) ) {
278
289
GameRunning = true ;
279
290
check = false ;
280
291
}
@@ -411,6 +422,16 @@ void StartBatteryThread() {
411
422
412
423
Mutex mutex_Misc = {0 };
413
424
425
+ void gpuLoadThread (void *) {
426
+ if (!GPULoadPerFrame && R_SUCCEEDED (nvCheck)) while (!threadexit) {
427
+ u8 average = 5 ;
428
+ u32 temp = 0 ;
429
+ nvIoctl (fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &temp);
430
+ GPU_Load_u = ((GPU_Load_u * (average-1 )) + temp) / average;
431
+ svcSleepThread (16'666'000 );
432
+ }
433
+ }
434
+
414
435
// Stuff that doesn't need multithreading
415
436
void Misc (void *) {
416
437
while (!threadexit) {
@@ -482,13 +503,13 @@ void Misc(void*) {
482
503
}
483
504
484
505
// GPU Load
485
- if (R_SUCCEEDED (nvCheck)) nvIoctl (fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &GPU_Load_u);
506
+ if (R_SUCCEEDED (nvCheck) && GPULoadPerFrame ) nvIoctl (fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &GPU_Load_u);
486
507
487
508
// FPS
488
509
if (GameRunning) {
489
510
if (SharedMemoryUsed) {
490
- FPS = *FPS_shared ;
491
- FPSavg = 19'200'000 .f / (std::accumulate<uint32_t *, float >(FPSticks_shared, FPSticks_shared+ 10 , 0 ) / 10 );
511
+ FPS = (NxFps -> FPS) ;
512
+ FPSavg = 19'200'000 .f / (std::accumulate<uint32_t *, float >(&(NxFps -> FPSticks[ 0 ]), &(NxFps -> FPSticks[ 10 ]) , 0 ) / 10 );
492
513
if (FPSavg > FPSmax) FPSmax = FPSavg;
493
514
if (FPSavg < FPSmin) FPSmin = FPSavg;
494
515
}
@@ -619,6 +640,7 @@ void StartThreads() {
619
640
threadCreate (&t2, CheckCore2, NULL , NULL , 0x1000 , 0x10 , 2 );
620
641
threadCreate (&t3, CheckCore3, NULL , NULL , 0x1000 , 0x10 , 3 );
621
642
threadCreate (&t4, Misc, NULL , NULL , 0x1000 , 0x3F , -2 );
643
+ threadCreate (&t5, gpuLoadThread, NULL , NULL , 0x1000 , 0x3F , -2 );
622
644
if (SaltySD) {
623
645
// Assign NX-FPS to default core
624
646
threadCreate (&t6, CheckIfGameRunning, NULL , NULL , 0x1000 , 0x38 , -2 );
@@ -629,6 +651,7 @@ void StartThreads() {
629
651
threadStart (&t2);
630
652
threadStart (&t3);
631
653
threadStart (&t4);
654
+ threadStart (&t5);
632
655
if (SaltySD) {
633
656
// Start NX-FPS detection
634
657
threadStart (&t6);
@@ -645,13 +668,15 @@ void CloseThreads() {
645
668
threadWaitForExit (&t2);
646
669
threadWaitForExit (&t3);
647
670
threadWaitForExit (&t4);
671
+ threadWaitForExit (&t5);
648
672
threadWaitForExit (&t6);
649
673
threadWaitForExit (&t7);
650
674
threadClose (&t0);
651
675
threadClose (&t1);
652
676
threadClose (&t2);
653
677
threadClose (&t3);
654
678
threadClose (&t4);
679
+ threadClose (&t5);
655
680
threadClose (&t6);
656
681
threadClose (&t7);
657
682
threadexit = false ;
@@ -663,8 +688,8 @@ void FPSCounter(void*) {
663
688
while (!threadexit) {
664
689
if (GameRunning) {
665
690
if (SharedMemoryUsed) {
666
- FPS = *FPS_shared ;
667
- FPSavg = 19'200'000 .f / (std::accumulate<uint32_t *, float >(FPSticks_shared, FPSticks_shared+ 10 , 0 ) / 10 );
691
+ FPS = (NxFps -> FPS) ;
692
+ FPSavg = 19'200'000 .f / (std::accumulate<uint32_t *, float >(&(NxFps -> FPSticks[ 0 ]), &(NxFps -> FPSticks[ 10 ]) , 0 ) / 10 );
668
693
}
669
694
}
670
695
else FPSavg = 254 ;
@@ -916,6 +941,11 @@ void ParseIniFile() {
916
941
}
917
942
batteryTimeLeftRefreshRate = rate;
918
943
}
944
+ if (parsedData[" status-monitor" ].find (" average_gpu_load" ) != parsedData[" status-monitor" ].end ()) {
945
+ auto key = parsedData[" status-monitor" ][" average_gpu_load" ];
946
+ convertToUpper (key);
947
+ GPULoadPerFrame = key.compare (" TRUE" );
948
+ }
919
949
}
920
950
921
951
} else {
0 commit comments