Early Z Culling, UAVs und Tiefentests
Early Z Culling, UAVs und Tiefentests
Warum gibt es eigentlich keinen post-Pixel-Shader Z-Reject für UAVs?
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Weil dann längst alles zu spät ist. Wer weiß, was in der Zwischenzeit reingeschrieben wurde.
Nebenbei: \cite, \ref, \emph, there, their, then, than, alles verschwimmt ... aber die Müdigkeit hilft, einfachere Sätze zu konstruieren.
Nebenbei: \cite, \ref, \emph, there, their, then, than, alles verschwimmt ... aber die Müdigkeit hilft, einfachere Sätze zu konstruieren.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Jammer-Thread
UAVs in Zukunft ein Flag geben (write-through on z-pass; im Pixel-Shader selbst ist die UAV nur read-only), und wenn der Pixel-Shader den z-Test passiert, den write-through durchführen. Natürlich sind das Einschränkungen; aber dennoch würde das die Verwendbarkeit von UAVs wohl doch einigermaßen erhöhen.CodingCat hat geschrieben:Weil dann längst alles zu spät ist. Wer weiß, was in der Zwischenzeit reingeschrieben wurde.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Kostet aber vermutlich Zusatz-Hardware, weil der ganze Kram dann zwischengespeichert werden muss?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Jammer-Thread
Ja natürlich kosten Features Zusatz-Hardware; wenn ich die flickernde Scheiße hier betrachte wäre mir das das aber wert. Der einzige Ausweg ist wohl, wie es mir aktuell erscheint, ein z-Prepass.CodingCat hat geschrieben:Kostet aber vermutlich Zusatz-Hardware, weil der ganze Kram dann zwischengespeichert werden muss?
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Du hast keine Möglichkeit, konservative Tiefen mit early-z rauszuschreiben?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Ist early-z in D3D11 denn garantiert? Das wäre mir sehr neu, normalerweise kann die GPU early-z Optimierungen nur unter ganz bestimmten Vorraussetzungen durchführen und auch dann nicht unbedingt auf per Fragment level. Es ist eben nur eine Optimierung, ich würde mich nie auf sowas als integralen Bestandteil meiner Programmlogik verlassen. Möglicherweise ist die GPU sogar gezwungen, early-z zu deaktivieren, wenn ein PixelShader in ein UAV schreibt!?
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
dot: Ja, du kannst es mit [earlydepthstencil] vor dem Pixel Shader erzwingen. Und nein, Early-Z funktioniert auch bei UAV-Access. Wieso auch nicht, UAVs garantieren eh so gut wie nichts. Sogar eigene Tiefen rausschreiben geht mit Early-Z, solange du mit SV_Depth[Less|LessEqual|GreaterEqual|Greater] garantierst, dass deine Tiefen die für korrektes Early-Z notwendige Monotonie einhalten. (Über die von dir angesprochene Hi-Z-Optimierung sagt [earlydepthstencil] btw. nichts aus.)
eXile: Alternativ kannst du natürlich eigene Tiefenpufferung per UAV implementieren, z.B. so:
Das ist mit Sicherheit wesentlich langsamer als ROPs auf Render Targets, erlaubt dir aber atomares Update beliebig vieler Größen in Abhängigkeit des Tiefentests.
eXile: Alternativ kannst du natürlich eigene Tiefenpufferung per UAV implementieren, z.B. so:
Code: Alles auswählen
int lastDepthOrLocked = 0;
do
{
// Optional early-out, if beneficial
if (depth >= abs(DepthBuffer[pos]))
break;
// Update depth buffer
InterlockedMin(DepthBuffer[pos], depth, lastDepthOrLocked);
if (depth < lastDepthOrLocked)
{
// Lock frame buffer via depth buffer
int lastDepth = 0;
InterlockedCompareExchange(DepthBuffer[pos], depth, -depth, lastDepth);
if (lastDepth == depth)
{
// Update UAVs
// Unlock frame buffer via depth buffer
InterlockedExchange(DepthBuffer[pos], depth);
}
}
} while(lastDepthOrLocked < 0);
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Jammer-Thread
Ich hatte gestern Abend fast das gleiche implementiert; auch wenn ich eine eigene Spin-Lock-UAV benutzt hatte (weil ich die Tiefen gerade noch als floats speichere). Irgendwo steckt hier aber noch der Wurm drin: Treiber-Resets und sogar zwei Neustarts (wegen eingefrorenem Systems trotz Watchdog) habe ich schon hinter mir.
Oh die wundervolle, mutige neue Welt der UAVs voller Treiberbugs. Vielen Dank für die Antwort, ich melde mich wieder wenn ich Benchmark-Zahlen habe.
Oh die wundervolle, mutige neue Welt der UAVs voller Treiberbugs. Vielen Dank für die Antwort, ich melde mich wieder wenn ich Benchmark-Zahlen habe.
Zuletzt geändert von eXile am 09.09.2012, 11:50, insgesamt 1-mal geändert.
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Naja, es wohl offenbar genau wie ich vermutet hab:CodingCat hat geschrieben:dot: Ja, du kannst es mit [earlydepthstencil] vor dem Pixel Shader erzwingen. Und nein, Early-Z funktioniert auch bei UAV-Access. Wieso auch nicht, UAVs garantieren eh so gut wie nichts. Sogar eigene Tiefen rausschreiben geht mit Early-Z, solange du mit SV_Depth[Less|LessEqual|GreaterEqual|Greater] garantierst, dass deine Tiefen die für korrektes Early-Z notwendige Monotonie einhalten. (Über die von dir angesprochene Hi-Z-Optimierung sagt [earlydepthstencil] btw. nichts aus.)
Ist imo auch logisch, da eine Optimierung nicht einfach so das beobachtbare Verhalten des Programms verändern sollte. Allerdings kannst du es wohl mit [earlydepthstencil] erzwingen, das is inzwischen wohl irgendwie wieder aus meinem Bewusstsein verschwunden.MSDN hat geschrieben:An application can force early depth-stencil testing by supplying the attribute or the hardware may execute early depth-stencil testing provided no depth values are written and no unordered access operations are performed in a shader as an optimization.
Zuletzt geändert von dot am 09.09.2012, 12:00, insgesamt 3-mal geändert.
Re: Jammer-Thread
Um es noch einmal klar zu machen: [earlydepthstencil] benutze ich natürlich schon; dennoch können Dreiecke bei konkaven Objekten aufpoppen.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Klar, die Idee hinter [earlydepthstencil] ist ja gerade, dass die Anwendung erklären kann, dass sie mit Early-Z-Culling umgehen kann.
Vorsicht mit Spin Locks: Immer im Locked-Fall Instruktionen überspringen und im Unlocked-Fall "spinnen" (umgekehrt zu typischen Spin Locks auf CPU, siehe Beispiel), andernfalls haut dich das SIMT-Modell direkt in den Deadlock. (Im Locked-Fall spinnende Threads würden sämtliche Unlocked-Threads in derselben Thread-Gruppe blockieren.)eXile hat geschrieben:Ich hatte gestern Abend fast das gleiche implementiert; auch wenn ich eine eigene Spin-Lock-UAV benutzt hatte (weil ich die Tiefen gerade noch als floats speichere). Irgendwo steckt hier aber noch der Wurm drin: Treiber-Resets und sogar zwei Neustarts (wegen eingefrorenem Systems trotz Watchdog) habe ich schon hinter mir.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Wenn ihr eigenes Depth Buffering implementieren wollt, ist ein gängiger Trick, einfach atomicMin() bzw. atomicMax() zu benutzen. Ja, das gibts nicht für floats, aber IEEE floats haben die nette Eigenschaft, dass das relative Ordering ihrer Bitpattern mit dem Ordering der float Werte übereinstimmt... ;)
Zuletzt geändert von dot am 09.09.2012, 12:16, insgesamt 1-mal geändert.
Re: Jammer-Thread
Ja, das wäre schon. Geht aber nicht auf floats:
Nachtrag: Ach herrje das sagst du ja selbst schon. Ich hab's auch nicht so mit dem Lesen.
Ich muss gleich ganz schnell weg; heute Abend geht's weiter. Thread darf abgetrennt werden.
Code: Alles auswählen
error X3681: ps_5_0 only supports interlocked operations on scalar [cn]int[/cn] or
[cn]uint[/cn] data
Ich muss gleich ganz schnell weg; heute Abend geht's weiter. Thread darf abgetrennt werden.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Das tut mein Depth Buffering Code oben bereits. Das Problem dabei ist, den ganzen Rest in Abhängigkeit des Tiefentests atomar zu aktualisieren, siehe Code-Snippet.dot hat geschrieben:Wenn ihr eigenes Depth Buffering implementieren wollt, ist ein gängiger Trick, einfach atomicMin() bzw. atomicMax() zu benutzen. Ja, das gibts nicht für floats, aber IEEE floats haben die nette Eigenschaft, dass das relative Ordering ihrer Bitpattern mit dem Ordering der float Werte übereinstimmt... ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Ja, mir ging es vor allem um das Problem mit atomicMin() auf float. Allerdings funktioniert das auch nur unter gewissen Einschränkungen, da das Ordering nur für eine Interpretation als signed Magnitude Integer ganz stimmt, nicht fürs Zweierkomplement. Aber unter Umständen gut genug...
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Early Z Culling, UAVs und Tiefentests
Ja, für Tiefentest ist das eigentlich immer gut genug, weil Tiefen selten negative sind. Ansonsten Hilfsfunktionen:
Code: Alles auswählen
/// Converts the given float into an integer bit representation maintaining relative order.
int asint_ordered(float f)
{
int i = asint(f);
if (i < 0)
i = (1 << 31) - i;
return i;
}
int2 asint_ordered(float2 f) { return int2(asint_ordered(f.x), asint_ordered(f.y)); }
int3 asint_ordered(float3 f) { return int3(asint_ordered(f.x), asint_ordered(f.y), asint_ordered(f.z)); }
int4 asint_ordered(float4 f) { return int4(asint_ordered(f.x), asint_ordered(f.y), asint_ordered(f.z), asint_ordered(f.w)); }
/// Converts the given ordered integer bit representation into the corresponding float.
float asfloat_ordered(int i)
{
if (i < 0)
i = (1 << 31) - i;
return asfloat(i);
}
float2 asfloat_ordered(int2 i) { return float2(asfloat_ordered(i.x), asfloat_ordered(i.y)); }
float3 asfloat_ordered(int3 i) { return float3(asfloat_ordered(i.x), asfloat_ordered(i.y), asfloat_ordered(i.z)); }
float4 asfloat_ordered(int4 i) { return float4(asfloat_ordered(i.x), asfloat_ordered(i.y), asfloat_ordered(i.z), asfloat_ordered(i.w)); }
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Ich habe gerade eben testweise sämtliche Synchronisation aus diesem Code genommen:CodingCat hat geschrieben:eXile: Alternativ kannst du natürlich eigene Tiefenpufferung per UAV implementieren, z.B. so:
Das ist mit Sicherheit wesentlich langsamer als ROPs auf Render Targets, erlaubt dir aber atomares Update beliebig vieler Größen in Abhängigkeit des Tiefentests.Code: Alles auswählen
int lastDepthOrLocked = 0; do { // Optional early-out, if beneficial if (depth >= abs(DepthBuffer[pos])) break; // Update depth buffer InterlockedMin(DepthBuffer[pos], depth, lastDepthOrLocked); if (depth < lastDepthOrLocked) { // Lock frame buffer via depth buffer int lastDepth = 0; InterlockedCompareExchange(DepthBuffer[pos], depth, -depth, lastDepth); if (lastDepth == depth) { // Update UAVs // Unlock frame buffer via depth buffer InterlockedExchange(DepthBuffer[pos], depth); } } } while(lastDepthOrLocked < 0);
Code: Alles auswählen
// Optional early-out, if beneficial
if (depth >= abs(DepthBuffer[pos]))
break;
// Update depth buffer
int lastDistBits = 0;
InterlockedMin(DepthBuffer[pos], depth, lastDistBits);
if (depth < lastDistBits)
{
// Update UAVs
}
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite