Commit d93b9559 by Xinghua Cao Committed by Commit Bot

Translate uniform block with large matrix array to StructuredBuffer

There is a slow compiling issue if translate a uniform block with a large matrix array member to cbuffer, so translate the uniform block to StructuredBuffer. But pack_matrix pragma directive is invalid for matrix element of StructuredBuffer, so pack the matrix into a structure firstly, and then specifies packing alignment for the matrix in this structure, last the structure is used as StructuredBuffer element. Bug: angleproject:4206 Change-Id: I5a2a512e57b37dcdb88c3060d0d078b46f72eb5e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2154525 Commit-Queue: Xinghua Cao <xinghua.cao@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org>
parent 853a03f9
...@@ -86,28 +86,31 @@ bool IsInStd140UniformBlock(TIntermTyped *node) ...@@ -86,28 +86,31 @@ bool IsInStd140UniformBlock(TIntermTyped *node)
return false; return false;
} }
bool IsInstanceUniformBlock(TIntermTyped *node) const TInterfaceBlock *GetInterfaceBlockOfUniformBlockNearestIndexOperator(TIntermTyped *node)
{ {
TIntermBinary *binaryNode = node->getAsBinaryNode(); const TIntermBinary *binaryNode = node->getAsBinaryNode();
if (binaryNode) if (binaryNode)
{ {
return IsInstanceUniformBlock(binaryNode->getLeft()); if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
{
return binaryNode->getLeft()->getType().getInterfaceBlock();
}
} }
const TVariable &variable = node->getAsSymbolNode()->variable(); const TIntermSymbol *symbolNode = node->getAsSymbolNode();
const TType &variableType = variable.getType(); if (symbolNode)
const TType &type = node->getType();
if (type.getQualifier() == EvqUniform)
{ {
// determine if it is instance uniform block. const TVariable &variable = symbolNode->variable();
const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); const TType &variableType = variable.getType();
return interfaceBlock && variableType.isInterfaceBlock();
if (variableType.getQualifier() == EvqUniform &&
variable.symbolType() == SymbolType::UserDefined)
{
return variableType.getInterfaceBlock();
}
} }
return false; return nullptr;
} }
const char *GetHLSLAtomicFunctionStringAndLeftParenthesis(TOperator op) const char *GetHLSLAtomicFunctionStringAndLeftParenthesis(TOperator op)
...@@ -1634,6 +1637,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1634,6 +1637,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
else else
{ {
outputTriplet(out, visit, "", "[", "]"); outputTriplet(out, visit, "", "[", "]");
if (visit == PostVisit)
{
const TInterfaceBlock *interfaceBlock =
GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
if (interfaceBlock &&
mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(
*interfaceBlock))
{
const TField *field = interfaceBlock->fields()[0];
if (field->type()->isMatrix())
{
out << "._matrix_" << Decorate(field->name());
}
}
}
} }
} }
break; break;
...@@ -1650,6 +1668,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1650,6 +1668,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
else else
{ {
outputTriplet(out, visit, "", "[", "]"); outputTriplet(out, visit, "", "[", "]");
if (visit == PostVisit)
{
const TInterfaceBlock *interfaceBlock =
GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
if (interfaceBlock &&
mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(
*interfaceBlock))
{
const TField *field = interfaceBlock->fields()[0];
if (field->type()->isMatrix())
{
out << "._matrix_" << Decorate(field->name());
}
}
}
} }
break; break;
} }
...@@ -1707,11 +1740,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1707,11 +1740,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
node->getLeft()->getType().getInterfaceBlock(); node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = interfaceBlock->fields()[index->getIConst(0)]; const TField *field = interfaceBlock->fields()[index->getIConst(0)];
bool instanceUniformBlock = IsInstanceUniformBlock(node->getLeft());
if (structInStd140UniformBlock || if (structInStd140UniformBlock ||
(instanceUniformBlock && mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(*interfaceBlock))
mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(
*interfaceBlock)))
{ {
out << "_"; out << "_";
} }
...@@ -3621,5 +3651,4 @@ const char *OutputHLSL::generateOutputCall() const ...@@ -3621,5 +3651,4 @@ const char *OutputHLSL::generateOutputCall() const
return "generateOutput()"; return "generateOutput()";
} }
} }
} // namespace sh } // namespace sh
...@@ -779,7 +779,17 @@ TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString( ...@@ -779,7 +779,17 @@ TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString(
const TField &field = *interfaceBlock.fields()[0]; const TField &field = *interfaceBlock.fields()[0];
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage(); const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
typeString = InterfaceBlockFieldTypeString(field, blockStorage, true); typeString = InterfaceBlockFieldTypeString(field, blockStorage, true);
const TType &fieldType = *field.type();
if (fieldType.isMatrix())
{
if (arrayIndex == GL_INVALID_INDEX || arrayIndex == 0)
{
hlsl += "struct matrix" + Decorate(field.name()) + " { " + typeString + " _matrix_" +
Decorate(field.name()) + "; };\n";
}
typeString = "matrix" + Decorate(field.name());
}
if (instanceVariable != nullptr) if (instanceVariable != nullptr)
{ {
...@@ -879,11 +889,10 @@ bool ResourcesHLSL::shouldTranslateUniformBlockToStructuredBuffer( ...@@ -879,11 +889,10 @@ bool ResourcesHLSL::shouldTranslateUniformBlockToStructuredBuffer(
{ {
const TType &fieldType = *interfaceBlock.fields()[0]->type(); const TType &fieldType = *interfaceBlock.fields()[0]->type();
// TODO(anglebug.com/4206): Support uniform block contains only a matrix array member,
// and fix row-major/column-major conversion issue.
return (mCompileOptions & SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER) == 0 && return (mCompileOptions & SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER) == 0 &&
mSRVRegister < kMaxInputResourceSlotCount && interfaceBlock.fields().size() == 1u && mSRVRegister < kMaxInputResourceSlotCount && interfaceBlock.fields().size() == 1u &&
fieldType.getStruct() != nullptr && fieldType.getNumArraySizes() == 1u && (fieldType.getStruct() != nullptr || fieldType.isMatrix()) &&
fieldType.getNumArraySizes() == 1u &&
fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer; fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer;
} }
} // namespace sh } // namespace sh
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment