SPIRV-VM
SPIRV-VM copied to clipboard
SPIRV-VM does not follow SPIRV standarts and result is wrong
maybe im wrong, but
https://www.khronos.org/registry/spir-v/specs/unified1/GLSL.std.450.html
Pow Result is x raised to the y power; xy. The resulting value is undefined if x < 0. Result is undefined if x = 0 and y ≤ 0.
FClamp Result is min(max(x, minVal), maxVal). The resulting value is undefined if minVal > maxVal. The semantics used by min() and max() are those of FMin and FMax.
SmoothStep The resulting value is undefined if edge0 ≥ edge1.
And others where the result should be inf or nan in SPIRV-VM its not.
Also dFd https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/dFdx.xhtml
Expressions that imply higher order derivatives such as dFdx(dFdx(n)) have undefined results, as do mixed-order derivatives such as dFdx(dFdy(n)). It is assumed that the expression p is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.
and dFd in the SPIRV-VM just does not work the same as on GPU (SPIRV-VM result incorrect): shader code for test:
void mainImage( out vec4 Oc, in vec2 I )
{
if(mod(I.x+I.y,5.)<2.5){
vec4 tO = vec4(mod(I.x,2.),mod(I.y,2.),0.,0.);
if(length(tO)==0.||int(I.x+I.y)==int(iResolution.x/2.)){Oc=vec4(1.);return;}
vec4 a = dFdx(tO)*(mod(I.x,2.)>1.?-1.:1.);
vec4 b = dFdy(tO)*(mod(I.y,2.)>1.?-1.:1.);
if(length(abs(a)+abs(b))==0.||isnan((dot(a,b)))||isinf((dot(a,b)))||int(I.x+I.y-50.)==int(iResolution.x/2.)){Oc=vec4(1.,0.,1.,1.);return;}
a+=tO;
b+=tO;
vec4 diag = a+b-tO;
float t = 0.;
if(t<1.){
if(mod(I.x,2.)<1.) tO=b;
} else if (t >2.&&t<3.) {
if(mod(I.y,2.)<1.) tO=a;
} else if (t >4.&&t<5.) {
if(float(mod(I.y,2.)<1.)+float(mod(I.x,2.)<1.)==1. ) tO=diag;
}
Oc=tO;
Oc.a=1.;
}
else Oc=vec4(I/iResolution.xy,0.,1.);
}
Correct/expected result (screenshot from Vulkan application, but it same in Browser in OpenGL mode):
Result from SPIRV-VM:
My guess: That a return value is undefined, does not mean, that it is INF or NAN. To use some 'c' jargon slightly out of context 'it could even contain nasal demons', which means: The implementation may return whatever it wants even in inconsistent ways.
That a return value is undefined, does not mean, that it is INF or NAN.
on the GPU GLSL is NAN or INF and many people include me expect NAN or INF in many cases as a result
without NAN and INF any my own shader that longer than 100 lines of code will just work completely wrong
this fact makes it impossible to use SPIRV-VM to actually "debug" anything because behavior of emulation completely different to real GPU shaders result
I have tested the shader code with my interpreter SPVM,seems like there is still a bit different with expected result