8
8
#include " Cafe/HW/Latte/Core/LatteTexture.h"
9
9
#include " Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
10
10
11
- // #define LOG_READBACK_TIME
11
+ // #define LOG_READBACK_TIME
12
12
13
13
struct LatteTextureReadbackQueueEntry
14
14
{
15
+ HRTick initiateTime;
15
16
uint32 lastUpdateDrawcallIndex;
16
17
LatteTextureView* textureView;
17
18
};
@@ -22,12 +23,12 @@ std::queue<LatteTextureReadbackInfo*> sTextureActiveReadbackQueue; // readbacks
22
23
void LatteTextureReadback_StartTransfer (LatteTextureView* textureView)
23
24
{
24
25
cemuLog_log (LogType::TextureReadback, " [TextureReadback-Start] PhysAddr {:08x} Res {}x{} Fmt {} Slice {} Mip {}" , textureView->baseTexture ->physAddress , textureView->baseTexture ->width , textureView->baseTexture ->height , textureView->baseTexture ->format , textureView->firstSlice , textureView->firstMip );
26
+ HRTick currentTick = HighResolutionTimer ().now ().getTick ();
25
27
// create info entry and store in ordered linked list
26
28
LatteTextureReadbackInfo* readbackInfo = g_renderer->texture_createReadback (textureView);
27
29
sTextureActiveReadbackQueue .push (readbackInfo);
28
30
readbackInfo->StartTransfer ();
29
- // debug_printf("[Tex-Readback] %08x %dx%d TM %d FMT %04x\n", textureView->baseTexture->physAddress, textureView->baseTexture->width, textureView->baseTexture->height, textureView->baseTexture->tileMode, textureView->baseTexture->format);
30
- readbackInfo->transferStartTime = HighResolutionTimer ().now ().getTick ();
31
+ readbackInfo->transferStartTime = currentTick;
31
32
}
32
33
33
34
/*
@@ -41,9 +42,15 @@ bool LatteTextureReadback_Update(bool forceStart)
41
42
for (size_t i = 0 ; i < sTextureScheduledReadbacks .size (); i++)
42
43
{
43
44
LatteTextureReadbackQueueEntry& entry = sTextureScheduledReadbacks [i];
44
- uint32 numPassedDrawcalls = LatteGPUState.drawCallCounter - entry.lastUpdateDrawcallIndex ;
45
- if (forceStart || numPassedDrawcalls >= 5 )
45
+ uint32 numElapsedDrawcalls = LatteGPUState.drawCallCounter - entry.lastUpdateDrawcallIndex ;
46
+ if (forceStart || numElapsedDrawcalls >= 5 )
46
47
{
48
+ #ifdef LOG_READBACK_TIME
49
+ double elapsedSecondsSinceInitiate = HighResolutionTimer::getTimeDiff (entry.initiateTime , HighResolutionTimer ().now ().getTick ());
50
+ char initiateElapsedTimeStr[32 ];
51
+ sprintf (initiateElapsedTimeStr, " %.4lfms" , elapsedSecondsSinceInitiate);
52
+ cemuLog_log (LogType::TextureReadback, " [TextureReadback-Update] Starting transfer for {:08x} after {} elapsed drawcalls. Time since initiate: {} Force-start: {}" , entry.textureView ->baseTexture ->physAddress , numElapsedDrawcalls, initiateElapsedTimeStr, forceStart?" yes" :" no" );
53
+ #endif
47
54
LatteTextureReadback_StartTransfer (entry.textureView );
48
55
// remove element
49
56
vectorRemoveByIndex (sTextureScheduledReadbacks , i);
@@ -91,6 +98,7 @@ void LatteTextureReadback_Initate(LatteTextureView* textureView)
91
98
}
92
99
// queue
93
100
LatteTextureReadbackQueueEntry queueEntry;
101
+ queueEntry.initiateTime = HighResolutionTimer ().now ().getTick ();
94
102
queueEntry.textureView = textureView;
95
103
queueEntry.lastUpdateDrawcallIndex = LatteGPUState.drawCallCounter ;
96
104
sTextureScheduledReadbacks .emplace_back (queueEntry);
@@ -112,6 +120,14 @@ void LatteTextureReadback_UpdateFinishedTransfers(bool forceFinish)
112
120
if (!readbackInfo->IsFinished ())
113
121
{
114
122
readbackInfo->waitStartTime = HighResolutionTimer ().now ().getTick ();
123
+ #ifdef LOG_READBACK_TIME
124
+ if (cemuLog_isLoggingEnabled (LogType::TextureReadback))
125
+ {
126
+ double elapsedSecondsTransfer = HighResolutionTimer::getTimeDiff (readbackInfo->transferStartTime , HighResolutionTimer ().now ().getTick ());
127
+ forceLog_printf (" [Texture-Readback] Force-finish: %08x Res %4d/%4d TM %d FMT %04x Transfer time so far: %.4lfms" , readbackInfo->hostTextureCopy .physAddress , readbackInfo->hostTextureCopy .width , readbackInfo->hostTextureCopy .height , readbackInfo->hostTextureCopy .tileMode , (uint32)readbackInfo->hostTextureCopy .format , elapsedSecondsTransfer * 1000.0 );
128
+ }
129
+ #endif
130
+ readbackInfo->forceFinish = true ;
115
131
readbackInfo->ForceFinish ();
116
132
// rerun logic since ->ForceFinish() can recurively call this function and thus modify the queue
117
133
continue ;
@@ -125,10 +141,13 @@ void LatteTextureReadback_UpdateFinishedTransfers(bool forceFinish)
125
141
}
126
142
// performance testing
127
143
#ifdef LOG_READBACK_TIME
128
- HRTick currentTick = HighResolutionTimer ().now ().getTick ();
129
- double elapsedSecondsTransfer = HighResolutionTimer::getTimeDiff (readbackInfo->transferStartTime , currentTick);
130
- double elapsedSecondsWaiting = HighResolutionTimer::getTimeDiff (readbackInfo->waitStartTime , currentTick);
131
- cemuLog_log (LogType::Force, " [Texture-Readback] {:08x} Res {:4}/{:4} TM {} FMT {:04x} ReadbackLatency: {:6.3}ms WaitTime: {:6.3}ms ForcedWait {}" , readbackInfo->hostTextureCopy .physAddress , readbackInfo->hostTextureCopy .width , readbackInfo->hostTextureCopy .height , readbackInfo->hostTextureCopy .tileMode , (uint32)readbackInfo->hostTextureCopy .format , elapsedSecondsTransfer * 1000.0 , elapsedSecondsWaiting * 1000.0 , forceFinish?" yes" :" no" );
144
+ if (cemuLog_isLoggingEnabled (LogType::TextureReadback))
145
+ {
146
+ HRTick currentTick = HighResolutionTimer ().now ().getTick ();
147
+ double elapsedSecondsTransfer = HighResolutionTimer::getTimeDiff (readbackInfo->transferStartTime , currentTick);
148
+ double elapsedSecondsWaiting = HighResolutionTimer::getTimeDiff (readbackInfo->waitStartTime , currentTick);
149
+ forceLog_printf (" [Texture-Readback] %08x Res %4d/%4d TM %d FMT %04x ReadbackLatency: %6.3lfms WaitTime: %6.3lfms ForcedWait %s" , readbackInfo->hostTextureCopy .physAddress , readbackInfo->hostTextureCopy .width , readbackInfo->hostTextureCopy .height , readbackInfo->hostTextureCopy .tileMode , (uint32)readbackInfo->hostTextureCopy .format , elapsedSecondsTransfer * 1000.0 , elapsedSecondsWaiting * 1000.0 , readbackInfo->forceFinish ? " yes" : " no" );
150
+ }
132
151
#endif
133
152
uint8* pixelData = readbackInfo->GetData ();
134
153
LatteTextureLoader_writeReadbackTextureToMemory (&readbackInfo->hostTextureCopy , 0 , 0 , pixelData);
0 commit comments