Share via


Warum werden gekachelte Ressourcen benötigt?

Gekachelte Ressourcen werden benötigt, sodass weniger GPU-Speicher (Graphics Processing Unit) verschwendet wird, um Speicherbereiche von Oberflächen zu speichern, von denen die Anwendung weiß, dass nicht zugegriffen wird, und die Hardware kann verstehen, wie sie über benachbarte Kacheln filtern kann.

In einem Grafiksystem (Betriebssystem, Anzeigetreiber und Grafikhardware) ohne Unterstützung gekachelter Ressourcen verwaltet das Grafiksystem alle Direct3D-Speicherzuordnungen mit granularer Unterressourcen. Bei einem Puffer ist der gesamte Puffer die Unterressource. Für eine Textur (z. B . Texture2D) ist jede MIP-Ebene eine Unterquelle. für ein Texturarray (z. B . Texture2DArray) ist jede MIP-Ebene in einem angegebenen Arrays slice eine Unterquelle. Das Grafiksystem macht nur die Möglichkeit verfügbar, die Zuordnung von Zuordnungen an dieser Subressourcengranularität zu verwalten. Im Kontext gekachelter Ressourcen bezieht sich "Zuordnung" darauf, Daten für die GPU sichtbar zu machen.

Angenommen, eine Anwendung weiß, dass ein bestimmter Renderingvorgang nur auf einen kleinen Teil einer Mipmap-Bildkette zugreifen muss (vielleicht nicht einmal auf den vollständigen Bereich einer bestimmten Mipmap). Im Idealfall könnte die App das Grafiksystem über diese Notwendigkeit informieren. Das Grafiksystem würde sich dann nur darum bemühen, sicherzustellen, dass der benötigte Arbeitsspeicher auf der GPU zugeordnet wird, ohne zu viel Arbeitsspeicher zu auslagern. In der Realität kann das Grafiksystem ohne unterstützung von gekachelten Ressourcen nur über den Arbeitsspeicher informiert werden, der auf der GPU bei der Granularität der Unterressourcen zugeordnet werden muss (z. B. ein Bereich voller Mipmap-Ebenen, auf die zugegriffen werden könnte). Es gibt auch keine Anforderungsfehler im Grafiksystem, daher muss möglicherweise viel überschüssiger GPU-Arbeitsspeicher verwendet werden, um vollständige Unterressourcen zugeordnet zu machen, bevor ein Renderingbefehl ausgeführt wird, der auf einen beliebigen Teil des Arbeitsspeichers verweist. Dies ist nur ein Problem, das die Verwendung großer Speicherzuordnungen in Direct3D ohne unterstützung von gekachelten Ressourcen erschwert.

Direct3D 11 unterstützt Texture2D-Oberflächen mit bis zu 16384 Pixeln auf einer bestimmten Seite. Ein Bild, das 16384 breit, 16384 hoch und 4 Bytes pro Pixel ist, würde 1 GB Videospeicher verbrauchen (und das Hinzufügen von Mipmaps würde diese Menge verdoppeln). In der Praxis muss selten auf alle 1 GB in einem einzelnen Renderingvorgang verwiesen werden.

Einige Spieleentwickler modellieren Geländeoberflächen mit einer Größe von 128K bis 128K. Die Art und Weise, wie sie dies für vorhandene GPUs erreichen, besteht darin, die Oberfläche in Kacheln zu unterteilen, die klein genug sind, um die Hardware verarbeiten zu können. Die Anwendung muss herausfinden, welche Kacheln möglicherweise benötigt werden, und sie in einen Cache mit Texturen auf der GPU - einem Software-Pagingsystem - laden. Ein erheblicher Nachteil dieses Ansatzes besteht darin, dass die Hardware nichts über das Paging weiß, das geschieht: Wenn ein Teil eines Bilds auf dem Bildschirm angezeigt werden muss, der sich über Kacheln erstreckt, weiß die Hardware nicht, wie eine feste Funktion (d. h. effiziente) Filterung über Kacheln ausgeführt werden soll. Dies bedeutet, dass die Anwendung, die ihre eigenen Softwarekacheln verwaltet, auf manuelle Texturfilterung im Shadercode zurückgreifen muss (was sehr teuer wird, wenn ein anisotroper Filter von guter Qualität gewünscht wird) und/oder Speichererstellungsrinnen um Kacheln verschwenden muss, die Daten von benachbarten Kacheln enthalten, sodass die Hardwarefilterung mit festen Funktionen weiterhin Unterstützung bieten kann.

