
cbuffer _Globals : register(b0)
{
  float3 g_cameraPos : packoffset(c0);
  float2 g_invScreenSize : packoffset(c1);
  float4x4 g_invViewProjMatrix : packoffset(c2);
  float4x4 g_viewToShadowMatrix : packoffset(c6);
  float4 g_shadowmapHalfSizeAndInvHalfSize : packoffset(c10);
  float4 g_shadowmapPoissonScale : packoffset(c11);
  float4 g_shadowmapNoiseTilingFactor : packoffset(c12);
  float g_shadowPenumbraSize : packoffset(c13);
  float4 g_pcssFilterParameters0 : packoffset(c14);
  float4 g_pcssFilterParameters1 : packoffset(c15);
  float4x4 g_shadowmapViewMatrix : packoffset(c16);
  float4 g_shadowmapScales : packoffset(c20);
  float3 g_lightDir : packoffset(c21);
  float4x4 g_shadowmapTransform : packoffset(c22);
  uint4 g_shadowmapDimensions : packoffset(c26);
}
SamplerState g_transShadowmapSampler_s : register(s1);
SamplerComparisonState g_shadowmapSampler_s : register(s0);
Texture2D<float4> g_shadowmapTexture : register(t0);
Texture2D<float4> g_transShadowmapTexture : register(t1);
Texture2DMS<float4,2> g_depthTexture : register(t2);

Texture2D<float4> StereoParams : register(t125);

void main(
  float4 v0 : SV_Position0,
  uint v1 : SV_SampleIndex0,
  out float4 o0 : SV_Target0)
{
  float4 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10;
  uint4 bitmask;

//Work out Inverse
//...Variables
float4 a1, a2, a3, a4;
float4 b1, b2, b3, b4;
float det;
//...Original Matrix
a1 = g_invViewProjMatrix._m00_m10_m20_m30;
a2 = g_invViewProjMatrix._m01_m11_m21_m31;
a3 = g_invViewProjMatrix._m02_m12_m22_m32;
a4 = g_invViewProjMatrix._m03_m13_m23_m33;
//...Determinant
det  = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));
//...Inverse Matrix Elements
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);
b1.xyzw /= det;
b2.xyzw /= det;
b3.xyzw /= det;
b4.xyzw /= det;
//End Inverse


  r0.xy = (int2)v0.xy;
  r0.zw = float2(0.000000e+000,0.000000e+000);
  r0.z = g_depthTexture.Load(r0.xyz,v1.x).x;
  r1.xy = g_invScreenSize.xy * v0.xy;
  r1.xy = r1.xy * float2(2.000000e+000,2.000000e+000) + float2(-1.000000e+000,-1.000000e+000);
  r0.xy = float2(1.000000e+000,-1.000000e+000) * r1.xy;
  r0.w = 1.000000000e+000;
  r1.x = dot(r0.xyzw, g_invViewProjMatrix._m03_m13_m23_m33);
  r1.x = 1.000000e+000 / r1.x;
  r2.x = dot(r0.xyzw, g_invViewProjMatrix._m00_m10_m20_m30);
  r2.y = dot(r0.xyzw, g_invViewProjMatrix._m01_m11_m21_m31);
  r2.z = dot(r0.xyzw, g_invViewProjMatrix._m02_m12_m22_m32);


