Proseminar Schnelle 3D-Grafik im WS 1998/99
am Lehrstuhl für Effiziente Algorithmen

Thema 13: Hardwareunterstützung

von E-MailMarc Layer
Betreuer: Thomas Fridetzky
1999-02-18
überarbeitet 1999-05-28

Inhalt

downEinführung
downArten von Hardwareunterstützung
downGrafikkarten ohne spezielle 3D-Unterstützung
down3D-Grafikkarten ohne Geometrieverarbeitung
downBeschleunigte Geometrieberechnung: CPU-Befehlserweiterungen
down3D-Grafikkarten mit Geometrieverarbeitung
downAusblick
downQuellen


Einführung

Die Entwicklung von 3D-Grafikhardware ist in den letzten Jahren rasant vorangeschritten. Während vor 10 Jahren realistisch wirkende 3D-Szenerien von teuren Großrechnern Einzelbild für Einzelbild berechnet werden mussten und deshalb nur im professionellen Bereich (z. B. Film, Präsentationen) verwendet werden konnten, verfügt heute nahezu jeder neu gekaufte PC für Zuhause bereits über eine leistungsfähige 3D-Grafikkarte.

Im PC-Bereich waren für diese Entwicklung vor allem auch Computerspiele verantwortlich. Zunächst wurden mangels Hardwareunterstützung 3D-Szenerien nur vom Hauptprozessor (CPU) berechnet und gezeichnet. Die Detailtiefe hing also stark von der Leistungsfähigkeit der CPU ab. Diese reichte erst Anfang der 90er Jahre für realistischere Darstellung, die im Laufe der Jahre immer aufwendiger wurde und deshalb die Entwicklung von speziellen Grafikkarten mit einem von der CPU unabhängigen Grafikprozessor herbeiführte.

Inzwischen hat deren Funktionsumfang so stark zugenommen, dass auch im Profibereich häufig PCs zur Erzeugung von 3D-Grafik verwendet werden, da sie verglichen mit teuren UNIX-Workstations eine vergleichbare Leistung zu einem weitaus geringeren Preis erzielen.

nach oben

Arten von Hardwareunterstützung

Ich werde hier auf vier Ansätze der Hardwareunterstützung zur Erzeugung von dreidimensionalen Grafiken in Echtzeit eingehen:

nach oben

Grafikkarten ohne spezielle 3D-Unterstützung

Bevor die ersten 3D-Karten entwickelt wurden, hatten Grafikkarten nur die Aufgabe, von der CPU erzeugte Bilder auf dem Monitor sichtbar zu machen. Manche von ihnen haben durchaus CPU-entlastende Funktionen wie z. B. das Durchführen von sog. Bit-Block-Transfers. Diese sind aber nicht für 3D-Grafik ausgelegt sondern eher, um z. B. das Verschieben von Fenstern zu beschleunigen.
 

Die Einbindung in das Computersystem ist in Abb.1 schematisch dargestellt.

Standard 2D Grafikkarte

Abb.1

Alle 2D- und 3D-Grafiken werden von der CPU berechnet und über den PCI-Bus in den Videospeicher geschrieben. Seit Mitte der 90er Jahre werden Bildformate mit mehr als 8-Bit zur Farbdarstellung von den meisten Karten unterstützt, so dass die realitätsnahe Darstellung nicht durch sichtbare Farbabstufungen getrübt werden muss. Üblich sind bei der Abspeicherung der Pixel im Videospeicher das Highcolor- (32768 mögliche Farben, 15 Bit 555-RGB, d. h. je 5 Bit für die Intensität von Rot, Grün und Blau), Realcolor- (65536 Farben, 16 Bit 565-RGB) und Truecolorformat (16777216 Farben, 24 Bit 888-RGB bzw. 32 Bit 8888-RGBA mit 8 Bit für den Alphawert).

Um die Zeichenaktivitäten, die für den Bildaufbau notwendig sind, vor dem Betrachter zu verbergen, kann der Videospeicher in der Regel in mehrere Bereiche, sog. Seiten eingeteilt werden. Dabei wird immer eine Seite, der Framebuffer auf dem Bildschirm dargestellt, während in die andere, den Backbuffer, geschrieben wird. Ist die zweite Seite bereit zur Anzeige, wird zwischen den beiden Seiten umgeschaltet, indem die Startadressen des Framebuffers auf die des Backbuffers gesetzt wird. Das Umschalten sollte jedoch nur bei vertikaler Synchronisation des Kathodenstrahls erfolgen, d. h. wenn er von der rechten unteren Ecke des Monitors zurück zur linken oberen Ecke läuft (und dabei abgeschaltet ist). Anderenfalls kann es zu unschönen Effekten wie gleichzeitiger Darstellung zweier Teilbilder (Splitscreen) oder "Schneegestöber" auf dem Bildschirm kommen. Im ungünstigsten Fall ist das Bild erst fertigberechnet, wenn der Strahlrücklauf bereits eingesetzt hat, es muss also auf den nächsten Rücklauf gewartet werden. Bei einer Bildwiederholfrequenz von 75Hz müsste in so einem Fall beispielsweise 1/75 s gewartet werden, d. h. 1/75=1,33% der Rechenzeit der CPU würde (bei einem Bild) verloren gehen.

Die Anzahl der darstellbaren Bilder pro Sekunde (Framerate) ist deswegen zum einen durch die Bildwiederholfrequenz f des Monitors bestimmt, zum anderen natürlich durch die Rechengeschwindigkeit der CPU, und durch das zeitliche Zusammentreffen von Bildberechnung und vertikalem Synchronisationssignal.

Neben den Zugriffen der CPU liest natürlich auch der RAMDAC (=RAM Digital-Analog-Converter) ständig den Videospeicher aus und wandelt dabei die digitalen Farbwerte in analoge Signale für den Monitor um.

Bei der eben verwendeten Bildwiederholfrequenz von 75Hz und einer Auflösung von 800*600 Bildpunkten mit 24-Bit (=3 Byte) Farbtiefe ergeben sich

800*600*3*75 = 108 MB ,

die pro Sekunde allein vom RAMDAC ausgelesen werden.

Damit der Videospeicher zusätzlich noch die Zugriffe der CPU bewältigen kann, gibt es eine Reihe von Optimierungsmöglichkeiten:

nach oben

3D-Grafikkarten ohne Geometrieverarbeitung

Dies sind die heute wohl meistverbreiteten Grafikkarten in neuen Computern. Die Grafikkarte verfügt über einen eigenen Prozessor, den sogenannten Rasterprozessor, der die von der CPU vorberechneten Polygone mit Texturen und Farbe überzieht.

Die CPU übernimmt alle Berechnungen auf Polygoneckpunktebene:

Damit der Rasterprozessor die Polygone möglichst schnell bearbeiten kann, werden größere Polygone in möglichst kleine Teilpolygone (meist Dreicke) zerlegt. Die fertig berechneten Eckpunktdaten mit RGBA-Werten, U/V-, Z/W-, X/Y-Koordinaten und Nebelwert F werden anschließend an den Rasterprozessor auf der 3D-Karte übergeben.

Dieser berechnet für jedes Polygon zeilenweise die Farbwerte der zu zeichnenden Pixel. Dabei wird für jeden Pixel die Rendering-Pipeline aus Abb.2 durchlaufen.

 

Schritte in der Rendering-Pipeline
 

Rendering-Pipeline

