Vulkan: Support struct initializers in shaders
Also adds a new test in GLSLTest to validate the initialization of
a struct on the same line as its declaration.
Bug: angleproject:2459
Change-Id: Ib37e20378f8ec76541db26392663bcba03390756
Reviewed-on: https://chromium-review.googlesource.com/1017340
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index fd1958c..14140eb 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -314,11 +314,6 @@
const TStructure *structure = type.getStruct();
declareStruct(structure);
-
- if (structure->symbolType() != SymbolType::Empty)
- {
- mDeclaredStructs.insert(structure->uniqueId().get());
- }
}
else if (type.getBasicType() == EbtInterfaceBlock)
{
@@ -1180,6 +1175,11 @@
out << ";\n";
}
out << "}";
+
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ mDeclaredStructs.insert(structure->uniqueId().get());
+ }
}
void TOutputGLSLBase::declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock)
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index 272d276..20c2146 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -78,9 +78,9 @@
void declareStruct(const TStructure *structure);
virtual void writeQualifier(TQualifier qualifier, const TSymbol *symbol);
+ bool structDeclared(const TStructure *structure) const;
private:
- bool structDeclared(const TStructure *structure) const;
void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock);
void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock);
diff --git a/src/compiler/translator/OutputVulkanGLSL.cpp b/src/compiler/translator/OutputVulkanGLSL.cpp
index c4b44b1..99b0e40 100644
--- a/src/compiler/translator/OutputVulkanGLSL.cpp
+++ b/src/compiler/translator/OutputVulkanGLSL.cpp
@@ -106,8 +106,11 @@
void TOutputVulkanGLSL::writeStructType(const TStructure *structure)
{
- declareStruct(structure);
- objSink() << ";\n";
+ if (!structDeclared(structure))
+ {
+ declareStruct(structure);
+ objSink() << ";\n";
+ }
}
} // namespace sh
diff --git a/src/compiler/translator/TranslatorVulkan.cpp b/src/compiler/translator/TranslatorVulkan.cpp
index f427d56..2dd790e 100644
--- a/src/compiler/translator/TranslatorVulkan.cpp
+++ b/src/compiler/translator/TranslatorVulkan.cpp
@@ -41,9 +41,6 @@
if (!mInGlobalScope)
{
- // We only want to declare the global structs in this traverser.
- // TODO(lucferron): Add a test in GLSLTest for this specific case.
- // http://anglebug.com/2459
return false;
}
@@ -53,22 +50,16 @@
if (type.isStructSpecifier())
{
- TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
- if (symbolNode != nullptr && symbolNode->variable().symbolType() == SymbolType::Empty)
- {
- mOutputVulkanGLSL->writeStructType(type.getStruct());
+ mOutputVulkanGLSL->writeStructType(type.getStruct());
+ TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
+ if (symbolNode && symbolNode->variable().symbolType() == SymbolType::Empty)
+ {
// Remove the struct specifier declaration from the tree so it isn't parsed again.
TIntermSequence emptyReplacement;
mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
emptyReplacement);
}
- else
- {
- // TODO(lucferron): Support structs with initializers correctly.
- // http://anglebug.com/2459
- UNIMPLEMENTED();
- }
}
return false;
@@ -256,7 +247,7 @@
bool hasGLFragColor = false;
bool hasGLFragData = false;
- for (const auto &outputVar : outputVariables)
+ for (const OutputVariable &outputVar : outputVariables)
{
if (outputVar.name == "gl_FragColor")
{