From fdbc80d13158e88b33a6765ae57b661a813b4a2c Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Thu, 20 Aug 2020 16:22:48 +0200 Subject: [PATCH] HLSL: Fix FragCoord.w. Need to invert it, SM 4.0+ uses W, not 1/W (like Vulkan/GL). --- .../frag/single-function-private-lut.asm.frag | 1 + .../asm/frag/texel-fetch-no-lod.asm.frag | 1 + reference/opt/shaders-hlsl/frag/builtins.frag | 1 + .../complex-expression-in-access-chain.frag | 1 + .../frag/input-attachment-ms.frag | 1 + .../shaders-hlsl/frag/input-attachment.frag | 1 + .../opt/shaders-hlsl/frag/sampler-array.frag | 1 + .../shaders-hlsl/frag/tex-sampling-ms.frag | 1 + .../shaders-hlsl/frag/texel-fetch-offset.frag | 1 + ...-interlock-callstack.sm51.fxconly.asm.frag | 1 + ...terlock-control-flow.sm51.fxconly.asm.frag | 1 + ...lock-split-functions.sm51.fxconly.asm.frag | 1 + .../shaders-hlsl-no-opt/frag/frag-coord.frag | 27 +++++++++++++++++++ ...types.fxconly.nofxc.sm62.native-16bit.frag | 1 + ...terlock-simple-callstack.sm51.fxconly.frag | 1 + .../frag/single-function-private-lut.asm.frag | 1 + .../asm/frag/texel-fetch-no-lod.asm.frag | 1 + reference/shaders-hlsl/frag/builtins.frag | 1 + .../complex-expression-in-access-chain.frag | 1 + .../frag/input-attachment-ms.frag | 1 + .../shaders-hlsl/frag/input-attachment.frag | 1 + .../shaders-hlsl/frag/sampler-array.frag | 1 + .../shaders-hlsl/frag/tex-sampling-ms.frag | 1 + .../shaders-hlsl/frag/texel-fetch-offset.frag | 1 + shaders-hlsl-no-opt/frag/frag-coord.frag | 8 ++++++ spirv_hlsl.cpp | 4 +++ 26 files changed, 62 insertions(+) create mode 100644 reference/shaders-hlsl-no-opt/frag/frag-coord.frag create mode 100644 shaders-hlsl-no-opt/frag/frag-coord.frag diff --git a/reference/opt/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag b/reference/opt/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag index 507bbe1d..269cecb3 100644 --- a/reference/opt/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag +++ b/reference/opt/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag @@ -55,6 +55,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.o_color = o_color; diff --git a/reference/opt/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag b/reference/opt/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag index 695d5fe9..74c12945 100644 --- a/reference/opt/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag +++ b/reference/opt/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag @@ -22,6 +22,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/opt/shaders-hlsl/frag/builtins.frag b/reference/opt/shaders-hlsl/frag/builtins.frag index 922eca7c..8432c42f 100644 --- a/reference/opt/shaders-hlsl/frag/builtins.frag +++ b/reference/opt/shaders-hlsl/frag/builtins.frag @@ -24,6 +24,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; vColor = stage_input.vColor; frag_main(); SPIRV_Cross_Output stage_output; diff --git a/reference/opt/shaders-hlsl/frag/complex-expression-in-access-chain.frag b/reference/opt/shaders-hlsl/frag/complex-expression-in-access-chain.frag index d9336c09..1de88244 100644 --- a/reference/opt/shaders-hlsl/frag/complex-expression-in-access-chain.frag +++ b/reference/opt/shaders-hlsl/frag/complex-expression-in-access-chain.frag @@ -28,6 +28,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; vIn = stage_input.vIn; vIn2 = stage_input.vIn2; frag_main(); diff --git a/reference/opt/shaders-hlsl/frag/input-attachment-ms.frag b/reference/opt/shaders-hlsl/frag/input-attachment-ms.frag index e206b837..54cb1dd9 100644 --- a/reference/opt/shaders-hlsl/frag/input-attachment-ms.frag +++ b/reference/opt/shaders-hlsl/frag/input-attachment-ms.frag @@ -24,6 +24,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; gl_SampleID = stage_input.gl_SampleID; frag_main(); SPIRV_Cross_Output stage_output; diff --git a/reference/opt/shaders-hlsl/frag/input-attachment.frag b/reference/opt/shaders-hlsl/frag/input-attachment.frag index d87661e5..34aaafcf 100644 --- a/reference/opt/shaders-hlsl/frag/input-attachment.frag +++ b/reference/opt/shaders-hlsl/frag/input-attachment.frag @@ -22,6 +22,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/opt/shaders-hlsl/frag/sampler-array.frag b/reference/opt/shaders-hlsl/frag/sampler-array.frag index 1eced29b..8ecdc6c3 100644 --- a/reference/opt/shaders-hlsl/frag/sampler-array.frag +++ b/reference/opt/shaders-hlsl/frag/sampler-array.frag @@ -24,6 +24,7 @@ void frag_main() void main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; vTex = stage_input.vTex; vIndex = stage_input.vIndex; frag_main(); diff --git a/reference/opt/shaders-hlsl/frag/tex-sampling-ms.frag b/reference/opt/shaders-hlsl/frag/tex-sampling-ms.frag index ca88cfae..d4dd78d8 100644 --- a/reference/opt/shaders-hlsl/frag/tex-sampling-ms.frag +++ b/reference/opt/shaders-hlsl/frag/tex-sampling-ms.frag @@ -26,6 +26,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/opt/shaders-hlsl/frag/texel-fetch-offset.frag b/reference/opt/shaders-hlsl/frag/texel-fetch-offset.frag index d7aa73d5..9bd27697 100644 --- a/reference/opt/shaders-hlsl/frag/texel-fetch-offset.frag +++ b/reference/opt/shaders-hlsl/frag/texel-fetch-offset.frag @@ -24,6 +24,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-callstack.sm51.fxconly.asm.frag b/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-callstack.sm51.fxconly.asm.frag index 3268995c..8a47b91b 100644 --- a/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-callstack.sm51.fxconly.asm.frag +++ b/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-callstack.sm51.fxconly.asm.frag @@ -28,5 +28,6 @@ void frag_main() void main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); } diff --git a/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-control-flow.sm51.fxconly.asm.frag b/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-control-flow.sm51.fxconly.asm.frag index 69277121..01bbe7dd 100644 --- a/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-control-flow.sm51.fxconly.asm.frag +++ b/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-control-flow.sm51.fxconly.asm.frag @@ -38,5 +38,6 @@ void frag_main() void main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); } diff --git a/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-split-functions.sm51.fxconly.asm.frag b/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-split-functions.sm51.fxconly.asm.frag index bd963a74..c1fb6ebb 100644 --- a/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-split-functions.sm51.fxconly.asm.frag +++ b/reference/shaders-hlsl-no-opt/asm/frag/pixel-interlock-split-functions.sm51.fxconly.asm.frag @@ -38,5 +38,6 @@ void frag_main() void main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); } diff --git a/reference/shaders-hlsl-no-opt/frag/frag-coord.frag b/reference/shaders-hlsl-no-opt/frag/frag-coord.frag new file mode 100644 index 00000000..17cb4c4b --- /dev/null +++ b/reference/shaders-hlsl-no-opt/frag/frag-coord.frag @@ -0,0 +1,27 @@ +static float4 gl_FragCoord; +static float3 FragColor; + +struct SPIRV_Cross_Input +{ + float4 gl_FragCoord : SV_Position; +}; + +struct SPIRV_Cross_Output +{ + float3 FragColor : SV_Target0; +}; + +void frag_main() +{ + FragColor = gl_FragCoord.xyz / gl_FragCoord.w.xxx; +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor = FragColor; + return stage_output; +} diff --git a/reference/shaders-hlsl-no-opt/frag/native-16bit-types.fxconly.nofxc.sm62.native-16bit.frag b/reference/shaders-hlsl-no-opt/frag/native-16bit-types.fxconly.nofxc.sm62.native-16bit.frag index ee082783..020831d0 100644 --- a/reference/shaders-hlsl-no-opt/frag/native-16bit-types.fxconly.nofxc.sm62.native-16bit.frag +++ b/reference/shaders-hlsl-no-opt/frag/native-16bit-types.fxconly.nofxc.sm62.native-16bit.frag @@ -66,6 +66,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; Input = stage_input.Input; InputI = stage_input.InputI; InputU = stage_input.InputU; diff --git a/reference/shaders-hlsl-no-opt/frag/pixel-interlock-simple-callstack.sm51.fxconly.frag b/reference/shaders-hlsl-no-opt/frag/pixel-interlock-simple-callstack.sm51.fxconly.frag index 55b71de2..aace6f58 100644 --- a/reference/shaders-hlsl-no-opt/frag/pixel-interlock-simple-callstack.sm51.fxconly.frag +++ b/reference/shaders-hlsl-no-opt/frag/pixel-interlock-simple-callstack.sm51.fxconly.frag @@ -28,5 +28,6 @@ void frag_main() void main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); } diff --git a/reference/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag b/reference/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag index 281c3976..9c71d08c 100644 --- a/reference/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag +++ b/reference/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag @@ -58,6 +58,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.o_color = o_color; diff --git a/reference/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag b/reference/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag index 695d5fe9..74c12945 100644 --- a/reference/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag +++ b/reference/shaders-hlsl/asm/frag/texel-fetch-no-lod.asm.frag @@ -22,6 +22,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/shaders-hlsl/frag/builtins.frag b/reference/shaders-hlsl/frag/builtins.frag index 922eca7c..8432c42f 100644 --- a/reference/shaders-hlsl/frag/builtins.frag +++ b/reference/shaders-hlsl/frag/builtins.frag @@ -24,6 +24,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; vColor = stage_input.vColor; frag_main(); SPIRV_Cross_Output stage_output; diff --git a/reference/shaders-hlsl/frag/complex-expression-in-access-chain.frag b/reference/shaders-hlsl/frag/complex-expression-in-access-chain.frag index d5ccb9b9..b2f99548 100644 --- a/reference/shaders-hlsl/frag/complex-expression-in-access-chain.frag +++ b/reference/shaders-hlsl/frag/complex-expression-in-access-chain.frag @@ -31,6 +31,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; vIn = stage_input.vIn; vIn2 = stage_input.vIn2; frag_main(); diff --git a/reference/shaders-hlsl/frag/input-attachment-ms.frag b/reference/shaders-hlsl/frag/input-attachment-ms.frag index fb065e55..954fa1a9 100644 --- a/reference/shaders-hlsl/frag/input-attachment-ms.frag +++ b/reference/shaders-hlsl/frag/input-attachment-ms.frag @@ -30,6 +30,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; gl_SampleID = stage_input.gl_SampleID; frag_main(); SPIRV_Cross_Output stage_output; diff --git a/reference/shaders-hlsl/frag/input-attachment.frag b/reference/shaders-hlsl/frag/input-attachment.frag index 0b815ae0..b0e297c5 100644 --- a/reference/shaders-hlsl/frag/input-attachment.frag +++ b/reference/shaders-hlsl/frag/input-attachment.frag @@ -27,6 +27,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/shaders-hlsl/frag/sampler-array.frag b/reference/shaders-hlsl/frag/sampler-array.frag index e941357d..fd08d423 100644 --- a/reference/shaders-hlsl/frag/sampler-array.frag +++ b/reference/shaders-hlsl/frag/sampler-array.frag @@ -38,6 +38,7 @@ void frag_main() void main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; vTex = stage_input.vTex; vIndex = stage_input.vIndex; frag_main(); diff --git a/reference/shaders-hlsl/frag/tex-sampling-ms.frag b/reference/shaders-hlsl/frag/tex-sampling-ms.frag index 14353153..854ad501 100644 --- a/reference/shaders-hlsl/frag/tex-sampling-ms.frag +++ b/reference/shaders-hlsl/frag/tex-sampling-ms.frag @@ -25,6 +25,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/shaders-hlsl/frag/texel-fetch-offset.frag b/reference/shaders-hlsl/frag/texel-fetch-offset.frag index f2a02e16..c7ae589d 100644 --- a/reference/shaders-hlsl/frag/texel-fetch-offset.frag +++ b/reference/shaders-hlsl/frag/texel-fetch-offset.frag @@ -23,6 +23,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_FragCoord = stage_input.gl_FragCoord; + gl_FragCoord.w = 1.0 / gl_FragCoord.w; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/shaders-hlsl-no-opt/frag/frag-coord.frag b/shaders-hlsl-no-opt/frag/frag-coord.frag new file mode 100644 index 00000000..e688659a --- /dev/null +++ b/shaders-hlsl-no-opt/frag/frag-coord.frag @@ -0,0 +1,8 @@ +#version 450 + +layout(location = 0) out vec3 FragColor; + +void main() +{ + FragColor = gl_FragCoord.xyz / gl_FragCoord.w; +} diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 7a33559a..51b3dd48 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -2396,7 +2396,11 @@ void CompilerHLSL::emit_hlsl_entry_point() if (legacy) statement(builtin, " = stage_input.", builtin, " + float4(0.5f, 0.5f, 0.0f, 0.0f);"); else + { statement(builtin, " = stage_input.", builtin, ";"); + // ZW are undefined in D3D9, only do this fixup here. + statement(builtin, ".w = 1.0 / ", builtin, ".w;"); + } break; case BuiltInVertexId: