One thing that I noticed using the Intel tool was that different shaders seemed to be used for the runway drawcalls to other drawcalls. That offered the possibility that if I could detect the use of that shader then I could alter the DepthStencil state in the DX10 wrapper.
Examining the shader directory under AppData\local the vast majority of shaders that FSX uses seem to be variants of general.fx presumably compiled with different options. The Intel GPA tool shows the shader assembly which isnt a lot of help. However setting it to display HLSL appears to show the binary code and so I was able to determine that the compiled PS shader for the runway draw call starts 0x4458424364DE0428. A lot of grepping located this in general10.fx_0xa40000000201827_0x0f
So what I did was build a wrapper D3D10Device object and use the Microsoft detours library to intercept the call. I had problems (probably something I was doing wrong with detours) calling the real DX10 create and so ended up calling the DX 10.1 create instead. The D3D10Device1 inherits from the D3D10Device so I guess thats ok.
In the wrapper I first created a DepthStencil which didn’t write to the Z Buffer. Then with a bit of playing around I was able to check when a Pixel Shaders was created if the code matched the string above and if so store a reference to it. Finally whenever SetShader was called I checking it against the stored reference and if I got a match inserted my DepthStencil.
So using this technique I was successfully able to fix the flashing runways.
However I have no guarantee that
- It will be stable
- It won’t mess up some other part of scenery drawing. i.e if the shader is used elsewhere
The next problem to look at is the runway markings. Notice how in DX10 how the yellow line goes over the white but the edge of the white goes over the yellow! Same problem different shader.
Here is the draw and again we have no depth stencil – so the edge of the white gets depth.
That was in general10.fx_0xa40000000221a21_0x0f
So that was fixable too.