Fix needStructMapping In previous logic, we didn't check the structure field member type. So when passing the non-struct member of a structure to a function, it would think that struct mapping was needed. In this patch, we add more checking so that struct mapping only happens when there are structure copy or passing a structure to a function. BUG=angleproject:2967 Change-Id: Ic98e884c8f8540e180cdf40a0e036ffef18c1689 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1638227 Commit-Queue: Jiajia Qin <jiajia.qin@intel.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp index 054dce9..3ff3ffd 100644 --- a/src/compiler/translator/OutputHLSL.cpp +++ b/src/compiler/translator/OutputHLSL.cpp
@@ -175,15 +175,27 @@ bool OutputHLSL::needStructMapping(TIntermTyped *node) { + ASSERT(node->getBasicType() == EbtStruct); for (unsigned int n = 0u; getAncestorNode(n) != nullptr; ++n) { TIntermNode *ancestor = getAncestorNode(n); const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode(); - if (ancestorBinary && ancestorBinary->getLeft()->getBasicType() == EbtStruct) + if (ancestorBinary) { switch (ancestorBinary->getOp()) { case EOpIndexDirectStruct: + { + const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct(); + const TIntermConstantUnion *index = + ancestorBinary->getRight()->getAsConstantUnion(); + const TField *field = structure->fields()[index->getIConst(0)]; + if (field->type()->getStruct() == nullptr) + { + return false; + } + break; + } case EOpIndexDirect: case EOpIndexIndirect: break;
diff --git a/src/tests/compiler_tests/HLSLOutput_test.cpp b/src/tests/compiler_tests/HLSLOutput_test.cpp index 8115977..feac602 100644 --- a/src/tests/compiler_tests/HLSLOutput_test.cpp +++ b/src/tests/compiler_tests/HLSLOutput_test.cpp
@@ -223,4 +223,33 @@ EXPECT_TRUE(foundInCode("_arr1029[2]")); // The unique id of the new array, arr, is 1030 EXPECT_TRUE(foundInCode("_arr1030[2]")); -} \ No newline at end of file +} + +// Test that passing a non-struct member of a std140 structure to a function won't trigger the +// struct mapping. +TEST_F(HLSLOutputTest, NonStructMemberAsFunctionArgument) +{ + constexpr char shaderString[] = R"(#version 300 es +precision highp float; +out vec4 my_FragColor; + +struct InstancingData +{ + vec4 data; +}; + +layout(std140) uniform InstanceBlock +{ + InstancingData instances[8]; +}; + +void main() +{ + int index = int(gl_FragCoord.x); + float result = dot(instances[index].data, vec4(1.0, 1.0, 1.0, 1.0)); + my_FragColor = vec4(result, 0.0, 0.0, 1.0); +})"; + + compile(shaderString); + EXPECT_FALSE(foundInCode("map_instances")); +}