Alter array instanced uniform buffer objects to use direct references to HLSL constant buffers.
This avoids using a shader scoped static storage buffer, with copies.
TRAC #23299
Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Authored-by: Jamie Madill
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index f183ab5..2bf96e5 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -291,7 +291,6 @@
TString uniforms;
TString interfaceBlocks;
- TString interfaceBlockInit;
TString varyings;
TString attributes;
@@ -346,16 +345,9 @@
if (arraySize > 0)
{
- interfaceBlocks += "static " + interfaceBlockStructName(interfaceBlockType) + " " + decorate(interfaceBlockType.getInstanceName()) +
- arrayString(interfaceBlockType) + ";\n\n";
-
for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
interfaceBlocks += interfaceBlockString(interfaceBlockType, interfaceBlock.registerIndex + arrayIndex, arrayIndex);
-
- const TString &instanceName = interfaceBlockType.getInstanceName();
- interfaceBlockInit += " " + decorate(instanceName) + "[" + str(arrayIndex) + "] = " +
- interfaceBlockInstanceString(interfaceBlockType, arrayIndex) + ";\n";
}
}
else
@@ -364,14 +356,6 @@
}
}
- if (!interfaceBlockInit.empty())
- {
- interfaceBlocks += "void dx_initConstantBuffers()\n"
- "{\n" +
- interfaceBlockInit +
- "}\n\n";
- }
-
for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
{
const TType &type = varying->second->getType();
@@ -1566,8 +1550,27 @@
}
break;
case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break;
- case EOpIndexDirect: outputTriplet(visit, "", "[", "]"); break;
- case EOpIndexIndirect: outputTriplet(visit, "", "[", "]"); break;
+ case EOpIndexDirect:
+ if (node->getLeft()->getBasicType() == EbtInterfaceBlock)
+ {
+ if (visit == PreVisit)
+ {
+ const TType &interfaceBlockType = node->getLeft()->getType();
+ mReferencedInterfaceBlocks[interfaceBlockType.getInstanceName()] = node->getLeft()->getAsSymbolNode();
+ out << interfaceBlockInstanceString(interfaceBlockType, node->getRight()->getAsConstantUnion()->getIConst(0));
+ return false;
+ }
+ }
+ else
+ {
+ outputTriplet(visit, "", "[", "]");
+ }
+ break;
+ case EOpIndexIndirect:
+ // We do not currently support indirect references to interface blocks
+ ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock);
+ outputTriplet(visit, "", "[", "]");
+ break;
case EOpIndexDirectStruct:
case EOpIndexDirectInterfaceBlock:
if (visit == InVisit)