Wenn eine gekachelte Darstellung von Oberflächenzuordnungen ein Feature der ersten Klasse im Grafiksystem sein könnte, könnte die Anwendung der Hardware mitteilen, welche Kacheln zur Verfügung gestellt werden sollen. Auf diese Weise wird weniger GPU-Arbeitsspeicher verschwendet, um Bereiche von Oberflächen zu speichern, von denen die Anwendung weiß, dass nicht auf sie zugegriffen wird, und die Hardware kann verstehen, wie sie über benachbarte Kacheln gefiltert wird, was einige der Probleme von Entwicklern verringert, die softwarebasierte Kacheln selbst ausführen.

Aber um eine vollständige Lösung zu bieten, muss etwas getan werden, um damit umzugehen, dass unabhängig davon, ob das Kacheln innerhalb einer Oberfläche unterstützt wird, die maximale Oberflächendimension derzeit 16384 beträgt – bei weitem nicht die 128K+, die Anwendungen bereits wollen. Nur die Anforderung, dass die Hardware größere Texturgrößen unterstützt, ist ein Ansatz, aber es gibt erhebliche Kosten und/oder Kompromisse für diese Route. Der Texturfilterpfad und der Renderingpfad von Direct3D 11 sind bereits hinsichtlich der Genauigkeit bei der Unterstützung von 16K-Texturen mit den anderen Anforderungen gesättigt, z. B. unterstützung von Viewportausdehnungen, die während des Renderings von der Oberfläche fallen, oder die Unterstützung der Texturumschließung vom Oberflächenrand während der Filterung. Eine Möglichkeit besteht darin, einen Kompromiss so zu definieren, dass die Funktionalität/Genauigkeit in irgendeiner Weise aufgegeben wird, wenn die Texturgröße über 16K ansteigt. Selbst mit dieser Zugeständnis können jedoch zusätzliche Hardwarekosten in Bezug auf die Adressierungsfunktion im gesamten Hardwaresystem erforderlich sein, um größere Texturgrößen zu verwenden.

Ein Problem, das ins Spiel kommt, wenn Texturen sehr groß werden, ist, dass die Einzelgenauigkeit der Gleitkommatexturkoordinaten (und die zugehörigen Interpolatoren zur Unterstützung der Rasterung) an Genauigkeit fehlt, um Standorte auf der Oberfläche genau anzugeben. Jittery-Texturfilterung würde sich ergeben. Eine teure Option wäre die Unterstützung von Interpolatoren mit doppelter Genauigkeit, obwohl dies angesichts einer vernünftigen Alternative übermäßig sein könnte.

Ein alternativer Name für gekachelte Ressourcen ist "Sparsetextur". "Sparse" vermittelt sowohl die gekachelte Natur der Ressourcen als auch vielleicht den Hauptgrund für deren Tilung - dass nicht alle von ihnen auf einmal abgebildet werden sollen. Tatsächlich könnte eine Anwendung eine gekachelte Ressource erstellen, in der absichtlich keine Daten für alle Regionen+Mips der Ressource erstellt werden. Der Inhalt selbst könnte also spärlich sein, und die Zuordnung des Inhalts im GPU-Speicher zu einem bestimmten Zeitpunkt wäre eine Teilmenge davon (noch spärlicher).

Ein weiteres Szenario, das von gekachelten Ressourcen bedient werden könnte, besteht darin, dass mehrere Ressourcen mit unterschiedlichen Dimensionen/Formaten denselben Arbeitsspeicher gemeinsam nutzen können. Manchmal verfügen Anwendungen über exklusive Ressourcengruppen, von denen bekannt ist, dass sie nicht gleichzeitig verwendet werden, oder über Ressourcen, die nur für eine sehr kurze Verwendung erstellt und dann zerstört werden, gefolgt von der Erstellung anderer Ressourcen. Eine Form der Allgemeinheit, die aus "gekachelten Ressourcen" herausfallen kann, besteht darin, dass der Benutzer mehrere verschiedene Ressourcen auf denselben (überlappenden) Speicher verweisen kann. Mit anderen Worten, die Erstellung und Zerstörung von "Ressourcen" (die eine Dimension/ein Format usw. definieren) kann aus Sicht der Anwendung von der Verwaltung des den Ressourcen zugrunde liegenden Arbeitsspeichers entkoppelt werden.

Gekachelte Ressourcen