From b16bea801c6a61b214d52af509163ba8c576ea5c Mon Sep 17 00:00:00 2001 From: "t.jung" <t.jung@gaijin.ru> Date: Thu, 15 Nov 2018 10:21:36 +0100 Subject: [PATCH] [HLSL/Spir-V] fix for incorrect spir-v on int dot(int, int) Decomposes OpDot into corresponding multiplies and additions. --- SPIRV/GlslangToSpv.cpp | 11 + Test/baseResults/hlsl.int.dot.frag.out | 339 +++++++++++++++++++++++++ Test/hlsl.int.dot.frag | 14 + gtests/Hlsl.FromFile.cpp | 3 +- 4 files changed, 366 insertions(+), 1 deletion(-) create mode 100644 Test/baseResults/hlsl.int.dot.frag.out create mode 100644 Test/hlsl.int.dot.frag diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 3569001cf..4a59ffe62 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -6914,6 +6914,17 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: // We might need the remaining arguments, e.g. in the EOpFrexp case. std::vector<spv::Id> callArguments(operands.begin(), operands.begin() + consumedOperands); id = builder.createBuiltinCall(typeId, extBuiltins >= 0 ? extBuiltins : stdBuiltins, libCall, callArguments); + } else if (opCode == spv::OpDot && !isFloat) { + // int dot(int, int) + // NOTE: never called for scalar/vector1, this is turned into simple mul before this can be reached + const int componentCount = builder.getNumComponents(operands[0]); + spv::Id mulOp = builder.createBinOp(spv::OpIMul, builder.getTypeId(operands[0]), operands[0], operands[1]); + builder.setPrecision(mulOp, precision); + id = builder.createCompositeExtract(mulOp, typeId, 0); + for (int i = 1; i < componentCount; ++i) { + builder.setPrecision(id, precision); + id = builder.createBinOp(spv::OpIAdd, typeId, id, builder.createCompositeExtract(operands[0], typeId, i)); + } } else { switch (consumedOperands) { case 0: diff --git a/Test/baseResults/hlsl.int.dot.frag.out b/Test/baseResults/hlsl.int.dot.frag.out new file mode 100644 index 000000000..afe44c85e --- /dev/null +++ b/Test/baseResults/hlsl.int.dot.frag.out @@ -0,0 +1,339 @@ +hlsl.int.dot.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:1 Function Definition: @main( ( temp 4-component vector of float) +0:1 Function Parameters: +0:? Sequence +0:2 Sequence +0:2 move second child to first child ( temp int) +0:2 'i' ( temp int) +0:2 Constant: +0:2 1 (const int) +0:3 Sequence +0:3 move second child to first child ( temp 1-component vector of int) +0:3 'i2' ( temp 1-component vector of int) +0:3 Constant: +0:3 2 (const int) +0:4 Sequence +0:4 move second child to first child ( temp 2-component vector of int) +0:4 'i3' ( temp 2-component vector of int) +0:4 Constant: +0:4 3 (const int) +0:4 3 (const int) +0:5 Sequence +0:5 move second child to first child ( temp 3-component vector of int) +0:5 'i4' ( temp 3-component vector of int) +0:5 Constant: +0:5 4 (const int) +0:5 4 (const int) +0:5 4 (const int) +0:6 Sequence +0:6 move second child to first child ( temp 4-component vector of int) +0:6 'i5' ( temp 4-component vector of int) +0:6 Constant: +0:6 5 (const int) +0:6 5 (const int) +0:6 5 (const int) +0:6 5 (const int) +0:8 move second child to first child ( temp int) +0:8 'i' ( temp int) +0:8 dot-product ( temp int) +0:8 'i' ( temp int) +0:8 'i' ( temp int) +0:9 move second child to first child ( temp 1-component vector of int) +0:9 'i2' ( temp 1-component vector of int) +0:9 Construct int ( temp 1-component vector of int) +0:9 dot-product ( temp int) +0:9 Construct int ( in int) +0:9 'i2' ( temp 1-component vector of int) +0:9 Construct int ( in int) +0:9 'i2' ( temp 1-component vector of int) +0:10 move second child to first child ( temp 2-component vector of int) +0:10 'i3' ( temp 2-component vector of int) +0:10 Construct ivec2 ( temp 2-component vector of int) +0:10 dot-product ( temp int) +0:10 'i3' ( temp 2-component vector of int) +0:10 'i3' ( temp 2-component vector of int) +0:11 move second child to first child ( temp 3-component vector of int) +0:11 'i4' ( temp 3-component vector of int) +0:11 Construct ivec3 ( temp 3-component vector of int) +0:11 dot-product ( temp int) +0:11 'i4' ( temp 3-component vector of int) +0:11 'i4' ( temp 3-component vector of int) +0:12 move second child to first child ( temp 4-component vector of int) +0:12 'i5' ( temp 4-component vector of int) +0:12 Construct ivec4 ( temp 4-component vector of int) +0:12 dot-product ( temp int) +0:12 'i5' ( temp 4-component vector of int) +0:12 'i5' ( temp 4-component vector of int) +0:13 Branch: Return with expression +0:13 Convert int to float ( temp 4-component vector of float) +0:13 add ( temp 4-component vector of int) +0:13 add ( temp 4-component vector of int) +0:13 add ( temp 4-component vector of int) +0:13 add ( temp 4-component vector of int) +0:13 'i' ( temp int) +0:13 Construct ivec4 ( temp 4-component vector of int) +0:13 Construct int ( temp int) +0:13 'i2' ( temp 1-component vector of int) +0:13 vector swizzle ( temp 4-component vector of int) +0:13 'i3' ( temp 2-component vector of int) +0:13 Sequence +0:13 Constant: +0:13 0 (const int) +0:13 Constant: +0:13 1 (const int) +0:13 Constant: +0:13 0 (const int) +0:13 Constant: +0:13 1 (const int) +0:13 vector swizzle ( temp 4-component vector of int) +0:13 'i4' ( temp 3-component vector of int) +0:13 Sequence +0:13 Constant: +0:13 0 (const int) +0:13 Constant: +0:13 1 (const int) +0:13 Constant: +0:13 2 (const int) +0:13 Constant: +0:13 0 (const int) +0:13 'i5' ( temp 4-component vector of int) +0:1 Function Definition: main( ( temp void) +0:1 Function Parameters: +0:? Sequence +0:1 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:1 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + + +Linked fragment stage: + + +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:1 Function Definition: @main( ( temp 4-component vector of float) +0:1 Function Parameters: +0:? Sequence +0:2 Sequence +0:2 move second child to first child ( temp int) +0:2 'i' ( temp int) +0:2 Constant: +0:2 1 (const int) +0:3 Sequence +0:3 move second child to first child ( temp 1-component vector of int) +0:3 'i2' ( temp 1-component vector of int) +0:3 Constant: +0:3 2 (const int) +0:4 Sequence +0:4 move second child to first child ( temp 2-component vector of int) +0:4 'i3' ( temp 2-component vector of int) +0:4 Constant: +0:4 3 (const int) +0:4 3 (const int) +0:5 Sequence +0:5 move second child to first child ( temp 3-component vector of int) +0:5 'i4' ( temp 3-component vector of int) +0:5 Constant: +0:5 4 (const int) +0:5 4 (const int) +0:5 4 (const int) +0:6 Sequence +0:6 move second child to first child ( temp 4-component vector of int) +0:6 'i5' ( temp 4-component vector of int) +0:6 Constant: +0:6 5 (const int) +0:6 5 (const int) +0:6 5 (const int) +0:6 5 (const int) +0:8 move second child to first child ( temp int) +0:8 'i' ( temp int) +0:8 dot-product ( temp int) +0:8 'i' ( temp int) +0:8 'i' ( temp int) +0:9 move second child to first child ( temp 1-component vector of int) +0:9 'i2' ( temp 1-component vector of int) +0:9 Construct int ( temp 1-component vector of int) +0:9 dot-product ( temp int) +0:9 Construct int ( in int) +0:9 'i2' ( temp 1-component vector of int) +0:9 Construct int ( in int) +0:9 'i2' ( temp 1-component vector of int) +0:10 move second child to first child ( temp 2-component vector of int) +0:10 'i3' ( temp 2-component vector of int) +0:10 Construct ivec2 ( temp 2-component vector of int) +0:10 dot-product ( temp int) +0:10 'i3' ( temp 2-component vector of int) +0:10 'i3' ( temp 2-component vector of int) +0:11 move second child to first child ( temp 3-component vector of int) +0:11 'i4' ( temp 3-component vector of int) +0:11 Construct ivec3 ( temp 3-component vector of int) +0:11 dot-product ( temp int) +0:11 'i4' ( temp 3-component vector of int) +0:11 'i4' ( temp 3-component vector of int) +0:12 move second child to first child ( temp 4-component vector of int) +0:12 'i5' ( temp 4-component vector of int) +0:12 Construct ivec4 ( temp 4-component vector of int) +0:12 dot-product ( temp int) +0:12 'i5' ( temp 4-component vector of int) +0:12 'i5' ( temp 4-component vector of int) +0:13 Branch: Return with expression +0:13 Convert int to float ( temp 4-component vector of float) +0:13 add ( temp 4-component vector of int) +0:13 add ( temp 4-component vector of int) +0:13 add ( temp 4-component vector of int) +0:13 add ( temp 4-component vector of int) +0:13 'i' ( temp int) +0:13 Construct ivec4 ( temp 4-component vector of int) +0:13 Construct int ( temp int) +0:13 'i2' ( temp 1-component vector of int) +0:13 vector swizzle ( temp 4-component vector of int) +0:13 'i3' ( temp 2-component vector of int) +0:13 Sequence +0:13 Constant: +0:13 0 (const int) +0:13 Constant: +0:13 1 (const int) +0:13 Constant: +0:13 0 (const int) +0:13 Constant: +0:13 1 (const int) +0:13 vector swizzle ( temp 4-component vector of int) +0:13 'i4' ( temp 3-component vector of int) +0:13 Sequence +0:13 Constant: +0:13 0 (const int) +0:13 Constant: +0:13 1 (const int) +0:13 Constant: +0:13 2 (const int) +0:13 Constant: +0:13 0 (const int) +0:13 'i5' ( temp 4-component vector of int) +0:1 Function Definition: main( ( temp void) +0:1 Function Parameters: +0:? Sequence +0:1 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:1 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + +// Module Version 10300 +// Generated by (magic number): 80007 +// Id's are bound by 84 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 82 + ExecutionMode 4 OriginUpperLeft + Source HLSL 500 + Name 4 "main" + Name 9 "@main(" + Name 13 "i" + Name 15 "i2" + Name 19 "i3" + Name 24 "i4" + Name 29 "i5" + Name 82 "@entryPointOutput" + Decorate 82(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeFunction 7(fvec4) + 11: TypeInt 32 1 + 12: TypePointer Function 11(int) + 14: 11(int) Constant 1 + 16: 11(int) Constant 2 + 17: TypeVector 11(int) 2 + 18: TypePointer Function 17(ivec2) + 20: 11(int) Constant 3 + 21: 17(ivec2) ConstantComposite 20 20 + 22: TypeVector 11(int) 3 + 23: TypePointer Function 22(ivec3) + 25: 11(int) Constant 4 + 26: 22(ivec3) ConstantComposite 25 25 25 + 27: TypeVector 11(int) 4 + 28: TypePointer Function 27(ivec4) + 30: 11(int) Constant 5 + 31: 27(ivec4) ConstantComposite 30 30 30 30 + 81: TypePointer Output 7(fvec4) +82(@entryPointOutput): 81(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 83: 7(fvec4) FunctionCall 9(@main() + Store 82(@entryPointOutput) 83 + Return + FunctionEnd + 9(@main(): 7(fvec4) Function None 8 + 10: Label + 13(i): 12(ptr) Variable Function + 15(i2): 12(ptr) Variable Function + 19(i3): 18(ptr) Variable Function + 24(i4): 23(ptr) Variable Function + 29(i5): 28(ptr) Variable Function + Store 13(i) 14 + Store 15(i2) 16 + Store 19(i3) 21 + Store 24(i4) 26 + Store 29(i5) 31 + 32: 11(int) Load 13(i) + 33: 11(int) Load 13(i) + 34: 11(int) IMul 32 33 + Store 13(i) 34 + 35: 11(int) Load 15(i2) + 36: 11(int) Load 15(i2) + 37: 11(int) IMul 35 36 + Store 15(i2) 37 + 38: 17(ivec2) Load 19(i3) + 39: 17(ivec2) Load 19(i3) + 40: 17(ivec2) IMul 38 39 + 41: 11(int) CompositeExtract 40 0 + 42: 11(int) CompositeExtract 38 1 + 43: 11(int) IAdd 41 42 + 44: 17(ivec2) CompositeConstruct 43 43 + Store 19(i3) 44 + 45: 22(ivec3) Load 24(i4) + 46: 22(ivec3) Load 24(i4) + 47: 22(ivec3) IMul 45 46 + 48: 11(int) CompositeExtract 47 0 + 49: 11(int) CompositeExtract 45 1 + 50: 11(int) IAdd 48 49 + 51: 11(int) CompositeExtract 45 2 + 52: 11(int) IAdd 50 51 + 53: 22(ivec3) CompositeConstruct 52 52 52 + Store 24(i4) 53 + 54: 27(ivec4) Load 29(i5) + 55: 27(ivec4) Load 29(i5) + 56: 27(ivec4) IMul 54 55 + 57: 11(int) CompositeExtract 56 0 + 58: 11(int) CompositeExtract 54 1 + 59: 11(int) IAdd 57 58 + 60: 11(int) CompositeExtract 54 2 + 61: 11(int) IAdd 59 60 + 62: 11(int) CompositeExtract 54 3 + 63: 11(int) IAdd 61 62 + 64: 27(ivec4) CompositeConstruct 63 63 63 63 + Store 29(i5) 64 + 65: 11(int) Load 13(i) + 66: 11(int) Load 15(i2) + 67: 27(ivec4) CompositeConstruct 66 66 66 66 + 68: 27(ivec4) CompositeConstruct 65 65 65 65 + 69: 27(ivec4) IAdd 68 67 + 70: 17(ivec2) Load 19(i3) + 71: 27(ivec4) VectorShuffle 70 70 0 1 0 1 + 72: 27(ivec4) IAdd 69 71 + 73: 22(ivec3) Load 24(i4) + 74: 27(ivec4) VectorShuffle 73 73 0 1 2 0 + 75: 27(ivec4) IAdd 72 74 + 76: 27(ivec4) Load 29(i5) + 77: 27(ivec4) IAdd 75 76 + 78: 7(fvec4) ConvertSToF 77 + ReturnValue 78 + FunctionEnd diff --git a/Test/hlsl.int.dot.frag b/Test/hlsl.int.dot.frag new file mode 100644 index 000000000..c293dc14b --- /dev/null +++ b/Test/hlsl.int.dot.frag @@ -0,0 +1,14 @@ +float4 main() : SV_Target { + int i = 1; + int1 i2 = 2; + int2 i3 = 3; + int3 i4 = 4; + int4 i5 = 5; + + i = dot(i, i); + i2 = dot(i2, i2); + i3 = dot(i3, i3); + i4 = dot(i4, i4); + i5 = dot(i5, i5); + return i + i2.xxxx + i3.xyxy + i4.xyzx + i5; +} \ No newline at end of file diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index a490ba0a5..809e52579 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -400,7 +400,8 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.wavequery.frag", "PixelShaderFunction"}, {"hlsl.wavereduction.comp", "CSMain"}, {"hlsl.wavevote.comp", "CSMain"}, - { "hlsl.type.type.conversion.valid.frag", "main" } + { "hlsl.type.type.conversion.valid.frag", "main" }, + {"hlsl.int.dot.frag", "main"} }), FileNameAsCustomTestSuffix ); -- GitLab