Store referenced interface blocks in a cleaner data structure
The previous code was hard to read since the referenced interface
blocks stored a different type of node depending on if the interface
block was instanced or not.
BUG=angleproject:2267
TEST=angle_unittests
Change-Id: Ie8fdb61a17280ca0875159702f819b884d08706b
Reviewed-on: https://chromium-review.googlesource.com/839443
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index ccd6037..04ce8eb 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -82,6 +82,12 @@
} // anonymous namespace
+TReferencedBlock::TReferencedBlock(const TInterfaceBlock *aBlock,
+ const TVariable *aInstanceVariable)
+ : block(aBlock), instanceVariable(aInstanceVariable)
+{
+}
+
void OutputHLSL::writeFloat(TInfoSinkBase &out, float f)
{
// This is known not to work for NaN on all drivers but make the best effort to output NaNs
@@ -896,7 +902,16 @@
if (interfaceBlock)
{
- mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] = node;
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ const TVariable *instanceVariable = nullptr;
+ if (variableType.isInterfaceBlock())
+ {
+ instanceVariable = &variable;
+ }
+ mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, instanceVariable);
+ }
}
else
{
@@ -1242,10 +1257,13 @@
{
if (visit == PreVisit)
{
- TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
TIntermSymbol *instanceArraySymbol = node->getLeft()->getAsSymbolNode();
- mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
- instanceArraySymbol;
+ TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, &instanceArraySymbol->variable());
+ }
const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
out << mUniformHLSL->UniformBlockInstanceString(instanceArraySymbol->getName(),
arrayIndex);
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index f046927..0e4135c 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -24,13 +24,22 @@
class StructureHLSL;
class TextureFunctionHLSL;
class TSymbolTable;
+class TVariable;
class ImageFunctionHLSL;
class UnfoldShortCircuit;
class UniformHLSL;
-// Maps from uniqueId to a symbol node or a variable.
-typedef std::map<int, TIntermSymbol *> ReferencedSymbols;
-typedef std::map<int, const TVariable *> ReferencedVariables;
+struct TReferencedBlock : angle::NonCopyable
+{
+ POOL_ALLOCATOR_NEW_DELETE();
+ TReferencedBlock(const TInterfaceBlock *block, const TVariable *instanceVariable);
+ const TInterfaceBlock *block;
+ const TVariable *instanceVariable; // May be nullptr if the block is not instanced.
+};
+
+// Maps from uniqueId to a variable.
+using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>;
+using ReferencedVariables = std::map<int, const TVariable *>;
class OutputHLSL : public TIntermTraverser
{
@@ -158,11 +167,8 @@
ReferencedVariables mReferencedUniforms;
- // Indexed by block id, not instance id. Stored nodes point to either the block instance in
- // the case of an instanced block, or a member uniform in the case of a non-instanced block.
- // TODO(oetuaho): Consider a different type of data structure for storing referenced interface
- // blocks. It needs to know the instance name if any and link to the TInterfaceBlock object.
- ReferencedSymbols mReferencedUniformBlocks;
+ // Indexed by block id, not instance id.
+ ReferencedInterfaceBlocks mReferencedUniformBlocks;
ReferencedVariables mReferencedAttributes;
ReferencedVariables mReferencedVaryings;
diff --git a/src/compiler/translator/UniformHLSL.cpp b/src/compiler/translator/UniformHLSL.cpp
index dc467f9..04f0ff7 100644
--- a/src/compiler/translator/UniformHLSL.cpp
+++ b/src/compiler/translator/UniformHLSL.cpp
@@ -457,21 +457,15 @@
}
}
-TString UniformHLSL::uniformBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks)
+TString UniformHLSL::uniformBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
{
TString interfaceBlocks;
- for (const auto &interfaceBlockReference : referencedInterfaceBlocks)
+ for (const auto &blockReference : referencedInterfaceBlocks)
{
- const TType &nodeType = interfaceBlockReference.second->getType();
- const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
-
- // nodeType.isInterfaceBlock() == false means the node is a field of a uniform block which
- // doesn't have instance name.
- const TString &instanceName =
- nodeType.isInterfaceBlock() ? interfaceBlockReference.second->getName() : "";
-
- if (instanceName != "")
+ const TInterfaceBlock &interfaceBlock = *blockReference.second->block;
+ const TVariable *instanceVariable = blockReference.second->instanceVariable;
+ if (instanceVariable != nullptr)
{
interfaceBlocks += uniformBlockStructString(interfaceBlock);
}
@@ -479,21 +473,20 @@
unsigned int activeRegister = mUniformBlockRegister;
mUniformBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
- if (instanceName != "" && nodeType.isArray())
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
{
- unsigned int interfaceBlockInstanceArraySize = nodeType.getOutermostArraySize();
- for (unsigned int arrayIndex = 0; arrayIndex < interfaceBlockInstanceArraySize;
- arrayIndex++)
+ unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
{
- interfaceBlocks += uniformBlockString(interfaceBlock, instanceName,
+ interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable,
activeRegister + arrayIndex, arrayIndex);
}
- mUniformBlockRegister += interfaceBlockInstanceArraySize;
+ mUniformBlockRegister += instanceArraySize;
}
else
{
- interfaceBlocks +=
- uniformBlockString(interfaceBlock, instanceName, activeRegister, GL_INVALID_INDEX);
+ interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable, activeRegister,
+ GL_INVALID_INDEX);
mUniformBlockRegister += 1u;
}
}
@@ -502,7 +495,7 @@
}
TString UniformHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
- const TString &instanceName,
+ const TVariable *instanceVariable,
unsigned int registerIndex,
unsigned int arrayIndex)
{
@@ -515,10 +508,10 @@
")\n"
"{\n";
- if (instanceName != "")
+ if (instanceVariable != nullptr)
{
hlsl += " " + InterfaceBlockStructName(interfaceBlock) + " " +
- UniformBlockInstanceString(instanceName, arrayIndex) + ";\n";
+ UniformBlockInstanceString(instanceVariable->name(), arrayIndex) + ";\n";
}
else
{
diff --git a/src/compiler/translator/UniformHLSL.h b/src/compiler/translator/UniformHLSL.h
index 427e713..914d663 100644
--- a/src/compiler/translator/UniformHLSL.h
+++ b/src/compiler/translator/UniformHLSL.h
@@ -37,7 +37,7 @@
// Must be called after uniformsHeader
void samplerMetadataUniforms(TInfoSinkBase &out, const char *reg);
- TString uniformBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks);
+ TString uniformBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
// Used for direct index references
static TString UniformBlockInstanceString(const TString &instanceName, unsigned int arrayIndex);
@@ -53,7 +53,7 @@
private:
TString uniformBlockString(const TInterfaceBlock &interfaceBlock,
- const TString &instanceName,
+ const TVariable *instanceVariable,
unsigned int registerIndex,
unsigned int arrayIndex);
TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,