Commit 84db5733 by Commit Bot Committed by Gerrit Code Review

Merge "Fix non statically used fragment input structs on HLSL"

parents e2a728aa 06a06f5e
...@@ -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);
} }
} }
......
...@@ -2477,7 +2477,8 @@ std::vector<PackedVarying> Program::getPackedVaryings( ...@@ -2477,7 +2477,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