float4 r28, r26, r27;
r26.xyz = r2.xyz * r1.xxx;
r26.w = 1.0;
r28.x = dot(r26.xyzw, b1.xyzw);
r28.y = dot(r26.xyzw, b2.xyzw);
r28.z = dot(r26.xyzw, b3.xyzw);
r28.w = dot(r26.xyzw, b4.xyzw);
float4 stereo = StereoParams.Load(0);
r28.x -= stereo.x * (r28.w - stereo.y); 
r26.x = dot(r28.xyzw, a1.xyzw);
r26.y = dot(r28.xyzw, a2.xyzw);
r26.z = dot(r28.xyzw, a3.xyzw);
r26.w = dot(r28.xyzw, a4.xyzw);
r2.xyz = r26.xyz / r1.xxx;

  r0.xyz = r2.xyz * r1.xxx;


  r0.w = 1.000000000e+000;
  r1.x = dot(r0.xyzw, g_shadowmapTransform._m00_m10_m20_m30);
  r1.y = dot(r0.xyzw, g_shadowmapTransform._m01_m11_m21_m31);
  r0.x = dot(r0.xyzw, g_shadowmapTransform._m02_m12_m22_m32);
  r0.y = g_shadowmapDimensions.x;
  r0.zw = r0.yy * r1.xy + float2(5.000000e-001,5.000000e-001);
  r1.x = g_transShadowmapTexture.SampleLevel(g_transShadowmapSampler_s, r1.xy, 0.000000000e+000).x;
  r1.x = 1.000000000e+000 + -r1.x;
  r0.y = 1.000000e+000 / r0.y;
  r1.yz = floor(r0.zw);
  r0.zw = -r1.yz + r0.zw;
  r1.yz = r1.yz * r0.yy;
  r2.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(2,0)).xyzw;
  r0.y = r0.z * 2.000000000e+000 + 2.000000000e+000;
  r3.xy = float2(4.000000e+000,1.000000e+000) + -r0.zw;
  r4.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(0,0)).xyzw;
  r5.xyzw = float4(1.000000e+000,4.000000e+000,3.000000e+000,2.000000e+000) + r0.zzzz;
  r6.xyzw = float4(1.000000e+000,2.000000e+000,3.000000e+000,5.000000e+000) + -r0.zzzz;
  r1.w = -r0.z * 2.000000000e+000 + 2.000000000e+000;
  r7.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(-2,0)).xyzw;
  r3.z = r0.z * -2.000000000e+000 + 4.000000000e+000;
  r8.xy = r7.wx * r1.ww;
  r3.zw = r7.zy * r3.zz + r8.xy;
  r3.w = r7.z * r6.z + r3.w;
  r3.w = r7.w * r1.w + r3.w;
  r3.w = r4.y * r5.y + r3.w;
  r3.w = r4.x * r6.w + r3.w;
  r3.w = r4.z * r5.z + r3.w;
  r3.w = r4.w * r3.x + r3.w;
  r2.y = dot(r2.yy, r0.zz);
  r3.w = r2.y + r3.w;
  r3.w = r2.x * r0.y + r3.w;
  r2.z = dot(r2.zz, r0.zz);
  r3.w = r2.z + r3.w;
  r8.y = r2.w * r5.w + r3.w;
  r9.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(0,-2)).xyzw;
  r10.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(-2,-2)).xyzw;
  r3.z = r10.y * r6.z + r3.z;
  r3.z = r10.x * r1.w + r3.z;
  r10.xyzw = r10.wzxy * r6.xyxy;
  r7.zw = r10.xz + r10.yw;
  r7.zw = r9.zy * float2(2.000000e+000,2.000000e+000) + r7.zw;
  r7.zw = r9.wx * float2(2.000000e+000,2.000000e+000) + r7.zw;
  r3.z = r4.z * r5.y + r3.z;
  r3.z = r4.w * r6.w + r3.z;
  r3.z = r9.y * r5.z + r3.z;
  r3.z = r9.x * r3.x + r3.z;
  r2.z = r3.z + r2.z;
  r0.y = r2.w * r0.y + r2.z;
  r9.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(2,-2)).xyzw;
  r2.z = r9.y * r0.z;
  r0.y = r2.z * 2.000000000e+000 + r0.y;
  r8.x = r9.x * r5.w + r0.y;
  r2.zw = r9.zy * r0.zz + r7.zw;
  r2.zw = r9.wx * r5.xx + r2.zw;
  r2.zw = r2.zw + r8.xy;
  r8.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(-2,2)).xyzw;
  r9.xyzw = r8.wzxy * r6.xyxy;
  r3.zw = r9.xz + r9.yw;
  r0.y = r8.z * r6.z + r3.w;
  r0.y = r8.w * r1.w + r0.y;
  r3.z = r7.y * r6.z + r3.z;
  r1.w = r7.x * r1.w + r3.z;
  r6.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(0,2)).xyzw;
  r7.xyzw = g_shadowmapTexture.GatherCmp(g_shadowmapSampler_s, r1.yz, r0.x, int2(2,2)).xyzw;
  r0.x = r6.y * 2.000000000e+000 + r0.y;
  r0.x = r6.x * 2.000000000e+000 + r0.x;
  r0.x = r6.z * r5.z + r0.x;
  r0.x = r6.w * r3.x + r0.x;
  r0.x = r7.y * r0.z + r0.x;
  r0.x = r7.x * r5.x + r0.x;
  r0.y = r7.z * r0.z;
  r0.x = r0.y * 2.000000000e+000 + r0.x;
  r0.y = r7.w * r5.w + r0.x;
  r1.y = r6.z * 2.000000000e+000 + r1.w;
  r1.y = r6.w * 2.000000000e+000 + r1.y;
  r1.y = r4.y * r5.z + r1.y;
  r1.y = r4.x * r3.x + r1.y;
  r0.z = r7.z * r0.z + r1.y;
  r0.z = r7.w * r5.x + r0.z;
  r0.z = r2.y + r0.z;
  r0.x = r2.x * r5.w + r0.z;
  r0.xy = r2.zw + r0.xy;
  r0.y = r0.y * r0.w;
  r0.x = r0.x * r3.y + r0.y;
  r0.x = 1.694915257e-002 * r0.x;
  o0.xyzw = r0.xxxx * r1.xxxx;
  return;
}
