Condividi tramite


Perché sono necessarie risorse affiancate?

Le risorse affiancate sono necessarie in modo che meno memoria gpu (Graphics Processing Unit) venga sprecata archiviando le aree delle superfici a cui l'applicazione sa di non essere accessibile e l'hardware può comprendere come filtrare i riquadri adiacenti.

In un sistema grafico (ovvero il sistema operativo, il driver di visualizzazione e l'hardware grafico) senza il supporto delle risorse affiancate, il sistema grafico gestisce tutte le allocazioni di memoria Direct3D con granularità di sottorisorsa. Per un buffer, l'intero buffer è la sottorisorsa. Per una trama (ad esempio , Texture2D), ogni livello mip è una sottorisorsa; per una matrice di trame ,ad esempio Texture2DArray, ogni livello mip in una determinata sezione di matrice è una sottorisorsa. Il sistema grafico espone solo la possibilità di gestire il mapping delle allocazioni in corrispondenza della granularità della sottorisorsa. Nel contesto delle risorse affiancate, il "mapping" fa riferimento a rendere i dati visibili alla GPU.

Si supponga che un'applicazione sappia che una determinata operazione di rendering deve accedere solo a una piccola parte di una catena mipmap di un'immagine (forse anche l'area completa di una determinata mipmap). Idealmente, l'app potrebbe informare il sistema grafico su questa esigenza. Il sistema grafico si preoccupa quindi solo di garantire che la memoria necessaria sia mappata sulla GPU senza paging in memoria eccessiva. In realtà, senza il supporto delle risorse affiancate, il sistema grafico può essere informato solo sulla memoria di cui è necessario eseguire il mapping sulla GPU con granularità di sottorisorsa( ad esempio, un intervallo di livelli mipmap completi a cui è possibile accedere). Nel sistema grafico non è richiesto alcun errore, quindi potenzialmente è necessario usare una grande quantità di memoria GPU in eccesso per eseguire il mapping di sottorisorse complete prima dell'esecuzione di un comando di rendering che fa riferimento a qualsiasi parte della memoria. Questo è solo un problema che rende difficile l'uso di allocazioni di memoria di grandi dimensioni in Direct3D senza il supporto delle risorse affiancate.

Direct3D 11 supporta superfici Texture2D con un massimo di 16384 pixel su un determinato lato. Un'immagine con 16384 larghezza di 16384 di altezza e 4 byte per pixel utilizzerebbe 1 GB di memoria video (e l'aggiunta di mipmap raddoppierebbe tale quantità). In pratica, è raramente necessario fare riferimento a tutti i 1 GB in una singola operazione di rendering.

Alcuni sviluppatori di giochi modellano superfici di terreno di dimensioni pari a 128.000 di 128.000. Il modo in cui si ottiene questo per lavorare sulle GPU esistenti consiste nell'suddividere la superficie in riquadri sufficientemente piccoli per l'hardware da gestire. L'applicazione deve determinare quali riquadri potrebbero essere necessari e caricarli in una cache di trame nella GPU, ovvero un sistema di paging software. Uno svantaggio significativo di questo approccio deriva dall'hardware che non conosce nulla sul paging che sta succedendo: quando una parte di un'immagine deve essere visualizzata sullo schermo che si sposta tra i riquadri, l'hardware non sa come eseguire il filtro a funzione fissa (ovvero efficiente) tra i riquadri. Ciò significa che l'applicazione che gestisce il proprio tiling software deve ricorrere al filtro manuale delle trame nel codice shader (che diventa molto costoso se si desidera un filtro anisotropico di buona qualità) e/o sprecare la creazione di grondaie di memoria intorno ai riquadri che contengono dati dai riquadri adiacenti in modo che il filtro hardware a funzione fissa possa continuare a fornire assistenza.

Se una rappresentazione affiancata delle allocazioni di superficie potrebbe essere una funzionalità di prima classe nel sistema grafico, l'applicazione potrebbe indicare all'hardware quali riquadri rendere disponibili. In questo modo, meno memoria GPU viene sprecata archiviando aree di superfici a cui l'applicazione sa non sarà accessibile e l'hardware può comprendere come filtrare tra riquadri adiacenti, alleviare alcuni dei problemi riscontrati dagli sviluppatori che eseguono la suddivisione del software autonomamente.

Tuttavia, per fornire una soluzione completa, è necessario fare qualcosa per affrontare il fatto che, indipendentemente dal fatto che la tillatura all'interno di una superficie sia supportata, la dimensione massima della superficie è attualmente 16384 - nessuna parte vicino alla 128K+ che le applicazioni desiderano già. È sufficiente richiedere l'hardware per supportare dimensioni di trama maggiori è un approccio, tuttavia ci sono costi significativi e/o compromessi per questa route. Il percorso del filtro delle trame e il percorso di rendering di Direct3D 11 sono già saturi in termini di precisione nel supporto di trame da 16.000 con gli altri requisiti, ad esempio il supporto di extent del riquadro di visualizzazione che cadono dalla superficie durante il rendering o il supporto del wrapping della trama dal bordo della superficie durante il filtro. Una possibilità consiste nel definire un compromesso, ad esempio che le dimensioni della trama aumentano oltre 16.000, la funzionalità/precisione viene data in qualche modo. Anche con questa concessione, tuttavia, potrebbero essere necessari costi hardware aggiuntivi in termini di capacità di indirizzamento in tutto il sistema hardware per passare a dimensioni di trama maggiori.

Un problema che entra in gioco quando le trame diventano molto grandi è che le coordinate di trama a virgola mobile a precisione singola (e gli interpolatori associati per supportare la rasterizzazione) esauriscono la precisione per specificare le posizioni sulla superficie in modo accurato. L'applicazione di filtri delle trame in jittery si sarebbe ripresa. Un'opzione costosa consiste nel richiedere il supporto dell'interpolatore a precisione doppia, anche se questo potrebbe essere eccessivamente alternativo.

Un nome alternativo per le risorse affiancate è "trama sparse". "Sparse" indica sia la natura affiancata delle risorse che, forse, il motivo principale per collegarli , che non tutti devono essere mappati contemporaneamente. In realtà, un'applicazione potrebbe creare in modo intenzionale una risorsa affiancata in cui non vengono creati dati per tutte le aree e i mips della risorsa. Quindi, il contenuto stesso potrebbe essere di tipo sparse e il mapping del contenuto nella memoria GPU in un determinato momento sarebbe un subset di tale (ancora più sparse).

Un altro scenario che potrebbe essere gestito dalle risorse affiancate consente a più risorse di dimensioni/formati diversi di condividere la stessa memoria. In alcuni casi le applicazioni hanno set esclusivi di risorse che non vengono usate contemporaneamente o risorse create solo per un uso molto breve e quindi eliminate, seguite dalla creazione di altre risorse. Una forma di generalità che può includere "risorse affiancate" è che è possibile consentire all'utente di puntare più risorse diverse alla stessa memoria (sovrapposta). In altre parole, la creazione e la distruzione di "risorse" (che definiscono una dimensione/formato e così via) possono essere separati dalla gestione della memoria sottostante le risorse dal punto di vista dell'applicazione.

Risorse affiancate