Demirug
2003-06-18, 10:14:28
Dem Test liegt ja eine Datei "PSShaders.txt" bei und ich gehe jetzt mal davon aus das die Shader welche dort enthalten sind auch benutzt werden.
;### Rxx_Mantissa
ps_2_0
def c0, 0.0f, 1.0f, %sf, 2.0f
mov r0, c0.y // mov r0, 1
mov r1, c0.z
add_pp r0, r0, r1 // + BIG NUMBER (but itself lower precision)
sub_pp r0, r0, r1 // - BIG NUMBER (but itself lower precision
mov_pp oC0, r0
;### Rxx_Exponent
ps_2_0
def c0, 1.0f, %sf, 16.0f, 0.125001f
mov r0, c0.y // mov r0, x
mul_pp r0, r0, r0 // mul r0, // r0 = x*x
rcp_pp r2, r0.x // mov r2, // r2 = 1/(x*x)
mul_pp r0, r0, r0 // mul r0, // r0 = x*x*x*x
mul_pp r0, r0, r2 // mul r0, r0, 1/(x*x)
mul_pp r0, r0, r2 // mul r0, r0, 1/(x*x)
mov_pp oC0, r0
;### ==========================================
;### Cxx_Mantissa
ps_2_0 // def c0, 0.0f, 1.0f, pp, pp+1
def c0, 0.0f, 1.0f, %sf, %sf
mov_pp r0, c0.w
mov_pp r1, c0.z
sub r0, r0, r1
mov oC0, r0
;### Cxx_Exponent
ps_2_0
def c0, 0.5f, %sf, %sf, 2.0f // 0.5f, x==y^^precision, Sqrt(x), 2.0f
mov_pp r0, c0.y // mov r0, x
mov_pp r1, c0.z // mov r1, Sqrt(x)
mul r0, r0, r1
mul r0, r0, r1
rcp r1, r0.x
min r0, r0, r1
mov oC0, r0 // if enought precision then == 1 else << 1
;### ==========================================
;### Txx_Mantissa
ps_2_0
dcl_pp t0.rg
mov r0.xy, t0
sub r0, r0.y, r0.x
mov oC0, r0
;### Txx_Exponent
ps_2_0
dcl_pp t0.rg
//def c0, 1.0f, 1.0f, 0.0f, 2.0f
mov r0.xy, t0
mul r1, r0.x, r0.y
mul r0, r1, r0.y
rcp r1, r0.x
min r0, r0, r1
//sub r0, c0.x, r1
mov oC0, r0
;### ==========================================
;### Rxx_Mantissa_BIG
ps_2_0
def c0, 0.0f, 1.0f, %sf, 2.0f
mov r0, c0.y // mov r0, 1
mov r1, c0.z // mov r1, 4096
//add_pp r0, r0, r1 // + BIG NUMBER (but itself lower precision)
//sub_pp r0, r0, r1 // - BIG NUMBER (but itself lower precision
add_pp r2, r0, r1 // + BIG NUMBER (but itself lower precision)
add_pp r3, r0, r1 // + BIG NUMBER (but itself lower precision)
add_pp r4, r0, r1 // + BIG NUMBER (but itself lower precision)
add_pp r5, r0, r1 // + BIG NUMBER (but itself lower precision)
sub_pp r2, r2, r1 // - BIG NUMBER (but itself lower precision
sub_pp r3, r3, r1 // - BIG NUMBER (but itself lower precision
sub_pp r4, r4, r1 // - BIG NUMBER (but itself lower precision
sub_pp r5, r5, r1 // - BIG NUMBER (but itself lower precision
add_pp r0, r2, r3
add_pp r1, r4, r5
add_pp r0, r0, r1
mov_pp oC0, r0
Es stellt sich mir aber nun die Frage wie das messe der Genauigkeit auf diese Art und weise funktionieren soll. Da bei jedem Shader Tempregister (r#) eine Rolle spielen kann die Genauigkeit bei den Texturkorrdinaten (t#) und Konstanten (c#) niemals höher als bei dem Temps sein. Mit fp16 wären die Temps ja aber sowieso zu ungenau würde da nicht mein zweites Problem ins Spiel kommen.
In der Spec steht ja noch diese nette Hintertür:
Implementations vary precision automatically based on precision of inputs to a given op for optimal performance.
Die Frage ist nun was ist die "precision of inputs" in diesem Zusammenhang? Die Genauigkeit des Registers aus dem der Wert geholt wird oder die Genauigkeit des Wertes welcher sich in dem Register befindet?
Zur Erklärung des unterschieds:
dcl_pp t0.rg (1)
mov r0.xy, t0 (2)
sub r0, r0.y, r0.x (3)
1. Mit dieser Zeile wird für t0 (Texturecoordinate) die reduzierte Genauigkeit erlaubt.
2. t0 (reduzierte genauigkeit) wird noch r0 koppiert (mov). in r0 (Tempregister soll fp24 sein) ist also nun ein Wert mit reduzierter Genauigkeit gespeichert.
3. gehen wir hier von dem Inhalt des r0 Register aus darf die Subtraktion (sub) mit reduzierter Genauigkeit durchgeführt werden gehen wir allerdings von dem Registertype aus muss sie mit normaler Genauigkeit durchgeführt werden. Abhängig von der Antwort auf diese Frage ergibt sich ob man nach dem durchführen der Operation in r0 ein Wert mit normaler oder reduzierter Genauigkeit findet.
Dieses Kettenspiel (wenn es erlaubt ist) könnte man dann sehr gut weiter spielen bis man am ende bei einem Shader landet der komplett nur mit reduzierter Genauigkeit arbeitet.
Noch zur Erklärung:
Ich hege keine Zweifel daran das nv bei den NV3X (x < 5) Chips unter DX die Tempregister in aller Regel nur mit reduzierter Genauigkeit laufen lässt. Bei den Konstanten dürfen sie das ja sowieso. Die Frage die ich mir nur Stelle ist in wie weit die Messmethode von digit-life als verlässlich anzusehen ist und ob dieses fp16 rechnen durch die Spec aufgrund der Hintertür nicht doch legal ist.
;### Rxx_Mantissa
ps_2_0
def c0, 0.0f, 1.0f, %sf, 2.0f
mov r0, c0.y // mov r0, 1
mov r1, c0.z
add_pp r0, r0, r1 // + BIG NUMBER (but itself lower precision)
sub_pp r0, r0, r1 // - BIG NUMBER (but itself lower precision
mov_pp oC0, r0
;### Rxx_Exponent
ps_2_0
def c0, 1.0f, %sf, 16.0f, 0.125001f
mov r0, c0.y // mov r0, x
mul_pp r0, r0, r0 // mul r0, // r0 = x*x
rcp_pp r2, r0.x // mov r2, // r2 = 1/(x*x)
mul_pp r0, r0, r0 // mul r0, // r0 = x*x*x*x
mul_pp r0, r0, r2 // mul r0, r0, 1/(x*x)
mul_pp r0, r0, r2 // mul r0, r0, 1/(x*x)
mov_pp oC0, r0
;### ==========================================
;### Cxx_Mantissa
ps_2_0 // def c0, 0.0f, 1.0f, pp, pp+1
def c0, 0.0f, 1.0f, %sf, %sf
mov_pp r0, c0.w
mov_pp r1, c0.z
sub r0, r0, r1
mov oC0, r0
;### Cxx_Exponent
ps_2_0
def c0, 0.5f, %sf, %sf, 2.0f // 0.5f, x==y^^precision, Sqrt(x), 2.0f
mov_pp r0, c0.y // mov r0, x
mov_pp r1, c0.z // mov r1, Sqrt(x)
mul r0, r0, r1
mul r0, r0, r1
rcp r1, r0.x
min r0, r0, r1
mov oC0, r0 // if enought precision then == 1 else << 1
;### ==========================================
;### Txx_Mantissa
ps_2_0
dcl_pp t0.rg
mov r0.xy, t0
sub r0, r0.y, r0.x
mov oC0, r0
;### Txx_Exponent
ps_2_0
dcl_pp t0.rg
//def c0, 1.0f, 1.0f, 0.0f, 2.0f
mov r0.xy, t0
mul r1, r0.x, r0.y
mul r0, r1, r0.y
rcp r1, r0.x
min r0, r0, r1
//sub r0, c0.x, r1
mov oC0, r0
;### ==========================================
;### Rxx_Mantissa_BIG
ps_2_0
def c0, 0.0f, 1.0f, %sf, 2.0f
mov r0, c0.y // mov r0, 1
mov r1, c0.z // mov r1, 4096
//add_pp r0, r0, r1 // + BIG NUMBER (but itself lower precision)
//sub_pp r0, r0, r1 // - BIG NUMBER (but itself lower precision
add_pp r2, r0, r1 // + BIG NUMBER (but itself lower precision)
add_pp r3, r0, r1 // + BIG NUMBER (but itself lower precision)
add_pp r4, r0, r1 // + BIG NUMBER (but itself lower precision)
add_pp r5, r0, r1 // + BIG NUMBER (but itself lower precision)
sub_pp r2, r2, r1 // - BIG NUMBER (but itself lower precision
sub_pp r3, r3, r1 // - BIG NUMBER (but itself lower precision
sub_pp r4, r4, r1 // - BIG NUMBER (but itself lower precision
sub_pp r5, r5, r1 // - BIG NUMBER (but itself lower precision
add_pp r0, r2, r3
add_pp r1, r4, r5
add_pp r0, r0, r1
mov_pp oC0, r0
Es stellt sich mir aber nun die Frage wie das messe der Genauigkeit auf diese Art und weise funktionieren soll. Da bei jedem Shader Tempregister (r#) eine Rolle spielen kann die Genauigkeit bei den Texturkorrdinaten (t#) und Konstanten (c#) niemals höher als bei dem Temps sein. Mit fp16 wären die Temps ja aber sowieso zu ungenau würde da nicht mein zweites Problem ins Spiel kommen.
In der Spec steht ja noch diese nette Hintertür:
Implementations vary precision automatically based on precision of inputs to a given op for optimal performance.
Die Frage ist nun was ist die "precision of inputs" in diesem Zusammenhang? Die Genauigkeit des Registers aus dem der Wert geholt wird oder die Genauigkeit des Wertes welcher sich in dem Register befindet?
Zur Erklärung des unterschieds:
dcl_pp t0.rg (1)
mov r0.xy, t0 (2)
sub r0, r0.y, r0.x (3)
1. Mit dieser Zeile wird für t0 (Texturecoordinate) die reduzierte Genauigkeit erlaubt.
2. t0 (reduzierte genauigkeit) wird noch r0 koppiert (mov). in r0 (Tempregister soll fp24 sein) ist also nun ein Wert mit reduzierter Genauigkeit gespeichert.
3. gehen wir hier von dem Inhalt des r0 Register aus darf die Subtraktion (sub) mit reduzierter Genauigkeit durchgeführt werden gehen wir allerdings von dem Registertype aus muss sie mit normaler Genauigkeit durchgeführt werden. Abhängig von der Antwort auf diese Frage ergibt sich ob man nach dem durchführen der Operation in r0 ein Wert mit normaler oder reduzierter Genauigkeit findet.
Dieses Kettenspiel (wenn es erlaubt ist) könnte man dann sehr gut weiter spielen bis man am ende bei einem Shader landet der komplett nur mit reduzierter Genauigkeit arbeitet.
Noch zur Erklärung:
Ich hege keine Zweifel daran das nv bei den NV3X (x < 5) Chips unter DX die Tempregister in aller Regel nur mit reduzierter Genauigkeit laufen lässt. Bei den Konstanten dürfen sie das ja sowieso. Die Frage die ich mir nur Stelle ist in wie weit die Messmethode von digit-life als verlässlich anzusehen ist und ob dieses fp16 rechnen durch die Spec aufgrund der Hintertür nicht doch legal ist.