Commit 06a06f5e by Olli Etuaho

Fix non statically used fragment input structs on HLSL

Add static use information to struct fields that mirrors the static use information on the struct itself. This way dynamically generated HLSL doesn't need special handling for initializing fragment inputs if they are structs. This fixes a problem with the previous code where dynamically generated HLSL ended up trying to initialize structs that are not declared in the HLSL output because they were not being referenced. BUG=angleproject:2104 TEST=angle_end2end_tests Change-Id: I21283ce4fe26515d62d95e61f8155dc9a9b44cf1
parent b74c769a
...@@ -66,6 +66,24 @@ VarT *FindVariable(const TString &name, std::vector<VarT> *infoList) ...@@ -66,6 +66,24 @@ VarT *FindVariable(const TString &name, std::vector<VarT> *infoList)
return nullptr; return nullptr;
} }
// Note that this shouldn't be called for interface blocks - static use information is collected for
// individual fields in case of interface blocks.
void MarkStaticallyUsed(ShaderVariable *variable)
{
if (!variable->staticUse)
{
if (variable->isStruct())
{
// Conservatively assume all fields are statically used as well.
for (auto &field : variable->fields)
{
MarkStaticallyUsed(&field);
}
}
variable->staticUse = true;
}
}
// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs, // Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
// and interface blocks. // and interface blocks.
class CollectVariablesTraverser : public TIntermTraverser class CollectVariablesTraverser : public TIntermTraverser
...@@ -406,7 +424,7 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol) ...@@ -406,7 +424,7 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
} }
if (var) if (var)
{ {
var->staticUse = true; MarkStaticallyUsed(var);
} }
} }
......
...@@ -2388,7 +2388,8 @@ std::vector<PackedVarying> Program::getPackedVaryings( ...@@ -2388,7 +2388,8 @@ std::vector<PackedVarying> Program::getPackedVaryings(
// Will get the vertex shader interpolation by default. // Will get the vertex shader interpolation by default.
auto interpolation = ref.second.get()->interpolation; auto interpolation = ref.second.get()->interpolation;
// Interpolation qualifiers must match. // Note that we lose the vertex shader static use information here. The data for the
// variable is taken from the fragment shader.
if (output->isStruct()) if (output->isStruct())
{ {
ASSERT(!output->isArray()); ASSERT(!output->isArray());
......
...@@ -741,10 +741,9 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, ...@@ -741,10 +741,9 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
const auto &varying = *packedVarying.varying; const auto &varying = *packedVarying.varying;
ASSERT(!varying.isBuiltIn() && !varying.isStruct()); ASSERT(!varying.isBuiltIn() && !varying.isStruct());
// Don't reference VS-only transform feedback varyings in the PS. // Don't reference VS-only transform feedback varyings in the PS. Note that we're relying on
// TODO: Consider updating the fragment shader's varyings with a parameter signaling that a // that the staticUse flag is set according to usage in the fragment shader.
// varying is only used in the vertex shader in MergeVaryings if (packedVarying.vertexOnly || !varying.staticUse)
if (packedVarying.vertexOnly || (!varying.staticUse && !packedVarying.isStructField()))
continue; continue;
pixelStream << " "; pixelStream << " ";
......
...@@ -3157,6 +3157,100 @@ TEST_P(GLSLTest, StructsWithSameMembersDisambiguatedByName) ...@@ -3157,6 +3157,100 @@ TEST_P(GLSLTest, StructsWithSameMembersDisambiguatedByName)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// Test that a varying struct that's not statically used in the fragment shader works.
// GLSL ES 3.00.6 section 4.3.10.
TEST_P(GLSLTest_ES3, VaryingStructNotStaticallyUsedInFragmentShader)
{
const std::string &vertexShader =
"#version 300 es\n"
"struct S {\n"
" vec4 field;\n"
"};\n"
"out S varStruct;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(1.0);\n"
" varStruct.field = vec4(0.0, 0.5, 0.0, 0.0);\n"
"}\n";
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"struct S {\n"
" vec4 field;\n"
"};\n"
"in S varStruct;\n"
"out vec4 col;\n"
"void main()\n"
"{\n"
" col = vec4(1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
}
// Test that a varying struct that's not declared in the fragment shader links successfully.
// GLSL ES 3.00.6 section 4.3.10.
TEST_P(GLSLTest_ES3, VaryingStructNotDeclaredInFragmentShader)
{
const std::string &vertexShader =
"#version 300 es\n"
"struct S {\n"
" vec4 field;\n"
"};\n"
"out S varStruct;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(1.0);\n"
" varStruct.field = vec4(0.0, 0.5, 0.0, 0.0);\n"
"}\n";
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 col;\n"
"void main()\n"
"{\n"
" col = vec4(1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
}
// Test that a varying struct that gets used in the fragment shader works.
TEST_P(GLSLTest_ES3, VaryingStructUsedInFragmentShader)
{
const std::string &vertexShader =
"#version 300 es\n"
"in vec4 inputAttribute;\n"
"struct S {\n"
" vec4 field;\n"
"};\n"
"out S varStruct;\n"
"void main()\n"
"{\n"
" gl_Position = inputAttribute;\n"
" varStruct.field = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}\n";
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 col;\n"
"struct S {\n"
" vec4 field;\n"
"};\n"
"in S varStruct;\n"
"void main()\n"
"{\n"
" col = varStruct.field;\n"
"}\n";
ANGLE_GL_PROGRAM(program, vertexShader, 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