The Direct3D11 hlsl pixel shaders were ported from the OpenGL2 glsl fragment shaders.
In the documentation for OpenGL glsl, the W component of gl_FragCoord is specified as being 1/w. However in Direct3D11 hlsl, the W component of SV_POSITION is just w - hence why fog appeared to not work.
The solution to this is simple - when calculating depth, multiply by w instead of dividing by w.