[HLSL Assembly] Compiler genereert zinloze instructie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Code moet efficiënter draaien. Dat altijd. En in het maken van dat soort efficiënte code is een compiler in de meeste gevallen rdelijk goed (herleiden doet 'ie best wel erg goed zelfs).

Maar er zijn ook gevalletjes waarvan je denkt: waarom dit nou weer? Daar hoort deze bij:

GAS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ps_3_0                  // compileprofiel
def c0, -0.5, 0, 0, 0   // de te gebruiken constantes
dcl_texcoord v0.xyz     // normal in view space (TEXCOORD0)
dcl_texcoord1 v1.xy     // diepte in screen space, zw (TEXCOORD1)
dcl_texcoord2 v2.xy     // texturecoordinaat (TEXCOORD2)
dcl_2d s0               // diffusetex sampler
texld r0, v2, s0        // sample de texture gebonden aan s0 op coordinaat v2, sla kleur op in r0
add r0, r0.w, c0.x      // aangezien we alleen r0.w nodig hebben, tel bij r0.w -0.5 op en sla weer op in r0
texkill r0              // en skip de texture als dus de alpha minder dan 0.5 is.
dp3 r0.x, v0, v0        // doe een dot product tussen normal en normal? wut? dit levert toch altijd 1 op...
rsq r0.x, r0.x          // neem de inverse wortel, dit levert de lengte van de vector op. En omdat we willen vermenigvuldigen tot [0,1] , nemen we inverse
mul oC0.xyz, r0.x, v0   // en vermenigvuldig met 1/lengte zodat vector -> [0,1]. zet neer in RT0.xyz
rcp r0.x, v1.y          // neem de omgekeerde diepte.w
mul oC0.w, r0.x, v1.x   // en vermenigvulding diepte.z daarmee (zoals hoort bij Projectie),  zet neer in RT0.w


Ik heb maal alvast de comments erbijgezet, maar wat ik dus doe is diepte (in A) en de genormaliseerde normaal (in RGB) van de pixel opslaan in een speciale Deferred Renderer-achtige buffer voor SSAO.

Dit is een nogal veelvoorkomende actie, dus wilde ik de assembly wel eens zien of er wat te verbeteren viel. Allemaal best helder, behalve regel 10 (regel 10 t/m 12 zijn de uitwerking van normalize() in HLSL).

Maar wat is daar ooit het nut van die dp3? Dat dotproduct levert toch altijd 1 (cos-1(1) = 0 graden verschil) op. Waarom kan die niet gewoon 1 laden in c0.y ofzo?

Laten we toch even aannemen dat r0.x netjes 1 wordt. Dan zal die door rsq veranderen in (wonderbaarlijk) 1: 1/wrtl(1) is natuurlijk ook gewoon 1. Dan de normaal zelf met 1 vermenigvuldigen heeft geen comments nodig.

Dit gaat gewoon nergens over, maar toch krijgt de DX9-compiler het voor mekaar om deze (lijkt me) shite in code te proppen.

Helaas zijn er bar weinig boekjes of tutorials die over assembly van HLSL gaan, wat best wel jammer is. :'(

Maar goed, weet iemand waar dit door komt?

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

dp3 = x * x + y * y + z * z
aka len_squared, nodig voor de nromalize

-niks-


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
'k Moet nooit zo laat nog een topic moeten openen over iets dat ik dus na lang aanstaren niet kon vatten.

Het staat dus gewoon op MSDN. :/

En jeps, je berekent netjes de lengte van dit ding op de pythagorasmanier. Daarom moet 'ie met zichzelf vermenigvuldigen. Ook best logisch. Hij moet alleen nog wrtl(resultaat) doen. Dat gebeurt dus hierna. En omdat er niks als div bestaat doet 'ie 1/x. En vermenigvuldigen maar. Tada, unit vector.

Wat een GoT-spam dit. 8)7