[DX11] VertexBuffer vs Shader vs InputLayout

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

[DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von Grinch »

Ich probiere derzeit optimiert das InputLayout für meine Vertexshader zu erstellen und dadurch aus den Modellen nur noch die Buffer mit IASetVertexBuffer zu setzen, die wirklich notwendig sind.
Dafür lese ich per D3DReflect das InputLayout aus dem Shader aus. Das funktioniert auch soweit ganz gut.
Das einzige Problem an dieser Methode ist der Slot und das Offset für die einzelnen InputElements. Aus dem Shader kann man diese logischerweise nicht auslesen, da man diese auch dort nicht angibt. Nur die Modelle mit der Liste der VertexBuffer und die Buffer wissen, welche Daten sie enthalten. Zu dem Zeitpunkt, wo ich den Shader und das InputLayout erstelle ist das Modell noch nicht vorhanden.
Normalerweise arbeite ich immer so, dass ich Position, Normalen, TexCoords,... jeweils in einen eigenen Buffer packe, also der Offset 0 ist und der Slot variiert. Theoretisch kann es aber auch Mischformen von Buffern mit mehreren Elementen geben. Der Shader sollte auch möglichst wiederverwendet werden können für unterschiedliche Modelle.
Bisher hatte ich das InputLayout immer an das Modell gekoppelt, wodurch aber für einige Shader zu viele VertexBuffer gesetzt werden.
Ich hoffe man versteht, was ich meine :mrgreen:

Die Frage ist, wie macht ihr das? Einfach als Konvention festlegen, dass Elemente immer in einzelnen Buffern geschrieben sein müssen. Oder immer alle Daten in einen Buffer schreiben und nur den Offset verschieben? Oder gibt es evtl. eine elegante Lösung, wie man geschickt InputLayout mit verschiedenen Elementkonstellationen erstellen kann.
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von dot »

Bei mir kümmert sich das Modell ums Erzeugen des Input Layout, immerhin ist das das einzige Objekt, das das genaue Layout seiner Buffer kennt.
Ich hab also sowas in der Art

Code: Alles auswählen

com_ptr<ID3D11InputLayout> createInputLayout(device, shader signature) const;
Oft mach ich es auch so, dass das Model Objekt selbst gar nicht rendert, sondern nur die Daten hält.
Man erzeugt dann z.B. ein Model::Drawable Objekt, das den Shader mit den Buffern verknüpft und erst das setzt dann den Draw Call ab.

Eigene Buffer für Position, Normale und Texcoords sind übrigens nicht unbedingt ideal, da GPUs es potentiell lieber haben, wenn die Daten interlaced sind.
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von Grinch »

Diese Verknüpfung von InputLayout und Shader finde ich bei DX10/11 semioptimal. Bei DX9 konnte man das InputLayout (VertexDeclaration) noch ohne Shader erstellen und einfach setzen. Genauso kann man jetzt das erzeugte InputLayout auch für andere Shader benutzen, auch wenn es nicht mit diesem erzeugt wurde. Und es kommen Warnings, wenn die Elemente nicht mit erwarteten Elementen im Shader übereinstimmen. Funktioniert aber trotzdem. Also braucht DX11 eigentlich den Shader zum Erstellen auch nicht.
Deswegen war meine Idee auch, dass der Shader sein Inputlayout selbst erstellt und dann beim Rendern aus dem Modell nur seine benötigten Buffer holt und setzt. Das funktioniert mit einzelnen Buffern ziemlich einfach. Wenn man alles in einen Buffer packt, wird es kompliziert, da sich die Offsets von Modell zu Modell verschieben können und damit eine neues InputLayout notwendig wird.
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von dot »

Grinch hat geschrieben:Diese Verknüpfung von InputLayout und Shader finde ich bei DX10/11 semioptimal. Bei DX9 konnte man das InputLayout (VertexDeclaration) noch ohne Shader erstellen und einfach setzen.
Ja, das ist vielleicht semioptimal für den Programmierer, weil der mehr denken muss, aber es ist wesentlich effizienter was den Overhead in der Runtime bzw. im Driver angeht, da die Shader Signature nur einmal beim Erzeugen des Layout gegen das Buffer Layout validiert werden muss. Bei D3D9 musste im schlimmsten Fall bei jedem einzelnen Draw Call neu validiert werden...

Mir gefällt es übrigens wesentlich besser als die D3D9 Lösung.
Grinch hat geschrieben:Und es kommen Warnings, wenn die Elemente nicht mit erwarteten Elementen im Shader übereinstimmen.
Ja, beim Erzeugen des Layout...
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von Grinch »

Das mit dem Validieren kann aber so auch nicht ganz stimmen.
Wenn ich als Bufferelemente
Position
Normal
Texcoord

habe und mit einem Shader, der nur Position benötigt das InputLayout erzeuge, kommen die Warnings beim Erzeugen.

Trotzdem kann ich das Inputlayout bei einem anderen Shader verwenden, der alle 3 Elemente verwendet. Für diesen wurde das Layout aber nicht validiert?!
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von dot »

Reines Glück, würd mich interessieren, ob das ohne Debug Runtime immer noch funktioniert und was passiert, wenn position mal nicht das erste Element ist...
MSDN hat geschrieben:You can create a single input-layout object for many shaders, as long as all of the shader-input signatures exactly match.
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von Grinch »

Wie machst du es dann, wenn du das gleiche Modell mit 2 Shadern ausgeben willst?
Für jeden Shader im Modell das entsprechende InputLayout erstellen und speichern? Die Liste kann u.U. ganz schön groß werden. Man kann zwar mit einem Pool arbeiten, trotzdem braucht man hier eine Mapping Shader<>InputLayout
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von dot »

Ich hab nur ein Layout pro Kombination von Shader und Model Klasse, nicht eines für jedes Model, da alle Instanzen der selben Klasse wohl das selbe Layout haben werden ;)
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

Re: [DX11] VertexBuffer vs Shader vs InputLayout

Beitrag von Grinch »

Ich werde meinen Ansatz mit dem InputLayout im Shader und dem raussuchen der benötigten Buffer mal zu Ende führen.
Evtl. baue ich dann nochmal um, dass das InputLayout doch im Modell zusammengebaut wird, hier aber auch mit Reflection aus dem Shader. Dann kann man dort direkt das InputLayout immer korrekt mit den Slots und Offsets zusammenbauen und es kommen auch keine Warnings.Denke das ist dann die Maximallösung.
Antworten