Commit 3fb490a7 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Faster check for vertex attribute aliasing

In preparation for matrix attribute aliasing support, where CalculateAliasingAttributes would get a bit more complex. This change adds a fast-check function to determine if there is any aliasing at all. Bug: angleproject:4249 Change-Id: Ib2aa08b2da29a194baa905ba8f9aa2cdef0ae2c5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2488127Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 8feb5c82
...@@ -2075,12 +2075,10 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas ...@@ -2075,12 +2075,10 @@ class SpirvVertexAttributeAliasingTransformer final : public SpirvTransformerBas
const std::vector<uint32_t> &spirvBlobIn, const std::vector<uint32_t> &spirvBlobIn,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
std::vector<const ShaderInterfaceVariableInfo *> &&variableInfoById, std::vector<const ShaderInterfaceVariableInfo *> &&variableInfoById,
gl::AttribArray<AliasingAttributeMap> &&aliasingAttributeMap,
SpirvBlob *spirvBlobOut) SpirvBlob *spirvBlobOut)
: SpirvTransformerBase(spirvBlobIn, variableInfoMap, gl::ShaderType::Vertex, spirvBlobOut) : SpirvTransformerBase(spirvBlobIn, variableInfoMap, gl::ShaderType::Vertex, spirvBlobOut)
{ {
mVariableInfoById = std::move(variableInfoById); mVariableInfoById = std::move(variableInfoById);
mAliasingAttributeMap = std::move(aliasingAttributeMap);
} }
bool transform(); bool transform();
...@@ -2154,13 +2152,59 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes() ...@@ -2154,13 +2152,59 @@ void SpirvVertexAttributeAliasingTransformer::preprocessAliasingAttributes()
const size_t indexBound = mSpirvBlobIn[kHeaderIndexIndexBound]; const size_t indexBound = mSpirvBlobIn[kHeaderIndexIndexBound];
mIsAliasingAttributeById.resize(indexBound + 1, false); mIsAliasingAttributeById.resize(indexBound + 1, false);
for (const AliasingAttributeMap &aliasingMap : mAliasingAttributeMap) // Go through attributes and find out which alias which.
for (size_t id = 0; id < mVariableInfoById.size(); ++id)
{ {
for (uint32_t aliasingId : aliasingMap.aliasingAttributes) const ShaderInterfaceVariableInfo *info = mVariableInfoById[id];
// Ignore non attribute or inactive ids.
if (info == nullptr || info->attributeComponentCount == 0 ||
!info->activeStages[gl::ShaderType::Vertex])
{
continue;
}
// Ignore matrix attributes for now.
// TODO: aliasing matrix attributes. http://anglebug.com/4249
if (info->isMatrixAttribute)
{
continue;
}
ASSERT(info->location != ShaderInterfaceVariableInfo::kInvalid);
ASSERT(info->location < mAliasingAttributeMap.size());
AliasingAttributeMap *aliasingMap = &mAliasingAttributeMap[info->location];
// If this is the first attribute in this location, remember it.
if (aliasingMap->attribute == 0)
{
aliasingMap->attribute = id;
continue;
}
// Otherwise, either add it to the list of aliasing attributes, or replace the main
// attribute (and add that to the list of aliasing attributes). The one with the largest
// number of component is used as the main attribute.
const ShaderInterfaceVariableInfo *curMainAttribute =
mVariableInfoById[aliasingMap->attribute];
ASSERT(curMainAttribute != nullptr && curMainAttribute->attributeComponentCount > 0 &&
!curMainAttribute->isMatrixAttribute);
uint32_t aliasingId;
if (info->attributeComponentCount > curMainAttribute->attributeComponentCount)
{ {
ASSERT(mIsAliasingAttributeById[aliasingId] == false); aliasingId = aliasingMap->attribute;
mIsAliasingAttributeById[aliasingId] = true; aliasingMap->attribute = id;
} }
else
{
aliasingId = id;
}
aliasingMap->aliasingAttributes.push_back(aliasingId);
ASSERT(mIsAliasingAttributeById[aliasingId] == false);
mIsAliasingAttributeById[aliasingId] = true;
} }
} }
...@@ -2588,64 +2632,39 @@ void SpirvVertexAttributeAliasingTransformer::writeVectorShuffle( ...@@ -2588,64 +2632,39 @@ void SpirvVertexAttributeAliasingTransformer::writeVectorShuffle(
copyInstruction(vectorShuffle.data(), kVectorShuffleInstructionBaseLength + fields.size()); copyInstruction(vectorShuffle.data(), kVectorShuffleInstructionBaseLength + fields.size());
} }
bool CalculateAliasingAttributes( bool HasAliasingAttributes(const ShaderInterfaceVariableInfoMap &variableInfoMap)
const std::vector<const ShaderInterfaceVariableInfo *> &variableInfoById,
gl::AttribArray<AliasingAttributeMap> *aliasingAttributeMapOut)
{ {
bool anyAliasing = false; gl::AttributesMask isLocationAssigned;
for (size_t id = 0; id < variableInfoById.size(); ++id) for (const auto &infoIter : variableInfoMap)
{ {
const ShaderInterfaceVariableInfo *info = variableInfoById[id]; const ShaderInterfaceVariableInfo &info = infoIter.second;
// Ignore non attribute or inactive ids. // Ignore non attribute or inactive ids.
if (info == nullptr || info->attributeComponentCount == 0 || if (info.attributeComponentCount == 0 || !info.activeStages[gl::ShaderType::Vertex])
!info->activeStages[gl::ShaderType::Vertex])
{ {
continue; continue;
} }
// Ignore matrix attributes for now. // Ignore matrix attributes for now.
// TODO: aliasing matrix attributes. http://anglebug.com/4249 // TODO: aliasing matrix attributes. http://anglebug.com/4249
if (info->isMatrixAttribute) if (info.isMatrixAttribute)
{ {
continue; continue;
} }
ASSERT(info->location != ShaderInterfaceVariableInfo::kInvalid); ASSERT(info.location != ShaderInterfaceVariableInfo::kInvalid);
ASSERT(info->location < aliasingAttributeMapOut->size());
AliasingAttributeMap *aliasingMap = &(*aliasingAttributeMapOut)[info->location]; // If there's aliasing, return immediately.
if (isLocationAssigned.test(info.location))
// If this is the first attribute in this location, remember it.
if (aliasingMap->attribute == 0)
{ {
aliasingMap->attribute = id; return true;
continue;
} }
anyAliasing = true; isLocationAssigned.set(info.location);
// Otherwise, either add it to the list of aliasing attributes, or replace the main
// attribute (and add that to the list of aliasing attributes). The one with the largest
// number of component is used as the main attribute.
const ShaderInterfaceVariableInfo *curMainAttribute =
variableInfoById[aliasingMap->attribute];
ASSERT(curMainAttribute != nullptr && curMainAttribute->attributeComponentCount > 0 &&
!curMainAttribute->isMatrixAttribute);
if (info->attributeComponentCount > curMainAttribute->attributeComponentCount)
{
aliasingMap->aliasingAttributes.push_back(aliasingMap->attribute);
aliasingMap->attribute = id;
}
else
{
aliasingMap->aliasingAttributes.push_back(id);
}
} }
return anyAliasing; return false;
} }
} // anonymous namespace } // anonymous namespace
...@@ -2867,22 +2886,14 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, ...@@ -2867,22 +2886,14 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
removeDebugInfo, variableInfoMap, shaderType, spirvBlobOut); removeDebugInfo, variableInfoMap, shaderType, spirvBlobOut);
ANGLE_GLSLANG_CHECK(callback, transformer.transform(), GlslangError::InvalidSpirv); ANGLE_GLSLANG_CHECK(callback, transformer.transform(), GlslangError::InvalidSpirv);
if (shaderType == gl::ShaderType::Vertex) // If there are aliasing vertex attributes, transform the SPIR-V again to remove them.
if (shaderType == gl::ShaderType::Vertex && HasAliasingAttributes(variableInfoMap))
{ {
gl::AttribArray<AliasingAttributeMap> aliasingAttributeMap; SpirvBlob preTransformBlob = std::move(*spirvBlobOut);
std::vector<const ShaderInterfaceVariableInfo *> &variableInfoById = SpirvVertexAttributeAliasingTransformer aliasingTransformer(
transformer.getVariableInfoByIdMap(); preTransformBlob, variableInfoMap, std::move(transformer.getVariableInfoByIdMap()),
spirvBlobOut);
// If there are aliasing vertex attributes, transform the SPIR-V again to remove them. ANGLE_GLSLANG_CHECK(callback, aliasingTransformer.transform(), GlslangError::InvalidSpirv);
if (CalculateAliasingAttributes(variableInfoById, &aliasingAttributeMap))
{
SpirvBlob preTransformBlob = std::move(*spirvBlobOut);
SpirvVertexAttributeAliasingTransformer aliasingTransformer(
preTransformBlob, variableInfoMap, std::move(variableInfoById),
std::move(aliasingAttributeMap), spirvBlobOut);
ANGLE_GLSLANG_CHECK(callback, aliasingTransformer.transform(),
GlslangError::InvalidSpirv);
}
} }
ASSERT(ValidateSpirv(*spirvBlobOut)); ASSERT(ValidateSpirv(*spirvBlobOut));
......
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