diff --git a/Test/baseResults/hlsl.conditional.frag.out b/Test/baseResults/hlsl.conditional.frag.out index 193c78827c47ff82fb1bade45c82ddefdd0cabd6..f72e25b0938935d40cb21869575b27688a54bf0b 100755 --- a/Test/baseResults/hlsl.conditional.frag.out +++ b/Test/baseResults/hlsl.conditional.frag.out @@ -5,11 +5,38 @@ gl_FragCoord origin is upper left 0:8 Function Definition: vectorCond( ( temp 4-component vector of float) 0:8 Function Parameters: 0:? Sequence -0:9 Branch: Return with expression -0:9 f4: direct index for structure ( uniform 4-component vector of float) -0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) -0:9 Constant: -0:9 2 (const uint) +0:10 Branch: Return with expression +0:9 add ( temp 4-component vector of float) +0:9 mix ( temp 4-component vector of float) +0:9 f4: direct index for structure ( uniform 4-component vector of float) +0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:9 Constant: +0:9 2 (const uint) +0:9 t4: direct index for structure ( uniform 4-component vector of float) +0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:9 Constant: +0:9 1 (const uint) +0:9 Convert float to bool ( temp 4-component vector of bool) +0:9 c4: direct index for structure ( uniform 4-component vector of float) +0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:9 Constant: +0:9 0 (const uint) +0:10 mix ( temp 4-component vector of float) +0:10 Construct vec4 ( temp 4-component vector of float) +0:10 f: direct index for structure ( uniform float) +0:10 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:10 Constant: +0:10 4 (const uint) +0:10 Construct vec4 ( temp 4-component vector of float) +0:10 t: direct index for structure ( uniform float) +0:10 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:10 Constant: +0:10 3 (const uint) +0:10 Convert float to bool ( temp 4-component vector of bool) +0:10 c4: direct index for structure ( uniform 4-component vector of float) +0:10 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:10 Constant: +0:10 0 (const uint) 0:14 Function Definition: @PixelShaderFunction(vf4; ( temp 4-component vector of float) 0:14 Function Parameters: 0:14 'input' ( in 4-component vector of float) @@ -142,11 +169,38 @@ gl_FragCoord origin is upper left 0:8 Function Definition: vectorCond( ( temp 4-component vector of float) 0:8 Function Parameters: 0:? Sequence -0:9 Branch: Return with expression -0:9 f4: direct index for structure ( uniform 4-component vector of float) -0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) -0:9 Constant: -0:9 2 (const uint) +0:10 Branch: Return with expression +0:9 add ( temp 4-component vector of float) +0:9 mix ( temp 4-component vector of float) +0:9 f4: direct index for structure ( uniform 4-component vector of float) +0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:9 Constant: +0:9 2 (const uint) +0:9 t4: direct index for structure ( uniform 4-component vector of float) +0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:9 Constant: +0:9 1 (const uint) +0:9 Convert float to bool ( temp 4-component vector of bool) +0:9 c4: direct index for structure ( uniform 4-component vector of float) +0:9 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:9 Constant: +0:9 0 (const uint) +0:10 mix ( temp 4-component vector of float) +0:10 Construct vec4 ( temp 4-component vector of float) +0:10 f: direct index for structure ( uniform float) +0:10 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:10 Constant: +0:10 4 (const uint) +0:10 Construct vec4 ( temp 4-component vector of float) +0:10 t: direct index for structure ( uniform float) +0:10 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:10 Constant: +0:10 3 (const uint) +0:10 Convert float to bool ( temp 4-component vector of bool) +0:10 c4: direct index for structure ( uniform 4-component vector of float) +0:10 'anon@0' (layout( row_major std140) uniform block{ uniform 4-component vector of float c4, uniform 4-component vector of float t4, uniform 4-component vector of float f4, uniform float t, uniform float f}) +0:10 Constant: +0:10 0 (const uint) 0:14 Function Definition: @PixelShaderFunction(vf4; ( temp 4-component vector of float) 0:14 Function Parameters: 0:14 'input' ( in 4-component vector of float) @@ -271,12 +325,12 @@ gl_FragCoord origin is upper left // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 116 +// Id's are bound by 141 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Fragment 4 "PixelShaderFunction" 109 112 + EntryPoint Fragment 4 "PixelShaderFunction" 134 137 ExecutionMode 4 OriginUpperLeft Source HLSL 500 Name 4 "PixelShaderFunction" @@ -290,17 +344,17 @@ gl_FragCoord origin is upper left MemberName 16($Global) 3 "t" MemberName 16($Global) 4 "f" Name 18 "" - Name 27 "a" - Name 29 "b" - Name 31 "c" - Name 33 "d" - Name 34 "ret" - Name 54 "e" - Name 76 "f" - Name 107 "input" - Name 109 "input" - Name 112 "@entryPointOutput" - Name 113 "param" + Name 53 "a" + Name 55 "b" + Name 57 "c" + Name 59 "d" + Name 60 "ret" + Name 80 "e" + Name 101 "f" + Name 132 "input" + Name 134 "input" + Name 137 "@entryPointOutput" + Name 138 "param" MemberDecorate 16($Global) 0 Offset 0 MemberDecorate 16($Global) 1 Offset 16 MemberDecorate 16($Global) 2 Offset 32 @@ -308,8 +362,8 @@ gl_FragCoord origin is upper left MemberDecorate 16($Global) 4 Offset 52 Decorate 16($Global) Block Decorate 18 DescriptorSet 0 - Decorate 109(input) Location 0 - Decorate 112(@entryPointOutput) Location 0 + Decorate 134(input) Location 0 + Decorate 137(@entryPointOutput) Location 0 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -323,138 +377,163 @@ gl_FragCoord origin is upper left 19: TypeInt 32 1 20: 19(int) Constant 2 21: TypePointer Uniform 7(fvec4) - 26: TypePointer Function 19(int) - 28: 19(int) Constant 5 - 30: 19(int) Constant 6 - 32: 19(int) Constant 7 - 57: TypeBool - 58: TypeInt 32 0 - 59: 58(int) Constant 0 - 65: 19(int) Constant 10 - 74: 19(int) Constant 11 - 78: TypePointer Function 6(float) - 81: 58(int) Constant 1 - 108: TypePointer Input 7(fvec4) - 109(input): 108(ptr) Variable Input - 111: TypePointer Output 7(fvec4) -112(@entryPointOutput): 111(ptr) Variable Output + 24: 19(int) Constant 1 + 27: 19(int) Constant 0 + 30: TypeBool + 31: TypeVector 30(bool) 4 + 32: 6(float) Constant 0 + 33: 7(fvec4) ConstantComposite 32 32 32 32 + 36: 19(int) Constant 4 + 37: TypePointer Uniform 6(float) + 41: 19(int) Constant 3 + 52: TypePointer Function 19(int) + 54: 19(int) Constant 5 + 56: 19(int) Constant 6 + 58: 19(int) Constant 7 + 83: TypeInt 32 0 + 84: 83(int) Constant 0 + 90: 19(int) Constant 10 + 99: 19(int) Constant 11 + 103: TypePointer Function 6(float) + 106: 83(int) Constant 1 + 133: TypePointer Input 7(fvec4) + 134(input): 133(ptr) Variable Input + 136: TypePointer Output 7(fvec4) +137(@entryPointOutput): 136(ptr) Variable Output 4(PixelShaderFunction): 2 Function None 3 5: Label - 107(input): 11(ptr) Variable Function - 113(param): 11(ptr) Variable Function - 110: 7(fvec4) Load 109(input) - Store 107(input) 110 - 114: 7(fvec4) Load 107(input) - Store 113(param) 114 - 115: 7(fvec4) FunctionCall 14(@PixelShaderFunction(vf4;) 113(param) - Store 112(@entryPointOutput) 115 + 132(input): 11(ptr) Variable Function + 138(param): 11(ptr) Variable Function + 135: 7(fvec4) Load 134(input) + Store 132(input) 135 + 139: 7(fvec4) Load 132(input) + Store 138(param) 139 + 140: 7(fvec4) FunctionCall 14(@PixelShaderFunction(vf4;) 138(param) + Store 137(@entryPointOutput) 140 Return FunctionEnd 9(vectorCond(): 7(fvec4) Function None 8 10: Label 22: 21(ptr) AccessChain 18 20 23: 7(fvec4) Load 22 - ReturnValue 23 + 25: 21(ptr) AccessChain 18 24 + 26: 7(fvec4) Load 25 + 28: 21(ptr) AccessChain 18 27 + 29: 7(fvec4) Load 28 + 34: 31(bvec4) FOrdNotEqual 29 33 + 35: 7(fvec4) Select 34 26 23 + 38: 37(ptr) AccessChain 18 36 + 39: 6(float) Load 38 + 40: 7(fvec4) CompositeConstruct 39 39 39 39 + 42: 37(ptr) AccessChain 18 41 + 43: 6(float) Load 42 + 44: 7(fvec4) CompositeConstruct 43 43 43 43 + 45: 21(ptr) AccessChain 18 27 + 46: 7(fvec4) Load 45 + 47: 31(bvec4) FOrdNotEqual 46 33 + 48: 7(fvec4) Select 47 44 40 + 49: 7(fvec4) FAdd 35 48 + ReturnValue 49 FunctionEnd 14(@PixelShaderFunction(vf4;): 7(fvec4) Function None 12 13(input): 11(ptr) FunctionParameter 15: Label - 27(a): 26(ptr) Variable Function - 29(b): 26(ptr) Variable Function - 31(c): 26(ptr) Variable Function - 33(d): 26(ptr) Variable Function - 34(ret): 11(ptr) Variable Function - 54(e): 26(ptr) Variable Function - 55: 26(ptr) Variable Function - 67: 26(ptr) Variable Function - 76(f): 11(ptr) Variable Function - 77: 11(ptr) Variable Function - Store 27(a) 28 - Store 29(b) 30 - Store 31(c) 32 - Store 33(d) 32 - 35: 19(int) Load 27(a) - 36: 6(float) ConvertSToF 35 - 37: 7(fvec4) Load 13(input) - 38: 7(fvec4) VectorTimesScalar 37 36 - 39: 19(int) Load 29(b) - 40: 6(float) ConvertSToF 39 - 41: 7(fvec4) Load 13(input) - 42: 7(fvec4) VectorTimesScalar 41 40 - 43: 7(fvec4) FAdd 38 42 - 44: 19(int) Load 31(c) - 45: 6(float) ConvertSToF 44 - 46: 7(fvec4) Load 13(input) - 47: 7(fvec4) VectorTimesScalar 46 45 - 48: 7(fvec4) FAdd 43 47 - 49: 19(int) Load 33(d) - 50: 6(float) ConvertSToF 49 - 51: 7(fvec4) Load 13(input) - 52: 7(fvec4) VectorTimesScalar 51 50 - 53: 7(fvec4) FAdd 48 52 - Store 34(ret) 53 - 56: 19(int) Load 29(b) - 60: 57(bool) INotEqual 56 59 - SelectionMerge 62 None - BranchConditional 60 61 64 - 61: Label - 63: 19(int) Load 33(d) - Store 31(c) 63 - Store 55 63 - Branch 62 - 64: Label - Store 55 65 - Branch 62 - 62: Label - 66: 19(int) Load 55 - Store 27(a) 66 - Store 54(e) 66 - 68: 19(int) Load 27(a) - 69: 57(bool) INotEqual 68 59 - SelectionMerge 71 None - BranchConditional 69 70 73 - 70: Label - 72: 19(int) Load 31(c) - Store 33(d) 72 - Store 67 72 - Branch 71 - 73: Label - Store 67 74 - Branch 71 - 71: Label - 75: 19(int) Load 67 - Store 29(b) 75 - 79: 78(ptr) AccessChain 34(ret) 59 - 80: 6(float) Load 79 - 82: 78(ptr) AccessChain 13(input) 81 - 83: 6(float) Load 82 - 84: 57(bool) FOrdLessThan 80 83 - SelectionMerge 86 None - BranchConditional 84 85 91 - 85: Label - 87: 19(int) Load 31(c) - 88: 6(float) ConvertSToF 87 - 89: 7(fvec4) Load 13(input) - 90: 7(fvec4) VectorTimesScalar 89 88 - Store 77 90 - Branch 86 - 91: Label - 92: 19(int) Load 33(d) - 93: 6(float) ConvertSToF 92 - 94: 7(fvec4) Load 13(input) - 95: 7(fvec4) VectorTimesScalar 94 93 - Store 77 95 - Branch 86 - 86: Label - 96: 7(fvec4) Load 77 - Store 76(f) 96 - 97: 19(int) Load 54(e) - 98: 6(float) ConvertSToF 97 - 99: 7(fvec4) Load 34(ret) - 100: 7(fvec4) VectorTimesScalar 99 98 - 101: 7(fvec4) Load 76(f) - 102: 7(fvec4) FAdd 100 101 - 103: 7(fvec4) FunctionCall 9(vectorCond() - 104: 7(fvec4) FAdd 102 103 - ReturnValue 104 + 53(a): 52(ptr) Variable Function + 55(b): 52(ptr) Variable Function + 57(c): 52(ptr) Variable Function + 59(d): 52(ptr) Variable Function + 60(ret): 11(ptr) Variable Function + 80(e): 52(ptr) Variable Function + 81: 52(ptr) Variable Function + 92: 52(ptr) Variable Function + 101(f): 11(ptr) Variable Function + 102: 11(ptr) Variable Function + Store 53(a) 54 + Store 55(b) 56 + Store 57(c) 58 + Store 59(d) 58 + 61: 19(int) Load 53(a) + 62: 6(float) ConvertSToF 61 + 63: 7(fvec4) Load 13(input) + 64: 7(fvec4) VectorTimesScalar 63 62 + 65: 19(int) Load 55(b) + 66: 6(float) ConvertSToF 65 + 67: 7(fvec4) Load 13(input) + 68: 7(fvec4) VectorTimesScalar 67 66 + 69: 7(fvec4) FAdd 64 68 + 70: 19(int) Load 57(c) + 71: 6(float) ConvertSToF 70 + 72: 7(fvec4) Load 13(input) + 73: 7(fvec4) VectorTimesScalar 72 71 + 74: 7(fvec4) FAdd 69 73 + 75: 19(int) Load 59(d) + 76: 6(float) ConvertSToF 75 + 77: 7(fvec4) Load 13(input) + 78: 7(fvec4) VectorTimesScalar 77 76 + 79: 7(fvec4) FAdd 74 78 + Store 60(ret) 79 + 82: 19(int) Load 55(b) + 85: 30(bool) INotEqual 82 84 + SelectionMerge 87 None + BranchConditional 85 86 89 + 86: Label + 88: 19(int) Load 59(d) + Store 57(c) 88 + Store 81 88 + Branch 87 + 89: Label + Store 81 90 + Branch 87 + 87: Label + 91: 19(int) Load 81 + Store 53(a) 91 + Store 80(e) 91 + 93: 19(int) Load 53(a) + 94: 30(bool) INotEqual 93 84 + SelectionMerge 96 None + BranchConditional 94 95 98 + 95: Label + 97: 19(int) Load 57(c) + Store 59(d) 97 + Store 92 97 + Branch 96 + 98: Label + Store 92 99 + Branch 96 + 96: Label + 100: 19(int) Load 92 + Store 55(b) 100 + 104: 103(ptr) AccessChain 60(ret) 84 + 105: 6(float) Load 104 + 107: 103(ptr) AccessChain 13(input) 106 + 108: 6(float) Load 107 + 109: 30(bool) FOrdLessThan 105 108 + SelectionMerge 111 None + BranchConditional 109 110 116 + 110: Label + 112: 19(int) Load 57(c) + 113: 6(float) ConvertSToF 112 + 114: 7(fvec4) Load 13(input) + 115: 7(fvec4) VectorTimesScalar 114 113 + Store 102 115 + Branch 111 + 116: Label + 117: 19(int) Load 59(d) + 118: 6(float) ConvertSToF 117 + 119: 7(fvec4) Load 13(input) + 120: 7(fvec4) VectorTimesScalar 119 118 + Store 102 120 + Branch 111 + 111: Label + 121: 7(fvec4) Load 102 + Store 101(f) 121 + 122: 19(int) Load 80(e) + 123: 6(float) ConvertSToF 122 + 124: 7(fvec4) Load 60(ret) + 125: 7(fvec4) VectorTimesScalar 124 123 + 126: 7(fvec4) Load 101(f) + 127: 7(fvec4) FAdd 125 126 + 128: 7(fvec4) FunctionCall 9(vectorCond() + 129: 7(fvec4) FAdd 127 128 + ReturnValue 129 FunctionEnd diff --git a/Test/hlsl.conditional.frag b/Test/hlsl.conditional.frag index 8efef351cc7e09e8302696dfa7ed69de658f2dbb..69ff8f7e2a05b14f14cde35cb29396b631a002a6 100644 --- a/Test/hlsl.conditional.frag +++ b/Test/hlsl.conditional.frag @@ -6,8 +6,8 @@ float f; float4 vectorCond() { - return f4; // return (c4 ? t4 : f4) + -// (c4 ? t : f ); + return (c4 ? t4 : f4) + + (c4 ? t : f ); } float4 PixelShaderFunction(float4 input) : COLOR0 diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 85c0151deb0e18585a17bed1ca6c9b61cb73ecd1..b4999a927ce430f15a911208860f4d52c940e642 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -1271,7 +1271,8 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, // // For "?:" test nodes. There are three children; a condition, // a true path, and a false path. The two paths are specified -// as separate parameters. +// as separate parameters. For vector 'cond', the true and false +// are not paths, but vectors to mix. // // Specialization constant operations include // - The ternary operator ( ? : ) @@ -1304,10 +1305,30 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true if (falseBlock->getType() != trueBlock->getType()) return nullptr; - // - // See if all the operands are constant, then fold it otherwise not. - // + // Handle a vector condition as a mix + if (!cond->getType().isScalarOrVec1()) { + TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary, + cond->getType().getVectorSize()); + // smear true/false operations if needed + if (trueBlock->getType().isScalarOrVec1()) + trueBlock = addShapeConversion(EOpAssign, targetVectorType, trueBlock); + if (falseBlock->getType().isScalarOrVec1()) + falseBlock = addShapeConversion(EOpAssign, targetVectorType, falseBlock); + + // make the mix operation + TIntermAggregate* mix = makeAggregate(loc); + mix = growAggregate(mix, falseBlock); + mix = growAggregate(mix, trueBlock); + mix = growAggregate(mix, cond); + mix->setType(targetVectorType); + mix->setOp(EOpMix); + + return mix; + } + + // Now have a scalar condition... + // Eliminate the selection when the condition is a scalar and all operands are constant. if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) { if (cond->getAsConstantUnion()->getConstArray()[0].getBConst()) return trueBlock; diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 8e66c04a097efbc28912501790ffdf2fc648e80f..f58f74204c37cc1cf6d44b81e55a0a873ae8fd94 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -2536,7 +2536,7 @@ bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node) if (! acceptTokenClass(EHTokQuestion)) return true; - node = parseContext.convertConditionalExpression(token.loc, node); + node = parseContext.convertConditionalExpression(token.loc, node, false); if (node == nullptr) return false; diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 142604eaaa6b098176bd82897e4f177b1706d2cf..67da2e990643ffc03236610d4dd07e2ec1687492 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -4529,9 +4529,9 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi // Convert to a scalar boolean, or if not allowed by HLSL semantics, // report an error and return nullptr. -TIntermTyped* HlslParseContext::convertConditionalExpression(const TSourceLoc& loc, TIntermTyped* condition) +TIntermTyped* HlslParseContext::convertConditionalExpression(const TSourceLoc& loc, TIntermTyped* condition, bool mustBeScalar) { - if (!condition->getType().isScalarOrVec1()) { + if (mustBeScalar && !condition->getType().isScalarOrVec1()) { error(loc, "requires a scalar", "conditional expression", ""); return nullptr; } diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 14c9809ea4874b815d5d4c45f0360a5027841116..947fef771de3d847a80d2fe36c9a8e064f80fe36 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -102,7 +102,7 @@ public: const glslang::TString* component); void handleRegister(const TSourceLoc&, TQualifier&, const glslang::TString* profile, const glslang::TString& desc, int subComponent, const glslang::TString*); - TIntermTyped* convertConditionalExpression(const TSourceLoc&, TIntermTyped*); + TIntermTyped* convertConditionalExpression(const TSourceLoc&, TIntermTyped*, bool mustBeScalar = true); TIntermAggregate* handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler); bool parseMatrixSwizzleSelector(const TSourceLoc&, const TString&, int cols, int rows, TSwizzleSelectors<TMatrixSelector>&);