PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Unterschied zwischen Texture-Buffer-Objects und Parameter-Buffer-Objects bei OpenGL


Asmodeus
2006-11-27, 14:27:02
Durch die neuen OpenGL Extensions für die G80 Familie stehen ja nun z.B. die Extensions GL_EXT_texture_buffer_object und GL_NV_parameter_buffer_object zur Verfügung. Ich frage mich nun allerdings, wo bei beiden eigentlich die Unterschiede liegen? So wie ich es verstanden habe, bieten doch beide im Grunde die gleiche Funktionaliät (die Möglichkeit, in den Shadern auf größere Arrays von Daten zuzugreifen, wobei der Inhalt der Arrays zur Laufzeit auch jederzeit geändert werden kann). Wieso gibt es also zwei Extensions, die beide das gleiche machen? Oder anders gefragt, da es zwei gibt, mit der gleichen Funktionalität, unterscheiden sie sich vielleicht in der Performance? Ich möchte bei mir in einigen Vertex-Shadern diese Buffer nutzen. Bisher gab es ja von Nvidia immer den Warnhinweis, Texturen im Vertexshader nicht als Buffer für Werte zu missbrauchen, da die Performance schlecht ist. Gilt das für die G80 auch noch, und würde also eher gegen einen Einsatz eines Texture-Buffers im Vertex-Shader sprechen? Gibt es deshalb dann vielleicht die Parameter-Buffer, da sie beim Einsatz im Vertex-Shader die bessere Performance liefern? Das kann ich mir aber irgendwie nicht vorstellen, denn Daten sind doch Daten, egal durch welche Extension sie nun angebunden werden, oder?

Gruss, Carsten.

Demirug
2006-11-27, 14:54:50
Texturen im Vertexshader sind jetzt kein Problem mehr.

Die beiden Extensions spiegeln zwei unterschiedliche Direct3D 10 Konzepte wieder.

GL_NV_parameter_buffer_object entspricht den Konstanten Buffern
GL_EXT_texture_buffer_object entspricht einem Shader Resource View auf ein Buffer Objekt.

In den Effektfiles/HLSL auch als cbuffer und tbuffer bezeichnet.

Der wesentliche Unterschied bei OpenGL zwischen den beiden Extensions ist nun das man bei GL_EXT_texture_buffer_object den Buffer mit einer Leseanweisung explizit auslesen muss. GL_NV_parameter_buffer_object dagegen stellt die Werte direkt als array im shader code zur Verfügung.

Was die Performance angeht so ist das ohne Guidelines schwer zu sagen. Da bei D3D10 aber in allen Beispielen cbuffer vorgezogen werden würde ich auf GL_NV_parameter_buffer_object tippen. Allerdings bin ich mir nicht sicher in wie weit das ohne NV_gpu _program4 überhaupt funktioniert.

Asmodeus
2006-11-27, 15:14:57
Erstmal danke für die ausführlichen Erläuterungen Demirug. Das finde ich dann natürlich etwas problematisch. Die GL_NV_... Extensions wollte ich eigentlich wenn möglich nicht benutzen. Denn das größte Manko, dass ich sehe, GL_NV_gpu_program4 und GL_NV_parameter_buffer_object sind ja nicht über GLSL nutzbar, oder?

Weiterhin gibt es ja noch GL_EXT_bindable_uniform. Dort kann man zwar auch Buffer übergeben, doch wenn ich es richtig verstanden habe, eben nur vergleichsweise winzige Buffer, oder habe ich folgenden Abschnitt falsch verstanden:


10. How to provide the ability to use bindable uniform arrays (or bindable
uniform arrays of structures) where the amount of data can differ based
on the buffer object bound to it?

DISCUSSION: In other words, the size of the bindable uniform is no
longer declared in the shader, but determined by the buffer object
backing it. This can be achieved through a variety of ways:

bindable uniform vec3 foo[1];

Where we would allow indexing 'off the end' of the array 'foo', because
it is backed by a buffer object. The actual size of the array will be
implicitly inferred from the buffer object bound to it. It'll be the
shader's responsibility to not index outside the size of the buffer
object. That in turn means that the layout in buffer object memory of a
bindable uniform needs to be exposed to the application.

Or we could support something like:

bindable uniform vec3 foo[100000]; // Some really big number
and make all accesses inside the buffer object bound to "foo" legal.

Or we could support something like:

bindable uniform float foo[];
foo[3] = 1.0;
foo[i] = .

Where 'i' could be a run-time index.

RESOLUTION: For now, we will not support this functionality.


EDIT: Vielleicht noch zur besseren Erklärung: Alles was ich eigentlich mach will, würde folgendes Szenario erfüllen: Ich verwende die GL_EXT_bindable_uniform Extension mit zugehörigem Buffer und im Shader habe ich dann folgendes für meine gebundene Uniform-Variable stehen:

bindable uniform float ArrayValues[4096];

Ich bin mir nun nur nicht sicher ob das so eben funktioniert. Ich brauche genau 4096 float-Werte, es ist also nicht nur als wahllose Beispielszahl gewählt. Mich verunsichert der Kommentar in der Beschreibung (//Some really big number), denn mir ist nun nicht klar, ob 4096 auch schon zu groß ist, oder ob das noch geht.

Gruss, Carsten.

Demirug
2006-11-27, 15:37:52
Die nvidia Extensions nutzen den Assemblerartigen Syntax.

Um mit den binable uniforms größere Buffer zu nutzen muss man mit Strukturen arbeiten.

11. Do we want to have bindable namespaces instead of the uniform qualifier
"bindable"?

DISCUSSION: Something like this:

bindable {
vec3 blarg;
int booyah;
};

where "blarg" and "booyah" can be referred to directly, but are both
bindable to the same buffer. You can achieve this with bindable uniforms
stored in structures:

bindable uniform struct {
vec3 blarg;
int booyah;
} foo;

but then have to use "foo.blarg" and "foo.booyah".

Ausprobiert habe ich das aber bisher nicht weil für mich derzeit die NV extensions besser geeignet sind.

Asmodeus
2006-11-27, 15:51:24
Nur bei Punkt 11 steht doch abschließend auch dabei:


RESOLUTION: Not in this extension. This might be nice programming sugar,
but not essential. Such a feature may be added in a future extension
building on this one.


Ich werd es wohl erstmal mit GL_texture_buffer_objects probieren. Ich habe 4096 Werte, davon lese ich 16 pro Shaderdurchlauf. Nach 256 Shaderdurchläufen wird der Buffer mit neuen 4096 Werten aktualisiert und es geht wieder von vorn los. Beim Lesen der 16 Werte handelt es sich also um 16 Texturzugriffe, was ja nicht gerade wenig ist. Nur bei einem Konstantenpuffer müssen die 4096 Werte am Anfang ja auch erstmal irgendwie dem Shader übergeben werden, oder? Es ist also die Frage, ob einmal 4096 Werte übergeben und dann 256 mal 16 davon benutzen wirklich so viel schneller geht, wie 256 mal 16 Werte aus einer Buffer-Texture lesen.

Gruss, Carsten.

ScottManDeath
2006-11-27, 21:57:32
Texture Buffer gehen über das Texture Subsystem, und damit durch den Texture Cache, während dies bei Constants nicht so ist. Es hängt dann von Deinem Access Pattern ab, ob es Cache freundlich ist, oder nicht.

Constantbuffer wechseln/updaten ist allerdings bei G80 mit geringerem Overhead verbunden als bei vorigen GPU Generationen....

Ansonsten beides coden und benchen =)

Demirug
2006-11-27, 22:11:35
Constantbuffer wechseln/updaten ist allerdings bei G80 mit geringerem Overhead verbunden als bei vorigen GPU Generationen....

Konstanten Buffer gab es aber vor dem G80 doch gar nicht. Ich denke aber du willst darauf hinaus dass jetzt das Fragment Program bei Veränderungen der Konstanten nicht mehr aufwendig gepatched werden muß.

Ansonsten beides coden und benchen =)

Zum Glück ist es bei Direct3D 10 relative einfach zwischen Konstanten und Texture buffer zu wechseln. Sonst würde ich nächstes Jahr wohl wahnsinnig werden.

Coda
2006-11-27, 22:24:36
Zum Glück ist es bei Direct3D 10 relative einfach zwischen Konstanten und Texture buffer zu wechseln. Sonst würde ich nächstes Jahr wohl wahnsinnig werden.

Weil G80 das eine und R600 das andere lieber mag? ;)

Demirug
2006-11-27, 22:37:43
Weil G80 das eine und R600 das andere lieber mag? ;)

Keine Ahnung. Aber wenn man an einer größeren Engine mitarbeitet muß man mit sowas ja rechnen. Aber selbst wenn beide Chips ähnlich reagieren kann es sich ja Situationsabhängig ändern und zum Benchen muß es eine Option geben es schnell zu ändern.

ScottManDeath
2006-11-27, 23:51:12
Konstanten Buffer gab es aber vor dem G80 doch gar nicht. Ich denke aber du willst darauf hinaus dass jetzt das Fragment Program bei Veränderungen der Konstanten nicht mehr aufwendig gepatched werden muß.

Jups, das meinte ich, und darüber hinausgehend noch gewisse Optimierungen für den Bufferwechsel ...