   GPU Noise Generation, Different Results in MDX and XNA
  I've spent far too many hours trying to figure out what is going on with my noise generation code... and I've given up.Using a single octave of noise I get the same results in both MDX and XNA, pictured below:However, as soon as I add multiple octaves of noise to the XNA version I get this horrible fracture pattern (highlighted in first pic and normal map included to show it more clearly), along with lots of horizontal banding in the generated noise.However, in MDX I get something like this (pictured is 10 octaves):The shader I'm using is someone else's, but all the variables I'm passing in have the exact same values in both versions, the perm texture is exactly the same in both version (I saved the MDX version and have been loading it up in the XNA version to make sure), A8R8G8B8 in MDX and SurfaceFormat.Color in XNA. Outputing to an R32F texture and SurfaceFormat.Single respectively.The shader is identical in both versions... I'm just at a total loss as to what is going on. The only thing I can think of is that it's a compiler problem (I heard XNA doesn't use the latest version of fxc), but it can't imagine that causing this... would it?I've tried using PIX, but it's been less than helpful, especially as I can't seem to get the same depth of information from my XNA version as I can from the MDX version, although that's probably due to my ignorance in using PIX.Edit: Realised I left out the source for the shader... duh.float fF2 = 0.366025403784f;float fG2 = 0.211324865405f;float fONE= 0.00390625f;float fONEHALF = 0.001953125f;float2 v2LacunarityGain = { 2.0, 0.5 };float4 TexScale;float2 CoarserTexOffset;float  ZScaleMax;float  OneOverTextureSize;float  OneOverHalfTexSize;texture tCoarserElevation;texture tpermTexture;sampler CoarserElevation = sampler_state {    texture = <tCoarserElevation>;    MipFilter = NONE;    MinFilter = POINT;    MagFilter = POINT;    AddressU = WRAP;    AddressV = WRAP; };sampler permTexture = sampler_state {    texture = <tpermTexture>;    MipFilter = NONE;    MinFilter = POINT;    MagFilter = POINT;    AddressU = WRAP;    AddressV = WRAP;};float Simplex2D(float2 P){  float s = (P.x + P.y) * fF2;  float2 Pi = floor(P + s);  float t = (Pi.x + Pi.y) * fG2;  float2 P0 = Pi - t;  Pi = Pi * fONE + fONEHALF;  float2 Pf0 = P - P0;  float2 o1;  o1.x = step(Pf0.y, Pf0.x);  o1.y = 1.0f - o1.x; // Noise contribution from simplex origin  float2 grad0 = tex2D(permTexture, Pi).gb * 4.0f - 1.0f;  float t0 = 0.5 - dot(Pf0, Pf0);  float n0 = step(0.0f, t0) * t0 * t0 * t0 * t0 * dot(grad0, Pf0);  // Noise contribution from middle corner  float2 Pf1 = Pf0 - o1 + fG2;  float2 grad1 = tex2D(permTexture, Pi + o1*fONE).gb * 4.0 - 1.0;  float t1 = 0.5 - dot(Pf1, Pf1);  float n1 = step(0.0f, t1) * t1 * t1 * t1 * t1 * dot(grad1, Pf1);    // Noise contribution from last corner  float2 Pf2 = Pf0 - (1.0f - 2.0f * fG2);  float2 grad2 = tex2D(permTexture, Pi + float2(fONE, fONE)).gb * 4.0 - 1.0;  float t2 = 0.5 - dot(Pf2, Pf2);  float n2 = step(0.0f, t2) * t2 * t2 * t2 * t2 * dot(grad2, Pf2);    // Sum up and scale the result to cover the range [-1,1]  return 70.0 * (n0 + n1 + n2);}float ridge(float h, const float m_Offset){h = m_Offset - abs(h);return h * h;}float getRidgeMF( float2 P ){float4 m_FreqAmp = float4( 1.0, 0.5, 0.0, 1.0);float2 m_prevN = float2( 1.0, 0.0 );    int m_Octaves = 10;for(int i = 0; i < m_Octaves; i++){m_prevN.y = ridge(Simplex2D( P * m_FreqAmp.xx ), m_FreqAmp.w);m_FreqAmp.z += m_prevN.y * m_FreqAmp.y * m_prevN.x;m_prevN.x = m_prevN.y;m_FreqAmp.xy *= v2LacunarityGain.xy;}return m_FreqAmp.z;}// Vertex Shaderstruct VS_INPUT{    float2 Pos  : POSITION;    float2 Tex1 : TEXCOORD0;};struct VS_OUTPUT{  float4 Pos    : POSITION;  float2 Tex1   : TEXCOORD0;};VS_OUTPUT Projection(VS_INPUT In){    VS_OUTPUT o; o.Pos  = float4( float2(In.Pos.x, -In.Pos.y) * OneOverHalfTexSize + float2(-1, 1), 0, 1);  o.Tex1 = In.Tex1.xy;    return o;}float4 Update(float2 p_uv : TEXCOORD0) : COLOR{  float2 Tg_uv = p_uv.xy * TexScale.xy + TexScale.zw;  float zf = floor( saturate( getRidgeMF( Tg_uv * 1.0/32768.0 ) ) * ZScaleMax );  p_uv = floor( p_uv.xy + 0.5 );  float2 p_uv_div2 = p_uv / 2;  float4 uvc = floor(float4( (p_uv_div2 + float2(0.5 , 0) ),(p_uv_div2 + float2(0 , 0.5) ))) * OneOverTextureSize + CoarserTexOffset.xyxy;  float zc0 = floor( tex2D(CoarserElevation, float4(uvc.xy,0,1)).r );  float zc1 = floor( tex2D(CoarserElevation, float4(uvc.zw,0,1)).r );    float zf_zd = zf + saturate( ((zc0 + zc1) / 2 - zf + 4096) / 8192 );    return float4(zf_zd, 0, 0, 0);} technique UpdatePhase {  pass p0  { ZEnable = false;ZWriteEnable = false;AlphaBlendEnable = false;CullMode = none;FVF = XYZ | TEX1;VertexShader = compile vs_1_1 Projection();    PixelShader = compile ps_3_0 Update();  }}
  You can't use a vs_1_1 vertex shader with a ps_3_0 pixel shader, you have to use vs_3_0.  Nvidia drivers used to actually let you get away with this, but I know ATI driver always did nasty things.  Either way the debug runtimes will yell at you for doing it. [smile]   ;  Would that actually result in the above though... I mean, it seems pretty extreme considering the noise generation is in the pixel shader. I'm also inclined to think this isn't the problem either, since it works with 1 octave of noise.I'll switch it up when I get home and see what happens.Note that all of the above screenshots are taken on a PC with an nVidia graphics card. I'm not had a chance to throw it on the ATI rig for testing yet... since well, I want it working first.   ;  Based on what MJP said, it sounds like it's very plausibly a result of the different compilers. MDX uses the shader compiler from April 2006, and XNA uses the shader compiler from October 2006. Needless to say, they're not really giving you the latest and greatest in shader features. If you're in the mood to do yet another port, you could see what happens with SlimDX, which will use a current compiler.   ;Quote:Original post by PromitBased on what MJP said, it sounds like it's very plausibly a result of the different compilers. MDX uses the shader compiler from April 2006, and XNA uses the shader compiler from October 2006.Based on this though, surely XNA should give the same results as the previously released compiler (which it does... for 1 octave of noise)? XNA is where the problem lies, not in the MDX version.As an aside based on this though, is there a way to make XNA use the latest compiler?   ;  The only technique I know of was that one guy wrote an XNA Content Pipeline plugin that would compile the shaders using SlimDX and then load the binary blobs into XNA at runtime. I don't know if that's available online -- googling isn't helping much at the moment.   ;  Google eventually came up with this, I'll try it later when I can.I'm still not convinced it is the compiler... but if it is, I guess I'll have egg on my face.   ;Quote:Original post by adt7Based on this though, surely XNA should give the same results as the previously released compiler (which it does... for 1 octave of noise)? XNA is where the problem lies, not in the MDX version.Well it's not really a compiler issue...according to the spec that DX drivers are supposed to follow it is illegal to combine an ps_3_0 shader with anything other than a vs_3_0 shader.  This means the driver might be okay with it if you break the rules, or it might do all sorts of weird things (like what you're seeing).  I think the fact that it worked with the old version of the compiler and doesn't with the newer one is just a quirk of the driver, and nothing more.   ;  Switching to vs3_0... no joy.Using the debug runtimes... no output.However, using PIX it seems the MDX version compiles out into a shader and a preshader, whereas the XNA version omits the preshader.Also, the "def c11" lines differ between the shaders, sadly I know basically nothing about shaders in asm.MDX shader://// Generated by Microsoft (R) D3DX9 Shader Compiler 9.12.589.0000//// Parameters:////   float fG2;////// Registers:////   Name    Reg   Size//   ------------ ----- ----//   fG2c0  1////// Default values:////   fG2//c0   = { 0.211325, 0, 0, 0 };//    preshader    add r1.w, c0.x, c0.x    neg r0.w, r1.w    add c9.x, r0.w, (1)// approximately 3 instructions used//// Generated by Microsoft (R) D3DX9 Shader Compiler 9.12.589.0000//// Parameters:////   sampler2D CoarserElevation;//   float2 CoarserTexOffset;//   float OneOverTextureSize;//   float4 TexScale;//   float ZScaleMax;//   float fF2;//   float fG2;//   float fONE;//   float fONEHALF;//   sampler2D permTexture;//   float2 v2LacunarityGain;////// Registers:////   NameReg   Size//   ------------------ ----- ----//   fF2 c0  1//   fG2 c1  1//   fONEc2  1//   fONEHALF c3  1//   v2LacunarityGain   c4  1//   TexScale c5  1//   CoarserTexOffset   c6  1//   ZScaleMaxc7  1//   OneOverTextureSize c8  1//   CoarserElevation   s0  1//   permTexture   s1  1////// Default values:////   fF2//c0   = { 0.366025, 0, 0, 0 };////   fG2//c1   = { 0.211325, 0, 0, 0 };////   fONE//c2   = { 0.00390625, 0, 0, 0 };////   fONEHALF//c3   = { 0.00195313, 0, 0, 0 };////   v2LacunarityGain//c4   = { 2, 0.5, 0, 0 };////   TexScale//c5   = { 0, 0, 0, 0 };////   CoarserTexOffset//c6   = { 0, 0, 0, 0 };////   ZScaleMax//c7   = { 0, 0, 0, 0 };////   OneOverTextureSize//c8   = { 0, 0, 0, 0 };//    ps_3_0    def c10, 3.05175781e-005, 0, 1, 0.5    def c11, -0, 1, 4, -1    def c12, 70, 0.5, -0, 4096    def c13, 0.000122070313, 0, 0, 0    defi i0, 10, 0, 0, 0    dcl_texcoord v0.xy  // p_uv<0,1>    dcl_2d s0    dcl_2d s1#line 158 "C:\Users\Alex\Desktop\GPUgc1.1-Sharp\WindowsApplication1\bin\x86\Debug\Update.fx"    mad r0.xy, v0, c5, c5.zwzw  // Tg_uv<0,1>    mul r6.xy, r0, c10.x  // getRidgeMF::P<0,1>    mov r0.x, c10.z  // getRidgeMF::m_FreqAmp<0>    mov r0.y, c10.w  // getRidgeMF::m_FreqAmp<1>    mov r0.z, c11.x  // getRidgeMF::m_FreqAmp<2>    mov r0.w, c10.z  // getRidgeMF::m_prevN<0>    rep i0#line 126 mul r1.xy, r6, r0.x  // Simplex2D::P<0,1>#line 58 add r1.w, r1.y, r1.x mad r1.xy, r1.w, c0.x, r1 frc r2.xy, r1 add r1.xy, r1, -r2  // Simplex2D::Pi<0,1> add r1.w, r1.y, r1.x mad r2.xy, r1.w, -c1.x, r1  // Simplex2D::P0<0,1>#line 64 mad r4.xy, r6, r0.x, -r2  // Simplex2D::Pf0<0,1> mov r1.w, c2.x  // ::fONE<0> mad r5.xy, r1, r1.w, c3.x  // Simplex2D::Pi<0,1>#line 82 add r3.xy, r4, -c9.x  // Simplex2D::Pf2<0,1> add r1.xy, r5, c2.x texld r1, r1, s1 mad r1.xy, r1.yzzw, c11.z, c11.w  // Simplex2D::grad2<0,1>#line 67 add r1.w, -r4.y, r4.x#line 85 dp2add r2.w, r1, r3, c11.x#line 67 cmp r2.x, r1.w, c11.y, c11.x  // Simplex2D::o1<0>#line 71 texld r1, r5, s1 mad r1.xy, r1.yzzw, c11.z, c11.w  // Simplex2D::grad0<0,1>#line 77 add r2.yz, -r2.x, c10.z#line 73 dp2add r3.w, r1, r4, c11.x#line 77 mad r1.xy, r2.xzzw, c2.x, r5 texld r1, r1, s1 add r2.xy, r4, -r2 add r2.xy, r2, c1.x  // Simplex2D::Pf1<0,1> dp2add r1.w, r2, -r2, c10.w  // Simplex2D::t1<0> mad r1.xy, r1.yzzw, c11.z, c11.w  // Simplex2D::grad1<0,1> mul r1.z, r1.w, r1.w dp2add r1.x, r1, r2, c11.x mul r1.y, r1.z, r1.z cmp r1.z, r1.w, c11.y, c11.x#line 72 dp2add r1.w, r4, -r4, c10.w  // Simplex2D::t0<0>#line 79 mul r1.y, r1.y, r1.z#line 73 mul r1.z, r1.w, r1.w#line 79 mul r1.x, r1.x, r1.y  // Simplex2D::n1<0>#line 73 mul r1.y, r1.z, r1.z cmp r1.z, r1.w, c11.y, c11.x#line 84 dp2add r1.w, r3, -r3, c10.w  // Simplex2D::t2<0>#line 73 mul r1.z, r1.y, r1.z#line 85 mul r1.y, r1.w, r1.w mul r1.y, r1.y, r1.y cmp r1.w, r1.w, c11.y, c11.x#line 88 mad r1.z, r1.z, r3.w, r1.x#line 85 mul r1.w, r1.y, r1.w#line 88 mad r1.w, r1.w, r2.w, r1.z mul r1.w, r1.w, c12.x  // ::Simplex2D<0>#line 113 add r1.w, -r1_abs.w, c10.z  // ridge::h<0> mul r1.w, r1.w, r1.w  // ::ridge<0>#line 127 mul r1.z, r0.y, r1.w mad r0.z, r1.z, r0.w, r0.z  // getRidgeMF::m_FreqAmp<2> mul r0.xy, r0, c4  // getRidgeMF::m_FreqAmp<0,1> mov r0.w, r1.w  // getRidgeMF::m_prevN<0>    endrep    mov_sat r2.w, r0.z#line 161    add r0.yz, v0.xyxw, c10.w    frc r1.yz, r0    add r2.yz, r0, -r1  // p_uv<1,0>    mul r0.yz, r2, c10.w  // p_uv_div2<1,0>#line 165    mad r0.xw, r2.zyzy, c10.w, c10.w    frc r1, r0    mad r0, r2.zyzy, c12.y, c12.yzzy#line 159    mul r2.w, r2.w, c7.x#line 165    add r0, -r1, r0#line 159    frc r2.z, r2.w#line 165    mov r1.w, c8.x  // ::OneOverTextureSize<0>    mad r0, r0, r1.w, c6.xyxy  // uvc<0,1,2,3>    texld r1, r0, s0    texld r0, r0.zwzw, s0    frc r0.z, r1.x    frc r0.w, r0.x    add r0.z, r1.x, -r0.z  // zc0<0>    add r0.y, r0.x, -r0.w  // zc1<0>#line 159    add r0.w, r2.w, -r2.z  // zf<0>#line 170    add r0.z, r0.z, r0.y    mad r0.z, r0.z, c10.w, -r0.w    add r0.z, r0.z, c12.w    mul_sat r0.z, r0.z, c13.x    add oC0.x, r0.w, r0.z  // ::GPUgcUpdate<0>    mov oC0.yzw, c11.x  // ::GPUgcUpdate<1,2,3>// approximately 95 instruction slots used (5 texture, 90 arithmetic)XNA shader://// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000//// Parameters:////   sampler2D CoarserElevation;//   float2 CoarserTexOffset;//   float OneOverTextureSize;//   float4 TexScale;//   float ZScaleMax;//   float fF2;//   float fG2;//   float fONE;//   float fONEHALF;//   sampler2D permTexture;//   float2 v2LacunarityGain;////// Registers:////   NameReg   Size//   ------------------ ----- ----//   fF2 c0  1//   fG2 c1  1//   fONEc2  1//   fONEHALF c3  1//   v2LacunarityGain   c4  1//   TexScale c5  1//   CoarserTexOffset   c6  1//   ZScaleMaxc7  1//   OneOverTextureSize c8  1//   CoarserElevation   s0  1//   permTexture   s1  1////// Default values:////   fF2//c0   = { 0.366025, 0, 0, 0 };////   fG2//c1   = { 0.211325, 0, 0, 0 };////   fONE//c2   = { 0.00390625, 0, 0, 0 };////   fONEHALF//c3   = { 0.00195313, 0, 0, 0 };////   v2LacunarityGain//c4   = { 2, 0.5, 0, 0 };////   TexScale//c5   = { 0, 0, 0, 0 };////   CoarserTexOffset//c6   = { 0, 0, 0, 0 };////   ZScaleMax//c7   = { 0, 0, 0, 0 };////   OneOverTextureSize//c8   = { 0, 0, 0, 0 };//    ps_3_0    def c9, 1, 3.05175781e-005, 0, 0.5    def c10, -0, 1, 4, 2    def c11, 70, 0.5, -0, 4096    def c12, 0.000122070313, 0, 0, 0    defi i0, 10, 0, 0, 0    dcl_texcoord v0.xy  // p_uv<0,1>    dcl_2d s0    dcl_2d s1#line 158 "C:\Users\Alex\Documents\Visual Studio 2008\Projects\GPUClipmap\GPUClipmap\Content\Update.fx"    mul r2.xy, v0, c5    add r1.xy, r2, c5.zwzw  // Tg_uv<0,1>    mul r0.xy, r1, c9.x    mul r16.xy, r0, c9.y  // getRidgeMF::P<0,1>    mov r3.w, c9.x  // getRidgeMF::m_FreqAmp<0>    mov r2.w, c9.w  // getRidgeMF::m_FreqAmp<1>    mov r1.w, c10.x  // getRidgeMF::m_FreqAmp<2>    mov r0.w, c9.x  // getRidgeMF::m_prevN<0>    rep i0#line 126 mul r9.xy, r16, r3.w  // Simplex2D::P<0,1>#line 58 add r7.w, r9.y, r9.x mul r6.w, r7.w, c0.x  // Simplex2D::s<0> add r13.xy, r9, r6.w frc r15.xy, r13 mov r15.xy, -r15 add r10.xy, r13, r15  // Simplex2D::Pi<0,1> add r5.w, r10.y, r10.x mul r14.w, r5.w, c1.x  // Simplex2D::t<0> mov r12.xy, -r14.w add r11.xy, r10, r12  // Simplex2D::P0<0,1> mul r8.xy, r10, c2.x add r8.xy, r8, c3.x  // Simplex2D::Pi<0,1> mov r11.xy, -r11 add r9.xy, r9, r11  // Simplex2D::Pf0<0,1>#line 67 mov r7.w, -r9.y add r4.w, r9.x, r7.w cmp r1.x, r4.w, c10.y, c10.x  // Simplex2D::o1<0> mov r6.w, -r1.x add r1.y, r6.w, c9.x  // Simplex2D::o1<1>#line 71 texld r14, r8, s1 mul r5.xy, r14, c10.z add r4.xy, r5, -c9.x  // Simplex2D::grad0<0,1> mul r16.xy, r9, r9 add r12.w, r16.x, r16.y mov r12.w, -r12.w add r15.w, r12.w, c9.w  // Simplex2D::t0<0> add r3.z, r15.w, c10.x cmp r0.z, r3.z, c10.y, c10.x mul r2.z, r15.w, r0.z mul r1.z, r15.w, r2.z mul r13.w, r15.w, r1.z mul r11.w, r15.w, r13.w mul r16.xy, r4, r9 add r14.w, r16.x, r16.y mul r5.w, r11.w, r14.w  // Simplex2D::n0<0>#line 76 mov r3.xy, -r1 add r2.xy, r9, r3 add r14.xy, r2, c1.x  // Simplex2D::Pf1<0,1> mul r0.xy, r1, c2.x add r15.xy, r8, r0 texld r13, r15, s1 mul r13.xy, r13, c10.z add r12.xy, r13, -c9.x  // Simplex2D::grad1<0,1> mul r16.xy, r14, r14 add r10.w, r16.x, r16.y mov r10.w, -r10.w add r5.z, r10.w, c9.w  // Simplex2D::t1<0> add r8.w, r5.z, c10.x cmp r9.w, r8.w, c10.y, c10.x mul r7.w, r5.z, r9.w mul r6.w, r5.z, r7.w mul r4.w, r5.z, r6.w mul r3.z, r5.z, r4.w mul r16.xy, r12, r14 add r12.w, r16.x, r16.y mul r6.w, r3.z, r12.w  // Simplex2D::n1<0>#line 82 mov r0.x, c10.w mul r2.z, r0.x, c1.x mov r2.z, -r2.z add r10.w, r2.z, c9.x mov r11.xy, -r10.w add r5.xy, r9, r11  // Simplex2D::Pf2<0,1> add r7.xy, r8, c2.x texld r12, r7, s1 mul r6.xy, r12, c10.z add r4.xy, r6, -c9.x  // Simplex2D::grad2<0,1> mul r16.xy, r5, r5 add r1.z, r16.x, r16.y mov r1.z, -r1.z add r10.w, r1.z, c9.w  // Simplex2D::t2<0> add r15.w, r10.w, c10.x cmp r13.w, r15.w, c10.y, c10.x mul r14.w, r10.w, r13.w mul r11.w, r10.w, r14.w mul r8.w, r10.w, r11.w mul r7.w, r10.w, r8.w mul r16.xy, r4, r5 add r9.w, r16.x, r16.y mul r4.w, r7.w, r9.w  // Simplex2D::n2<0>#line 88 add r12.w, r5.w, r6.w add r3.z, r4.w, r12.w mul r0.z, r3.z, c11.x  // ::Simplex2D<0>#line 126 mov r0.z, r0.z  // ridge::h<0>#line 113 mov r1.z, -r0.z mov r2.z, -r1.z add r15.w, r0.z, r2.z cmp r13.w, r15.w, r0.z, r1.z mov r13.w, -r13.w add r14.w, r13.w, c9.x  // ridge::h<0> mul r11.w, r14.w, r14.w  // ::ridge<0>#line 126 mov r11.w, r11.w  // getRidgeMF::m_prevN<1> mul r10.w, r2.w, r11.w mul r8.w, r0.w, r10.w add r1.w, r1.w, r8.w  // getRidgeMF::m_FreqAmp<2> mov r0.w, r11.w  // getRidgeMF::m_prevN<0> mov r3.y, r2.w mul r2.xw, r3.wyzy, c4.xyzy  // getRidgeMF::m_FreqAmp<0,1> mov r3.w, r2.x  // getRidgeMF::m_FreqAmp<0> mov r2.w, r2.w  // getRidgeMF::m_FreqAmp<1>    endrep    mov r9.w, r1.w  // getRidgeMF::m_FreqAmp<2>#line 132    mov r9.w, r9.w  // ::getRidgeMF<0>#line 159    add r7.w, r9.w, c10.x    cmp r6.w, r7.w, r9.w, c10.x    add r5.w, r6.w, -c9.x    cmp r4.w, r5.w, c9.x, r6.w    mul r3.w, r4.w, c7.x    frc r12.w, r3.w    mov r12.w, -r12.w    add r12.w, r3.w, r12.w  // zf<0>    add r0.yz, v0.xyxw, c9.w    frc r1.yz, r0    mov r1.yz, -r1    add r15.yz, r0, r1  // p_uv<1,0>    mul r11.yz, r15, c9.w  // p_uv_div2<1,0>#line 165    add r11.xw, r11.zyzy, c9.w    frc r10, r11    mov r10, -r10    add r9, r11.zyzy, c11.yzzy    add r8, r10, r9    mul r7, r8, c8.x    add r5, r7, c6.xyxy  // uvc<0,1,2,3>    texld r6, r5, s0    frc r2.w, r6.x    mov r2.w, -r2.w    add r15.w, r6.x, r2.w  // zc0<0>    texld r4, r5.zwzw, s0    frc r1.w, r4.x    mov r1.w, -r1.w    add r0.w, r4.x, r1.w  // zc1<0>    add r13.w, r15.w, r0.w    mul r10.w, r13.w, c9.w    mov r14.w, -r12.w    add r8.w, r10.w, r14.w    add r11.w, r8.w, c11.w    mul r9.w, r11.w, c12.x    add r7.w, r9.w, c10.x    cmp r6.w, r7.w, r9.w, c10.x    add r5.w, r6.w, -c9.x    cmp r4.w, r5.w, c9.x, r6.w    add r3.w, r12.w, r4.w  // zf_zd<0>    mov oC0.x, r3.w  // ::GPUgcUpdate<0>    mov oC0.yzw, c10.x  // ::GPUgcUpdate<1,2,3>// approximately 156 instruction slots used (5 texture, 151 arithmetic)Armed with this, can I make XNA use the version that was compiled in the MDX version and see what if it works then?   ;  ... I have egg on my face.I've set up my effect in XNA to compile with the latest FXC... and it works.Thanks to both of you, once again MJP you are a fantastic help.There definitely needs to be an article on one of the popular XNA sites about setting this up, maybe I'll write it up myself.Whilst I'm on the subject, I can't believe Microsoft are actively pushing XNA, yet it has stoneage tools like this causing problems. I knwo the latest compiler drops vs_1_1 support, but why can't it autodetect which compiler to use?   