Impostare una trama in un pixel shader e renderlo il bersaglio del rendering?
-
06-07-2019 - |
Domanda
Mi chiedevo, se renderizzo una scena usando uno shader a cui passo una trama che è anche il bersaglio del rendering per quella scena, causerebbe comportamenti indesiderati?
Quindi sostanzialmente:
texture t;
shader->SetTexture("texture",t);
device->SetRenderTarget( 0, t->surface );
shader->Begin("effect")
// do some more shader stuff
device->EndScene();
che cosa causerà esattamente?
Se non deseleziono la destinazione di rendering prima del rendering, la trama funzionerà comunque lo stesso? Suppongo solo che le modifiche finali non vengano scritte nella trama fino a quando non viene chiamato device- > End?
Soluzione
Presumo tu stia parlando di DirectX9. La documentazione non dice nulla su questo caso specifico, ma posso dirti quanto segue:
Suppongo solo che le modifiche finali non vengano scritte nella trama finché non viene chiamato device- > End
Questo è un presupposto sbagliato. Pensaci, stai supponendo che tutti i pixel di tutti i triangoli che disegni verranno memorizzati 'da qualche parte' e tutti i tuoi recuperi di trama eseguiti senza che i pixel vengano riscritti sulla destinazione di rendering. Ciò richiede una quantità arbitraria di memoria e pertanto non è possibile.
In pratica:
- l'hardware di solito elabora i triangoli come vengono, molti contemporaneamente
- aggiorna il frame buffer (che nel tuo caso è il supporto della memoria di trama) quando vuole, supponendo che non ci possano essere condizioni di gara
Quindi, supponendo che DX9 non si lamenta (provalo se vuoi davvero sapere, non faccio più DX9), sarà non definito.
Detto questo, DirectX10 è più esplicito al riguardo ( fonte ):
Se attualmente sono presenti anche risorse secondarie rilegato per leggere o scrivere (forse in un'altra parte della pipeline), quei punti vincenti verranno annullati per impedire la stessa risorsa secondaria essere letto e scritto contemporaneamente in un'unica operazione di rendering.
Quindi, in DirectX10, l'impostazione della trama verrà rimossa dall'API.
Altri suggerimenti
Anche se non posso sottolineare i dettagli, sono abbastanza sicuro che si tratti di un comportamento indefinito. Il metodo utilizzato da una scheda grafica per ombreggiare i frammenti può variare (fare quantità diverse alla volta, ecc.), Ma in ogni caso pratico, fa più di un frammento alla volta. Questo significa che dovrai leggere e scrivere nelle stesse posizioni, causando condizioni di gara. Non credo sia raccomandato.
Il runtime di debug ti impedirà di fare questo e fornirà un avviso. Il runtime di rilascio "potrebbe" (ma probabilmente non funzionerà).
Il problema deriva dal fatto che c'è un ritardo tra il caricamento del pixel da una trama e il suo utilizzo. Questo problema viene risolto caricando un blocco di texel in una cache. Le scritture sono memorizzate e scritte direttamente nella memoria. Quindi probabilmente ti ritroverai con un problema che potrebbe leggere un texel che potrebbe essere già stato aggiornato ma la cache non sarà aggiornata. Se stai leggendo SOLO il testo che ti viene scritto, "puoi" funzionano ma realisticamente tali dettagli di implementazione sono lasciati agli IHV. Non hanno l'obbligo di consentire che ciò funzioni.
Come detto da altri ... è un comportamento molto indefinito.