2016-06-28 20 views
0

Ich habe eine Kernelfunktion (Compute Shader), die in der Nähe Pixel eines Pixels aus einer Textur liest und basierend auf den alten Pixelwerten den Wert des aktuellen Pixels aktualisiert (es ist keine einfache Faltung).iOS Metal - Lesen alter Werte beim Schreiben in Textur

Ich habe versucht, eine Kopie der Textur mit BlitCommandEncoder erstellen und füttern die Kernel-Funktion mit 2 Texturen - eine schreibgeschützte und eine andere schreibgeschützt. Leider ist dieser Ansatz GPU-weise zeitaufwendig.

Was ist die effizienteste (GPU- und Speicher-weise) Art, alte Werte aus einer Textur zu lesen, während der Inhalt aktualisiert wird?

+0

Haben Sie Ihre App mit Time Profiler (in Instrumenten) und GPU Frame Capture (in Xcode) profiliert? Wenn Sie feststellen, wie viel Zeit Sie damit verbringen, Ressourcen zuzuweisen, den Kernel zu kopieren und auszuführen, können Sie herausfinden, was Sie zuerst optimieren möchten. – warrenm

+0

@warrenm Vielen Dank für Ihre Antwort. Es stellt sich heraus, dass die Routine, die mit dem "BlitCommandEncoder" arbeitet, eine andere, zeitraubende Funktion aufruft, die die Verzögerung verursacht, die Blit-Operationen waren nicht die primäre Quelle der Verzögerung - es war meine Schuld. Beim Betrachten von GPU Frame Capture habe ich jedoch festgestellt, dass die Dauer von Blit-Operationen nicht erwähnt wird (im Gegensatz zu Compute-Operationen) - gibt es keine Möglichkeit, diese zu messen (oder fehlt mir etwas)? – sarasvati

+0

Ich glaube nicht, dass es derzeit eine Möglichkeit gibt, die Dauer von Compute-Encodern in GPU Frame Capture zu erfassen, sorry. – warrenm

Antwort

2

(Bit spät, aber oh well)

Es gibt keine Möglichkeit, es mit der Arbeit nur eine Textur, weil die GPU machen könnte, ist eine hochparallele Prozessor: Ihr Kernel, die Sie für ein einzelnes Pixel schrieb aufgerufen wird Parallel zu allen Pixeln kannst du nicht sagen, welcher zuerst geht.

Sie brauchen also unbedingt 2 Texturen. Die Art und Weise, wie Sie es wahrscheinlich tun sollten, besteht darin, zwei Texturen zu verwenden, wobei die eine die "alte" und die andere die "neue" ist. Zwischen Pässen wechseln Sie die Rolle der Texturen, jetzt ist alt neu und neu alt. Hier sind einige PseudoSwift:

0

Ich habe viel iOS-Metall-Code geschrieben, der Proben (oder liest) aus der gleichen Textur, in die es Rendering ist. Ich benutze die Render-Pipeline, setze meine Textur als Renderziel-Anhang und lade sie auch als Quelltextur. Es funktioniert gut.

klar zu sein, ein effizienterer Ansatz ist es, die color() Attribut in Ihrem Fragment-Shader zu verwenden, aber das ist nur geeignet, wenn alles, was Sie brauchen, wird der Wert des aktuellen Fragment ist, keine anderen in der Nähe Positionen. Wenn Sie von anderen Positionen im Renderziel lesen müssen, würde ich das Renderziel als Quelltextur in den Fragment-Shader laden.