PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dynamic Branching mit GLSL


Asmodeus
2004-10-22, 14:48:09
Mich würde interessieren, welche Extensions ich verwenden muss, welchen Treiber und was eventuell noch alles nötig ist, damit ich in meinen GLSL-Fragmentprogrammen Dynamic Branching auf einer 6800ter Karte verwenden kann.

Gruss, Carsten.

Coda
2004-10-22, 14:51:37
Hm da müsste nVidia erstmal ne entsprechende Extension bringen.
Bisher gibt's das nur als Erweiterung für ARB_fragment_program (NV_fragment_program2)

RLZ
2004-10-22, 15:00:46
Sicher?
Da man den Shadersourcecode ja dem Treiber übergibt, müsste der beim Compilieren doch automatisch alles nutzen was ihm zur Verfügung steht.
So war doch eigentlich die Grundidee bei GLSL *grübel*
Wenn du eine SM 3.0 Karte hast kannst du das doch einfach testen.
Bau nen Shader mit ner Verzweigung drin. Ein Zweig geht auf ne super billige Berechnung und einer auf ne arschteure. Und fütter ihn dann mit einheitlichen Daten zum Testen.

Asmodeus
2004-10-22, 15:12:20
Sicher?
Da man den Shadersourcecode ja dem Treiber übergibt, müsste der beim Compilieren doch automatisch alles nutzen was ihm zur Verfügung steht.
So war doch eigentlich die Grundidee bei GLSL *grübel*
Wenn du eine SM 3.0 Karte hast kannst du das doch einfach testen.
Bau nen Shader mit ner Verzweigung drin. Ein Zweig geht auf ne super billige Berechnung und einer auf ne arschteure. Und fütter ihn dann mit einheitlichen Daten zum Testen.

Ja, werd ich einfach mal probieren. Aber, ich wollte es eigentlich noch simpler (zu simpel?) machen:


vec4 Texture0Color = texture2D(Texture0,gl_TexCoord[0].xy);

if(Texture0Color.a == 0.0)
discard;

// Lichtberechnung folgt ...


Das wäre doch der simpelste Fall einer dynamischen Verzweigung, oder?

Gruss, Carsten.

RLZ
2004-10-22, 15:43:06
Sollte es tun. Pass halt nur auf, dass du Shaderlimitiert bist durch die Lichtberechnung. Sonst ist das Ergebnis nicht sehr aussagekräftig ;)

Asmodeus
2004-10-22, 15:46:51
Sollte es tun. Pass halt nur auf, dass du Shaderlimitiert bist durch die Lichtberechnung. Sonst ist das Ergebnis nicht sehr aussagekräftig ;)

Eine "Instruktion" mehr und auf einer 9800XT muss der Shader in Software ausgeführt werden, ich denke, noch Shaderlimitierter kann man fast nicht sein ;)

Gruss, Carsten.

Coda
2004-10-22, 15:48:38
Da man den Shadersourcecode ja dem Treiber übergibt, müsste der beim Compilieren doch automatisch alles nutzen was ihm zur Verfügung steht.
So war doch eigentlich die Grundidee bei GLSL *grübel*
Nein, GLSL hat einen Standard, will man mehr Features braucht man Extensions.

RLZ
2004-10-22, 16:07:14
Naja im offiziellen GLSL Buch stehts mal imo anders drin.
Ausserdem ists ja nicht wirklich ein neues Feature. Er soll ja die If-Anweisung nur beim Compilieren anders behandeln.
Wir werden aber ja sehen, was beim Test raus kommt.

pajofego
2004-10-22, 16:11:22
Ja, werd ich einfach mal probieren. Aber, ich wollte es eigentlich noch simpler (zu simpel?) machen:


vec4 Texture0Color = texture2D(Texture0,gl_TexCoord[0].xy);

if(Texture0Color.a == 0.0)
discard;

// Lichtberechnung folgt ...


Das wäre doch der simpelste Fall einer dynamischen Verzweigung, oder?

Gruss, Carsten.

Habe diesen Hinweis bzgl. dynamic branching gefunden vielleicht ist er hilfreich:

Hinweis zu discard (http://www.gpgpu.org/forums/viewtopic.php?t=532)

Gruss pajofego

Coda
2004-10-22, 16:52:26
Ausserdem ists ja nicht wirklich ein neues Feature. Er soll ja die If-Anweisung nur beim Compilieren anders behandeln.
Ein if mit einer Konstante ist aber etwas anderes als ein if mit einer Variable.

Corrail
2004-10-22, 17:00:18
AFAIK sollte ab den 65er Treibern CG 1.3 enthalten sein, was es möglich machen sollte die NV40 Features unter GLSL zu nutzen. Sicher bin ich mir da aber nicht, bin noch nicht dazu gekommen es auszutesten.

Gast
2004-10-22, 17:05:07
Nein, GLSL hat einen Standard, will man mehr Features braucht man Extensions.

Definiere Features.
Der Standard beschreibt mehr oder weniger die Grammatik und vorhandene Sprachfeatures ("eingebaute" Varyings beispielsweise).
Die Sprache selber hat dabei keinerlei Einschränkungen, was Schleifen, Verzweigungen oder andere grundlegende Algorithmenbausteine betrifft. Der einzig begrenzende Faktor ist die darunterliegende Hardware. Zum Beispiel kannst du ohne Probleme einen syntaktisch absolut korrekten Vertexshader schreiben, der aus einer Textur sampled, das wird allerdings nur auf'm NV40 funktionieren, andere Hardware wird dir beim compilieren mitteilen, dass es das entweder nicht unterstützt oder in Software emuliert.
GLSL ist definitiv ne ganz nette Geschichte, auch wenn einige Stimmen meinen, die Sprache wäre an einigen Stellen unnötigerweise restrikitv.
Positiv hinzu kommt, dass die "Verwaltung" von GLSL getrennt ist mittels arb_shader_objects. Sollte also es tatsächlich passieren, dass irgendein Grafikchiphersteller entschliesst SM4 vor der Einführung von Longhorn und WGF in einen Chip zu basteln, so muss man lediglich die Extensions definieren, die das neue Shadermodel beschreiben (analog zu den jetzigen Models arb_vertex_shader und arb_fragment_shader). Man kann also die GLSL und arb_program_objects weiterhin genauso nutzen wie bisher, aber anstatt ein vertexshader object oder fragmentshader object zu erstellen, erstellt man ein shader object gemäß den SM4 Aufbau.

ScottManDeath
2004-10-22, 17:09:20
Am besten Du nimmst das nvEmulate Tool (auf der nVidia developer Seite) und schaltest die Option an den ASM Code als Datei auszugeben. Dann siehst Du welches Profil er nutzt und den generierten Code.

Asmodeus
2004-10-22, 17:19:26
Zuerst wäre zu sagen, dass es leider nicht so einfach funktioniert.
Es findet also kein dynamic branching statt, egal, ob ich es mit discard oder eben mit einem eigenen Branch für die komplexe Lichtberechnung versuche.

Über NVemulate erhalte ich ausserdem noch folgende Informationen:


!!ARBfp1.0
OPTION NV_fragment_program2;
OPTION ATI_draw_buffers;
# cgc version 1.3.0001, build date Sep 30 2004 14:14:01
# command line args: -q -profile fp40 -entry main -strict -oglsl -D__GLSL_CG_DATA_TYPES -D__GLSL_CG_STDLIB -D__GLSL_SAMPLER_RECT
#vendor NVIDIA Corporation
#version 1.0.02
#profile fp40
#program main


Treiber ist übrigens der 66.81

Gruss, Carsten.

Asmodeus
2004-10-22, 17:45:45
Ich habe noch mal verschiedene Shader ausprobiert. Und erstaunlich finde ich, dass die sehr komplexen Shader auf einer alten 9800XT schneller laufen, als auf der 6800 Ultra. Kann ich mir auch nicht so richtig erklären.

Gruss, Carsten.

RLZ
2004-10-22, 18:15:41
Weder google noch den opengl.org Forum bringen einen da weiter...
Jetzt mal angenommen, der Compiler wäre in der Lage die dynamic branches zu bauen, könnte es noch passieren, dass er einfach zu doof ist. Vielleicht sieht er ne Möglichkeit das Branching durch einen Vorfaktor einfacher hinzukriegen als durch richtiges dynamic branching, weil der eine Branch einfach leer ist.
Aber eher glaub ich schon, dass NV die Funktionalität noch nicht für GLSL anbieten. Vielleicht weiss ja noch jemand mehr... (Demi?, Zeckensack?)

Ich habe noch mal verschiedene Shader ausprobiert. Und erstaunlich finde ich, dass die sehr komplexen Shader auf einer alten 9800XT schneller laufen, als auf der 6800 Ultra. Kann ich mir auch nicht so richtig erklären.

Eigentlich war ich die Tage schon drauf und dran ne 6800 zu kaufen, weil ich Branches in GLSL benutzen wollte. Irgendwie bringt mich dein Problem und diese Aussage dazu das Ganze doch nochmal stark zu überdenken...
:down:

KiBa
2004-10-22, 21:37:11
uns wie siehts mit sampeln von texturen im vertexshader aus, funktioniert das wenigstens schon?

Asmodeus
2004-10-23, 10:53:24
In dem ganzen Zusammenhang würde mich auch noch mal folgendes interessieren. Welche Pixelshaderversion kann ich denn auf ner ATI 9800XT unter GLSL nutzen und welche Pixelshaderversion auf einer NV 6800 Ultra?
Mir ist nämlich noch folgendes aufgefallen:

So viel ich weiss, kann man unter PS2.0 96 Instruktionen verwenden. Wenn ich nun für GLSL ein Fragmentprogramm mit mehr als 96 Instruktionen schreibe, so meldet mir der ATI Compiler bei meiner 9800XT, dass der Shader in Software ausgeführt werden muss.
Auf der 6800 Ultra lässt sich ein Fragmentprogramm unter GLSL mit mehr als 96 Instruktionen aber auch nicht kompilieren. Dort erhalte ich dann immer die dubiose Fehlermeldung "unbekanntes Zeichen in Zeile XX".

Vielleicht könnte das auch nochmal jemand anderes bei sich testen.

Gruss, Carsten

Corrail
2004-10-23, 11:51:00
Diese 96 Instruktionsbeschränkung gilt auschließlich für DirectX Pixel Shader. Für OpenGL Fragment Programs gibt es diese Limitierung nur wenn die Hardware nicht mehr Instruktionen unterstützt (wie z.B. R3xx). Dein "unbekanntes Zeichen in Zeile XX" Fehler sollte meiner Meinung nach nicht auf Instruktionsbeschränkung zurückzuführen sein.

RLZ
2004-10-23, 11:59:49
Also der 66.81 ist scheinbar der erste Treiber, der die SM3.0 Funktionen unter GLSL zur Verfügung stellt. Könnt mir vorstellen, dass es noch leicht buggy ist....
Versuch mal ne Schleife mit dynamischer Abbruchsbedingung oder Texturzugriff im VS. Das scheint es offenbar normalerweise zu tun (Link (http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=11;t=000446)).

Coda
2004-10-23, 12:04:06
Ich habe noch mal verschiedene Shader ausprobiert. Und erstaunlich finde ich, dass die sehr komplexen Shader auf einer alten 9800XT schneller laufen, als auf der 6800 Ultra. Kann ich mir auch nicht so richtig erklären.

Gruss, Carsten.
Wahrscheinlich ist der ATi GLSL Compiler schon besser. Probier das mal mit ARB_fragment_program.

Asmodeus
2004-10-23, 12:43:13
Also, wie es aussieht, scheint von SM3.0 alles mit GLSL zu funktionieren mit den aktuellen Treibern, ausser eben das dynamische Branchen.

Diese 96 Instruktionsbeschränkung gilt auschließlich für DirectX Pixel Shader. Für OpenGL Fragment Programs gibt es diese Limitierung nur wenn die Hardware nicht mehr Instruktionen unterstützt (wie z.B. R3xx). Dein "unbekanntes Zeichen in Zeile XX" Fehler sollte meiner Meinung nach nicht auf Instruktionsbeschränkung zurückzuführen sein.

Wäre gut, wenn Du das bei Dir trotzdem mal nachprüfen könntest. Der merkwürdige Fehler "unbekanntes Zeichen in Zeile XX" weisst komischer Weise immer auf ne beliebige Zeile wo eine schliessende Klammer steht ("}") oder auf die letzte schliessende Klammer der main Methode. Und wie gesagt, wenn ich diese Klammern beibehalte, und an einer anderen Stelle des Fragmentprogrammes Befehle lösche, die mit dieser Klammerung auch gar nichts zu tun haben und somit unter 96 Instruktionen komme, dann wird das Fragmentprogramm auch anstandslos kompiliert.

Gruss, Carsten.

Asmodeus
2004-10-23, 14:58:54
Hab jetzt auch mal wieder den GLSL Parser Test laufen lassen, und mit dem 66.81 Treiber ist das Ergebnis ziemlich mieß. Es wird gerade mal ein Score von 48 Prozent erreicht. Das erklärt vielleicht so einiges. Falls jemand andere Ergebnisse mit anderen Treiberversionen hat, kann er die ja mal posten.

Gruss, Carsten.

Xmas
2004-10-23, 17:36:06
Hab jetzt auch mal wieder den GLSL Parser Test laufen lassen, und mit dem 66.81 Treiber ist das Ergebnis ziemlich mieß. Es wird gerade mal ein Score von 48 Prozent erreicht. Das erklärt vielleicht so einiges. Falls jemand andere Ergebnisse mit anderen Treiberversionen hat, kann er die ja mal posten.

Gruss, Carsten.
Dem Ergebnis solltest du nicht unbedingt in dem Sinne trauen, da der NVidia-Compiler wegen standardmäßig aktivierter Extensions mehr verarbeitet als er eigentlich sollte. AFAIK sind nur die wenigsten Fehler auf Nichtverarbeitung eines gültigen Shaders zurückzuführen.

Corrail
2004-10-24, 01:08:03
Dem Ergebnis solltest du nicht unbedingt in dem Sinne trauen, da der NVidia-Compiler wegen standardmäßig aktivierter Extensions mehr verarbeitet als er eigentlich sollte. AFAIK sind nur die wenigsten Fehler auf Nichtverarbeitung eines gültigen Shaders zurückzuführen.

Und der Rest der Fehler ist auf mangelnde GLSL 1.1 Unterstützung zurückzuführen (#version, #extension, ...)

Wäre gut, wenn Du das bei Dir trotzdem mal nachprüfen könntest. Der merkwürdige Fehler "unbekanntes Zeichen in Zeile XX" weisst komischer Weise immer auf ne beliebige Zeile wo eine schliessende Klammer steht ("}") oder auf die letzte schliessende Klammer der main Methode. Und wie gesagt, wenn ich diese Klammern beibehalte, und an einer anderen Stelle des Fragmentprogrammes Befehle lösche, die mit dieser Klammerung auch gar nichts zu tun haben und somit unter 96 Instruktionen komme, dann wird das Fragmentprogramm auch anstandslos kompiliert.

Ich bilde mir ein irgendwo mal gelesen zu haben, dass es ein Problem machen kann wenn nach dem "}" von der main Funktion noch Zeichen (Leerzeichen, Zeilenumbruch, ...) sind. Probier das mal aus. Ansonsten schick mir bitte mal deinen Beispiel Code.

Asmodeus
2004-10-24, 14:22:09
...
Ich bilde mir ein irgendwo mal gelesen zu haben, dass es ein Problem machen kann wenn nach dem "}" von der main Funktion noch Zeichen (Leerzeichen, Zeilenumbruch, ...) sind. Probier das mal aus. Ansonsten schick mir bitte mal deinen Beispiel Code.

Ja, genau daran lag es wohl, jetzt funktioniert die Sache so wie es sollte, auch mit mehr als 96 Instruktionen.

Gruss, Carsten.

Asmodeus
2004-11-03, 09:38:56
Nach dem das dynamische Branchen ja leider noch nicht so richtig zu funktionieren scheint, habe ich einige Modifikationen vorgenommen, um das Problem mittels statischem Branching im Fragmentprogramm unter GLSL zu lösen. Nur leider habe ich langsam die Vermutung, ich mache grundsetzlich was falsch, denn auch durch das statische Branching ergibt sich kein Geschwindigkeitsvorteil.

Vor der Modifikation sah die Sache etwa so aus (Pseudocode):



...

void main (void)
{
komplexe Berechnungen;

simple Berechnung;
}


Mit statischem Branching sieht die Sache jetzt so aus:



uniform float Value;
...

void main (void)
{
if(Value == 0.0)
{
komplexe Berechnungen;
}

simple Berechnung;
}


Es wäre noch dazu zu sagen, dass grob geschätzt etwa 15 Prozent der Fragmente mit der komplexen Berechnung und der simplen Berechnung abgearbeitet werden und die anderen 85 Prozent nur mit der simplen Berechnung. Meiner Meinung nach sollte man da schon einen Unterschied zu vorher merken, wo ja auch für die 85 Prozent die komplexe Berechnung mit durchgeführt wurde. Oder hab ich einfach was übersehen?

Gruss, Carsten.

Asmodeus
2004-11-18, 10:46:29
Schade, dass bisher wohl noch niemand anderes Gelegenheit hatte, die Sachen mit dem statischen und dynamischen Branching unter GLSL auf NV40 Hardware mal bei sich zu testen.

Leider haben meine Tests mit dem aktuellen 66.93 Treiber wieder das gleiche Bild geliefert. Es findet weder ein statisches, geschweige denn ein dynamisches Branching unter GLSL auf meiner NV40 statt.

Gruss, Carsten.

Demirug
2004-11-18, 11:00:34
Laut nVidia gibt es einen internen Treiber der es kann aber es ist noch nicht in den offiziellen.

Bei statischem Branching sollte man aber laut der gleichen Quellen derzeit prüfen ob man nicht besser für die Unterschiedlichen Varianten eigene Shader benutzt da dies meist noch schneller ist.

Asmodeus
2004-11-18, 11:05:59
Laut nVidia gibt es einen internen Treiber der es kann aber es ist noch nicht in den offiziellen.

Bei statischem Branching sollte man aber laut der gleichen Quellen derzeit prüfen ob man nicht besser für die Unterschiedlichen Varianten eigene Shader benutzt da dies meist noch schneller ist.

Ja, da hast Du recht, bin jetzt doch wieder auf mehrere Shader ausgewichen und ein Geschwindigkeitszuwachs tritt trotz Shaderumschaltung ein.

Außerdem hab ich noch folgende interessante Aussage im Netz gefunden:


Dynamic branching is much more interesting but most people tend to forget that there are certain restrictions in what can be placed inside code that's executed conditionally and that doing dynamic branching efficiently is extremely hard in hardware. While I expect that NV drivers will use massive unrolling and inlining in shaders using static branching (in the end they have 16k instructions available!) I am quite interested to see how well nv40 performs at truly data-dependant branching - there are a lot of people on the net who suggest (not without a reason, it seems to) that this feature will give perfomance improvements in very few cases, if any. To sum things up - a lot depends on quality of NVIDIA implementation.


Sieht also ganz danach aus, als wäre dynamic branching zumindest auf der NV40 Hardware auch noch nicht das "Allheilmittel" für Performancezuwachs.

Gruss, Carsten.

Demirug
2004-11-18, 11:13:54
Sieht also ganz danach aus, als wäre dynamic branching zumindest auf der NV40 Hardware auch noch nicht das "Allheilmittel" für Performancezuwachs.

Gruss, Carsten.

Für den NV40 sind die Umgebungsbedingungen für Dynamic Branching im Pixelshader recht klar definiert.

- Branchblöcke haben ~1000 Pixel.
- Branchanweisungen (IF/ELSE/ENDIF) kosten 2 zusätzliche Takte.
- Branchanweisungen brechen die globale Shader Optimierung auf. Jeder Block muss einzelen optimiert werden. Dadurch können weitere Takte verloren gehen.

Im Vertexshader sieht das besser aus weil diese ja MIND sind.