Proper handling of Interface Block indexing
This is a first step in handling interface blocks
properly by allowing indexing of blocks to be handled
properly. This does not include any interaction with
the Program, which will come in a following step.
No WebGL tests were injured in the making of this cl.
Change-Id: I575b08502f7f4dd63ca7b57f2ca0630367adf0de
Reviewed-on: https://swiftshader-review.googlesource.com/3589
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 59e1065..d268672 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -322,11 +322,14 @@
}
break;
case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
if(visit == PostVisit)
{
- ASSERT(leftType.isStruct());
+ ASSERT(leftType.isStruct() || (leftType.isInterfaceBlock()));
- const TFieldList& fields = leftType.getStruct()->fields();
+ const TFieldList& fields = (node->getOp() == EOpIndexDirectStruct) ?
+ leftType.getStruct()->fields() :
+ leftType.getInterfaceBlock()->fields();
int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0;
@@ -1436,9 +1439,9 @@
return index * type.getElementSize() + componentCount(type, registers);
}
- if(type.isStruct())
+ if(type.isStruct() || type.isInterfaceBlock())
{
- const TFieldList& fields = type.getStruct()->fields();
+ const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
int elements = 0;
for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
@@ -1484,9 +1487,9 @@
return registerSize(type, registers);
}
- if(type.isStruct())
+ if(type.isStruct() || type.isInterfaceBlock())
{
- const TFieldList& fields = type.getStruct()->fields();
+ const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
int elements = 0;
for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
@@ -1559,12 +1562,12 @@
TIntermTyped *left = binary->getLeft();
TIntermTyped *right = binary->getRight();
- if(binary->getOp() == EOpIndexDirect)
+ switch(binary->getOp())
{
+ case EOpIndexDirect:
parameter.index += right->getAsConstantUnion()->getIConst(0);
- }
- else if(binary->getOp() == EOpIndexIndirect)
- {
+ break;
+ case EOpIndexIndirect:
if(left->getArraySize() > 1)
{
parameter.rel.type = registerType(binary->getRight());
@@ -1572,12 +1575,14 @@
parameter.rel.scale = 1;
parameter.rel.deterministic = true;
}
- }
- else if(binary->getOp() == EOpIndexDirectStruct)
- {
+ break;
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
parameter.index += right->getAsConstantUnion()->getIConst(0);
+ break;
+ default:
+ UNREACHABLE(binary->getOp());
}
- else UNREACHABLE(binary->getOp());
}
}
}
@@ -1768,8 +1773,11 @@
}
break;
case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
{
- const TFieldList& fields = left->getType().getStruct()->fields();
+ const TFieldList& fields = (binary->getOp() == EOpIndexDirectStruct) ?
+ left->getType().getStruct()->fields() :
+ left->getType().getInterfaceBlock()->fields();
int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0;
@@ -1975,6 +1983,7 @@
case EOpVectorSwizzle:
case EOpIndexDirect:
case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
return cost(binary->getLeft(), budget - 0);
case EOpAdd:
case EOpSub:
@@ -2156,17 +2165,18 @@
{
const TType &type = uniform->getType();
ASSERT(!IsSampler(type.getBasicType()));
+ TInterfaceBlock *block = type.getAsInterfaceBlock();
TIntermSymbol *symbol = uniform->getAsSymbolNode();
- ASSERT(symbol);
+ ASSERT(symbol || block);
- if(symbol)
+ if(symbol || block)
{
int index = lookup(uniforms, uniform);
if(index == -1)
{
index = allocate(uniforms, uniform);
- const TString &name = symbol->getSymbol().c_str();
+ const TString &name = symbol ? symbol->getSymbol() : block->name();
declareUniform(type, name, index);
}
@@ -2225,7 +2235,8 @@
}
else if(binary)
{
- ASSERT(binary->getOp() == EOpIndexDirect || binary->getOp() == EOpIndexIndirect || binary->getOp() == EOpIndexDirectStruct);
+ ASSERT(binary->getOp() == EOpIndexDirect || binary->getOp() == EOpIndexIndirect ||
+ binary->getOp() == EOpIndexDirectStruct || binary->getOp() == EOpIndexDirectInterfaceBlock);
return samplerRegister(binary->getLeft()); // Index added later
}
@@ -2266,6 +2277,7 @@
}
TIntermSymbol *varSymbol = variable->getAsSymbolNode();
+ TInterfaceBlock *varBlock = variable->getType().getAsInterfaceBlock();
if(varSymbol)
{
@@ -2289,6 +2301,29 @@
}
}
}
+ else if(varBlock)
+ {
+ for(unsigned int i = 0; i < list.size(); i++)
+ {
+ if(list[i])
+ {
+ TInterfaceBlock *listBlock = list[i]->getType().getAsInterfaceBlock();
+
+ if(listBlock)
+ {
+ if(listBlock->name() == varBlock->name())
+ {
+ ASSERT(listBlock->arraySize() == varBlock->arraySize());
+ ASSERT(listBlock->fields() == varBlock->fields());
+ ASSERT(listBlock->blockStorage() == varBlock->blockStorage());
+ ASSERT(listBlock->matrixPacking() == varBlock->matrixPacking());
+
+ return i;
+ }
+ }
+ }
+ }
+ }
return -1;
}
diff --git a/src/OpenGL/compiler/Types.h b/src/OpenGL/compiler/Types.h
index 0457627..cb2722c 100644
--- a/src/OpenGL/compiler/Types.h
+++ b/src/OpenGL/compiler/Types.h
@@ -361,6 +361,7 @@
TInterfaceBlock *getInterfaceBlock() const { return interfaceBlock; }
void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
+ TInterfaceBlock *getAsInterfaceBlock() const { return isInterfaceBlock() ? getInterfaceBlock() : nullptr; }
bool isVector() const { return primarySize > 1 && !isMatrix(); }
bool isScalar() const { return primarySize == 1 && !isMatrix() && !structure; }