PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : DOOM III: Effizienz inside?


Demirug
2004-09-14, 11:56:17
Vorsicht! Es folgt Carmack bashing.

Wie angekündigt lästere ich jetzt noch ein bischen über die DOOM III Engine. Es steht natürlich jedem frei mich danach als Idiot, Klugscheißer oder sonst was zu bezeichnen.

Es geht mal wieder um den inzwischen berühmten DOOM III Shader welcher schon Humus zu Modifikationen motiviert hat. In diesem Shader ist nun noch viel mehr Zündstoff enthalten als es den Anschein hat. Vereinfacht gesagt errechnet dieser Shader für Objekte mit Bumps die Pixelfarbe welche aufgrund der spekularen und diffusen Beleuchtung entsteht. Nun benutzt DOOM III diesen Shader aber nicht nur für diese Luxusausführung der Pixelbeleuchtung sondern auch für die abgespeckten Sparversionen. Nachweisbar werden auch Objekte ohne Bumps damit gerendert. Ebenso kommt dieser Shader zum Einsatz wenn die aktuelle Lichtquelle überhaupt kein Diffuses oder spekulares Licht ausstrahlt. Da der Shader dies aber immer mit berechnet werden die entsprechenden Shaderteile einfach durch entsprechende Konfigurationen neutral gesetzt. Hat zum Beispiel das Objekt keine Bumps wird einfach als Normalmap eine Texture gesetzt welche für das Bumpmapping neutrale Vektoren enthält. Ähnliches gilt für das spekualare und diffuse Licht. Dieser universal Shader besteht also aus 3 Teilen und jeder Teil kann für das Endergebnis unwichtig sein. Aus diesem Grund habe ich einmal für alle Kombinationen aus diesen 3 teilen entsprechende Shader erstellt welche immer nur die Teile berechnen die am Ende auch wirksam sind. Bei 3 Teilen sind das 8 Kombinationen. Diese 8 Shader habe ich dann von einem entsprechenden nVidia Tool untersuchen lassen. Dieses Tool gibt für jeden Shader die Ausführungsdauer in Takte pro Pixel an. Die folgende Tabelle enthält die Ergebnisse.

Bump Specular Diffuse | CineFX I CineFX II CineFX III
0 0 0 | 2 2 1
0 0 1 | 15 15 8
0 1 0 | 36 34 17.75
0 1 1 | 41 39 20.5
1 0 0 | 2 2 1
1 0 1 | 26 25 11.25
1 1 0 | 56 52 22
1 1 1 | 63 61 25

Daraus ergeben sich folgenden Leistungssteigerungen gegenüber dem Originalshader.

Bump Specular Diffuse | CineFX I CineFX II CineFX III
0 0 0 | +3050.0% +2950.0% +1150.0%
0 0 1 | + 320.0% + 306.7% + 212.5%
0 1 0 | + 75.0% + 79.4% + 40.8%
0 1 1 | + 53.7% + 56.4% + 22.0%
1 0 0 | +3050.0% +2950.0% +1150.0%
1 0 1 | + 142.3% + 144.0% + 152.5%
1 1 0 | + 12.5% + 17.3% + 13.6%
1 1 1 | + 0.0% + 0.0% + 0.0%

Zusätzlich können bei den Shadern welche nicht alle Optionen nutzen weitere Leistunggewinnen durch einsparen von Füllrate und Bandbreite erreicht werden. Für den Bump und Diffuseanteil muss jeweils eine Texture ausgelesen werden. Für den Spekularanteil sind es zwei. Dazu kommen dann noch weitere 3 Texturen die immer gebraucht werden sobald der Spekular oder Diffuseanteil zum tragen kommt. Also eigentlich immer.

Es werden zwar die meisten Objekten mit allen 3 Aspekten (Bump, Spekular, Diffuse) gerendert aber in jedem Frame gibt es ein paar Ausnahmen. An dieser Stelle verschenkt die Engine ganz klar Leistung. Die Beurteilung dieser Tatsache soll jedem selbst überlassen werden. Für mich persönlich ist das aber bei einer Engine die sich dermaßen lange in der Entwicklung befand ein Unding eine solch einfache Möglichkeit zur Optimierung ungenutzt zu lassen.

Jesus
2004-09-14, 12:03:15
hm irgendwie kann ich mir nicht vorstellen dass JC das unwissentlich getan hat. Wieso sollte er sowas machen, wo er doch schon damit begonnen hat angepasst Shader zu programmieren.

Andererseits bedeutet das dass NV dort durch ein Replacement an geeigneter Stelle gewaltigst an Performance gewinnen kann ( was wohl auch erklärt wieso die min-fps Werte bei NV Karten wesentlich besser sind ), anders als der Humus Shader der ja immer noch in den unnötigsten Situationen verwendet werden muss, solange kein "kreatives" Shaderreplacment betrieben wird.

D-Swat
2004-09-14, 12:22:26
@Demi:
Könnte es sein, dass das Ändern des Shaders länger dauert, als der Zeitgewinn, den man durch spezielle Shader hat?
Evtl. hat Carmack deswegen nur einen universellen Shader.

Coda
2004-09-14, 12:27:25
Wenn man die Szene nach Shader und dann nach Material sortiert sollte das eigentlich nicht zu großen Problemen führen.

Mave@Work
2004-09-14, 12:41:16
Demi woher kommen denn die Kommawerte bei CineFXIII ?
(z.B. 17.75)

DanMan
2004-09-14, 12:49:45
Ich seh das als ein "nice to have", aber wenns ein einziger Shader schnell genug kann...

RLZ
2004-09-14, 12:54:47
Wie gross sind die Anteile der nicht voll ausgenutzten Shader?
Auf jeden Fall hätte sich da wohl noch wesentlich mehr optimeren gelassen als es getan wurde.
Carmack ist imho auch ein ziemlicher Exzentriker, der von Teamarbeit nicht viel hält. Wahrscheinlich hat er die ganzen Jahre allein da dran rumgebastelt.
Früher ging das halt noch, dass er alleine eine ganze Engine gebaut hat. Heut wohl nichtmehr...
Vielleicht sollte er wirklich lieber Raumschiffe bauen :biggrin:


Ich seh das als ein "nice to have", aber wenns ein einziger Shader schnell genug kann...

Sag das jemandem, der keine HighEnd-Karte hat und an der Spielbarkeitsgrenze liegt...

Botcruscher
2004-09-14, 13:22:31
Hmm reine Speku. Könnte nicht dort der Grund liegen warum NV schneller ist?
Wenn Nvidia solche shader ersetzt und Ati nicht. Ausserdem hatte NV ja genug Zeit sich darauf einzustellen.

PS: Würde auch erklähren warum bei der BQ "kein" Unterschied ist.

Asmodeus
2004-09-14, 13:29:46
Meiner Meinung nach macht die Sache nur unter einem Gesichtspunkt Sinn:
Wenn man dynamische Verzweigungen in Fragmentshadern als baldigen, weitverbreiteten "Standard" ansieht. Dann braucht es nur einige kleine Modifikationen an dem einen Shaderprogramm und schon sollten auch dort immer nur wirklich die Teile abgearbeitet werden, die für das aktuelle Fragment notwendig sind. Und dieser Änderungsaufwand wäre bei weitem (per Patch z.B.) geringer, als vorher in der Engine z.B. Sortiermethoden zu implementieren, oder die Level so abzuspeichern, dass sie für die Abarbeitung mit mehreren Shadern optimiert ist.
Und wenn man überlegt, dass die Engine ja sicher noch paar Jahre für andere Spiele herhalten wird, und dynamisches Verzweigen dann sowieso Standard ist, dann macht das schon Sinn.

Gruss, Carsten.

Botcruscher
2004-09-14, 13:34:41
Warum bitte wird aber für etwas was in der Zukunft benutzt werden könnte soviel Leistung "verbraten"?
Und nicht erst dann eingesetzt wenn man es brauch?

Asmodeus
2004-09-14, 13:46:11
Warum bitte wird aber für etwas was in der Zukunft benutzt werden könnte soviel Leistung "verbraten"?
Und nicht erst dann eingesetzt wenn man es brauch?

Wie gesagt, ist nur meine Meinung. Wenn man den anderen Ansatz verfolgt hätte, wäre es, wie Coda schon geschrieben hat, nötig gewesen, eine Vorsortierung der Szenen oder Level vorzunehmen. Und das müsste die Engine ja leisten. Der Implementierungsaufwand ist vielleicht nicht unerheblich, so dass deshalb mit Blick auf die Gegenwart (NV40 kann dynamisches Branching im Fragmentshader), und die Zukunft (Ati zieht 2005 nach) auf diesen Mehraufwand verzichtet wurde.

Gruss, Carsten.

DrumDub
2004-09-14, 14:18:27
nun ja, veilleicht hat sich jc aber auch gedacht, dass die ihvs da lieber die treiber auf die jeweilge hw optimieren sollen und sich keinen unnötigen stress gemacht hat. mit anderen worten: er ist faul. :ugly:

aths
2004-09-14, 14:23:58
nun ja, veilleicht hat sich jc aber auch gedacht, dass die ihvs da lieber die treiber auf die jeweilge hw optimieren sollen und sich keinen unnötigen stress gemacht hat. mit anderen worten: er ist faul. :ugly:Oder er sagte sich, wenn 10% (die Zahl ist aus der Luft gegriffen) aller Pixel weniger brauchen lohnt es nicht, dafür Shader zu selektieren. Das wäre Opferung von etwas Leistung für leichtere Wartbarkeit des Hauptshaders.

Gast
2004-09-14, 14:26:04
warum schickt das mal nicht jemand per e-mail an id, humus hat das doch auch gemacht um zu erfahren warum carmack den shader nicht so angepasst hat wie er.

DrumDub
2004-09-14, 14:40:10
Oder er sagte sich, wenn 10% (die Zahl ist aus der Luft gegriffen) aller Pixel weniger brauchen lohnt es nicht, dafür Shader zu selektieren.

das selektieren sollte doch nicht das problem sein. (oder besteht da ein unterschied zwischen der zuordnung unter ogl und dx?) man muss nur erst mal unterschiedliche shader schreiben. und das hat er nicht gemacht, wenn ich demirug richtig verstanden habe. jc hat also ein art universalshader geschrieben, der in gewissen situationen einfach leistung verschenkt.

die überlegung von asmodeus macht daher schon irgendwie sinn, aber wenn man die heute verfügbare hw anschaut wiederrum nicht. ich spekuliere eher darauf, dass er es anderen überlassen wollte sich mit den optimierungen zu befassen. über humus tweak war er ja auch nicht sauer oder so. er meinte halt nur, dass diese spezielle methode nicht universell einsetzbar ist.

Corrail
2004-09-14, 14:59:35
Andererseits bedeutet das dass NV dort durch ein Replacement an geeigneter Stelle gewaltigst an Performance gewinnen kann ( was wohl auch erklärt wieso die min-fps Werte bei NV Karten wesentlich besser sind ), anders als der Humus Shader der ja immer noch in den unnötigsten Situationen verwendet werden muss, solange kein "kreatives" Shaderreplacment betrieben wird.

In diesem Fall wird ein Shader Replacement problematisch, weil es ja immer der gleiche Shader ist. Der Treiber müsste hierfür alle Texturen und Werte für Bump Mapping, Specular, ... untersuchen um zu schauen welcher der 8 Shader die Demi aufgelistet hat jetzt wirklich zum einsatz kommt. Wäre möglich, aber IMHO sehr aufwendig!

Ich glaube aber auch, wie Aths sagt, dass man ohne Aufteilung der Pixel in die genannten Shader man keine voreiligen Schlüsse ziehen sollte. Wenn ein Großteil (ich sag jetzt mal über 80%) mit dem vollen Shader berechnet werden dann zahlt es sich meiner Meinung nach nicht aus mehrere Shader zu verwenden. Die Engine frisst jetzt schon genug CPU Leistung.
Außerdem wäre ein "PS3.0" Patch dadurch viel einfacher.

Aquaschaf
2004-09-14, 15:12:21
Oder er sagte sich, wenn 10% (die Zahl ist aus der Luft gegriffen) aller Pixel weniger brauchen lohnt es nicht, dafür Shader zu selektieren. Das wäre Opferung von etwas Leistung für leichtere Wartbarkeit des Hauptshaders.

Soo oft wird ein Shader nicht in die Werkstatt müssen glaube ich ;) Bei einem derart Hardware-fordernden Spiel würde ich sagen, dass es generell falsch ist Leistung zu opfern...

RoKo
2004-09-14, 15:32:42
Ja mei, die Engine ist doch im innersten für GeForce1 gedacht und nicht für Shaderspielereien. Ich denke, sowas wie Shader auswechseln ist einfach deswegen nicht drin, weil es im alten Design der Engine nicht vorgesehen ist. Dass überhaupt ein Shader reingeladen ist, könnte man möglicherweise sogar als Hack ansehen.

aths
2004-09-14, 15:45:12
In diesem Fall wird ein Shader Replacement problematisch, weil es ja immer der gleiche Shader ist. Der Treiber müsste hierfür alle Texturen und Werte für Bump Mapping, Specular, ... untersuchen um zu schauen welcher der 8 Shader die Demi aufgelistet hat jetzt wirklich zum einsatz kommt. Wäre möglich, aber IMHO sehr aufwendig!Bin zu faul, den Shader rauszusuchen. Wenn dort mit Konstanten gearbeitet wird, wäre es jedenfalls ein leichtes, Alternativshader zu nehmen.

Corrail
2004-09-14, 15:48:41
Bin zu faul, den Shader rauszusuchen. Wenn dort mit Konstanten gearbeitet wird, wäre es jedenfalls ein leichtes, Alternativshader zu nehmen.

Und wie schauts mit der Normalmap aus? Laut Demirug wird wenn kein Bump Mapping verwendet wird eine Texture mit lauter (0,0,1)-Werten verwendet, oder hab ich das falsch verstanden? Wenn es so ist wirds ein wenig komplexer.

Aquaschaf
2004-09-14, 15:50:40
Ja mei, die Engine ist doch im innersten für GeForce1 gedacht und nicht für Shaderspielereien. Ich denke, sowas wie Shader auswechseln ist einfach deswegen nicht drin, weil es im alten Design der Engine nicht vorgesehen ist. Dass überhaupt ein Shader reingeladen ist, könnte man möglicherweise sogar als Hack ansehen.

Das ergibt keinen Sinn. "Für Geforce 1 gedacht" war die Engine vor 5 Jahren vielleicht.

aths
2004-09-14, 15:54:21
Und wie schauts mit der Normalmap aus? Laut Demirug wird wenn kein Bump Mapping verwendet wird eine Texture mit lauter (0,0,1)-Werten verwendet, oder hab ich das falsch verstanden? Wenn es so ist wirds ein wenig komplexer.Ich weiß nicht, wie der Treiber auf Texturen zugreift. Wenn er sie indiziert, braucht er nur ein mal feststellen, welche Textur die "flache" Normalmap darstellt.

Demirug
2004-09-14, 16:51:30
- Der Shader ist kein Fall für dynamische Branching sondern für statisches Branching weil alle Pixel die zu einem Objekt gehören den gleichen Teil des Shaders ausführen müssen. Statisches Branching kann man mit jeder DX9 Hardware sehr gut über die CPU nachbilden. Farcry macht es im Ansatz und HL2 macht es fast perfekt.

- Ob Spekulares und Diffuse Licht benutzt wird kann man relative einfach an jeweils einer Konstaten feststellen.

- Beim Bumpmapping ist es schon etwas komplizierter. Hier müssen die Texturen beim anlagen überprüft werden ob sie nur einen Wert über die gesamte Fläsche enthalten. Sobald dann eine solche Texture auf die entsprechenden Stage gesetzt wird hat man den letzten Trigger.

- Um sowas in einen Treiber zu bauen sollte weniger als ein Tag erforderlich sein.

KiBa
2004-09-14, 17:31:52
wie groß ist denn nun eigentlich der anteil der pixel, die auch effizienter gerendert werden könnten? und wo im spiel kommen die vor?

Demirug
2004-09-14, 17:46:19
wie groß ist denn nun eigentlich der anteil der pixel, die auch effizienter gerendert werden könnten? und wo im spiel kommen die vor?

Der Anteil und die Positionen sind abhängig von Leveldesign.

Birdman
2004-09-14, 18:29:37
JC geht es imho nie um das letzte Quentchen Leistung - das sah man schon bei Q3 wo er auf die VM anstelle der precompiled DLL's gesetzt hat.
Dadurch hat man mit damaliger Hardware auch mal locker 20% Speed verschenkt...und Quake3 war damals auch extremst Hardwarefordernd, wie heute Doom3.

aths
2004-09-14, 20:38:11
JC geht es imho nie um das letzte Quentchen Leistung - das sah man schon bei Q3 wo er auf die VM anstelle der precompiled DLL's gesetzt hat.Was für eine VM und was für precompiled DLLs?

DevilX
2004-09-14, 22:10:51
Es gibt für quake DLL'S die für AMD Prozessoren kompiliert wurden..
ich denke die sind gemeint

HellHorse
2004-09-14, 23:31:06
das sah man schon bei Q3 wo er auf die VM anstelle der precompiled DLL's gesetzt hat.
IIRC sah man diese DLLs von Seiten id's überhaupt nicht gerne, da sie zu Problemen mit crossplatform (Linux/Mac) Mods führten.

3dzocker
2004-09-15, 01:02:19
hab zwar keine Ahnung von was hier geredet wird, aber kann man nun den schlechten??? universellen Shader durch ne bessere Version, z.B. per Patch verbessern/ersetzen???
Und was würde das bringen???
Und wenns was bringt, gibts dann nen Patch???

tschau

Corrail
2004-09-15, 01:27:44
hab zwar keine Ahnung von was hier geredet wird, aber kann man nun den schlechten??? universellen Shader durch ne bessere Version, z.B. per Patch verbessern/ersetzen???
Und was würde das bringen???
Und wenns was bringt, gibts dann nen Patch???

tschau

Erstens, dieser univerelle Shader ist nicht schlecht. Er ist für einige Anwendungen, wo kein Bump Mapping, Specular, ... verwendet wird zu überladen.
Zweitens bezweifle ich dass es einen Patch geben wird wo verschiedene Shader verwendet werden. Theoretisch wäre das sehr wohl möglich, aber man müsste die halbe Engine umschreiben und alle Maps ändern.

3dzocker
2004-09-15, 01:36:33
naja ich schrieb ja,ich weiß nicht worum es geht, ich versteh es so, daß der Carmacksche Shader um irgendwas zu berechnen Werte mit einrechnet die er eigentlich garnicht mit benutzen müßte (halt die Tabelle da von Demirug mit den 1 und 0) und daß das dann zu Performanceverlusten führt.

tschau

Corrail
2004-09-15, 01:38:21
naja ich schrieb ja,ich weiß nicht worum es geht, ich versteh es so, daß der Carmacksche Shader um irgendwas zu berechnen Werte mit einrechnet die er eigentlich garnicht mit benutzen müßte (halt die Tabelle da von Demirug mit den 1 und 0) und daß das dann zu Performanceverlusten führt.

tschau

Genauso ist es auch, nur deshalb ist es kein "schlechter" Shader ;)

tb
2004-09-15, 03:02:47
Vorsicht! Es folgt Carmack bashing.

Wie angekündigt lästere ich jetzt noch ein bischen über die DOOM III Engine. Es steht natürlich jedem frei mich danach als Idiot, Klugscheißer oder sonst was zu bezeichnen.

Es geht mal wieder um den inzwischen berühmten DOOM III Shader welcher schon Humus zu Modifikationen motiviert hat. In diesem Shader ist nun noch viel mehr Zündstoff enthalten als es den Anschein hat. Vereinfacht gesagt errechnet dieser Shader für Objekte mit Bumps die Pixelfarbe welche aufgrund der spekularen und diffusen Beleuchtung entsteht. Nun benutzt DOOM III diesen Shader aber nicht nur für diese Luxusausführung der Pixelbeleuchtung sondern auch für die abgespeckten Sparversionen. Nachweisbar werden auch Objekte ohne Bumps damit gerendert. Ebenso kommt dieser Shader zum Einsatz wenn die aktuelle Lichtquelle überhaupt kein Diffuses oder spekulares Licht ausstrahlt. Da der Shader dies aber immer mit berechnet werden die entsprechenden Shaderteile einfach durch entsprechende Konfigurationen neutral gesetzt. Hat zum Beispiel das Objekt keine Bumps wird einfach als Normalmap eine Texture gesetzt welche für das Bumpmapping neutrale Vektoren enthält. Ähnliches gilt für das spekualare und diffuse Licht. Dieser universal Shader besteht also aus 3 Teilen und jeder Teil kann für das Endergebnis unwichtig sein. Aus diesem Grund habe ich einmal für alle Kombinationen aus diesen 3 teilen entsprechende Shader erstellt welche immer nur die Teile berechnen die am Ende auch wirksam sind. Bei 3 Teilen sind das 8 Kombinationen. Diese 8 Shader habe ich dann von einem entsprechenden nVidia Tool untersuchen lassen. Dieses Tool gibt für jeden Shader die Ausführungsdauer in Takte pro Pixel an. Die folgende Tabelle enthält die Ergebnisse.

Bump Specular Diffuse | CineFX I CineFX II CineFX III
0 0 0 | 2 2 1
0 0 1 | 15 15 8
0 1 0 | 36 34 17.75
0 1 1 | 41 39 20.5
1 0 0 | 2 2 1
1 0 1 | 26 25 11.25
1 1 0 | 56 52 22
1 1 1 | 63 61 25

Daraus ergeben sich folgenden Leistungssteigerungen gegenüber dem Originalshader.

Bump Specular Diffuse | CineFX I CineFX II CineFX III
0 0 0 | +3050.0% +2950.0% +1150.0%
0 0 1 | + 320.0% + 306.7% + 212.5%
0 1 0 | + 75.0% + 79.4% + 40.8%
0 1 1 | + 53.7% + 56.4% + 22.0%
1 0 0 | +3050.0% +2950.0% +1150.0%
1 0 1 | + 142.3% + 144.0% + 152.5%
1 1 0 | + 12.5% + 17.3% + 13.6%
1 1 1 | + 0.0% + 0.0% + 0.0%

Zusätzlich können bei den Shadern welche nicht alle Optionen nutzen weitere Leistunggewinnen durch einsparen von Füllrate und Bandbreite erreicht werden. Für den Bump und Diffuseanteil muss jeweils eine Texture ausgelesen werden. Für den Spekularanteil sind es zwei. Dazu kommen dann noch weitere 3 Texturen die immer gebraucht werden sobald der Spekular oder Diffuseanteil zum tragen kommt. Also eigentlich immer.

Es werden zwar die meisten Objekten mit allen 3 Aspekten (Bump, Spekular, Diffuse) gerendert aber in jedem Frame gibt es ein paar Ausnahmen. An dieser Stelle verschenkt die Engine ganz klar Leistung. Die Beurteilung dieser Tatsache soll jedem selbst überlassen werden. Für mich persönlich ist das aber bei einer Engine die sich dermaßen lange in der Entwicklung befand ein Unding eine solch einfache Möglichkeit zur Optimierung ungenutzt zu lassen.

Stellen sich nur zwei Fragen:

1. Im groben Durchschnitt, wieviele Pixel werden mit welchen Aspekten berechnet ? Wenn bei ~85 % alles Pixel alle drei Aspekte verwendet werden, dann kostet das Umschalten des Shaders vielleicht mehr Zeit, als der Gewinn durch die kürzere Ausführungszeit!?

2. Is es so nicht vielleicht viel einfacher, für die IHV's ,in den Treibern entsprechende Optimierungen dieses Universalshaders einzubauen?

3. Es würde zu Carmacks universellem Ansatz passen - (fast) alles wird über den selben "Pfad" gerendert, nicht wie bei älteren Engines, spezielles Material-> spezieller "Pfad" ...

4. Spätestens beim nächsten Doom 3 Engine basierenden Spiel (Quake 4?) werden wir hoffentlich sehen, ob und wie leistungsfähig das Materialsystem ist.

5. Werden nicht benötigte Sampler auf NULL gesetzt oder "leere" Texturen ?

Thomas

Demirug
2004-09-15, 07:11:38
Erstens, dieser univerelle Shader ist nicht schlecht. Er ist für einige Anwendungen, wo kein Bump Mapping, Specular, ... verwendet wird zu überladen.
Zweitens bezweifle ich dass es einen Patch geben wird wo verschiedene Shader verwendet werden. Theoretisch wäre das sehr wohl möglich, aber man müsste die halbe Engine umschreiben und alle Maps ändern.

Wenn man das richtig macht muss da keine einzige Map angefasst werden und die halbe Engine ist wohl auch etwas übertrieben. Lediglich das Materialsystem muss etwas angepasst werden.

Demirug
2004-09-15, 07:21:27
Stellen sich nur zwei Fragen:

1. Im groben Durchschnitt, wieviele Pixel werden mit welchen Aspekten berechnet ? Wenn bei ~85 % alles Pixel alle drei Aspekte verwendet werden, dann kostet das Umschalten des Shaders vielleicht mehr Zeit, als der Gewinn durch die kürzere Ausführungszeit!?

2. Is es so nicht vielleicht viel einfacher, für die IHV's ,in den Treibern entsprechende Optimierungen dieses Universalshaders einzubauen?

3. Es würde zu Carmacks universellem Ansatz passen - (fast) alles wird über den selben "Pfad" gerendert, nicht wie bei älteren Engines, spezielles Material-> spezieller "Pfad" ...

4. Spätestens beim nächsten Doom 3 Engine basierenden Spiel (Quake 4?) werden wir hoffentlich sehen, ob und wie leistungsfähig das Materialsystem ist.

5. Werden nicht benötigte Sampler auf NULL gesetzt oder "leere" Texturen ?

Thomas

1. Ist wie gesagt Projektierungsabhängig. Der Overhead wegen dem Shaderwechsel macht mir dabei eigentlich weniger sorgen. Es müsste ja jede benötige Variante nur einmal aktiviert werden. Ein Statewechsel hat man sowieso vor jedem Objekt weil die Engine es für notwendig hält alle Programmparameter (auch die welche sich nicht geändert haben) neu zu übergeben.

2. Nein, es ist nicht trivial dieses Problem generisch zu lösen aber durchaus auf kosten von CPU Leistung machbar. Die Engine verfügt aber über viel mehr Detaildaten um dieses Problem zu lösen.

3. Ja, vom Ansatz her passt es nur besser wird es davon auch nicht.

4. Das Materialsystem selbst mag schon mächtig sein allerdings unterstützt es offensichtlich bei Materialvarianten keine Optimierungen.

5. Es sind default Texturen mit jeweils einem Inhalt der neutral für die Berechnung ist. Auf NULL setzten bringt ja nicht immer was weil ja dann der "falsche" Wert ausgelesen werden würde.

aths
2004-09-15, 12:36:02
4. Das Materialsystem selbst mag schon mächtig sein allerdings unterstützt es offensichtlich bei Materialvarianten keine Optimierungen.Könnte man stattdessen (statt 8 Einzelshader) auch einen Generalshader nehmen, der mit static branching arbeitet? Oder wäre das weniger effizient?

Coda
2004-09-17, 16:37:10
Eigentlich dürfte static branching das optimale sein, aber ich glaube ARB_fragment_program kann das gar nicht. (Demirug?)

Birdman
2004-09-17, 18:41:12
Es gibt für quake DLL'S die für AMD Prozessoren kompiliert wurden..
ich denke die sind gemeint
Gibts auch für Intel/P4, nur war die AMD Gemeinde hier natürlich aktiver, da bei diesem Game der Athlon deutlich langsamer als der P4 war.

Demirug
2004-09-17, 18:50:05
aths, Code,

Fragment Programme unterstützen wie Coda schon sagt kein statische Branching. Das schliesst natürlich nicht aus das der Treiber sowas in der Art doch daraus macht.

Allerdings sollte man selbst beim Einsatz von statischem Branching die Objekte so vorsortieren das man möglichst jede Variante nur einmal benutzt um die Umschaltungen zu reduzieren.

Coda
2004-09-17, 19:49:08
Also dürfte theoretisch das abschalten von Specular keinerlei Mehr-Performance bringen bei Doom 3?

Demirug
2004-09-17, 19:58:46
Also dürfte theoretisch das abschalten von Specular keinerlei Mehr-Performance bringen bei Doom 3?

Doch es kann schneller werden weil ja dann nur noch eine konstante kleine Specularmap eingesetzt wird. Da kann Bandbreite und auch Fillrate gespart werden.

del_4901
2004-09-18, 15:31:37
aths, Code,

Fragment Programme unterstützen wie Coda schon sagt kein statische Branching. Das schliesst natürlich nicht aus das der Treiber sowas in der Art doch daraus macht.

Allerdings sollte man selbst beim Einsatz von statischem Branching die Objekte so vorsortieren das man möglichst jede Variante nur einmal benutzt um die Umschaltungen zu reduzieren.

Mhm, vielleicht ist Carmis Occlusion Culling Algo, so ausgelegt, das kein effizientes Shadersortieren mehr in der Engine möglich ist???? Ob nun absichtlich oder durch einen "Unfall" sei erstmal so dahingestellt. Währe das möglich?

Coda
2004-09-18, 16:03:46
Naja nach dem Occ-Culling hat er ja die sichtbare Geometrie, und die muss er eh schon nach Texturen sortieren, also könnte er an der Stelle auch gleich nach Shadern sortieren.

Demirug
2004-09-18, 17:33:43
Naja nach dem Occ-Culling hat er ja die sichtbare Geometrie, und die muss er eh schon nach Texturen sortieren, also könnte er an der Stelle auch gleich nach Shadern sortieren.

muss er? Überhaupt nichts muss er und er tut auch nichts in dieser Richtung.

Die Engine pumpt die Objekte ohne Rücksicht auf Verluste zur Grafikkarte. In dem Kommdostrom gibt es dann noch teilweise recht unsinnige Anweisungsfolgen. Da werden States vor einem Drawcall enabled und danach gleich wieder disabeld. Soweit ja noch in Ordnung aber beim folgenden Drawcall wiederholt sich das gleiche Spiel wieder.

Vorsichtig geschätz könnte man mindestens die Hälfte aller OpenGL Aufrufe sparen. Eher mehr.

marco42
2004-09-18, 17:53:45
muss er? Überhaupt nichts muss er und er tut auch nichts in dieser Richtung.

Die Engine pumpt die Objekte ohne Rücksicht auf Verluste zur Grafikkarte. In dem Kommdostrom gibt es dann noch teilweise recht unsinnige Anweisungsfolgen. Da werden States vor einem Drawcall enabled und danach gleich wieder disabeld. Soweit ja noch in Ordnung aber beim folgenden Drawcall wiederholt sich das gleiche Spiel wieder.

Vorsichtig geschätz könnte man mindestens die Hälfte aller OpenGL Aufrufe sparen. Eher mehr.

Wenn der Treiber das abfaengt sollte es doch nicht so viel kosten.

Demirug
2004-09-18, 18:12:56
Wenn der Treiber das abfaengt sollte es doch nicht so viel kosten.

Treiber sind überlicherweise nicht darauf ausgelegt sowas auszusortieren. In jedem Fall bezahlt man solche Aktionen aber mit CPU Leistung.

tb
2004-09-18, 20:00:06
Irgend ne Idee warum die Engine das macht? Vergessener Testcode ?

Thomas

marco42
2004-09-18, 20:18:10
Treiber sind überlicherweise nicht darauf ausgelegt sowas auszusortieren. In jedem Fall bezahlt man solche Aktionen aber mit CPU Leistung.

Das ist schon klar, aber wie hoch ist die. Wenn du es selbst verwaltest, kostet es ja auch.

marco42
2004-09-18, 20:19:05
Irgend ne Idee warum die Engine das macht? Vergessener Testcode ?

Thomas

Das macht den Code einfacher. Du musst dich nicht um einen globalen State kuemmern.

Demirug
2004-09-18, 21:18:53
Das ist schon klar, aber wie hoch ist die. Wenn du es selbst verwaltest, kostet es ja auch.

In der Regel aber weniger weil man mehr Informationen als der Treiber hat.

Ich habe mal in den nVidia Treiber ein wenig im Debugger untersucht. Die meisten Funktionen übernehmen einfach die daten in interne Buffer und setzten dann ein Flag das sich etwas geändert hat. In den Drawcalls wird dann entsprechend aufgrund der Flags die Pipeconfig neu berechnet. Je weniger Flags gesetzt sind desto schneller geht das.

Das ist das normale Verhalten des Treibers. Da er aber jede Function dynamisch ändern kann wäre es durchaus denkbar das sich bei manchen Spiel/Anwendung das verhalten etwas ändert.

Demirug
2004-09-18, 21:28:42
Irgend ne Idee warum die Engine das macht? Vergessener Testcode ?

Thomas

Nein, sowas bezeichnet man als simplifiziertes Statemanagment.

Man teil alle Renderstates in zwei Gruppen auf. Für die erste Gruppe werden default Werte vorgegeben. Für die zweite Gruppe bleibt undefiniert.

Ändert eine Funktion einen der Renderstates mit Defaultwert muss sie in wieder zurück setzten bevor sie verlassen wird. Benutzt eine Funktion einen Renderstate der zweiten Gruppe muss sie in auf jeden Fall setzten.

Eigentlich raten aber alle IHV davon ab das Problem auf diese Art zu lösen. Bei OpenGL hat es aber in der Regel nicht ganz so heftig rein wie bei D3D.

IIRC hatte die Entwickler von HALO bei der PC Version wegen einen solchen vereinfachten Statemangement heftige Leistungseinbrüche.

zeckensack
2004-09-18, 21:38:48
Nein, sowas bezeichnet man als simplifiziertes Statemanagment.

Man teil alle Renderstates in zwei Gruppen auf. Für die erste Gruppe werden default Werte vorgegeben. Für die zweite Gruppe bleibt undefiniert.

Ändert eine Funktion einen der Renderstates mit Defaultwert muss sie in wieder zurück setzten bevor sie verlassen wird. Benutzt eine Funktion einen Renderstate der zweiten Gruppe muss sie in auf jeden Fall setzten.

Eigentlich raten aber alle IHV davon ab das Problem auf diese Art zu lösen. Bei OpenGL hat es aber in der Regel nicht ganz so heftig rein wie bei D3D.

IIRC hatte die Entwickler von HALO bei der PC Version wegen einen solchen vereinfachten Statemangement heftige Leistungseinbrüche.Die Jungs von Bungie nutzten früher (http://www.gamershell.com/news/571.html) auch mal eine andere Grafik-API ;)

betasilie
2004-09-18, 21:42:50
Frage:
Wie wahrscheinlich ist es, dass NV mit ihrem Shaderreplacement genau hier anpackt?

Ich finde die Geschichte schon sehr seltsam. D³ ist so lange in der Entwicklung gewesen und dann so ein ineffizienter Shaderaufbau und der Sponsor in Form von NV hat direkt beim Start einen Treiber parrat, der mit enorm effizienten Austauschshadern auftrumpft. Seltsam. :|

Demirug
2004-09-18, 21:58:55
Frage:
Wie wahrscheinlich ist es, dass NV mit ihrem Shaderreplacement genau hier anpackt?

Ich finde die Geschichte schon sehr seltsam. D³ ist so lange in der Entwicklung gewesen und dann so ein ineffizienter Shaderaufbau und der Sponsor in Form von NV hat direkt beim Start einen Treiber parrat, der mit enorm effizienten Austauschshadern auftrumpft. Seltsam. :|

Denkbar ist alles wobei ich nicht glaube das nVidia JC dazu geraten hat das ganze so zu programmieren. Sie haben es aber frühzeitig erkannt und sich darauf eingestellt.

Bei ATI hat man immer so ein bischen das Problem das sie nicht aus den Puschen kommen solange etwas nicht veröffentlich ist. nVidia ist da meist etwas mehr bemüht wenn man Treiber-Fehler findet.

betasilie
2004-09-18, 22:02:14
Denkbar ist alles wobei ich nicht glaube das nVidia JC dazu geraten hat das ganze so zu programmieren. Sie haben es aber frühzeitig erkannt und sich darauf eingestellt.
Wobei ich noch nichtmal zwangsläufig andenken muss, dass NV unbedingt den Vorschlag gemacht haben muss, denn cleverere Geschäftsmänner sind die id-Bosse sowieso. ;)

Bin ja mal gespannt wie sich das bei Folgeprodukten auf Basis der D³-Engine verhält.

marco42
2004-09-18, 23:32:45
Benutzt er eigentlich gl[Push|Pop]Attrib?

Demirug
2004-09-18, 23:44:10
Benutzt er eigentlich gl[Push|Pop]Attrib?

Nein, im wesentlichen sind es immer wieder zwei Blöcke die sich wiederholen.

glBindBufferARB(GL_ARRAY_BUFFER,427)
glVertexPointer(4,GL_FLOAT,16,0x0000)
glStencilOpSeparateATI(GL_BACK,GL_KEEP,GL_KEEP,GL_INCR_WRAP)
glStencilOpSeparateATI(GL_FRONT,GL_KEEP,GL_KEEP,GL_DECR_WRAP)
glDisable(GL_CULL_FACE)
glDrawElements(GL_TRIANGLES,48,GL_UNSIGNED_INT,0x2097def0) VP=5
glEnable(GL_CULL_FACE)
glCullFace(GL_FRONT)

