From 589aaff11cacf590d766bd3518f6dd037bfe4df9 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 5 Nov 2020 17:53:38 +0100 Subject: [PATCH] Don't use roundEven() to implement round() in DX9 compatibility mode --- Test/baseResults/hlsl.round.dx10.frag.out | 60 +++++++++++++++++++ Test/baseResults/hlsl.round.dx9.frag.out | 70 +++++++++++++++++++++++ Test/hlsl.round.dx10.frag | 4 ++ Test/hlsl.round.dx9.frag | 4 ++ glslang/HLSL/hlslParseHelper.cpp | 4 ++ glslang/HLSL/hlslParseables.cpp | 2 +- gtests/Hlsl.FromFile.cpp | 2 + 7 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 Test/baseResults/hlsl.round.dx10.frag.out create mode 100644 Test/baseResults/hlsl.round.dx9.frag.out create mode 100644 Test/hlsl.round.dx10.frag create mode 100644 Test/hlsl.round.dx9.frag diff --git a/Test/baseResults/hlsl.round.dx10.frag.out b/Test/baseResults/hlsl.round.dx10.frag.out new file mode 100644 index 000000000..be72dc597 --- /dev/null +++ b/Test/baseResults/hlsl.round.dx10.frag.out @@ -0,0 +1,60 @@ +hlsl.round.dx10.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:2 Function Definition: PixelShaderFunction(vf4; ( temp 4-component vector of float) +0:2 Function Parameters: +0:2 'input' ( in 4-component vector of float) +0:? Sequence +0:3 Branch: Return with expression +0:3 roundEven ( temp 4-component vector of float) +0:3 'input' ( in 4-component vector of float) +0:? Linker Objects + + +Linked fragment stage: + +WARNING: Linking fragment stage: Entry point not found + +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:2 Function Definition: PixelShaderFunction(vf4; ( temp 4-component vector of float) +0:2 Function Parameters: +0:2 'input' ( in 4-component vector of float) +0:? Sequence +0:3 Branch: Return with expression +0:3 roundEven ( temp 4-component vector of float) +0:3 'input' ( in 4-component vector of float) +0:? Linker Objects + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 17 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" + ExecutionMode 4 OriginUpperLeft + Source HLSL 500 + Name 4 "main" + Name 11 "PixelShaderFunction(vf4;" + Name 10 "input" + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 9: TypeFunction 7(fvec4) 8(ptr) + 4(main): 2 Function None 3 + 5: Label + Return + FunctionEnd +11(PixelShaderFunction(vf4;): 7(fvec4) Function None 9 + 10(input): 8(ptr) FunctionParameter + 12: Label + 13: 7(fvec4) Load 10(input) + 14: 7(fvec4) ExtInst 1(GLSL.std.450) 2(RoundEven) 13 + ReturnValue 14 + FunctionEnd diff --git a/Test/baseResults/hlsl.round.dx9.frag.out b/Test/baseResults/hlsl.round.dx9.frag.out new file mode 100644 index 000000000..9333c7dcf --- /dev/null +++ b/Test/baseResults/hlsl.round.dx9.frag.out @@ -0,0 +1,70 @@ +hlsl.round.dx9.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:2 Function Definition: PixelShaderFunction(vf4; ( temp 4-component vector of float) +0:2 Function Parameters: +0:2 'input' ( in 4-component vector of float) +0:? Sequence +0:3 Branch: Return with expression +0:3 round ( temp 4-component vector of float) +0:3 'input' ( in 4-component vector of float) +0:? Linker Objects + + +Linked fragment stage: + +WARNING: Linking fragment stage: Entry point not found + +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:2 Function Definition: PixelShaderFunction(vf4; ( temp 4-component vector of float) +0:2 Function Parameters: +0:2 'input' ( in 4-component vector of float) +0:? Sequence +0:3 Branch: Return with expression +0:3 round ( temp 4-component vector of float) +0:3 'input' ( in 4-component vector of float) +0:? Linker Objects + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 18 + + Capability Shader + 2: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 5 "main" + ExecutionMode 5 OriginUpperLeft + 1: String "" + Source HLSL 500 1 "// OpModuleProcessed auto-map-locations +// OpModuleProcessed auto-map-bindings +// OpModuleProcessed entry-point main +// OpModuleProcessed client vulkan100 +// OpModuleProcessed target-env vulkan1.0 +// OpModuleProcessed keep-uncalled +// OpModuleProcessed hlsl-offsets +#line 1 +" + Name 5 "main" + Name 12 "PixelShaderFunction(vf4;" + Name 11 "input" + 3: TypeVoid + 4: TypeFunction 3 + 7: TypeFloat 32 + 8: TypeVector 7(float) 4 + 9: TypePointer Function 8(fvec4) + 10: TypeFunction 8(fvec4) 9(ptr) + 5(main): 3 Function None 4 + 6: Label + Return + FunctionEnd +12(PixelShaderFunction(vf4;): 8(fvec4) Function None 10 + 11(input): 9(ptr) FunctionParameter + 13: Label + Line 1 3 0 + 14: 8(fvec4) Load 11(input) + 15: 8(fvec4) ExtInst 2(GLSL.std.450) 1(Round) 14 + ReturnValue 15 + FunctionEnd diff --git a/Test/hlsl.round.dx10.frag b/Test/hlsl.round.dx10.frag new file mode 100644 index 000000000..cd88334cc --- /dev/null +++ b/Test/hlsl.round.dx10.frag @@ -0,0 +1,4 @@ +float4 PixelShaderFunction(float4 input) : COLOR0 +{ + return round(input); +} diff --git a/Test/hlsl.round.dx9.frag b/Test/hlsl.round.dx9.frag new file mode 100644 index 000000000..cd88334cc --- /dev/null +++ b/Test/hlsl.round.dx9.frag @@ -0,0 +1,4 @@ +float4 PixelShaderFunction(float4 input) : COLOR0 +{ + return round(input); +} diff --git a/glslang/HLSL/hlslParseHelper.cpp b/glslang/HLSL/hlslParseHelper.cpp index ea31837e8..abe0f34e6 100644 --- a/glslang/HLSL/hlslParseHelper.cpp +++ b/glslang/HLSL/hlslParseHelper.cpp @@ -5492,6 +5492,10 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct op = fnCandidate->getBuiltInOp(); if (builtIn && op != EOpNull) { + // SM 4.0 and above guarantees roundEven semantics for round() + if (!hlslDX9Compatible() && op == EOpRound) + op = EOpRoundEven; + // A function call mapped to a built-in operation. result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, arguments, fnCandidate->getType()); diff --git a/glslang/HLSL/hlslParseables.cpp b/glslang/HLSL/hlslParseables.cpp index 025cb5e11..4673b4601 100644 --- a/glslang/HLSL/hlslParseables.cpp +++ b/glslang/HLSL/hlslParseables.cpp @@ -1123,7 +1123,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil symbolTable.relateToOperator("reflect", EOpReflect); symbolTable.relateToOperator("refract", EOpRefract); symbolTable.relateToOperator("reversebits", EOpBitFieldReverse); - symbolTable.relateToOperator("round", EOpRoundEven); + symbolTable.relateToOperator("round", EOpRound); symbolTable.relateToOperator("rsqrt", EOpInverseSqrt); symbolTable.relateToOperator("saturate", EOpSaturate); symbolTable.relateToOperator("sign", EOpSign); diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 4d1cb50b2..de071b9f3 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -313,6 +313,7 @@ INSTANTIATE_TEST_SUITE_P( {"hlsl.promote.binary.frag", "main"}, {"hlsl.promote.vec1.frag", "main"}, {"hlsl.promotions.frag", "main"}, + {"hlsl.round.dx10.frag", "main"}, {"hlsl.rw.atomics.frag", "main"}, {"hlsl.rw.bracket.frag", "main"}, {"hlsl.rw.register.frag", "main"}, @@ -490,6 +491,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( ToSpirv, HlslDX9CompatibleTest, ::testing::ValuesIn(std::vector{ + {"hlsl.round.dx9.frag", "main"}, {"hlsl.sample.dx9.frag", "main"}, {"hlsl.sample.dx9.vert", "main"}, }),