HLSL fråga

Allting som har med programmering att göra.

HLSL fråga

Inläggav Hildenborg » 31 okt 2009, 21:56

Jag försöker bli klok på HLSL...
I en pixel shader, kan man läsa värdet från destination?
Eller måste man först rendera till texture, byta rendertarget, och sedan använda den texturen som input?
Känns väldigt omständigt och prestandaslösande...
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg

Re: HLSL fråga

Inläggav TheSpaceMan » 31 okt 2009, 22:52

Dvs, du menar om du kan läsa datan till den plats du ska skriva till?

isf ska du kunna genom rendertarget får tag på surface och använda den som en input.
Dock vet jag inte om den updateras i realtid så att säga eller först efter shadern är slut. Men om det som sagt är den "förra" datan så borde det gå.


Jag är ute och cyklar, från destinationen, dvs du vill ha färgvärdet på den pixel du ska rita just nu?
Det är väl det du får från Tex2D när du matar in uv coordinaterna?

Eller så menar du något helt annat totalt...
TheSpaceMan
 
Inlägg: 102
Blev medlem: 11 maj 2009, 23:31
Ort: Nottingham

Re: HLSL fråga

Inläggav sirGustav » 31 okt 2009, 23:31

Om jag inte helt har missuppfattat hur pipelinen fungerar, så går det inte, och imho är det en bra sak, parallel-processing med beroenden låter inte kul :)
sirGustav
 
Inlägg: 45
Blev medlem: 06 jun 2009, 14:46
Ort: Malmö

Re: HLSL fråga

Inläggav Hildenborg » 01 nov 2009, 11:59

Jag hade liksom bara fått för mig att man kunde t.ex. läsa in pixeldata från skärmen (den position man var på gång att skriva till), för att t.ex. göra egna blending funktioner etc.
Men tydligen så är detta något man inte kan göra... Utan att först rendera till en textur.
Lite dumt, jag hade en plan för en multipassrendering som inte är möjlig på det sätt jag tänkt mig...

Mjoho jaha... Får tänka om då.
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg

Re: HLSL fråga

Inläggav sirGustav » 01 nov 2009, 20:16

Du kan läsa den interpolerade färgen, textur koordinater och valfri texel från texturen, och på så sätt göra egna blending-funktioner, men det går inte att läsa tidigare skriva pixlar. Dock om man kan räkna ut hur grannen ser ut, alternativt approximera, så kan man använda det istället. Enklast att se shaders som enkelriktade/write-only strömmar :)
sirGustav
 
Inlägg: 45
Blev medlem: 06 jun 2009, 14:46
Ort: Malmö

Re: HLSL fråga

Inläggav Hildenborg » 01 nov 2009, 23:25

Jag har skrivit en shader som gör komplett frustum culling av boundboxes mot de sex frustum planen, samt går igenom en PVS lista för en hel scen. Men, efter det så har jag en texture (som jag läser ut till en array), där pixlarna är svarta eller vita beroende på om geometrin skall ritas eller ej.
Tanken jag hade, var att göra ett extra pass, där jag skapade en länkad lista av indexarna til pixlarna, så man sedan snabbt kunde rita ut geometrin. Men om jag skall göra det, så måste jag alltså skapa en till rendertarget, och i andra passet ta resultatet från det första passet som en intextur.
Jag får nog performance testa det hela, och se om det är vettigt att göra så, eller om C#'s array sort funktioner är snabbare...

Jag vet att jag använder shaders på ett sätt som det inte är tänkt, men det är iaf. snabbare än C#.
Lite häftigt är det dock... Jag gör nästan hela frustum cullingen av en Quake 3 bana med en HLSL shader :)
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg

Re: HLSL fråga

Inläggav VilleK » 02 nov 2009, 11:49

Ja det är häftigt att man verkar kunna lägga ut så mycket funktionalitet i shaders numera. Jag har inte hållit på med shaders sen första generationen och då gick det knappt att göra någonting alls pga av alla begränsningar i programstorlek och komplexitet samt många buggar. Så det är alltså snabbare att skicka all geometri till GPU:n och göra culling i shadern än att försöka göra culling i C#?

Måste du konvertera all indata till texturer eller kan man skicka in godtyckliga datastrukturer som t.ex. PVS informationen?
Användarvisningsbild
VilleK
 
Inlägg: 30
Blev medlem: 12 maj 2009, 09:26

Re: HLSL fråga

Inläggav Hildenborg » 02 nov 2009, 20:53

