Commit 088031e6 by Olli Etuaho Committed by Commit Bot

HLSL: Disambiguate between struct function parameters

Structs with different names but identical members are treated as ambiguous by the native HLSL compiler when looking up user-defined functions. Add the struct name to the function name to work around this limitation. BUG=chromium:731324 TEST=angle_end2end_tests Change-Id: Ie80ac0f1374bc5ac05dfebef3f94e2da7cdfc581 Reviewed-on: https://chromium-review.googlesource.com/558929 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 50c562de
...@@ -455,12 +455,21 @@ TString DisambiguateFunctionName(const TIntermSequence *parameters) ...@@ -455,12 +455,21 @@ TString DisambiguateFunctionName(const TIntermSequence *parameters)
for (auto parameter : *parameters) for (auto parameter : *parameters)
{ {
const TType &paramType = parameter->getAsTyped()->getType(); const TType &paramType = parameter->getAsTyped()->getType();
// Disambiguation is needed for float2x2 and float4 parameters. These are the only parameter // Parameter types are only added to function names if they are ambiguous according to the
// types that HLSL thinks are identical. float2x3 and float3x2 are different types, for // native HLSL compiler. Other parameter types are not added to function names to avoid
// example. Other parameter types are not added to function names to avoid making function // making function names longer.
// names longer.
if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat) if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
{ {
// Disambiguation is needed for float2x2 and float4 parameters. These are the only
// built-in types that HLSL thinks are identical. float2x3 and float3x2 are different
// types, for example.
disambiguatingString += "_" + TypeString(paramType);
}
else if (paramType.getBasicType() == EbtStruct)
{
// Disambiguation is needed for struct parameters, since HLSL thinks that structs with
// the same fields but a different name are identical.
ASSERT(paramType.getStruct()->name() != "");
disambiguatingString += "_" + TypeString(paramType); disambiguatingString += "_" + TypeString(paramType);
} }
} }
......
...@@ -3133,6 +3133,30 @@ TEST_P(GLSLTest, VariableHidesUserDefinedFunctionAfterInitializer) ...@@ -3133,6 +3133,30 @@ TEST_P(GLSLTest, VariableHidesUserDefinedFunctionAfterInitializer)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// Test that structs with identical members are not ambiguous as function arguments.
TEST_P(GLSLTest, StructsWithSameMembersDisambiguatedByName)
{
const std::string &fragmentShader =
"precision mediump float;\n"
"uniform float u_zero;\n"
"struct S { float foo; };\n"
"struct S2 { float foo; };\n"
"float get(S s) { return s.foo + u_zero; }\n"
"float get(S2 s2) { return 0.25 + s2.foo + u_zero; }\n"
"void main()\n"
"{\n"
" S s;\n"
" s.foo = 0.5;\n"
" S2 s2;\n"
" s2.foo = 0.25;\n"
" gl_FragColor = vec4(0.0, get(s) + get(s2), 0.0, 1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
drawQuad(program.get(), "inputAttribute", 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(GLSLTest, ANGLE_INSTANTIATE_TEST(GLSLTest,
ES2_D3D9(), ES2_D3D9(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment