Commit 08b9ad57 by Le Hoang Quyen Committed by Commit Bot

Metal: Prevent vertex shader's inactive varying from being removed

If vertex shader declares a varying but doesn't use it, and this varying is being used in fragment shader, linking will fail because the varying would be removed by spirv-cross. Fix: initilize the unused varying with zero(s). New test: GLSLTest.InactiveVaryingInVertexActiveInFragment. Bug: angleproject:2634 Change-Id: Ia37acd8eea85d5da4ddbca6457d6cddb1b41662c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2281796 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 82359f92
......@@ -18,7 +18,12 @@
#include "common/utilities.h"
#include "compiler/translator/OutputVulkanGLSLForMetal.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/tree_ops/InitializeVariables.h"
#include "compiler/translator/tree_util/BuiltIn.h"
#include "compiler/translator/tree_util/FindMain.h"
#include "compiler/translator/tree_util/FindSymbolNode.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/ReplaceVariable.h"
#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
#include "compiler/translator/util.h"
......@@ -79,6 +84,41 @@ ANGLE_NO_DISCARD bool AppendVertexShaderPositionYCorrectionToMain(TCompiler *com
return RunAtTheEndOfShader(compiler, root, assignment, symbolTable);
}
// Initialize unused varying outputs.
ANGLE_NO_DISCARD bool InitializeUnusedOutputs(TIntermBlock *root,
TSymbolTable *symbolTable,
const InitVariableList &unusedVars)
{
if (unusedVars.empty())
{
return true;
}
TIntermSequence *insertSequence = new TIntermSequence;
for (const sh::ShaderVariable &var : unusedVars)
{
ASSERT(!var.active);
const TIntermSymbol *symbol = FindSymbolNode(root, var.name);
ASSERT(symbol);
TIntermSequence *initCode = CreateInitCode(symbol, false, false, symbolTable);
insertSequence->insert(insertSequence->end(), initCode->begin(), initCode->end());
}
if (insertSequence)
{
TIntermFunctionDefinition *main = FindMain(root);
TIntermSequence *mainSequence = main->getBody()->getSequence();
// Insert init code at the start of main()
mainSequence->insert(mainSequence->begin(), insertSequence->begin(), insertSequence->end());
}
return true;
}
} // anonymous namespace
TranslatorMetal::TranslatorMetal(sh::GLenum type, ShShaderSpec spec) : TranslatorVulkan(type, spec)
......@@ -119,6 +159,26 @@ bool TranslatorMetal::translate(TIntermBlock *root,
}
}
// Initialize unused varying outputs to avoid spirv-cross dead-code removing them in later
// stage. Only do this if SH_INIT_OUTPUT_VARIABLES is not specified.
if ((getShaderType() == GL_VERTEX_SHADER || getShaderType() == GL_GEOMETRY_SHADER_EXT) &&
!(compileOptions & SH_INIT_OUTPUT_VARIABLES))
{
InitVariableList list;
for (const sh::ShaderVariable &var : mOutputVaryings)
{
if (!var.active)
{
list.push_back(var);
}
}
if (!InitializeUnusedOutputs(root, &getSymbolTable(), list))
{
return false;
}
}
// Write translated shader.
root->traverse(&outputGLSL);
......
......@@ -4624,6 +4624,34 @@ TEST_P(GLSLTest, StructsWithSameMembersDisambiguatedByName)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Test that an inactive varying in vertex shader but used in fragment shader can be linked
// successfully.
TEST_P(GLSLTest, InactiveVaryingInVertexActiveInFragment)
{
// http://anglebug.com/4820
ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
constexpr char kVS[] =
"attribute vec4 inputAttribute;\n"
"varying vec4 varColor;\n"
"void main()\n"
"{\n"
" gl_Position = inputAttribute;\n"
"}\n";
constexpr char kFS[] =
"precision mediump float;\n"
"varying vec4 varColor;\n"
"void main()\n"
"{\n"
" gl_FragColor = varColor;\n"
"}\n";
ANGLE_GL_PROGRAM(program, kVS, kFS);
drawQuad(program.get(), "inputAttribute", 0.5f);
ASSERT_GL_NO_ERROR();
}
// 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)
......
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