2016-04-25 25 views
3

Ich habe einen HLSL-Shader, einige Ressourcen definiert, etwa ein konstanter Puffer:Kann ich Bindungspunkte in einem kompilierten D3D-Shader ändern?

cbuffer MyCB : register(b0); 

Wenn ich meine Shader kompiliere, werde ich das Register durch das Reflection-API der Lage sein, die Abfrage dann. Aber ist es möglich das Register (zum Beispiel, zu b3) in einem kompilierten Shader Blob in ähnlicher Weise zu ändern, können Sie Bindungspunkte zu Ressourcen in einem kompilierten OpenGL-Programm zuweisen?

Antwort

3

Es gibt keine API zum Ändern der Shaderbindungen zur Laufzeit in einem kompilierten Shader.

Wenn Sie durch viele Reifen gesprungen sind, könnten Sie dies mit dynamic shader linking im Shader Model 5.0 erreichen, obwohl es eine Menge Arbeit wäre und es nicht wirklich wert wäre, wenn es eine sehr einfache Alternative gibt - einfach ein neues erstellen kompilierter Shader mit den gewünschten Bindungen.

+0

Sie können auch die [shader linking] (https://msdn.microsoft.com/en-us/library/windows/desktop/dn466359.aspx) Technologie betrachten - eine Direct3D 11, die der alten entspricht "FWLINK" -Technik –

+0

@MuertoExcobito Ich möchte die Bindungen zur Laufzeit ändern. Der Grund dafür ist, dass in D3D12 ein Problem auftritt, wenn Ressourcen von verschiedenen Shader-Stufen (PS und VS) demselben Register zugeordnet werden: Solche Ressourcen müssen in verschiedene Deskriptor-Tabellen eingegeben werden. Ich möchte, dass alle meine Ressourcen in einer einzigen Deskriptor-Tabelle sind und ich kann mir nur vorstellen, Bindings in kompilierten Shadern neu zuzuweisen, damit sie sich nicht überschneiden. Ich denke, dass es möglich ist, sich mit dem Bytecode zu beschäftigen (timjones.tw/blog/archive/2015/09/02/...), aber ich hatte gehofft, dass es einen offiziellen Weg gibt, dies zu tun. – Egor

+0

Wenn ich nicht falsch verstanden habe, können Sie einfach Ihre HLSL-Shader bearbeiten und sicherstellen, dass sich die Bindungen nicht überlappen. Das direkte Bearbeiten von Bytecode ist möglich, aber mühsam und nicht unbedingt vorwärtskompatibel. – MuertoExcobito

1

Sie können dies durch die Angabe eines BaseShaderRegister ungleich Null ist, oder unter Verwendung verschiedener RegisterSpace Werte in der D3D12_DESCRIPTOR_RANGE Struktur in erreichen. Wenn Codeänderungen nicht möglich sind, können Sie jeden Satz von Registern implizit isolieren, indem Sie die Eigenschaft ShaderVisibility des Root-Parameters festlegen. Dies isoliert zum Beispiel VSb0 von PSb0. Weitere Informationen finden Sie unter developer video zum Thema.

Das einzige Mal, dass Sie Probleme bekommen, ist, wenn Sie tatsächlich zwei Ressourcen explizit an denselben Slot gebunden haben und Speicherplatz registrieren (indem Sie ihn explizit mit der Syntax des Shadermodells 5.1 angeben). In diesem Fall wird von Ihnen erwartet, dass Sie wissen, dass Register in D3D12 über Kreuz geteilt werden, und es liegt an Ihnen, sicherzustellen, dass Sie keine Kollisionen haben.

In D3D11, tritt dieses Problem nicht, da jede Stufe ein eigenes Register Raum (VSb0 ist nicht das gleiche wie PSb0) und Sie nicht Aktien selbst wenn man wollte. Dennoch, wenn Sie aus irgendeinem Grund eine Komponente hart-codiert haben, um Daten an VSb0 anzuhängen, aber Ihr Vertex-Shader wurde bereits kompiliert, um es bei b1 zu erwarten, können Sie nicht viel tun.

+0

Ich habe darüber nachgedacht, genau das Gleiche zu tun: verschiedene Shaderstufen mit unterschiedlichen Leerzeichen zu versehen, um alle Deskriptoren in einer Tabelle zu haben. Das Problem ist, dass ich keinen Zugriff auf den Shader-Quellcode haben möchte.Wenn ich in der Lage wäre, den Shader-Code wie folgt zu ändern: cbuffer CBinVS: register (b0, space0); 'und' cbuffer CBinPS: register (b0, space1); ', das würde mein Problem lösen. Was ich habe, ist der Quellcode mit Registerbindungen, die möglicherweise in Konflikt stehen. Und ich frage mich, ob ich solche Konflikte programmatisch korrigieren kann _ohne den Quellcode zu ändern. – Egor

+0

@Egor Sofern Sie den Quellcode nicht bereits geändert haben, um den Registerbereich explizit anzugeben, sollten sie sich bereits in anderen Bereichen befinden. Alle Vertex-Shader-Bindungen sind im Raum 0 und alle Pixel-Shader-Bindungen sind im Raum 4. – MooseBoys

+0

_Alle Vertex-Shader-Bindungen sind im Raum 0 und alle Pixel-Shader-Bindungen sind im Raum 4_ Wie hast du das erreicht? Diese [MSDN-Seite] (https://msdn.microsoft.com/en-us/library/windows/desktop/dn899207 (v = vs.85) .aspx) sagt speziell: Wenn das Schlüsselwort "space" weggelassen wird, wird das Der Standardraumindex von 0 wird implizit dem Bereich zugewiesen. Ich habe das überprüft und alle Bindungen in allen Shaderstufen sind in der Tat 0. – Egor