Commit c71862aa by Olli Etuaho Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent 02f15239
......@@ -82,6 +82,12 @@ bool IsInStd140InterfaceBlock(TIntermTyped *node)
} // 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 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
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 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{
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);
......
......@@ -24,13 +24,22 @@ namespace sh
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 @@ class OutputHLSL : public TIntermTraverser
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;
......
......@@ -457,21 +457,15 @@ void UniformHLSL::samplerMetadataUniforms(TInfoSinkBase &out, const char *reg)
}
}
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 @@ TString UniformHLSL::uniformBlocksHeader(const ReferencedSymbols &referencedInte
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::uniformBlocksHeader(const ReferencedSymbols &referencedInte
}
TString UniformHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
const TString &instanceName,
const TVariable *instanceVariable,
unsigned int registerIndex,
unsigned int arrayIndex)
{
......@@ -515,10 +508,10 @@ TString UniformHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
")\n"
"{\n";
if (instanceName != "")
if (instanceVariable != nullptr)
{
hlsl += " " + InterfaceBlockStructName(interfaceBlock) + " " +
UniformBlockInstanceString(instanceName, arrayIndex) + ";\n";
UniformBlockInstanceString(instanceVariable->name(), arrayIndex) + ";\n";
}
else
{
......
......@@ -37,7 +37,7 @@ class UniformHLSL : angle::NonCopyable
// 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 @@ class UniformHLSL : angle::NonCopyable
private:
TString uniformBlockString(const TInterfaceBlock &interfaceBlock,
const TString &instanceName,
const TVariable *instanceVariable,
unsigned int registerIndex,
unsigned int arrayIndex);
TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
......
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