Abb.2

  1. Zunächst werden aus den Eckpunktdaten durch Interpolation die für jeden Pixel benötigten Werte (RGRA, UV, W, Z, XY) bestimmt.
  2. Mit Hilfe der W-Koordinate erfolgt eine Perspektiv-Korrektur dieser Werte, um Verzerrungen auszuzschließen, die bei alleiniger Verwendung der Z-Koordinate auftreten würden.
  3. Der Z-Wert des aktuellen Pixels wird mit dem Z-Wert eines evtl. bereits im Bildschirmspeicher befindlichen Pixels an der selben X/Y-Koordinate verglichen. Nur wenn
  4. Zaktuell <ZBuffer ,

    wird der Pixel überzeichnet, ansonsten wird die Pipeline abgebrochen.

  5. Als nächstes wird der Stencil-Test durchgeführt. Mittels Stenciling lassen sich Bildschirmbereiche vor dem Überschreiben mit Polygonen schützen, wodurch es möglich wird, statische Objekte wie z. B. die Innenansicht eines Cockpits nicht bei jeder Szene nachladen zu müssen. Sollte der aktuelle Pixel geschützt sein, wird ebenfalls die Pipeline abgebrochen.
  6. Der Pixel wird texturiert:

    Dabei werden meist mehrere Bildpunkte der Textur mittels den U-V-Koordinaten gefiltert, um die Farbe eines Pixels zu bestimmen. Unter Umständen werden dabei sogar mehrere Texturen übereinandergelegt (Multitexturing), beispielsweise eine Schmutztextur über die normale Objekttextur.

    Wie man leicht sieht, werden bei der Texturierung enorme Datenmengen benötigt, denn bereits bei der bilinearen Filterung werden vier Texel für jeden Pixel gefiltert, beim Multitexturing sogar ein Vielfaches davon. Dies kann leicht zu Bandbreitenproblemen im Texturspeicher führen.

    Deswegen werden Texturen meistens platzsparend abgelegt, um den Umfang der zu übertragenden Daten möglichst gering zu halten:
    • komprimierte Texturen: die nötige Kompression/Dekompression kann ohne großen Zeitverlust durch die Grafikhardware durchgeführt werden
    • Verwendung von 8 Bit Paletten-Texturen: jeder Texelwert repräsentiert einen Eintrag in einer Palette (color look-up table, CLUT) mit höherer Farbauflösung (meist 24 Bit). Dies spart einerseits Speicher und bietet darüberhinaus die Möglichkeit durch einfachen Palettenwechsel das Aussehen einer Textur zu verändern
    • Verwendung von 16 Bit Texturen (565 RGB, 5551/4444 RGBA): Die Texturfarben werden zur Berechnung ins interne 8888-Bit RGBA Format umgewandelt, und benötigen zur Speicherung nur den halben Platz.

    Beim Zugriff auf die Texturen gibt es grundsätzlich zwei Möglichkeiten:

    1. Falls die 3D-Karte über einen ausreichend großen eigenen Speicher verfügt, werden die Texturen dort abgelegt. Dies entlastet den Hauptspeicher und den Datenbus, da Texturdaten nicht ständig übertragen werden müssen, und außerdem kann der Grafikchip auf den lokalen Speicher schneller zugreifen. Der Nachteil dabei ist, dass zusätzlicher Speicher natürlich zusätzliche Kosten bedeutet, und er unter Umständen die meiste Zeit überhaupt nicht ausgefüllt wird.
    2. Die andere Möglichkeit ist es, die Texturen im Hauptspeicher zu belassen. Der Grafikchip greift dann mittels AGP direkt darauf zu, genauso, als würden sie sich auf der Grafikkarte befinden. Dadurch ist es möglich, Texturspeicher einzusparen, bzw. Texturen, die über das Volumen des Grafikkartenspeichers hinausgehen, flexibel aus dem Hauptspeicher zu entnehmen. Wird AGP allerdings als Ersatz für Texturspeicher eingesetzt, ist mit erheblichen Performance-Verlusten zu rechnen, da der Hauptspeicher dann nicht nur von der CPU benutzt wird, sondern ständig Zugriffe seitens der 3D-Karte bearbeiten muss. Weil aber Texturen meist nicht-sequentiell gelesen werden (wegen der UV-Koordinatenumrechnung und gewissen Filtertechniken), führt die Latenzzeit der Speicherchips (also das Einstellen auf eine neue Schreib-/Lese-Adresse) zur weiteren Verschlechterung der Situation.

    AGP eignet sich also hauptsächlich zu Unterstützung des lokalen Texturspeichers, z. B. für große oder selten benötigte Texturen.

  7. Der Texturierte Pixel wird mit einem Lichtanteil gemischt (durch Multiplikation oder Addition). Um das plötzliche Auftauchen von Objekten aus der hinteren Clipebene zu vermeiden, wird der Pixel nun je nach Abstand zum Betrachter mit einem Nebelanteil versehen.
  8. Zum Schluss wird mit Hilfe des Alphawertes die Transparenz des Pixels bestimmt, und anteilig mit der Farbe bereits gezeichneter Pixel gemischt. Dabei hat man das Problem, dass beim Alphablending das Ergebnis von der Reihenfolge der transparenten Polygone abhängt. Diese müssen deshalb bereits bei der Geometrieberechnung (von der CPU) relativ aufwendig tiefensortiert werden. Deshalb bemüht man sich (heutzutage jedenfalls noch), die Anzahl transparenter Polygone möglichst gering zu halten.
  9. Der fertig gerenderte Pixel wird am Ende der Pipeline in den Bildschirmspeicher geschrieben. Aus Performance-Gründen kann es nötig sein, den mit 24-Bit Farbtiefe berechneten Pixel nur mit 16-Bit abzuspeichern. Um dabei auftretende sichtbare Farbabstufungen zu vermeiden, ist im Grafikchip meist auch Dithering implementiert.
nach oben

Beschleunigte Geometrieberechnung:
CPU-Befehlserweiterungen

Trotz immer schnellerer CPUs berechnet der Rasterprozessor in der Regel die Polygone schneller, als sie geliefert werden können. Deswegen wurden bestimmte Befehlserweiterungen eingeführt, die eine schnellere Fließkommaberechnung möglich machen.
 

3DNow! von AMD

3DNow! ist als Fließkomma-Erweiterung des von Intel entwickelten MMX-Befehlssatzes ausgelegt, der bis dahin nur ganzzahlige Berechnungen zuließ. Die acht 64 Bit Fließkommaregister der Floating-Point-Unit (FPU) werden dabei in je zwei 32 Bit Fließkommaregister einfacher Genauigkeit aufgeteilt (das ergibt insgesamt 16 Register). Damit 3DNow! verwendet werden kann, muss erst in den MMX-Modus umgeschaltet werden, um die Fließkommaregister verfügbar zu machen (ein gleichzeitiger Betrieb von FPU und MMX/3DNow! ist also nicht möglich). Das Umschalten kostet ca. 70 Prozessortakte.

Der Prozessor verfügt über zwei fully-pipelined arbeitende Ausführungseinheiten, d. h. in jedem Takt tritt ein Befehl in die Befehlpipeline ein, und in jedem Takt wird die Ausführung eines Befehls (am Ende der Pipeline) abgeschlossen. Jede der Einheiten führt unabhängig voneinander (natürlich nur, wenn die Operanden unabhängig sind) mit jedem Befehl auf einem der Registerpaare zwei identische Operationen aus (single instruction-multiple data, SIMD). Dadurch ergeben sich also maximal 2 Befehle pro Takt * 2 Fließkommaoperationen pro Befehl = 4 Fließkommaoperationen pro Takt .

3Dnow! Befehlskombinationen

Abb.3


Abb.3 zeigt eine Übersicht über die verfügbaren 3DNow!/MMX-Befehle. Parallel von beiden Ausführungseinheiten ausgeführt werden können nur Operationen aus verschiedenen Kästen.

Dies ermöglicht z. B. Folgen von Multiplikationen und Additionen, die bei bei der für Translationen oft benötigten Matrix-Vektor-Multiplikation auftreten, zeitsparend abzuarbeiten. Leider würde aber eine 4x4-Matrix bereits alle 16-Register belegen, so dass gerade bei Transformationen mehrerer Vektoren bestimmte Matrixzeilen immer wieder nachgeladen werden müssen.

Weitere Nachteile sind, dass die bei der Beleuchtungsberechnung häufig gebrauchte Potenzfunktion nicht vorhanden ist, also nach Umschalten aus dem MMX-Modus von der normalen FPU berechnet werden muss, und dass die in der Regel auf die Iterationsberechnung folgende Multiplikation nicht parallel abgearbeitet werden kann.

 
Katmai New Instructions (KNI) von Intel

Der KNI-Satz wurde erstmals im kürzlich eingeführten Pentium III implementiert. Anders als 3DNow! enthält der Prozessor einen eigenen KNI-Registersatz mit acht 128 Bit-Registern, unterteilt in je vier 32 Bit Fließkommaregister einfacher Genauigkeit (insgesamt 32 Register, also doppelt so viele wie 3DNow!). Es gibt nur eine Ausführungseinheit, die dafür aber auf den vier Registern eines der 128 Bit Registern vier identische Operationen ausführt (SIMD).

Der Befehlssatz entspricht etwa dem von AMD, der Vorteil der KNI gegenüber 3DNow! ist jedoch, dass sie von der FPU unabhängig ausgeführt werden können. Dadurch spart man sich zum einen das Umschalten in den MMX-Modus, zum anderen kann die fehlende Potenzfunktion parallel von der FPU berechnet werden.

