|
Uno degli obiettivi principali delle DirectX 10 è quello di ridurre
in modo significativo il sovraccarico della CPU nelle operazioni di
rendering. Le DirectX 10, perciò, presentano tre modi per risolvere
questo problema. Anzitutto il costo, in termini di cicli di CPU, delle
chiamate di drawing e di cambiamento di stato è stato ridotto attraverso
una riprogettazione completa delle parti di codice critiche del core
delle API. Sono state poi introdotte nuove feature per ridurre la
dipendenza dalla CPU ed, infine, ulteriori nuove funzionalità sono state
aggiunte per permettere di eseguire più compiti con un solo comando.
La nuova architettura delle DirectX 10 prevede una maggiore vicinanza
a quelle che sono le caratteristiche dell'hardware grafico, permettendo
così di sfruttare meglio le caratteristiche di quest'ultimo. Molte
funzionalità legacy, integrate per compatibilità nelle API attuali sono
state rimosse completamente, nel segno dell'efficienza e di un runtime
più leggero.
Le ottimizzazioni integrate nelle DirectX 10 partono dal
miglioramento dell'esecuzione del task della validazione.
Tale processo assicura che i dati e le istruzioni inviati
dall'applicazione siano correttamente formattati e non siano causa di
potenziali problemi per la scheda grafica.

Come si può vedere dalla tabella, nelle API DirectX 9 il processo di
validazione viene chiamato per ogni esecuzione del gioco. Con le DirectX
10, invece, tale processo viene eseguito una sola volta, durante il processo di creazione delle risorse
e non durante l'esecuzione di ogni ciclo del gioco.
Fra le nuove caratteristiche introdotte con le DirectX 10 ne troviamo
ancora molte altre utili a ridurre l'intervento della CPU. Texture arrays,
predicated draw e stream out sono quelle di cui parleremo nelle prossime
righe.
La tecnologia texture arrays, permette di immagazzinare fino a 512
texture in un array. Per la gestione di questa struttura sono state
anche implementate nuove istruzioni, gestite direttamente dalla GPU, che
permettono ad un programma di indicizzare dinamicamente le texture nell'array.
La funzione che va sotto il nome di predicated draw è nuovamente
realizzata senza richiedere l'intervento della CPU. Nelle scene 3D
tipiche, molti oggetti sono spesso nascosti da altri oggetti. In questi
casi, andare a disegnare gli oggetti nascosti richiede risorse che
saranno poi sprecate, in quanto la presenza o meno del determinato
oggetto non ha nessuna influenza visiva sulla scena finale. Le GPU
moderne utilizzano vari algoritmi per determinare quali sono gli oggetti
o parte di essi che non serve renderizzare in quanto non risulteranno
visibili. Ma, comunque sia, accade sempre che qualche
oggetto sfugga ai suddetti metodi. Per prevenire ulteriormente tale
spreco di risorse gli sviluppatori utilizzano una tecnica chiamata
appunto predicated draw (oppure occlusion query), nella quale gli oggetti
complessi sono disegnati in prima approssimazione come fossero una
semplice scatola. Se il disegno della scatola non ha effetti
sull'immagine finale, l'oggetto complesso non è disegnato affatto. Con
le API DirectX 9 e precedenti, la soluzione della occlusion query era
realizzata utilizzando sia risorse di CPU che di GPU. Con le DirectX 10,
come è facile immaginare, questo processo passa interamente in mano alla
GPU.
Con le API precedenti alle DirectX 10, gli stati erano gestiti in
modo molto elaborato e preciso. Uno stato definisce il comportamento
delle varie parti della pipeline grafica. Per esempio, nel vertex
shader, lo stato del layout del buffer dei vertici definisce il formato
dei vertici di ingresso. Più in generale, gli stati aiutano a definire i
diversi formati dei vertici e delle texture ed il comportamento delle
parti fisse delle funzioni della pipeline. Con il modello di gestione
degli stati nelle DirectX 9, il programmatore gestisce gli stati a basso
livello e questo fa si che siano necessari molti cambiamenti di stato
per riconfigurare tutta la pipeline. Tutto questo causa
un elevato overhead sulla CPU. Inoltre, le applicazioni 3D
utilizzano i comandi per le gestione degli stati in rapida successione,
ma nelle DirectX 9 manca completamente un modo per realizzare tale
sequenza in modalità batch. Questo crea un accumulo di sovraccarico sulla CPU che determina
subito un limite alle performance. Le DirectX 10 introducono due nuovi
costrutti, in tal senso, denominati state objects e constant buffers.
Questi, in poche parole, permettono di eseguire in modalità batch le
operazioni più comuni riducendo notevolmente il costo della gestione
degli stati.
Per rendere i cambiamenti di stato
più efficienti, le DirectX 10 implementano un nuovo modello che prevede
la gestione a più alto livello, usando appunto gli state objects. La
grande varietà di stati presenti nelle DirectX 9 è stata consolidata,
nelle DirectX 10, in soli cinque state objects: InputLayout (vertex
buffer layout), Sampler, Rasterizer, DepthStencil e Blend. Questi state
objects catturano le proprietà essenziali dei vari stadi della pipeline
permettendo di effettuare un cambiamento di stato, che prima richiedeva
un certo numero di comandi, con una sola chiamata. Questo permette
ancora di ridurre il sovraccarico sulla CPU.
L'altra funzionalità interessante introdotta con le DirectX 10,
influisce sull'utilizzo delle costanti. Con questo termine vengono
indicati i parametri dotati di un valore predefinito che vengono
utilizzati in tutti i programmi di shader. Per esempio, il numero di
luci di una scena, la loro intensità, il colore ed la
posizione sono definiti tutti come costanti.

In un gioco, le costanti
sono spesso aggiornate ad un diverso valore al fine di riflettere i
cambiamenti dell'ambiente o dei caratteri. Proprio a causa dell'elevato
numero di costanti necessarie e del frequente aggiornamento del loro
valore, queste sono causa di un ulteriore overhead sulle API. Con le
DirectX 10, i constant buffers permettono di salvare fino a 4096
costanti in un buffer che può essere aggiornato tutto con una sola
chiamata.

Grazie a tutti questi miglioramenti, le DirectX 10 richiedono un
minore intervento della CPU nella creazione di una scena 3D. Nel grafico
qui sopra possiamo osservare l'influenza sulle varie funzionalità delle
nuove features come lo stream output, il texture arrays ed il predicated
draw.
|