Split OutputHLSL structure code into new module.
Refactoring patch only.
BUG=angle:466
Change-Id: I2c57096e1e24574e7de3d35d608645fde3b0c681
Reviewed-on: https://chromium-review.googlesource.com/203730
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 2e88b52..220898e 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -19,6 +19,7 @@
#include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/util.h"
+#include "compiler/translator/StructureHLSL.h"
#include <algorithm>
#include <cfloat>
@@ -27,119 +28,6 @@
namespace sh
{
-class Std140PaddingHelper
-{
- public:
- explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes)
- : mPaddingCounter(0),
- mElementIndex(0),
- mStructElementIndexes(structElementIndexes)
- {}
-
- int elementIndex() const { return mElementIndex; }
-
- int prePadding(const TType &type)
- {
- if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
- {
- // no padding needed, HLSL will align the field to a new register
- mElementIndex = 0;
- return 0;
- }
-
- const GLenum glType = GLVariableType(type);
- const int numComponents = gl::UniformComponentCount(glType);
-
- if (numComponents >= 4)
- {
- // no padding needed, HLSL will align the field to a new register
- mElementIndex = 0;
- return 0;
- }
-
- if (mElementIndex + numComponents > 4)
- {
- // no padding needed, HLSL will align the field to a new register
- mElementIndex = numComponents;
- return 0;
- }
-
- const int alignment = numComponents == 3 ? 4 : numComponents;
- const int paddingOffset = (mElementIndex % alignment);
- const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0);
-
- mElementIndex += paddingCount;
- mElementIndex += numComponents;
- mElementIndex %= 4;
-
- return paddingCount;
- }
-
- TString prePaddingString(const TType &type)
- {
- int paddingCount = prePadding(type);
-
- TString padding;
-
- for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
- {
- padding += " float pad_" + str(mPaddingCounter++) + ";\n";
- }
-
- return padding;
- }
-
- TString postPaddingString(const TType &type, bool useHLSLRowMajorPacking)
- {
- if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
- {
- return "";
- }
-
- int numComponents = 0;
-
- if (type.isMatrix())
- {
- // This method can also be called from structureString, which does not use layout qualifiers.
- // Thus, use the method parameter for determining the matrix packing.
- //
- // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
- // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
- //
- const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
- const GLenum glType = GLVariableType(type);
- numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
- }
- else if (type.getStruct())
- {
- const TString &structName = QualifiedStructNameString(*type.getStruct(), useHLSLRowMajorPacking, true);
- numComponents = mStructElementIndexes.find(structName)->second;
-
- if (numComponents == 0)
- {
- return "";
- }
- }
- else
- {
- const GLenum glType = GLVariableType(type);
- numComponents = gl::UniformComponentCount(glType);
- }
-
- TString padding;
- for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
- {
- padding += " float pad_" + str(mPaddingCounter++) + ";\n";
- }
- return padding;
- }
-
- private:
- int mPaddingCounter;
- int mElementIndex;
- const std::map<TString, int> &mStructElementIndexes;
-};
-
TString OutputHLSL::TextureFunction::name() const
{
TString name = "gl_texture";
@@ -260,6 +148,8 @@
mExcessiveLoopIndex = NULL;
+ mStructureHLSL = new StructureHLSL;
+
if (mOutputType == SH_HLSL9_OUTPUT)
{
if (mContext.shaderType == SH_FRAGMENT_SHADER)
@@ -282,7 +172,8 @@
OutputHLSL::~OutputHLSL()
{
- delete mUnfoldShortCircuit;
+ SafeDelete(mUnfoldShortCircuit);
+ SafeDelete(mStructureHLSL);
}
void OutputHLSL::output()
@@ -426,7 +317,7 @@
{
TString hlsl;
- Std140PaddingHelper padHelper(mStd140StructElementIndexes);
+ Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();
for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
{
@@ -688,15 +579,7 @@
mActiveAttributes.push_back(attributeVar);
}
- for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
- {
- out << *structDeclaration;
- }
-
- for (Constructors::iterator constructor = mConstructors.begin(); constructor != mConstructors.end(); constructor++)
- {
- out << *constructor;
- }
+ out << mStructureHLSL->structsHeader();
if (mUsesDiscardRewriting)
{
@@ -2251,9 +2134,11 @@
if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal))
{
- if (variable->getType().getStruct())
+ TStructure *structure = variable->getType().getStruct();
+
+ if (structure)
{
- addConstructor(variable->getType(), StructNameString(*variable->getType().getStruct()), NULL);
+ mStructureHLSL->addConstructor(variable->getType(), StructNameString(*structure), NULL);
}
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
@@ -2378,9 +2263,11 @@
if (symbol)
{
- if (symbol->getType().getStruct())
+ TStructure *structure = symbol->getType().getStruct();
+
+ if (structure)
{
- addConstructor(symbol->getType(), StructNameString(*symbol->getType().getStruct()), NULL);
+ mStructureHLSL->addConstructor(symbol->getType(), StructNameString(*structure), NULL);
}
out << argumentString(symbol);
@@ -2593,7 +2480,7 @@
case EOpConstructStruct:
{
const TString &structName = StructNameString(*node->getType().getStruct());
- addConstructor(node->getType(), structName, &node->getSequence());
+ mStructureHLSL->addConstructor(node->getType(), structName, &node->getSequence());
outputTriplet(visit, structName + "_ctor(", ", ", ")");
}
break;
@@ -3194,73 +3081,13 @@
return "{" + string + "}";
}
-TString OutputHLSL::defineNamelessStruct(const TStructure &structure)
-{
- return defineStruct(structure, false, false, NULL);
-}
-
-TString OutputHLSL::defineQualifiedStruct(const TStructure &structure, bool useHLSLRowMajorPacking,
- bool useStd140Packing)
-{
- if (useStd140Packing)
- {
- Std140PaddingHelper padHelper(mStd140StructElementIndexes);
- return defineStruct(structure, useHLSLRowMajorPacking, true, &padHelper);
- }
- else
- {
- return defineStruct(structure, useHLSLRowMajorPacking, false, NULL);
- }
-}
-
-TString OutputHLSL::defineStruct(const TStructure &structure, bool useHLSLRowMajorPacking,
- bool useStd140Packing, Std140PaddingHelper *padHelper)
-{
- const TFieldList &fields = structure.fields();
- const bool isNameless = (structure.name() == "");
- const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing);
- const TString declareString = (isNameless ? "struct" : "struct " + structName);
-
- TString string;
- string += declareString + "\n"
- "{\n";
-
- for (unsigned int i = 0; i < fields.size(); i++)
- {
- const TField &field = *fields[i];
- const TType &fieldType = *field.type();
- const TStructure *fieldStruct = fieldType.getStruct();
- const TString &fieldTypeString = fieldStruct ?
- QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
- useStd140Packing) :
- TypeString(fieldType);
-
- if (padHelper)
- {
- string += padHelper->prePaddingString(fieldType);
- }
-
- string += " " + fieldTypeString + " " + DecorateField(field.name(), structure) + ArrayString(fieldType) + ";\n";
-
- if (padHelper)
- {
- string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking);
- }
- }
-
- // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable
- string += (isNameless ? "} " : "};\n");
-
- return string;
-}
-
void OutputHLSL::outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters)
{
TInfoSinkBase &out = mBody;
if (visit == PreVisit)
{
- addConstructor(type, name, parameters);
+ mStructureHLSL->addConstructor(type, name, parameters);
out << name + "(";
}
@@ -3274,277 +3101,6 @@
}
}
-void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
-{
- if (name == "")
- {
- return; // Nameless structures don't have constructors
- }
-
- if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
- {
- return; // Already added
- }
-
- TType ctorType = type;
- ctorType.clearArrayness();
- ctorType.setPrecision(EbpHigh);
- ctorType.setQualifier(EvqTemporary);
-
- typedef std::vector<TType> ParameterArray;
- ParameterArray ctorParameters;
-
- const TStructure* structure = type.getStruct();
- if (structure)
- {
- mStructNames.insert(name);
-
- // Add element index
- storeStd140ElementIndex(*structure, false);
- storeStd140ElementIndex(*structure, true);
-
- const TString &structString = defineQualifiedStruct(*structure, false, false);
-
- if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end())
- {
- // Add row-major packed struct for interface blocks
- TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
- defineQualifiedStruct(*structure, true, false) +
- "#pragma pack_matrix(column_major)\n";
-
- TString std140String = defineQualifiedStruct(*structure, false, true);
- TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
- defineQualifiedStruct(*structure, true, true) +
- "#pragma pack_matrix(column_major)\n";
-
- mStructDeclarations.push_back(structString);
- mStructDeclarations.push_back(rowMajorString);
- mStructDeclarations.push_back(std140String);
- mStructDeclarations.push_back(std140RowMajorString);
- }
-
- const TFieldList &fields = structure->fields();
- for (unsigned int i = 0; i < fields.size(); i++)
- {
- ctorParameters.push_back(*fields[i]->type());
- }
- }
- else if (parameters)
- {
- for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
- {
- ctorParameters.push_back((*parameter)->getAsTyped()->getType());
- }
- }
- else UNREACHABLE();
-
- TString constructor;
-
- if (ctorType.getStruct())
- {
- constructor += name + " " + name + "_ctor(";
- }
- else // Built-in type
- {
- constructor += TypeString(ctorType) + " " + name + "(";
- }
-
- for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
- {
- const TType &type = ctorParameters[parameter];
-
- constructor += TypeString(type) + " x" + str(parameter) + ArrayString(type);
-
- if (parameter < ctorParameters.size() - 1)
- {
- constructor += ", ";
- }
- }
-
- constructor += ")\n"
- "{\n";
-
- if (ctorType.getStruct())
- {
- constructor += " " + name + " structure = {";
- }
- else
- {
- constructor += " return " + TypeString(ctorType) + "(";
- }
-
- if (ctorType.isMatrix() && ctorParameters.size() == 1)
- {
- int rows = ctorType.getRows();
- int cols = ctorType.getCols();
- const TType ¶meter = ctorParameters[0];
-
- if (parameter.isScalar())
- {
- for (int row = 0; row < rows; row++)
- {
- for (int col = 0; col < cols; col++)
- {
- constructor += TString((row == col) ? "x0" : "0.0");
-
- if (row < rows - 1 || col < cols - 1)
- {
- constructor += ", ";
- }
- }
- }
- }
- else if (parameter.isMatrix())
- {
- for (int row = 0; row < rows; row++)
- {
- for (int col = 0; col < cols; col++)
- {
- if (row < parameter.getRows() && col < parameter.getCols())
- {
- constructor += TString("x0") + "[" + str(row) + "][" + str(col) + "]";
- }
- else
- {
- constructor += TString((row == col) ? "1.0" : "0.0");
- }
-
- if (row < rows - 1 || col < cols - 1)
- {
- constructor += ", ";
- }
- }
- }
- }
- else
- {
- ASSERT(rows == 2 && cols == 2 && parameter.isVector() && parameter.getNominalSize() == 4);
-
- constructor += "x0";
- }
- }
- else
- {
- size_t remainingComponents = ctorType.getObjectSize();
- size_t parameterIndex = 0;
-
- while (remainingComponents > 0)
- {
- const TType ¶meter = ctorParameters[parameterIndex];
- const size_t parameterSize = parameter.getObjectSize();
- bool moreParameters = parameterIndex + 1 < ctorParameters.size();
-
- constructor += "x" + str(parameterIndex);
-
- if (ctorType.getStruct())
- {
- ASSERT(remainingComponents == parameterSize || moreParameters);
- ASSERT(parameterSize <= remainingComponents);
-
- remainingComponents -= parameterSize;
- }
- else if (parameter.isScalar())
- {
- remainingComponents -= parameter.getObjectSize();
- }
- else if (parameter.isVector())
- {
- if (remainingComponents == parameterSize || moreParameters)
- {
- ASSERT(parameterSize <= remainingComponents);
- remainingComponents -= parameterSize;
- }
- else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
- {
- switch (remainingComponents)
- {
- case 1: constructor += ".x"; break;
- case 2: constructor += ".xy"; break;
- case 3: constructor += ".xyz"; break;
- case 4: constructor += ".xyzw"; break;
- default: UNREACHABLE();
- }
-
- remainingComponents = 0;
- }
- else UNREACHABLE();
- }
- else if (parameter.isMatrix())
- {
- int column = 0;
- while (remainingComponents > 0 && column < parameter.getCols())
- {
- constructor += "[" + str(column) + "]";
-
- if (remainingComponents < static_cast<size_t>(parameter.getRows()))
- {
- switch (remainingComponents)
- {
- case 1: constructor += ".x"; break;
- case 2: constructor += ".xy"; break;
- case 3: constructor += ".xyz"; break;
- default: UNREACHABLE();
- }
-
- remainingComponents = 0;
- }
- else
- {
- remainingComponents -= parameter.getRows();
-
- if (remainingComponents > 0)
- {
- constructor += ", x" + str(parameterIndex);
- }
- }
-
- column++;
- }
- }
- else UNREACHABLE();
-
- if (moreParameters)
- {
- parameterIndex++;
- }
-
- if (remainingComponents)
- {
- constructor += ", ";
- }
- }
- }
-
- if (ctorType.getStruct())
- {
- constructor += "};\n"
- " return structure;\n"
- "}\n";
- }
- else
- {
- constructor += ");\n"
- "}\n";
- }
-
- mConstructors.insert(constructor);
-}
-
-void OutputHLSL::storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking)
-{
- Std140PaddingHelper padHelper(mStd140StructElementIndexes);
- const TFieldList &fields = structure.fields();
-
- for (unsigned int i = 0; i < fields.size(); i++)
- {
- padHelper.prePadding(*fields[i]->type());
- }
-
- // Add remaining element index to the global map, for use with nested structs in standard layouts
- const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true);
- mStd140StructElementIndexes[structName] = padHelper.elementIndex();
-}
-
const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const ConstantUnion *constUnion)
{
TInfoSinkBase &out = mBody;