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"));
+}