Don't use roundEven() to implement round() in DX9 compatibility mode
authorrdb <git@rdb.name>
Thu, 5 Nov 2020 16:53:38 +0000 (17:53 +0100)
committerrdb <git@rdb.name>
Wed, 16 Dec 2020 17:35:42 +0000 (18:35 +0100)
Test/baseResults/hlsl.round.dx10.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.round.dx9.frag.out [new file with mode: 0644]
Test/hlsl.round.dx10.frag [new file with mode: 0644]
Test/hlsl.round.dx9.frag [new file with mode: 0644]
glslang/HLSL/hlslParseHelper.cpp
glslang/HLSL/hlslParseables.cpp
gtests/Hlsl.FromFile.cpp

diff --git a/Test/baseResults/hlsl.round.dx10.frag.out b/Test/baseResults/hlsl.round.dx10.frag.out
new file mode 100644 (file)
index 0000000..be72dc5
--- /dev/null
@@ -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 (file)
index 0000000..9333c7d
--- /dev/null
@@ -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 (file)
index 0000000..cd88334
--- /dev/null
@@ -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 (file)
index 0000000..cd88334
--- /dev/null
@@ -0,0 +1,4 @@
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+    return round(input);
+}
index ea31837..abe0f34 100644 (file)
@@ -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());
index 025cb5e..4673b46 100644 (file)
@@ -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);
index 4d1cb50..de071b9 100644 (file)
@@ -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<FileNameEntryPointPair>{
+        {"hlsl.round.dx9.frag", "main"},
         {"hlsl.sample.dx9.frag", "main"},
         {"hlsl.sample.dx9.vert", "main"},
     }),