nach oben

3D-Grafikkarten mit Geometrieverarbeitung

Die höchste Beschleunigung von 3D-Grafik wird derzeit aber von 3D-Karten mit Geometrieprozessor erzielt. Die Grafikkarte muss nur noch Befehle erhalten, die zum Aufbau einer Szene nötig sind, die aufwendige Geometrieberechnung entfällt dann für die CPU komplett.

Derartige Grafikkarten findet man aber (noch) nur im Profi-Bereich, da die entsprechenden Architekturen recht aufwendig und teuer sind.

Ich werde diesen Bereich anhand eines speziellen Vertreters dieser Art vorstellen, nämlich der RealiZm von Intergraph. Man kann bei ihr nicht mehr von einer Grafikkarte sprechen, vielmehr besteht sie aus einem Set von drei PCI-Steckkarten. Ihre Einbindung ist schematisch in Abb.4 dargestellt.

Auf einer Karte sitzt der Geometrieprozessor mit eigenem lokalen Speicher, auf der zweiten sind der Rasterprozessor, der Texturspeicher und der Framebuffer untergebracht. Die dritte Grafikkarte entspricht im Prinzip einer normalen VGA-Karte und dient nur zur Darstellung des Bildes und zur Wahrung der Kompatibilität.

Intergraph RealiZm

Abb.4

 
Rasterprozessor und Display-Karte wurden bereits beschrieben, deswegen werde ich mich hier auf die Eigenschaften des Geometrieprozessors konzentrieren.

Der Geometrieprozessor besteht aus 7 digitalen Signalprozessoren (DSPs), wie in Abb.5 dargestellt.

Geometrieprozessor

Abb.5
 

Jeder der DSPs verfügt über eine eigene Befehlswarteschlange und einen 2 Mbit großen lokalen Speicher. Sechs von ihnen bearbeiten parallel die ihnen zugewiesenen vertices (multiple instruction-multiple data, MIMD). Sollte bei der Befehlsverteilung ein DSP eine volle Befehlswarteschlange haben, so wird dies vermerkt und der Befehl wird an den nächsten gegeben. Dadurch ist gewährleistet, dass kein Prozessor unausgelastet ist. Mit Hilfe des Weitergabevermerks kann der siebte DSP, der die Koordination der berechneten Daten übernimmt, diese wieder in die ursprüngliche Reihenfolge bringen.

Bei der Geometrieverarbeitung werden die entstehenden Polygone in kleine Dreiecke zerlegt, diese dann transformiert, geclippt, mit Texturkoordinaten versehen und beleuchtet, wie bereits bei der Geometrieverarbeitung durch die CPU gesagt.

Die fertig berechneten Polygondaten werden dann an den Rasterprozessor weitergegeben, der daraus eine farbige Szene generiert, die schließlich von der Display-Karte dargestellt wird.

nach oben

Ausblick

Die Leistungsfähigkeit von Grafikkarten ist in den letzten Jahren enorm gestiegen, von der einfachen "darstellenden", bis zur selbst rechnenden 3D-Karte. Genauso sind natürlich auch die Anforderungen der Anwender an immer mehr Farben, schnellere, realistischere Grafik mit immer höherer Komplexität. Es ist möglich, dass in nicht allzu ferner Zukunft die Geometrieverarbeitung standardmäßig auf jeder 3D-Grafikkarte zu finden sein wird, nebenbei wird die Gesamtleistungsfähigkeit natürlich weiter steigen, so dass immer mehr Polygone pro Zeiteinheit berechnet werden können.

Eines Tages wird man dann wahrscheinlich Zusatzprozessoren benötigen, die die 3D-Chips entlasten…

nach oben

kleiner Nachtrag

(1999-10-06)
Die prophezeite "nicht allzu ferne Zukunft" liegt nun unmittelbar vor uns: DirectX 7.0 unterstützt bereits Geometrieverarbeitung durch den 3D-Chip und erste Grafikkarten-Hersteller feilen bereits an Prototypen für den Massenmarkt. Das ganze wird wohl anfangs teuerer sein, als "normale" Karten, aber diese früher oder später ersetzen…


Quellen

nach oben