[DX11] VertexBuffer vs Shader vs InputLayout
[DX11] VertexBuffer vs Shader vs InputLayout
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.
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.
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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
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.
Ich hab also sowas in der Art
Code: Alles auswählen
com_ptr<ID3D11InputLayout> createInputLayout(device, shader signature) const;
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.
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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.
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.
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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...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.
Mir gefällt es übrigens wesentlich besser als die D3D9 Lösung.
Ja, beim Erzeugen des Layout...Grinch hat geschrieben:Und es kommen Warnings, wenn die Elemente nicht mit erwarteten Elementen im Shader übereinstimmen.
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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?!
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?!
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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.
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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
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
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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 ;)
Re: [DX11] VertexBuffer vs Shader vs InputLayout
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.
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.