Commit 4d59f3c6 by Olli Etuaho

Make false blocks produced by RewriteElseBlocks sequence nodes

All child nodes of selection should be sequence nodes, so that they will output braces and extra braces can be removed from HLSL output. Also make RewriteElseBlocks to reuse common IntermTraverser functionality to simplify the code. TEST=WebGL conformance tests on D3D9 BUG=angleproject:1013 Change-Id: Iafdc05468b22d110abcd020cf52c646dd98fb4a0 Reviewed-on: https://chromium-review.googlesource.com/273608Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 46ccef19
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/NodeSearch.h" #include "compiler/translator/NodeSearch.h"
#include "compiler/translator/RemoveSwitchFallThrough.h" #include "compiler/translator/RemoveSwitchFallThrough.h"
#include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/SearchSymbol.h" #include "compiler/translator/SearchSymbol.h"
#include "compiler/translator/StructureHLSL.h" #include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/TranslatorHLSL.h" #include "compiler/translator/TranslatorHLSL.h"
...@@ -168,13 +167,6 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink) ...@@ -168,13 +167,6 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(treeRoot); const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(treeRoot);
makeFlaggedStructMaps(flaggedStructs); makeFlaggedStructMaps(flaggedStructs);
// Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
// use a vertex attribute as a condition, and some related computation in the else block.
if (mOutputType == SH_HLSL9_OUTPUT && mShaderType == GL_VERTEX_SHADER)
{
RewriteElseBlocks(treeRoot);
}
BuiltInFunctionEmulator builtInFunctionEmulator; BuiltInFunctionEmulator builtInFunctionEmulator;
InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator); InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator);
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot); builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot);
......
...@@ -32,23 +32,6 @@ class ElseBlockRewriter : public TIntermTraverser ...@@ -32,23 +32,6 @@ class ElseBlockRewriter : public TIntermTraverser
TIntermNode *rewriteSelection(TIntermSelection *selection); TIntermNode *rewriteSelection(TIntermSelection *selection);
}; };
TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type)
{
TType variableType(type, EbpHigh, EvqTemporary);
TIntermSymbol *node = new TIntermSymbol(-1, name, variableType);
node->setInternal(true);
return node;
}
TIntermBinary *MakeNewBinary(TOperator op, TIntermTyped *left, TIntermTyped *right, const TType &resultType)
{
TIntermBinary *binary = new TIntermBinary(op);
binary->setLeft(left);
binary->setRight(right);
binary->setType(resultType);
return binary;
}
TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand) TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
{ {
TIntermUnary *unary = new TIntermUnary(op, operand->getType()); TIntermUnary *unary = new TIntermUnary(op, operand->getType());
...@@ -73,7 +56,7 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -73,7 +56,7 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
TIntermNode *statement = (*node->getSequence())[statementIndex]; TIntermNode *statement = (*node->getSequence())[statementIndex];
TIntermSelection *selection = statement->getAsSelectionNode(); TIntermSelection *selection = statement->getAsSelectionNode();
if (selection && selection->getFalseBlock() != NULL) if (selection && selection->getFalseBlock() != nullptr)
{ {
// Check for if / else if // Check for if / else if
TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode(); TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode();
...@@ -103,20 +86,20 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -103,20 +86,20 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
{ {
ASSERT(selection != NULL); ASSERT(selection != nullptr);
nextTemporaryIndex();
TString temporaryName = "cond_" + str(mTemporaryIndex++);
TIntermTyped *typedCondition = selection->getCondition()->getAsTyped(); TIntermTyped *typedCondition = selection->getCondition()->getAsTyped();
TType resultType(EbtBool, EbpUndefined); TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition);
TIntermSymbol *conditionSymbolInit = MakeNewTemporary(temporaryName, EbtBool);
TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolInit,
typedCondition, resultType);
TIntermNode *negatedElse = NULL;
TIntermSelection *falseBlock = NULL; TIntermSelection *falseBlock = nullptr;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
if (selection->getFalseBlock()) if (selection->getFalseBlock())
{ {
TIntermAggregate *negatedElse = nullptr;
// crbug.com/346463 // crbug.com/346463
// D3D generates error messages claiming a function has no return value, when rewriting // D3D generates error messages claiming a function has no return value, when rewriting
// an if-else clause that returns something non-void in a function. By appending dummy // an if-else clause that returns something non-void in a function. By appending dummy
...@@ -126,24 +109,22 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) ...@@ -126,24 +109,22 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() : TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() :
mFunctionType->getBasicString(); mFunctionType->getBasicString();
TString rawText = "return (" + typeString + ")0"; TString rawText = "return (" + typeString + ")0";
negatedElse = new TIntermRaw(*mFunctionType, rawText); TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText);
negatedElse = new TIntermAggregate(EOpSequence);
negatedElse->getSequence()->push_back(returnNode);
} }
TIntermSymbol *conditionSymbolElse = MakeNewTemporary(temporaryName, EbtBool); TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType);
TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse); TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse);
falseBlock = new TIntermSelection(negatedCondition, falseBlock = new TIntermSelection(negatedCondition,
selection->getFalseBlock(), negatedElse); selection->getFalseBlock(), negatedElse);
} }
TIntermSymbol *conditionSymbolSel = MakeNewTemporary(temporaryName, EbtBool); TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, selection->getTrueBlock(), falseBlock);
selection->getTrueBlock(), falseBlock);
TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration);
declaration->getSequence()->push_back(storeCondition);
TIntermAggregate *block = new TIntermAggregate(EOpSequence); TIntermAggregate *block = new TIntermAggregate(EOpSequence);
block->getSequence()->push_back(declaration); block->getSequence()->push_back(storeCondition);
block->getSequence()->push_back(newSelection); block->getSequence()->push_back(newSelection);
return block; return block;
...@@ -151,9 +132,10 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) ...@@ -151,9 +132,10 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
} }
void RewriteElseBlocks(TIntermNode *node) void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex)
{ {
ElseBlockRewriter rewriter; ElseBlockRewriter rewriter;
rewriter.useTemporaryIndex(temporaryIndex);
node->traverse(&rewriter); node->traverse(&rewriter);
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
namespace sh namespace sh
{ {
void RewriteElseBlocks(TIntermNode *node); void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex);
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "compiler/translator/ArrayReturnValueToOutParameter.h" #include "compiler/translator/ArrayReturnValueToOutParameter.h"
#include "compiler/translator/OutputHLSL.h" #include "compiler/translator/OutputHLSL.h"
#include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/SeparateArrayInitialization.h" #include "compiler/translator/SeparateArrayInitialization.h"
#include "compiler/translator/SeparateDeclarations.h" #include "compiler/translator/SeparateDeclarations.h"
#include "compiler/translator/SeparateExpressionsReturningArrays.h" #include "compiler/translator/SeparateExpressionsReturningArrays.h"
...@@ -39,6 +40,13 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions) ...@@ -39,6 +40,13 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions)
// as a return value to use an out parameter to transfer the array data instead. // as a return value to use an out parameter to transfer the array data instead.
ArrayReturnValueToOutParameter(root, &temporaryIndex); ArrayReturnValueToOutParameter(root, &temporaryIndex);
// Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
// use a vertex attribute as a condition, and some related computation in the else block.
if (getOutputType() == SH_HLSL9_OUTPUT && getShaderType() == GL_VERTEX_SHADER)
{
sh::RewriteElseBlocks(root, &temporaryIndex);
}
sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), compileOptions); getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), compileOptions);
......
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