Commit f764fc02 by Shahbaz Youssefi Committed by Commit Bot

Fix varying linking by location

This change breaks the assumption everywhere that varyings can be identified uniquely by name throughout all stages of the pipeline. It further implements linking of varyings by location, if specified. Bug: angleproject:4355 Change-Id: Ie45e48879008c3f0c22d1da3d0d26f37c655e54e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2030026 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 58fc8b11
...@@ -405,13 +405,19 @@ void InitShaderStorageBlockLinker(const ProgramState &state, ShaderStorageBlockL ...@@ -405,13 +405,19 @@ void InitShaderStorageBlockLinker(const ProgramState &state, ShaderStorageBlockL
} }
// Find the matching varying or field by name. // Find the matching varying or field by name.
const sh::ShaderVariable *FindVaryingOrField(const ProgramMergedVaryings &varyings, const sh::ShaderVariable *FindOutputVaryingOrField(const ProgramMergedVaryings &varyings,
const std::string &name) ShaderType stage,
const std::string &name)
{ {
const sh::ShaderVariable *var = nullptr; const sh::ShaderVariable *var = nullptr;
for (const auto &ref : varyings) for (const ProgramVaryingRef &ref : varyings)
{ {
const sh::ShaderVariable *varying = ref.second.get(); if (ref.frontShaderStage != stage)
{
continue;
}
const sh::ShaderVariable *varying = ref.get(stage);
if (varying->name == name) if (varying->name == name)
{ {
var = varying; var = varying;
...@@ -1583,7 +1589,7 @@ angle::Result Program::link(const Context *context) ...@@ -1583,7 +1589,7 @@ angle::Result Program::link(const Context *context)
return angle::Result::Continue; return angle::Result::Continue;
} }
const auto &mergedVaryings = getMergedVaryings(); const ProgramMergedVaryings &mergedVaryings = getMergedVaryings();
gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex]; gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
if (vertexShader) if (vertexShader)
...@@ -1594,8 +1600,11 @@ angle::Result Program::link(const Context *context) ...@@ -1594,8 +1600,11 @@ angle::Result Program::link(const Context *context)
InitUniformBlockLinker(mState, &resources->uniformBlockLinker); InitUniformBlockLinker(mState, &resources->uniformBlockLinker);
InitShaderStorageBlockLinker(mState, &resources->shaderStorageBlockLinker); InitShaderStorageBlockLinker(mState, &resources->shaderStorageBlockLinker);
ShaderType tfStage = mState.mAttachedShaders[ShaderType::Geometry] ? ShaderType::Geometry
: ShaderType::Vertex;
if (!linkValidateTransformFeedback(context->getClientVersion(), mInfoLog, mergedVaryings, if (!linkValidateTransformFeedback(context->getClientVersion(), mInfoLog, mergedVaryings,
context->getCaps())) tfStage, context->getCaps()))
{ {
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1606,7 +1615,7 @@ angle::Result Program::link(const Context *context) ...@@ -1606,7 +1615,7 @@ angle::Result Program::link(const Context *context)
return angle::Result::Continue; return angle::Result::Continue;
} }
gatherTransformFeedbackVaryings(mergedVaryings); gatherTransformFeedbackVaryings(mergedVaryings, tfStage);
mState.updateTransformFeedbackStrides(); mState.updateTransformFeedbackStrides();
} }
...@@ -4107,6 +4116,7 @@ bool Program::linkValidateBuiltInVaryings(InfoLog &infoLog) const ...@@ -4107,6 +4116,7 @@ bool Program::linkValidateBuiltInVaryings(InfoLog &infoLog) const
bool Program::linkValidateTransformFeedback(const Version &version, bool Program::linkValidateTransformFeedback(const Version &version,
InfoLog &infoLog, InfoLog &infoLog,
const ProgramMergedVaryings &varyings, const ProgramMergedVaryings &varyings,
ShaderType stage,
const Caps &caps) const const Caps &caps) const
{ {
...@@ -4147,7 +4157,7 @@ bool Program::linkValidateTransformFeedback(const Version &version, ...@@ -4147,7 +4157,7 @@ bool Program::linkValidateTransformFeedback(const Version &version,
std::vector<unsigned int> subscripts; std::vector<unsigned int> subscripts;
std::string baseName = ParseResourceName(tfVaryingName, &subscripts); std::string baseName = ParseResourceName(tfVaryingName, &subscripts);
const sh::ShaderVariable *var = FindVaryingOrField(varyings, baseName); const sh::ShaderVariable *var = FindOutputVaryingOrField(varyings, stage, baseName);
if (var == nullptr) if (var == nullptr)
{ {
infoLog << "Transform feedback varying " << tfVaryingName infoLog << "Transform feedback varying " << tfVaryingName
...@@ -4328,7 +4338,8 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const ...@@ -4328,7 +4338,8 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const
return true; return true;
} }
void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings) void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings,
ShaderType stage)
{ {
// Gather the linked varyings that are used for transform feedback, they should all exist. // Gather the linked varyings that are used for transform feedback, they should all exist.
mState.mLinkedTransformFeedbackVaryings.clear(); mState.mLinkedTransformFeedbackVaryings.clear();
...@@ -4341,9 +4352,14 @@ void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyi ...@@ -4341,9 +4352,14 @@ void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyi
{ {
subscript = subscripts.back(); subscript = subscripts.back();
} }
for (const auto &ref : varyings) for (const ProgramVaryingRef &ref : varyings)
{ {
const sh::ShaderVariable *varying = ref.second.get(); if (ref.frontShaderStage != stage)
{
continue;
}
const sh::ShaderVariable *varying = ref.get(stage);
if (baseName == varying->name) if (baseName == varying->name)
{ {
mState.mLinkedTransformFeedbackVaryings.emplace_back( mState.mLinkedTransformFeedbackVaryings.emplace_back(
...@@ -4366,25 +4382,113 @@ void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyi ...@@ -4366,25 +4382,113 @@ void Program::gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyi
ProgramMergedVaryings Program::getMergedVaryings() const ProgramMergedVaryings Program::getMergedVaryings() const
{ {
ASSERT(mState.mAttachedShaders[ShaderType::Compute] == nullptr);
// Varyings are matched between pairs of consecutive stages, by location if assigned or
// by name otherwise. Note that it's possible for one stage to specify location and the other
// not: https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
// Map stages to the previous active stage in the rendering pipeline. When looking at input
// varyings of a stage, this is used to find the stage whose output varyings are being linked
// with them.
ShaderMap<ShaderType> previousActiveStage;
// Note that kAllGraphicsShaderTypes is sorted according to the rendering pipeline.
ShaderType lastActiveStage = ShaderType::InvalidEnum;
for (ShaderType stage : kAllGraphicsShaderTypes)
{
previousActiveStage[stage] = lastActiveStage;
if (mState.mAttachedShaders[stage])
{
lastActiveStage = stage;
}
}
// First, go through output varyings and create two maps (one by name, one by location) for
// faster lookup when matching input varyings.
ShaderMap<std::map<std::string, size_t>> outputVaryingNameToIndex;
ShaderMap<std::map<int, size_t>> outputVaryingLocationToIndex;
ProgramMergedVaryings merged; ProgramMergedVaryings merged;
// Gather output varyings.
for (Shader *shader : mState.mAttachedShaders) for (Shader *shader : mState.mAttachedShaders)
{ {
if (shader) if (!shader)
{
continue;
}
ShaderType stage = shader->getType();
for (const sh::ShaderVariable &varying : shader->getOutputVaryings())
{
merged.push_back({});
ProgramVaryingRef *ref = &merged.back();
ref->frontShader = &varying;
ref->frontShaderStage = stage;
// Always map by name. Even if location is provided in this stage, it may not be in the
// paired stage.
outputVaryingNameToIndex[stage][varying.name] = merged.size() - 1;
// If location is provided, also keep it in a map by location.
if (varying.location != -1)
{
outputVaryingLocationToIndex[stage][varying.location] = merged.size() - 1;
}
}
}
// Gather input varyings, and match them with output varyings of the previous stage.
for (Shader *shader : mState.mAttachedShaders)
{
if (!shader)
{ {
ShaderType shaderType = shader->getType(); continue;
for (const sh::ShaderVariable &varying : shader->getOutputVaryings()) }
ShaderType stage = shader->getType();
ShaderType previousStage = previousActiveStage[stage];
for (const sh::ShaderVariable &varying : shader->getInputVaryings())
{
size_t mergedIndex = merged.size();
if (previousStage != ShaderType::InvalidEnum)
{ {
ProgramVaryingRef *ref = &merged[varying.name]; // If location is provided, see if we can match by location.
ref->frontShader = &varying; if (varying.location != -1)
ref->frontShaderStage = shaderType; {
auto byLocationIter =
outputVaryingLocationToIndex[previousStage].find(varying.location);
if (byLocationIter != outputVaryingLocationToIndex[previousStage].end())
{
mergedIndex = byLocationIter->second;
}
}
// If not found, try to match by name.
if (mergedIndex == merged.size())
{
auto byNameIter = outputVaryingNameToIndex[previousStage].find(varying.name);
if (byNameIter != outputVaryingNameToIndex[previousStage].end())
{
mergedIndex = byNameIter->second;
}
}
} }
for (const sh::ShaderVariable &varying : shader->getInputVaryings())
// If no previous stage, or not matched by location or name, create a new entry for it.
if (mergedIndex == merged.size())
{ {
ProgramVaryingRef *ref = &merged[varying.name]; merged.push_back({});
ref->backShader = &varying; mergedIndex = merged.size() - 1;
ref->backShaderStage = shaderType;
} }
ProgramVaryingRef *ref = &merged[mergedIndex];
ref->backShader = &varying;
ref->backShaderStage = stage;
} }
} }
......
...@@ -568,7 +568,13 @@ class ProgramAliasedBindings final : angle::NonCopyable ...@@ -568,7 +568,13 @@ class ProgramAliasedBindings final : angle::NonCopyable
struct ProgramVaryingRef struct ProgramVaryingRef
{ {
const sh::ShaderVariable *get() const { return frontShader ? frontShader : backShader; } const sh::ShaderVariable *get(ShaderType stage) const
{
ASSERT(stage == frontShaderStage || stage == backShaderStage);
const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader;
ASSERT(ref);
return ref;
}
const sh::ShaderVariable *frontShader = nullptr; const sh::ShaderVariable *frontShader = nullptr;
const sh::ShaderVariable *backShader = nullptr; const sh::ShaderVariable *backShader = nullptr;
...@@ -576,7 +582,7 @@ struct ProgramVaryingRef ...@@ -576,7 +582,7 @@ struct ProgramVaryingRef
ShaderType backShaderStage = ShaderType::InvalidEnum; ShaderType backShaderStage = ShaderType::InvalidEnum;
}; };
using ProgramMergedVaryings = std::map<std::string, ProgramVaryingRef>; using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
class Program final : angle::NonCopyable, public LabeledObject class Program final : angle::NonCopyable, public LabeledObject
{ {
...@@ -1025,10 +1031,11 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -1025,10 +1031,11 @@ class Program final : angle::NonCopyable, public LabeledObject
bool linkValidateTransformFeedback(const Version &version, bool linkValidateTransformFeedback(const Version &version,
InfoLog &infoLog, InfoLog &infoLog,
const ProgramMergedVaryings &linkedVaryings, const ProgramMergedVaryings &linkedVaryings,
ShaderType stage,
const Caps &caps) const; const Caps &caps) const;
bool linkValidateGlobalNames(InfoLog &infoLog) const; bool linkValidateGlobalNames(InfoLog &infoLog) const;
void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings); void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage);
ProgramMergedVaryings getMergedVaryings() const; ProgramMergedVaryings getMergedVaryings() const;
int getOutputLocationForLink(const sh::ShaderVariable &outputVariable) const; int getOutputLocationForLink(const sh::ShaderVariable &outputVariable) const;
......
...@@ -25,34 +25,77 @@ namespace gl ...@@ -25,34 +25,77 @@ namespace gl
class InfoLog; class InfoLog;
struct ProgramVaryingRef; struct ProgramVaryingRef;
using ProgramMergedVaryings = std::map<std::string, ProgramVaryingRef>; using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
// A varying can have different names between stages if matched by the location layout qualifier.
// Additionally, same name varyings could still be of two identical struct types with different
// names. This struct contains information on the varying in one of the two stages. PackedVarying
// will thus contain two copies of this along with common information, such as interpolation or
// field index.
struct VaryingInShaderRef : angle::NonCopyable
{
VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn);
VaryingInShaderRef(VaryingInShaderRef &&other);
~VaryingInShaderRef();
VaryingInShaderRef &operator=(VaryingInShaderRef &&other);
const sh::ShaderVariable *varying;
ShaderType stage;
// Struct name
std::string parentStructName;
std::string parentStructMappedName;
};
struct PackedVarying : angle::NonCopyable struct PackedVarying : angle::NonCopyable
{ {
PackedVarying(const sh::ShaderVariable &varyingIn, sh::InterpolationType interpolationIn); // Throughout this file, the "front" stage refers to the stage that outputs the varying, and the
PackedVarying(const sh::ShaderVariable &varyingIn, // "back" stage refers to the stage that takes the varying as input. Note that this struct
// contains linked varyings, which means both front and back stage varyings are valid, except
// for the following which may have only one valid stage.
//
// - transform-feedback-captured varyings
// - builtins
// - separable program stages,
//
PackedVarying(VaryingInShaderRef &&frontVaryingIn,
VaryingInShaderRef &&backVaryingIn,
sh::InterpolationType interpolationIn);
PackedVarying(VaryingInShaderRef &&frontVaryingIn,
VaryingInShaderRef &&backVaryingIn,
sh::InterpolationType interpolationIn, sh::InterpolationType interpolationIn,
const std::string &parentStructNameIn,
const std::string &parentStructMappedNameIn,
GLuint fieldIndexIn); GLuint fieldIndexIn);
PackedVarying(PackedVarying &&other); PackedVarying(PackedVarying &&other);
~PackedVarying(); ~PackedVarying();
PackedVarying &operator=(PackedVarying &&other); PackedVarying &operator=(PackedVarying &&other);
bool isStructField() const { return !parentStructName.empty(); } bool isStructField() const { return !frontVarying.parentStructName.empty(); }
bool isArrayElement() const { return arrayIndex != GL_INVALID_INDEX; } bool isArrayElement() const { return arrayIndex != GL_INVALID_INDEX; }
std::string fullName() const // Return either front or back varying, whichever is available. Only used when the name of the
// varying is not important, but only the type is interesting.
const sh::ShaderVariable &varying() const
{
return frontVarying.varying ? *frontVarying.varying : *backVarying.varying;
}
std::string fullName(ShaderType stage) const
{ {
ASSERT(stage == frontVarying.stage || stage == backVarying.stage);
const VaryingInShaderRef &varying =
stage == frontVarying.stage ? frontVarying : backVarying;
std::stringstream fullNameStr; std::stringstream fullNameStr;
if (isStructField()) if (isStructField())
{ {
fullNameStr << parentStructName << "."; fullNameStr << varying.parentStructName << ".";
} }
fullNameStr << varying->name; fullNameStr << varying.varying->name;
if (arrayIndex != GL_INVALID_INDEX) if (arrayIndex != GL_INVALID_INDEX)
{ {
fullNameStr << "[" << arrayIndex << "]"; fullNameStr << "[" << arrayIndex << "]";
...@@ -63,22 +106,15 @@ struct PackedVarying : angle::NonCopyable ...@@ -63,22 +106,15 @@ struct PackedVarying : angle::NonCopyable
// Transform feedback varyings can be only referenced in the VS. // Transform feedback varyings can be only referenced in the VS.
bool vertexOnly() const bool vertexOnly() const
{ {
ShaderBitSet vertex; return frontVarying.stage == ShaderType::Vertex && backVarying.varying == nullptr;
vertex.set(ShaderType::Vertex);
return shaderStages == vertex;
} }
const sh::ShaderVariable *varying; VaryingInShaderRef frontVarying;
VaryingInShaderRef backVarying;
ShaderBitSet shaderStages;
// Cached so we can store sh::ShaderVariable to point to varying fields. // Cached so we can store sh::ShaderVariable to point to varying fields.
sh::InterpolationType interpolation; sh::InterpolationType interpolation;
// Struct name
std::string parentStructName;
std::string parentStructMappedName;
GLuint arrayIndex; GLuint arrayIndex;
// Field index in the struct. In Vulkan, this is used to assign a // Field index in the struct. In Vulkan, this is used to assign a
...@@ -112,14 +148,7 @@ struct PackedVaryingRegister final ...@@ -112,14 +148,7 @@ struct PackedVaryingRegister final
std::string tfVaryingName() const std::string tfVaryingName() const
{ {
if (packedVarying->isArrayElement() || packedVarying->isStructField()) return packedVarying->fullName(packedVarying->frontVarying.stage);
{
return packedVarying->fullName();
}
else
{
return packedVarying->varying->name;
}
} }
// Index to the array of varyings. // Index to the array of varyings.
...@@ -182,13 +211,11 @@ class VaryingPacking final : angle::NonCopyable ...@@ -182,13 +211,11 @@ class VaryingPacking final : angle::NonCopyable
return static_cast<unsigned int>(mRegisterList.size()); return static_cast<unsigned int>(mRegisterList.size());
} }
const std::vector<std::string> &getInactiveVaryingMappedNames() const const ShaderMap<std::vector<std::string>> &getInactiveVaryingMappedNames() const
{ {
return mInactiveVaryingMappedNames; return mInactiveVaryingMappedNames;
} }
const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
private: private:
bool packVarying(const PackedVarying &packedVarying); bool packVarying(const PackedVarying &packedVarying);
bool isFree(unsigned int registerRow, bool isFree(unsigned int registerRow,
...@@ -199,11 +226,20 @@ class VaryingPacking final : angle::NonCopyable ...@@ -199,11 +226,20 @@ class VaryingPacking final : angle::NonCopyable
unsigned int registerColumn, unsigned int registerColumn,
const PackedVarying &packedVarying); const PackedVarying &packedVarying);
using VaryingUniqueFullNames = ShaderMap<std::set<std::string>>;
void packUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames);
void packUserVaryingField(const ProgramVaryingRef &ref,
GLuint fieldIndex,
VaryingUniqueFullNames *uniqueFullNames);
void packUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript);
void packUserVaryingFieldTF(const ProgramVaryingRef &ref,
const sh::ShaderVariable &field,
GLuint fieldIndex);
std::vector<Register> mRegisterMap; std::vector<Register> mRegisterMap;
std::vector<PackedVaryingRegister> mRegisterList; std::vector<PackedVaryingRegister> mRegisterList;
std::vector<sh::ShaderVariable> mInputVaryings;
std::vector<PackedVarying> mPackedVaryings; std::vector<PackedVarying> mPackedVaryings;
std::vector<std::string> mInactiveVaryingMappedNames; ShaderMap<std::vector<std::string>> mInactiveVaryingMappedNames;
PackMode mPackMode; PackMode mPackMode;
}; };
......
...@@ -30,9 +30,11 @@ class VaryingPackingTest : public ::testing::TestWithParam<GLuint> ...@@ -30,9 +30,11 @@ class VaryingPackingTest : public ::testing::TestWithParam<GLuint>
VaryingPacking *varyingPacking) VaryingPacking *varyingPacking)
{ {
std::vector<PackedVarying> packedVaryings; std::vector<PackedVarying> packedVaryings;
for (const auto &shVarying : shVaryings) for (const sh::ShaderVariable &shVarying : shVaryings)
{ {
packedVaryings.push_back(PackedVarying(shVarying, shVarying.interpolation)); packedVaryings.push_back(PackedVarying(
VaryingInShaderRef(ShaderType::Vertex, &shVarying),
VaryingInShaderRef(ShaderType::Fragment, &shVarying), shVarying.interpolation));
} }
InfoLog infoLog; InfoLog infoLog;
......
...@@ -414,7 +414,7 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, ...@@ -414,7 +414,7 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking,
for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
{ {
const PackedVaryingRegister &registerInfo = registerInfos[registerIndex]; const PackedVaryingRegister &registerInfo = registerInfos[registerIndex];
const auto &varying = *registerInfo.packedVarying->varying; const auto &varying = registerInfo.packedVarying->varying();
ASSERT(!varying.isStruct()); ASSERT(!varying.isStruct());
// TODO: Add checks to ensure D3D interpolation modifiers don't result in too many // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many
...@@ -599,14 +599,15 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -599,14 +599,15 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
{ {
const PackedVaryingRegister &registerInfo = registerInfos[registerIndex]; const PackedVaryingRegister &registerInfo = registerInfos[registerIndex];
const auto &packedVarying = *registerInfo.packedVarying; const auto &packedVarying = *registerInfo.packedVarying;
const auto &varying = *packedVarying.varying; const auto &varying = *packedVarying.frontVarying.varying;
ASSERT(!varying.isStruct()); ASSERT(!varying.isStruct());
vertexGenerateOutput << " output.v" << registerIndex << " = "; vertexGenerateOutput << " output.v" << registerIndex << " = ";
if (packedVarying.isStructField()) if (packedVarying.isStructField())
{ {
vertexGenerateOutput << DecorateVariable(packedVarying.parentStructName) << "."; vertexGenerateOutput << DecorateVariable(packedVarying.frontVarying.parentStructName)
<< ".";
} }
vertexGenerateOutput << DecorateVariable(varying.name); vertexGenerateOutput << DecorateVariable(varying.name);
...@@ -798,19 +799,28 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps, ...@@ -798,19 +799,28 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
{ {
const PackedVaryingRegister &registerInfo = registerInfos[registerIndex]; const PackedVaryingRegister &registerInfo = registerInfos[registerIndex];
const auto &packedVarying = *registerInfo.packedVarying; const auto &packedVarying = *registerInfo.packedVarying;
const auto &varying = *packedVarying.varying;
// Don't reference VS-only transform feedback varyings in the PS.
if (packedVarying.vertexOnly())
{
continue;
}
const auto &varying = *packedVarying.backVarying.varying;
ASSERT(!varying.isBuiltIn() && !varying.isStruct()); ASSERT(!varying.isBuiltIn() && !varying.isStruct());
// Don't reference VS-only transform feedback varyings in the PS. Note that we're relying on // Note that we're relying on that the active flag is set according to usage in the fragment
// that the active flag is set according to usage in the fragment shader. // shader.
if (packedVarying.vertexOnly() || !varying.active) if (!varying.active)
{
continue; continue;
}
pixelPrologue << " "; pixelPrologue << " ";
if (packedVarying.isStructField()) if (packedVarying.isStructField())
{ {
pixelPrologue << DecorateVariable(packedVarying.parentStructName) << "."; pixelPrologue << DecorateVariable(packedVarying.backVarying.parentStructName) << ".";
} }
pixelPrologue << DecorateVariable(varying.name); pixelPrologue << DecorateVariable(varying.name);
......
...@@ -3141,7 +3141,7 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyi ...@@ -3141,7 +3141,7 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyi
for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
{ {
const auto &registerInfo = registerInfos[registerIndex]; const auto &registerInfo = registerInfos[registerIndex];
const auto &varying = *registerInfo.packedVarying->varying; const auto &varying = registerInfo.packedVarying->varying();
GLenum transposedType = gl::TransposeMatrixType(varying.type); GLenum transposedType = gl::TransposeMatrixType(varying.type);
int componentCount = gl::VariableColumnCount(transposedType); int componentCount = gl::VariableColumnCount(transposedType);
ASSERT(!varying.isBuiltIn() && !varying.isStruct()); ASSERT(!varying.isBuiltIn() && !varying.isStruct());
......
...@@ -6166,9 +6166,6 @@ void main() ...@@ -6166,9 +6166,6 @@ void main()
// Test that linking varyings by location works. // Test that linking varyings by location works.
TEST_P(GLSLTest_ES31, LinkVaryingsByLocation) TEST_P(GLSLTest_ES31, LinkVaryingsByLocation)
{ {
// http://anglebug.com/4355
ANGLE_SKIP_TEST_IF(IsVulkan() || IsMetal() || IsD3D11());
constexpr char kVS[] = R"(#version 310 es constexpr char kVS[] = R"(#version 310 es
precision highp float; precision highp float;
in vec4 position; in vec4 position;
......
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