OpenGL und Speicherlayouts

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
kristof
Beiträge: 91
Registriert: 19.01.2009, 13:05

OpenGL und Speicherlayouts

Beitrag von kristof »

Hallo zusammen,

ich bin momentan dabei die OpenGL API Aufrufe unter einem dünnen Wrapper zu verstecken, der im wesentlichen dafür sorgen soll, dass ich mir nicht andauernd Gedanken über das Speicherlayout meiner Vertex- und Texturdaten machen muss.

Ich verwende überall in meinem Programm eine eigene Vektorklasse, die etwa wie folgt aussieht:

Code: Alles auswählen

template<typename type, int n>
struct vec {
	type data[n];

	// Eine Ganze Menge Kontruktoren und Operatoren
};
Soweit ich weiss macht der C++ Standard allerdings keinerlei Aussagen darüber, wie diese Struktur im Speicher aussieht. Das heisst, ich kann nicht einfach ein Array von vec´s erzeugen und einen Zeiger darauf an glBufferData übergeben. Ist das soweit richtig?

Am liebsten würde ich sogar noch mehrere Vektoren gruppieren um Vertices zu bilden, die ich dann interleaved an OpenGL übergeben kann:

Code: Alles auswählen

struct vertex {
	vec<float,3> position;
	vec<unsigned char,4> color;
	// ...
};
Bleibt mir nichts anderes übrig, als die Daten kurz vor der Übergabe an OpenGL in ein Byte Array umzukopieren, sodass ich das Speicherlayout bestimmen kann?
Wie Löst ihr das, dass ihr im Programm elegant auf die Daten zugreifen könnt und OpenGL trotzdem ein definiertes Speicherlayout garantieren könnt?
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: OpenGL und Speicherlayouts

Beitrag von Artificial Mind »

1. http://glm.g-truc.net/ für Vektoren
2. Soweit ich weiß halten sich die "großen Compiler" an char ist byte-aligned, int/float ist 4-byte aligned. Wenn man nichts weiter zu einem struct schreibt, sollten die Daten also von oben nach unten im Speicher hintereinander liegen und wenn man nur ints/floats und 4 chars für Farben nutzt auch passend aneinander.

Sonst vielleicht das hier mal lesen: http://en.wikipedia.org/wiki/Data_structure_alignment
kristof
Beiträge: 91
Registriert: 19.01.2009, 13:05

Re: OpenGL und Speicherlayouts

Beitrag von kristof »

Danke. Soweit war mir das aber auch schon klar, dass die gängigen Compiler sich im alignement von structs sehr ähneln. Auch die von dir verlinkte glm nutzt das aus soweit ich das gesehen habe. Aber es muss doch einen eleganteren Weg geben, der nicht auf undefiniertem Verhalten beruht :-/
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: OpenGL und Speicherlayouts

Beitrag von Artificial Mind »

Code: Alles auswählen

#pragma pack(1)
Nicht standardisiert,dafür dokumentiert und well defined.
Benutzeravatar
Jeason
Beiträge: 41
Registriert: 07.09.2010, 22:58

Re: OpenGL und Speicherlayouts

Beitrag von Jeason »

kristof hat geschrieben:Das heisst, ich kann nicht einfach ein Array von vec´s erzeugen und einen Zeiger darauf an glBufferData übergeben. Ist das soweit richtig?
Also bei mir funktionierte das zumindest mit einem Color Struct und Textur Daten. Sprich ich konnte einfach ein Color Struct Array direkt an glTexImage2D als Zeiger übergeben.
Ich verkaufe diese feinen Lederjacken.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: OpenGL und Speicherlayouts

Beitrag von Artificial Mind »

Ja, das ist homogen genug, als das es funktioniert.
Wenn du aber in einem Vertex-Struct ein byte und dann ein float speicherst, dann sollte das Struct 8 byte groß sein, da der float 4-byte-aligned wird. Und das ist halt ein Problem, weil du in deiner Buffer-Deklaration wahrscheinlich 1 byte und 4 bytes mitt Stride von 5 bytes angibst.
kristof
Beiträge: 91
Registriert: 19.01.2009, 13:05

Re: OpenGL und Speicherlayouts

Beitrag von kristof »

Genau, das ist das Problem. Und theoretisch dürfte der Compiler auch alles 8-aligned, 3-aligned oder x-aligned im Speicher ablegen wenn er meint, dass das für die Zielplattform Sinn ergibt.
Aber ich denke, ich werde mich jetzt tatsächlich erstmal mit #pragma pack(1) zufrieden geben. Wenn allerdings noch jemand eine gute Idee hat, wäre ich sehr froh sie zu hören :)
Benutzeravatar
Lynxeye
Establishment
Beiträge: 145
Registriert: 27.02.2009, 16:50
Echter Name: Lucas
Wohnort: Hildesheim
Kontaktdaten:

Re: OpenGL und Speicherlayouts

Beitrag von Lynxeye »

Erst mal vorneweg: alle zur Zeit gebräuchlichen Platformen (x64, PPC, ARM) fordern ein natural Alignment der Daten, das Alignment der Daten ist also immer >= Größe der eingesetzten Datentypen. Zusätzlich nimmt kein Compiler ein Padding am Anfang der Struktur vor, sondern richtet die Struktur komplett am natural Alignment des größten Datentyps innerhalb der Struktur aus.

Das heißt im Klartext, dass wenn du etwas Handarbeit investierst und die Elemente deiner Struktur vom größten zum kleinsten Datentyp sortierst, benötigt der Compiler auf keine Fall ein Padding einzufügen.

Die pack Attribute sind zwar auf ziemlich jedem Compiler in irgendeiner Form verfügbar haben aber den Nachteil, dass dadurch evtl das natural Alignment zerstört wird und der Prozessor somit unaligned auf die Daten zugreifen muss, was erheblich Performance fressen kann. Sie sollten daher nur eingesetzt werden, wenn die Optimierung durch händisches sortieren der Strukturelemente nicht möglich ist.
glassbear
Establishment
Beiträge: 324
Registriert: 08.04.2003, 18:09
Alter Benutzername: Enrico_
Echter Name: Enrico
Wohnort: San Diego
Kontaktdaten:

Re: OpenGL und Speicherlayouts

Beitrag von glassbear »

Lynxeye hat geschrieben:Das heißt im Klartext, dass wenn du etwas Handarbeit investierst und die Elemente deiner Struktur vom größten zum kleinsten Datentyp sortierst, benötigt der Compiler auf keine Fall ein Padding einzufügen.
Das stimmt so nicht. Selbst mit der Groessen-Sortierung kann und wird der Compiler Padding am Ende hinzufuegen, zum Beispiel um das struct auf 64 Byte zu padden = 1 CPU Cache Line.
Schon mehrfach gesehen im GCC und hat mir dann meine SSE-Funktionen zerhauen :cry:
Ein Hoch auf uns Männer... Auf die Frau, die uns HAT ( oder hat, und nicht weiß, dass sie uns hat ) ...auf die Idiotinnen ... besser gesagt VOLLPFOSTINNEN ... die uns hatten und uns verloren haben ... und auf die GLÜCKLICHEN, die das Vergnügen & Glück haben werden uns kennenzulernen!
Benutzeravatar
Lynxeye
Establishment
Beiträge: 145
Registriert: 27.02.2009, 16:50
Echter Name: Lucas
Wohnort: Hildesheim
Kontaktdaten:

Re: OpenGL und Speicherlayouts

Beitrag von Lynxeye »

glassbear hat geschrieben:
Lynxeye hat geschrieben:Das heißt im Klartext, dass wenn du etwas Handarbeit investierst und die Elemente deiner Struktur vom größten zum kleinsten Datentyp sortierst, benötigt der Compiler auf keine Fall ein Padding einzufügen.
Das stimmt so nicht. Selbst mit der Groessen-Sortierung kann und wird der Compiler Padding am Ende hinzufuegen, zum Beispiel um das struct auf 64 Byte zu padden = 1 CPU Cache Line.
Schon mehrfach gesehen im GCC und hat mir dann meine SSE-Funktionen zerhauen :cry:
Das ist allerdings äußeres Padding, nicht inneres. Bei Größensortierung der Strukturelemente wird nie Padding innerhalb der Struktur auftreten. Natürlich wird der Compiler bei mehreren Instanzen der Struktur im Speicher äußeres Padding hinzuzufügen um das natural Alignment sichzustellen. Mit Cachelines hat das eher weniger zu tun, es sei denn du forderst den Compiler explizit dazu auf. Das maximale äußere Padding ist zum sicherstellen des natural Alignments immer sizeof(Größtes_Element_der_Struktur)-1. Aber selbst das lässt sich mit ein wenig Handarbeit vermeiden, indem man selbst seine Struktur am Ende entsprechend padded und die Stride beim Auslesen anpasst.
glassbear
Establishment
Beiträge: 324
Registriert: 08.04.2003, 18:09
Alter Benutzername: Enrico_
Echter Name: Enrico
Wohnort: San Diego
Kontaktdaten:

Re: OpenGL und Speicherlayouts

Beitrag von glassbear »

Von innen und aussen war oben nicht die Rede ;)
Ein Hoch auf uns Männer... Auf die Frau, die uns HAT ( oder hat, und nicht weiß, dass sie uns hat ) ...auf die Idiotinnen ... besser gesagt VOLLPFOSTINNEN ... die uns hatten und uns verloren haben ... und auf die GLÜCKLICHEN, die das Vergnügen & Glück haben werden uns kennenzulernen!
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: OpenGL und Speicherlayouts

Beitrag von dot »

Ich bin mir auch nicht sicher, was genau du mit dieser Unterscheidung zwischen "innerem" und "äußerem" Padding bezweckst. Ein struct hat eine bestimmte Größe, die muss per Definition in jedem Kontext gleich sein...
Antworten