2010-01-10 18 views
7

Ich schreibe meine eigene Grafikbibliothek (yep, seine Hausaufgaben :) und benutze Cuda, um alle Renderings und Berechnungen schnell zu machen.Zeichnen von Dreiecken mit CUDA

Ich habe Probleme mit dem Zeichnen gefüllter Dreiecke. Ich habe es so geschrieben, dass ein Prozess ein Dreieck zeichnet. Es funktioniert ziemlich gut, wenn viele kleine Dreiecke in der Szene sind, aber es bricht die Performance total, wenn Dreiecke groß sind.

Meine Idee ist es, zwei Durchgänge zu machen. Zuerst berechnet man nur Tab mit Informationen über Scanlinien (von hier nach dort zeichnen). Dies wäre ein Dreieck pro Prozessberechnung wie im aktuellen Algorithmus. Zeichnen Sie im zweiten Durchlauf die Scanlinien mit mehr als einem Prozess pro Dreieck.

Aber wird es schnell genug sein? Vielleicht gibt es eine bessere Lösung?

Antwort

3

Sie können dies überprüfen blog: Eine Software-Rendering-Pipeline in CUDA. Ich denke nicht, dass dies der optimale Weg ist, aber zumindest teilt der Autor einige nützliche Quellen.

Zweitens, lesen Sie diese paper: Eine programmierbare, parallele Rendering-Architektur.Ich denke, es ist eines der neuesten Papier und es basiert auch auf CUDA.

Wenn ich dies zu tun hätte, würde ich mit einer Daten-Parallel Rasterung Pipeline wie in Larrabee gehen (die TBR ist) oder sogar REYES und Anpassung an CUDA:

http://www.ddj.com/architect/217200602 http://home.comcast.net/~tom_forsyth/larrabee/Standford%20Forsyth%20Larrabee%202010.zip (siehe zweiter Teil der Präsentation)

http://graphics.stanford.edu/papers/mprast/

0

Ich vermute, dass Sie einige Missverständnisse über CUDA haben und wie man es benutzt, besonders da Sie auf einen "Prozess" verweisen, wenn es in der CUDA-Terminologie so etwas nicht gibt. Für die meisten CUDA-Anwendungen gibt es zwei wichtige Dinge, um eine gute Leistung zu erzielen: Optimieren des Speicherzugriffs und Sicherstellen, dass jeder 'aktive' CUDA-Thread in einem Warp denselben Vorgang ausführt wie andere aktive Threads im Warp. Beide klingen, als wären sie für Ihre Anwendung wichtig.

Um Ihren Speicherzugriff zu optimieren, möchten Sie sicherstellen, dass Ihre Lesevorgänge aus dem globalen Speicher und Ihre Schreibvorgänge in den globalen Speicher zusammengeführt werden. Sie können mehr darüber im CUDA-Programmierhandbuch lesen, aber es bedeutet im Wesentlichen, dass benachbarte Threads in einem Halb-Warp von benachbarten Speicherorten lesen oder in diese schreiben müssen. Außerdem sollte jeder Thread 4, 8 oder 16 Bytes gleichzeitig lesen oder schreiben.

Wenn Ihr Speicherzugriffsmuster zufällig ist, müssen Sie möglicherweise Texturspeicher verwenden. Wenn Sie auf Speicher zugreifen müssen, der von anderen Threads in einem Block gelesen wurde, sollten Sie gemeinsam genutzten Speicher verwenden.

In Ihrem Fall bin ich nicht sicher, was Ihre Eingabedaten sind, aber Sie sollten zumindest sicherstellen, dass Ihre Schreibvorgänge verschmolzen sind. Sie müssen wahrscheinlich einige nicht-triviale Anstrengungen investieren, damit Ihre Lesevorgänge effizient funktionieren.

Für den zweiten Teil würde ich empfehlen, dass jeder CUDA-Thread ein Pixel in Ihrem Ausgabebild verarbeitet. Bei dieser Strategie sollten Sie auf Schleifen in Ihren Kerneln achten, die abhängig von den Daten pro Thread länger oder kürzer ausgeführt werden. Jeder Thread in Ihren Warps sollte die gleiche Anzahl von Schritten in derselben Reihenfolge ausführen. Die einzige Ausnahme ist, dass es keine wirkliche Leistungseinbuße gibt, wenn einige Threads in einem Warp keine Operation ausführen, während die verbleibenden Threads dieselbe Operation zusammen ausführen.

Daher würde ich empfehlen, jeden Thread überprüfen, ob sein Pixel innerhalb eines bestimmten Dreiecks ist. Wenn nicht, sollte es nichts tun. Wenn dies der Fall ist, sollte die Ausgabefarbe für dieses Pixel berechnet werden.

Auch würde ich dringend empfehlen, mehr über CUDA zu lesen, da es scheint, als ob Sie in das tiefe Ende springen, ohne ein gutes Verständnis einiger grundlegender Grundlagen zu haben.

+1

Sorry über meine Sprache, Englisch ist nicht meine Muttersprache. Was ist die richtige Terminologie für die Verarbeitung von Grafikkarten? Nun, ich denke, ich verstehe CUDA ziemlich gut, aber ja, ich habe Mangel an Wissen in parallelen Algorithmen. Meine Eingabe besteht aus Scheitelpunkten im Clipping-Bereich, und ich musste Dreiecke zeichnen. Ich denke Algorithmus wo jedes Pixel sollte jedes Dreieck überprüfen würde nicht optimal sein. – qba

+0

Vermeiden Sie jedes Pixel, das jedes Dreieck überprüft, indem Sie Ihre Dreiecke mit einem BVH, KD-Tree oder R-Tree partitionieren. – whatnick

-1

nicht unhöflich zu sein, aber es ist nicht das, was Grafikkarten ausgelegt ist, auf jeden Fall zu tun? Scheint so, als ob die Verwendung der Standard APIs OpenGL und Direct3D mehr Sinn machen würde.

Warum nicht die APIs verwenden, um Ihre grundlegenden Rendering, anstatt CUDA, die viel niedriger Ebene ist? Wenn Sie zusätzliche Operationen ausführen möchten, die nicht unterstützt werden, können Sie sie mit CUDA oben anwenden. Oder sie als Shader implementieren.

+0

Ja, ja tatsächlich. Aber sein Ziel ist es, eine grafische Rasterungspipeline OHNE die traditionellen APIs zu erstellen. Betrachten Sie es als einen Beweis des Konzeptes oder des pädagogischen Zweckprojektes. – Stringer

+0

Ja sein Projekt für meine Studien. Wir mussten die Rasterung selbst durchführen. Die meisten Leute benutzen CPU, aber ich entschied mich für CUDA. – qba

+0

Hmm, in diesem Fall klingt es wie ein interessantes Projekt. Eine Art Back-Assward-Ansatz, aber trotzdem interessant. – BobMcGee