diff --git a/Test/baseResults/hlsl.clip.frag.out b/Test/baseResults/hlsl.clip.frag.out new file mode 100644 index 000000000..049bd8a2f --- /dev/null +++ b/Test/baseResults/hlsl.clip.frag.out @@ -0,0 +1,122 @@ +hlsl.clip.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:3 Function Definition: GetEntitySelectClip( ( temp float) +0:3 Function Parameters: +0:? Sequence +0:4 Branch: Return with expression +0:4 Constant: +0:4 1.000000 +0:8 Function Definition: @main( ( temp 4-component vector of float) +0:8 Function Parameters: +0:? Sequence +0:9 Test condition and select ( temp void) +0:9 Condition +0:9 Compare Less Than ( temp bool) +0:9 Function Call: GetEntitySelectClip( ( temp float) +0:9 Constant: +0:9 0.000000 +0:9 true case +0:9 Branch: Kill +0:11 Branch: Return with expression +0:11 Constant: +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:8 Function Definition: main( ( temp void) +0:8 Function Parameters: +0:? Sequence +0:8 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:8 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: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:3 Function Definition: GetEntitySelectClip( ( temp float) +0:3 Function Parameters: +0:? Sequence +0:4 Branch: Return with expression +0:4 Constant: +0:4 1.000000 +0:8 Function Definition: @main( ( temp 4-component vector of float) +0:8 Function Parameters: +0:? Sequence +0:9 Test condition and select ( temp void) +0:9 Condition +0:9 Compare Less Than ( temp bool) +0:9 Function Call: GetEntitySelectClip( ( temp float) +0:9 Constant: +0:9 0.000000 +0:9 true case +0:9 Branch: Kill +0:11 Branch: Return with expression +0:11 Constant: +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:8 Function Definition: main( ( temp void) +0:8 Function Parameters: +0:? Sequence +0:8 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:8 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 10000 +// Generated by (magic number): 80001 +// Id's are bound by 30 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 28 + ExecutionMode 4 OriginUpperLeft + Name 4 "main" + Name 8 "GetEntitySelectClip(" + Name 12 "@main(" + Name 28 "@entryPointOutput" + Decorate 28(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeFunction 6(float) + 10: TypeVector 6(float) 4 + 11: TypeFunction 10(fvec4) + 14: 6(float) Constant 1065353216 + 18: 6(float) Constant 0 + 19: TypeBool + 24: 10(fvec4) ConstantComposite 18 18 18 18 + 27: TypePointer Output 10(fvec4) +28(@entryPointOutput): 27(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 29: 10(fvec4) FunctionCall 12(@main() + Store 28(@entryPointOutput) 29 + Return + FunctionEnd +8(GetEntitySelectClip(): 6(float) Function None 7 + 9: Label + ReturnValue 14 + FunctionEnd + 12(@main(): 10(fvec4) Function None 11 + 13: Label + 17: 6(float) FunctionCall 8(GetEntitySelectClip() + 20: 19(bool) FOrdLessThan 17 18 + SelectionMerge 22 None + BranchConditional 20 21 22 + 21: Label + Kill + 22: Label + ReturnValue 24 + FunctionEnd diff --git a/Test/hlsl.clip.frag b/Test/hlsl.clip.frag new file mode 100644 index 000000000..a44c9e950 --- /dev/null +++ b/Test/hlsl.clip.frag @@ -0,0 +1,12 @@ + +float GetEntitySelectClip() +{ + return 1.0f; +} + +float4 main() : SV_TARGET +{ + clip(GetEntitySelectClip()); + + return 0; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index abc9e8d4f..fe4718297 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -93,6 +93,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.calculatelod.dx10.frag", "main"}, {"hlsl.calculatelodunclamped.dx10.frag", "main"}, {"hlsl.cast.frag", "PixelShaderFunction"}, + {"hlsl.clip.frag", "main"}, {"hlsl.comparison.vec.frag", "main"}, {"hlsl.conditional.frag", "PixelShaderFunction"}, {"hlsl.constructexpr.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 8b3a9936e..60ce1158c 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -2272,6 +2272,9 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte if (argAggregate == nullptr) return; + if (argAggregate->getSequence().empty()) + return; + // Buffer is the object upon which method is called, so always arg 0 TIntermTyped* bufferObj = argAggregate->getSequence()[0]->getAsTyped(); @@ -3747,7 +3750,9 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct // the symbol table for an arbitrary type. This is a temporary hack until that ability exists. // It will have false positives, since it doesn't check arg counts or types. if (arguments && arguments->getAsAggregate()) { - if (isStructBufferType(arguments->getAsAggregate()->getSequence()[0]->getAsTyped()->getType())) { + const TIntermSequence& sequence = arguments->getAsAggregate()->getSequence(); + + if (!sequence.empty() && isStructBufferType(sequence[0]->getAsTyped()->getType())) { static const int methodPrefixSize = sizeof(BUILTIN_PREFIX)-1; if (function->getName().length() > methodPrefixSize &&