Vielen Dank für die Antwort und die kleine Erklärung.
So etwas habe ich schon ungefähr vermutet. Meine Theorie:
Das GetRenderTargetData hat mein TempSurface vermutlich nur markiert, daß dort jetzt Daten aus dem RenderTargetSurface hingehören,
aber erst, wenn ich auf die Daten im TempSurface zugreife, wird tatsächlich versucht, die Daten vom RenderTargetSurface zum TempSurface zu kopieren,
da kommt dann der GPU-Sync und ich muss warten.
Mmmmh... so ganz kann das aber auch nicht stimmen.
Das GetRenderTargetData braucht zu lange, als das ich davon ausgehen könnte, das es nur als Befehl in einer Warteliste verschwindet.
Wenn ich vor dem LockRect 100 Millisekunden warte, ändert sich an der Dauer vom LockRect nichts.
Ich kann mir hier nur vorstellen, daß das TempSurface wie bereits gesagt, nur zum kopieren markiert wird,
aber das was dann lange dauert, ist das Kopieren der Daten und nicht das Warten auf die GPU.
Wenn ich beim TempSurface zweimal hintereinander LockRect aufrufe, dauert nur das erste LockRect lange,
der zweite LockReckt braucht nur 0 Mikrosekunden, also quasi instant.
Code: Alles auswählen
ClassPerformanceCounter PC;
m_Direct3DDevice9->GetRenderTargetData(m_Direct3DSurface9, m_TempSurface);
UInt64 DurationGetRenderTargetData = PC.GetDurationInMicroseconds(); // 54
PC.Start();
Direct3D9::StructD3DLOCKED_RECT LR;
m_TempSurface->LockRect(&LR, pRect, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_DONOTWAIT | D3DLOCK_DISCARD);
UInt64 DurationLR = PC.GetDurationInMicroseconds(); // 7107
m_TempSurface->UnlockRect();
PC.Start();
Direct3D9::StructD3DLOCKED_RECT D3DLockedRect;
m_TempSurface->LockRect(&D3DLockedRect, pRect, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_DONOTWAIT);
UInt64 DurationLockRect = PC.GetDurationInMicroseconds(); // 0
Auf Direct3D9 wird immer nur von einem Thread gleichzeigt zugegriffen.
Wenn meine Vermutung stimmt, dauert das Kopieren vom RenderTargetSurface zum TempSurface so lange.
Verkleinere ich beide, geht es schneller. Das gleiche umgekehrt, z.B. bei QHD 2560x1440 dauert es immer ca. 30ms.
Ob ich in das RenderTarget male oder nicht, scheint keine spürbaren Auswirkungen auf das LockRect zu haben.
Ziemlich schwach, braucht fast pro Megabyte eine Millisekunde.
Ich hatte mal ein Video gesehen mit John Carmack, wo er sowas andeutet.
The process of updating a textures on the PC is on the order of “tens of thousands of times slower” than on the Xbox 360 and PS3
http://www.pcper.com/reviews/Editorial/ ... s-and-more
Das Interview auf Youtube:
https://www.youtube.com/watch?v=hapCuhAs1nA
Nun gut, weiter Analysieren wird mir wohl nix bringen, da muss ich mich wohl mit Pixel-Shadern rumschlagen.
Das ist natürlich ein ganz schön großer Brocken. Der hqx-Quellcode umfasst ca. 400 Kilobyte,
das in einen Pixel-Shader umzuprogrammieren, wird sicher kein Kinderspiel.