Clean up HLSL constructor output
Split generating HLSL struct constructors from generating built-in
type constructors, as these didn't have much in common. Struct
constructors are now only generated when they are needed, as opposed
to before, when they were generated on any use of a struct.
This changes built-in constructor naming to include "_ctor" and gets
rid of having special built-in type names just for constructors.
This will make it easier to do changes to constructor output, for
example to add constructors for structs in std140 layout. This might
be needed to implement SSBOs efficiently.
This includes one bug fix for writing out struct declarations for
varyings.
Also improves const-correctness of accessing structs through TType
in general.
BUG=angleproject:2218
TEST=angle_unittests, angle_end2end_tests
Change-Id: If865fb56f86486b9c4a2c31e016ea16427f4a5fa
Reviewed-on: https://chromium-review.googlesource.com/753883
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 7e84761..bb18beb 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -878,11 +878,13 @@
}
else
{
+ const TType &nodeType = node->getType();
TQualifier qualifier = node->getQualifier();
+ ensureStructDefined(nodeType);
+
if (qualifier == EvqUniform)
{
- const TType &nodeType = node->getType();
const TInterfaceBlock *interfaceBlock = nodeType.getInterfaceBlock();
if (interfaceBlock)
@@ -894,8 +896,6 @@
mReferencedUniforms[name] = node;
}
- ensureStructDefined(nodeType);
-
out << DecorateVariableIfNeeded(node->getName());
}
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
@@ -1654,7 +1654,7 @@
}
case EOpIndexDirectStruct:
{
- TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct();
+ const TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct();
int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
const TField *field = s->fields()[index];
@@ -1821,7 +1821,8 @@
else if (variable->getAsSymbolNode() &&
variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
{
- // Already added to constructor map
+ ASSERT(variable->getBasicType() == EbtStruct);
+ // ensureStructDefined has already been called.
}
else
UNREACHABLE();
@@ -1992,45 +1993,7 @@
return false;
}
case EOpConstruct:
- if (node->getBasicType() == EbtStruct)
- {
- if (node->getType().isArray())
- {
- UNIMPLEMENTED();
- }
- const TString &structName = StructNameString(*node->getType().getStruct());
- mStructureHLSL->addConstructor(node->getType(), structName, node->getSequence());
- outputTriplet(out, visit, (structName + "_ctor(").c_str(), ", ", ")");
- }
- else
- {
- const char *name = "";
- if (node->getType().getNominalSize() == 1)
- {
- switch (node->getBasicType())
- {
- case EbtFloat:
- name = "vec1";
- break;
- case EbtInt:
- name = "ivec1";
- break;
- case EbtUInt:
- name = "uvec1";
- break;
- case EbtBool:
- name = "bvec1";
- break;
- default:
- UNREACHABLE();
- }
- }
- else
- {
- name = node->getType().getBuiltInTypeNameString();
- }
- outputConstructor(out, visit, node->getType(), name, node->getSequence());
- }
+ outputConstructor(out, visit, node);
break;
case EOpEqualComponentWise:
outputTriplet(out, visit, "(", " == ", ")");
@@ -2742,21 +2705,23 @@
return "{" + string + "}";
}
-void OutputHLSL::outputConstructor(TInfoSinkBase &out,
- Visit visit,
- const TType &type,
- const char *name,
- const TIntermSequence *parameters)
+void OutputHLSL::outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node)
{
- if (type.isArray())
- {
- UNIMPLEMENTED();
- }
+ // Array constructors should have been already pruned from the code.
+ ASSERT(!node->getType().isArray());
if (visit == PreVisit)
{
- TString constructorName = mStructureHLSL->addConstructor(type, name, parameters);
-
+ TString constructorName;
+ if (node->getBasicType() == EbtStruct)
+ {
+ constructorName = mStructureHLSL->addStructConstructor(*node->getType().getStruct());
+ }
+ else
+ {
+ constructorName =
+ mStructureHLSL->addBuiltInConstructor(node->getType(), node->getSequence());
+ }
out << constructorName << "(";
}
else if (visit == InVisit)
@@ -2778,7 +2743,7 @@
const TStructure *structure = type.getStruct();
if (structure)
{
- out << StructNameString(*structure) + "_ctor(";
+ out << mStructureHLSL->addStructConstructor(*structure) << "(";
const TFieldList &fields = structure->fields();
@@ -3105,11 +3070,11 @@
void OutputHLSL::ensureStructDefined(const TType &type)
{
- TStructure *structure = type.getStruct();
-
+ const TStructure *structure = type.getStruct();
if (structure)
{
- mStructureHLSL->addConstructor(type, StructNameString(*structure), nullptr);
+ ASSERT(type.getBasicType() == EbtStruct);
+ mStructureHLSL->ensureStructDefined(*structure);
}
}