glBindBufferARB(GL_ARRAY_BUFFER,510)
glColorPointer(4,GL_UNSIGNED_BYTE,60,0x0038)
glVertexAttribPointerARB(11,3,GL_FLOAT,false,60,0x0014)
glVertexAttribPointerARB(10,3,GL_FLOAT,false,60,0x002c)
glVertexAttribPointerARB(9,3,GL_FLOAT,false,60,0x0020)
glVertexAttribPointerARB(8,2,GL_FLOAT,false,60,0x000c)
glVertexPointer(3,GL_FLOAT,60,0x0000)
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,4,[552.000000,-1652.000000,88.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,5,[1268.237427,-1480.518799,68.250000,1.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,6,[0.003333,0.000000,0.000000,-1.460000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,7,[0.000000,0.005556,0.000000,9.566667])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,8,[0.000000,0.000000,0.000000,1.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,9,[0.000000,0.000000,0.006250,0.150000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,10,[1.000000,0.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,11,[0.000000,1.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,12,[1.000000,0.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,13,[0.000000,1.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,14,[1.000000,0.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,15,[0.000000,1.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,16,[0.000000,0.000000,0.000000,0.000000])
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB,17,[1.000000,1.000000,1.000000,1.000000])
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,0,[1.129412,0.745098,0.172550,1.000000])
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,1,[1.129412,0.745098,0.172550,1.000000])
glActiveTextureARB(GL_TEXTURE1)
glBindTexture(GL_TEXTURE_2D,328)
glActiveTextureARB(GL_TEXTURE2)
glActiveTextureARB(GL_TEXTURE3)
glActiveTextureARB(GL_TEXTURE4)
glBindTexture(GL_TEXTURE_2D,329)
glActiveTextureARB(GL_TEXTURE5)
glBindTexture(GL_TEXTURE_2D,330)
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0x20962570) VP=1 FP=11 Textures[ (0,2) (0,14) (1,328) (2,21) (3,22) (4,329) (5,330) (6,7) ]

Bei den Binds ändern sich natürlich die Namen.

zeckensack
2004-09-18, 23:56:32
Demirug,
lauschst du eigentlich beide rendering contexts ab? Es müsste nämlich mindestens zwei geben, einen für den PBuffer (render-to-texture ist unter GL nicht ganz unkompliziert (http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=3;t=012414)), und einen für den sichtbaren Framebuffer. In letzterem passiert IMO kaum etwas aufregendes. Meistens nur Postpro. Ein Quad pro Frame, oder so ähnlich.

Der zweite von dir gepostete Schnipsel sieht mir nämlich arg nach so einem Postpro-Effekt aus ...

Demirug
2004-09-19, 00:09:29
Demirug,
lauschst du eigentlich beide rendering contexts ab? Es müsste nämlich mindestens zwei geben, einen für den PBuffer (render-to-texture ist unter GL nicht ganz unkompliziert (http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=3;t=012414)), und einen für den sichtbaren Framebuffer. In letzterem passiert IMO kaum etwas aufregendes. Meistens nur Postpro. Ein Quad pro Frame, oder so ähnlich.

Der zweite von dir gepostete Schnipsel sieht mir nämlich arg nach so einem Postpro-Effekt aus ...

Das ist mit GLIntercept aufgezeichnet. Der zweite Schnipsel gehört zum Lichtpass und kommt sehr häufig vor. Unter anderem erkennt man das auch am benutzten Fragmentprogramm. Hinter dem FP 11 verbirgt sich nämlich das bekannte Programm an dem schon Humus rumgeändert hat.

Es sind über 15000 Anweisungen für einen Frame ich denke also das alles dabei ist.

marco42
2004-09-19, 14:40:04
Das ist mit GLIntercept aufgezeichnet. Der zweite Schnipsel gehört zum Lichtpass und kommt sehr häufig vor. Unter anderem erkennt man das auch am benutzten Fragmentprogramm. Hinter dem FP 11 verbirgt sich nämlich das bekannte Programm an dem schon Humus rumgeändert hat.

Es sind über 15000 Anweisungen für einen Frame ich denke also das alles dabei ist.

Ich kenne nicht den Scenegraph von Doom 3, kann also nicht beurteilen, ob es sich lohnt nach dem state zu sortieren. Behalten eigentlich programs ihren state, wie sie es unter GLSL tun? Mich wuerde es wirklich interessieren, wieviel es kostet. Ich habe es aehnlich implementiert, wobei ich GPU limitiert bin.

Coda
2004-09-19, 17:04:10
muss er? Überhaupt nichts muss er und er tut auch nichts in dieser Richtung.
Urks. Das hätte ich nicht erwartet.

zeckensack
2004-09-19, 17:09:28
Ich kenne nicht den Scenegraph von Doom 3, kann also nicht beurteilen, ob es sich lohnt nach dem state zu sortieren. Behalten eigentlich programs ihren state, wie sie es unter GLSL tun?ARB_fp kennt zwei Sorten von Konstanten. "Environment parameters" sind global, gelten also für alle Programme. "Local parameters" gelten nur für das gerade gebundene Programm, und sind (für eben dieses Programm) dann dauerhaft, bis sie wieder geändert werden.

Doom 3 nutzt, so wie es in Demirug's Schnipsel aussieht, ausschließlich die erste Variante.