I XNA, så kompilerar man C# till en bytecode, som sedan JIT kompileras när programmet körs igång. Vilket gör att man aldrig får upp C++ hastighet på det hela.
När man ritar ut en Quake 3 bana, så går man först igenom en PVS (potentially visible set), och sedan så kollar man om boundboxen för geometridelarna finns inom frustumet.
Ett PVS är i Quake 3's fall en 2d array med bools, där en dimension är de olika områden på kartan man kan befinna sig på (man finner ett sådant ställe genom att söka sig genom ett bsp träd). Den andra dimensionen är de olika geometriska objekten som finns på kartan.
Jag har förenklat förklaringen lite, det finns en del mer att ta hänsyn till...
I Quake 3 fallet, så har man sparat minne genom att spara PVS'en som bitar, så man måste göra lite boleanska operationer och shifts för att gå igenom PVS'en.
Att testa all geometri mot PVS'en samt att testa boundboxes mot de sex frustum planen, kommer att kräva rätt mycket från CPU'n när koden är JIT kompilerad...

Så, vad jag gjort, är att skapa en textur med floats, där övre halvan av texturen är min värdet på boundboxes, och nedre halvan är max. Sen har jag en annan textur där jag har hela PVS arrayen. Och så ritar jag en quad som kör igenom hela alltet och levererar ut en ny textur där pixlarna är satta beroende på om deras motsvarande geometri behöver ritas eller ej. Och då det görs med 48 parallella shaders, så går det väldigt fort.
Dessutom så är CPU'n ledig att användas under tiden. Så, när jag sedan slår igång split screen, så kan jag låta två trådar arbeta samtidigt på en kärna, där ena tråden kör utritning, och den andra state sorterar datat som kommer ut. På så sätt kommer jag förhoppningsvis att maximera användandet av GPU/CPU.

Eftersom XNA snor en av de tre kärnorna åt sig själv på XBox 360, så innebär detta att jag har en kärna kvar till fysik, vilket i min enkla spelide' borde räcka.

Jag måste dock erkänna, att den mesta hastigheten jag optimerat fram hittills, har jag fått utav att state sortera utritningen, så jag ändrar state i hårdvaran så lite som möjligt.
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg

Re: HLSL fråga

Inläggav VilleK » 02 nov 2009, 21:49

Aha, smart! Så shader-cullningen sker som ett pass innan utritningen där resultatet är en textur som anger ifall geometrin ska ritas eller ej. Därefter skickar du via C# ut den synliga geometrin.

Hur valde du just 48? Är det så många rendertargets som Xbox GPU:n klarar av att hantera parallellt? Eller är det 48 shaders som gör varsin slice på en och samma rendertarget?

Sen tänkte jag på texturen med PVS-information. Prestandan på shader-cullningen borde vara beroende av hur cache-vänlig texturen är. Om originaldata är 1 bit kan du då behålla det i texturen för att göra minnesåtgången mindre? Och "aktuell position" dimensionen av texturen borde vara Y-axeln eftersom den då jobbar mot samma X-rad som ligger sekventiellt i minnet och därmed mer cache-vänligt.
Användarvisningsbild
VilleK
 
Inlägg: 30
Blev medlem: 12 maj 2009, 09:26

Re: HLSL fråga

Inläggav Hildenborg » 02 nov 2009, 22:41

VilleK skrev:Hur valde du just 48? Är det så många rendertargets som Xbox GPU:n klarar av att hantera parallellt? Eller är det 48 shaders som gör varsin slice på en och samma rendertarget?

Det är XBox GPU'n som har 48 shaders. Nuförtiden har grafikkorten många fler...
Varje shader arbetar parallellt, på så vis att dom hanterar varsin pixel som skall ritas ut.

VilleK skrev:Sen tänkte jag på texturen med PVS-information. Prestandan på shader-cullningen borde vara beroende av hur cache-vänlig texturen är. Om originaldata är 1 bit kan du då behålla det i texturen för att göra minnesåtgången mindre? Och "aktuell position" dimensionen av texturen borde vara Y-axeln eftersom den då jobbar mot samma X-rad som ligger sekventiellt i minnet och därmed mer cache-vänligt.

Den värstingbanan som jag har valt som stresstest, innehåller såpass mycket information i sin PVS, att jag inte kan lagra den annat än som bitpackad data.
Och då shaders inte kan bittesta, så blir det ju lite problematiskt... Men jag löste det så här:
  1.  
  2.         float byte= tex2D(visimapSampler, tc).a;
  3.         for(float v=0.5f;v>mask && v>0.00390625;v*=0.5f)
  4.         {
  5.             if(byte>=v)
  6.             {
  7.                 byte-=v;
  8.             }
  9.         }
  10.         if(byte>=v) {color=float4(1.0f,1.0f,1.0f,1.0f);}
  11.  

Där variabeln "mask" är biten jag vill testa om den är satt i "byte". Jag har då preparerat "mask" så att den är 256/(1<<bit).
Tanken är helt enkelt att loopa, och för varje steg kolla om den nuvarande översta biten är satt, i så fall subtrahera den från masken. Och så gör man tills dess att man antingen kommit ned till sista biten, eller till den man vill testa. Om kvarvarande masken är lika med eller större än bitvärdet man testar emot, så är biten satt.
Jag kunde inte komma på något snabbare sätt att bittesta när man arbetar med hårdvara som är optimerad för float...
Tips emottages gärna :)
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg


Återgå till Programmering

Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 0 gäster

cron