Ah, finally got it working. The diagnosis was complicated by the fact that I thought GL wasn’t working, but in fact it was - it’s just the issue with the slightly faulty projection made it look like it wasn’t. The D3D9 problem was that I forgot I had to compensate for the fact that Ogre uses right-handed coordinates, instead of the left-handed ones used by D3D normally. Once I knew it was just D3D this didn’t take too long to work out!
I can now use reflection / refraction planes with arbitrary geometry, without artefacts and without having to resort to clipping techniques that are not supported on 100% of cards. Phew! Here’s a random shot of the updated render-to-texture demo; note that this is all fixed-function, no fancy shaders at all.