Commit e53c98ba by Jamie Madill

Add work-around for D3D9 shader compiler bug.

With certain selection statements with a vertex input in the condition and side-effects in the else-block, we'd run in to a D3D9 compiler bug which would cause incorrect results. We can work around this bug in D3D9 by selectively rewriting these statements to use an 'else if' clause instead of 'else'. BUG=322794 Change-Id: I93c96fb201ff4959c00d9a36321faac7e0343278 Reviewed-on: https://chromium-review.googlesource.com/184681Reviewed-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 7993190b
...@@ -133,6 +133,7 @@ ...@@ -133,6 +133,7 @@
<ClInclude Include="..\..\src\compiler\translator\OutputGLSL.h"/> <ClInclude Include="..\..\src\compiler\translator\OutputGLSL.h"/>
<ClInclude Include="..\..\src\compiler\translator\FlagStd140Structs.h"/> <ClInclude Include="..\..\src\compiler\translator\FlagStd140Structs.h"/>
<ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h"/> <ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h"/>
<ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h"/>
<ClInclude Include="..\..\src\compiler\translator\PoolAlloc.h"/> <ClInclude Include="..\..\src\compiler\translator\PoolAlloc.h"/>
<ClInclude Include="..\..\src\compiler\translator\BuiltInFunctionEmulator.h"/> <ClInclude Include="..\..\src\compiler\translator\BuiltInFunctionEmulator.h"/>
<ClInclude Include="..\..\src\compiler\translator\ValidateOutputs.h"/> <ClInclude Include="..\..\src\compiler\translator\ValidateOutputs.h"/>
...@@ -188,11 +189,11 @@ ...@@ -188,11 +189,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\third_party\compiler\ArrayBoundsClamper.cpp"/> <ClCompile Include="..\..\src\third_party\compiler\ArrayBoundsClamper.cpp"/>
<ClCompile Include="..\..\src\common\event_tracer.cpp"/>
<ClCompile Include="..\..\src\common\utilities.cpp"/> <ClCompile Include="..\..\src\common\utilities.cpp"/>
<ClCompile Include="..\..\src\common\RefCountObject.cpp"/> <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
<ClCompile Include="..\..\src\common\mathutil.cpp"/> <ClCompile Include="..\..\src\common\mathutil.cpp"/>
<ClCompile Include="..\..\src\common\debug.cpp"/> <ClCompile Include="..\..\src\common\debug.cpp"/>
<ClCompile Include="..\..\src\common\event_tracer.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\HLSLLayoutEncoder.cpp"/> <ClCompile Include="..\..\src\compiler\translator\HLSLLayoutEncoder.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\InfoSink.cpp"/> <ClCompile Include="..\..\src\compiler\translator\InfoSink.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\OutputESSL.cpp"/> <ClCompile Include="..\..\src\compiler\translator\OutputESSL.cpp"/>
...@@ -209,6 +210,7 @@ ...@@ -209,6 +210,7 @@
<ClCompile Include="..\..\src\compiler\translator\PoolAlloc.cpp"/> <ClCompile Include="..\..\src\compiler\translator\PoolAlloc.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\BlockLayoutEncoder.cpp"/> <ClCompile Include="..\..\src\compiler\translator\BlockLayoutEncoder.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\ossource_win.cpp"/> <ClCompile Include="..\..\src\compiler\translator\ossource_win.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\RewriteElseBlocks.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"/> <ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\QualifierAlive.cpp"/> <ClCompile Include="..\..\src\compiler\translator\QualifierAlive.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\util.cpp"/> <ClCompile Include="..\..\src\compiler\translator\util.cpp"/>
......
...@@ -43,9 +43,6 @@ ...@@ -43,9 +43,6 @@
<ClInclude Include="..\..\src\common\event_tracer.h"> <ClInclude Include="..\..\src\common\event_tracer.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\common\event_tracer.cpp">
<Filter>common</Filter>
</ClCompile>
<ClInclude Include="..\..\src\common\commit.h"> <ClInclude Include="..\..\src\common\commit.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
...@@ -67,6 +64,9 @@ ...@@ -67,6 +64,9 @@
<ClInclude Include="..\..\src\common\version.h"> <ClInclude Include="..\..\src\common\version.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\common\event_tracer.cpp">
<Filter>common</Filter>
</ClCompile>
<ClInclude Include="..\..\src\common\utilities.h"> <ClInclude Include="..\..\src\common\utilities.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
...@@ -118,6 +118,9 @@ ...@@ -118,6 +118,9 @@
<ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h"> <ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h">
<Filter>compiler\translator</Filter>
</ClInclude>
<ClCompile Include="..\..\src\compiler\translator\TranslatorHLSL.cpp"> <ClCompile Include="..\..\src\compiler\translator\TranslatorHLSL.cpp">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClCompile> </ClCompile>
...@@ -181,6 +184,9 @@ ...@@ -181,6 +184,9 @@
<ClInclude Include="..\..\src\compiler\translator\ConstantUnion.h"> <ClInclude Include="..\..\src\compiler\translator\ConstantUnion.h">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\compiler\translator\RewriteElseBlocks.cpp">
<Filter>compiler\translator</Filter>
</ClCompile>
<ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"> <ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClCompile> </ClCompile>
......
...@@ -133,6 +133,7 @@ ...@@ -133,6 +133,7 @@
<ClInclude Include="..\..\src\compiler\translator\OutputGLSL.h"/> <ClInclude Include="..\..\src\compiler\translator\OutputGLSL.h"/>
<ClInclude Include="..\..\src\compiler\translator\FlagStd140Structs.h"/> <ClInclude Include="..\..\src\compiler\translator\FlagStd140Structs.h"/>
<ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h"/> <ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h"/>
<ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h"/>
<ClInclude Include="..\..\src\compiler\translator\PoolAlloc.h"/> <ClInclude Include="..\..\src\compiler\translator\PoolAlloc.h"/>
<ClInclude Include="..\..\src\compiler\translator\BuiltInFunctionEmulator.h"/> <ClInclude Include="..\..\src\compiler\translator\BuiltInFunctionEmulator.h"/>
<ClInclude Include="..\..\src\compiler\translator\ValidateOutputs.h"/> <ClInclude Include="..\..\src\compiler\translator\ValidateOutputs.h"/>
...@@ -188,11 +189,11 @@ ...@@ -188,11 +189,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\third_party\compiler\ArrayBoundsClamper.cpp"/> <ClCompile Include="..\..\src\third_party\compiler\ArrayBoundsClamper.cpp"/>
<ClCompile Include="..\..\src\common\event_tracer.cpp"/>
<ClCompile Include="..\..\src\common\utilities.cpp"/> <ClCompile Include="..\..\src\common\utilities.cpp"/>
<ClCompile Include="..\..\src\common\RefCountObject.cpp"/> <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
<ClCompile Include="..\..\src\common\mathutil.cpp"/> <ClCompile Include="..\..\src\common\mathutil.cpp"/>
<ClCompile Include="..\..\src\common\debug.cpp"/> <ClCompile Include="..\..\src\common\debug.cpp"/>
<ClCompile Include="..\..\src\common\event_tracer.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\HLSLLayoutEncoder.cpp"/> <ClCompile Include="..\..\src\compiler\translator\HLSLLayoutEncoder.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\InfoSink.cpp"/> <ClCompile Include="..\..\src\compiler\translator\InfoSink.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\OutputESSL.cpp"/> <ClCompile Include="..\..\src\compiler\translator\OutputESSL.cpp"/>
...@@ -209,6 +210,7 @@ ...@@ -209,6 +210,7 @@
<ClCompile Include="..\..\src\compiler\translator\PoolAlloc.cpp"/> <ClCompile Include="..\..\src\compiler\translator\PoolAlloc.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\BlockLayoutEncoder.cpp"/> <ClCompile Include="..\..\src\compiler\translator\BlockLayoutEncoder.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\ossource_win.cpp"/> <ClCompile Include="..\..\src\compiler\translator\ossource_win.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\RewriteElseBlocks.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"/> <ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\QualifierAlive.cpp"/> <ClCompile Include="..\..\src\compiler\translator\QualifierAlive.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\util.cpp"/> <ClCompile Include="..\..\src\compiler\translator\util.cpp"/>
......
...@@ -43,9 +43,6 @@ ...@@ -43,9 +43,6 @@
<ClInclude Include="..\..\src\common\event_tracer.h"> <ClInclude Include="..\..\src\common\event_tracer.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\common\event_tracer.cpp">
<Filter>common</Filter>
</ClCompile>
<ClInclude Include="..\..\src\common\commit.h"> <ClInclude Include="..\..\src\common\commit.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
...@@ -67,6 +64,9 @@ ...@@ -67,6 +64,9 @@
<ClInclude Include="..\..\src\common\version.h"> <ClInclude Include="..\..\src\common\version.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\common\event_tracer.cpp">
<Filter>common</Filter>
</ClCompile>
<ClInclude Include="..\..\src\common\utilities.h"> <ClInclude Include="..\..\src\common\utilities.h">
<Filter>common</Filter> <Filter>common</Filter>
</ClInclude> </ClInclude>
...@@ -118,6 +118,9 @@ ...@@ -118,6 +118,9 @@
<ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h"> <ClInclude Include="..\..\src\compiler\translator\MapLongVariableNames.h">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h">
<Filter>compiler\translator</Filter>
</ClInclude>
<ClCompile Include="..\..\src\compiler\translator\TranslatorHLSL.cpp"> <ClCompile Include="..\..\src\compiler\translator\TranslatorHLSL.cpp">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClCompile> </ClCompile>
...@@ -181,6 +184,9 @@ ...@@ -181,6 +184,9 @@
<ClInclude Include="..\..\src\compiler\translator\ConstantUnion.h"> <ClInclude Include="..\..\src\compiler\translator\ConstantUnion.h">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\compiler\translator\RewriteElseBlocks.cpp">
<Filter>compiler\translator</Filter>
</ClCompile>
<ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"> <ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp">
<Filter>compiler\translator</Filter> <Filter>compiler\translator</Filter>
</ClCompile> </ClCompile>
......
...@@ -294,6 +294,7 @@ enum TQualifier ...@@ -294,6 +294,7 @@ enum TQualifier
{ {
EvqTemporary, // For temporaries (within a function), read/write EvqTemporary, // For temporaries (within a function), read/write
EvqGlobal, // For globals read/write EvqGlobal, // For globals read/write
EvqInternal, // For internal use, not visible to the user
EvqConst, // User defined constants and non-output parameters in functions EvqConst, // User defined constants and non-output parameters in functions
EvqAttribute, // Readonly EvqAttribute, // Readonly
EvqVaryingIn, // readonly, fragment shaders only EvqVaryingIn, // readonly, fragment shaders only
......
...@@ -11,8 +11,12 @@ ...@@ -11,8 +11,12 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <limits>
#include <stdio.h>
#include "compiler/translator/PoolAlloc.h" #include "compiler/translator/PoolAlloc.h"
#include "compiler/translator/compilerdebug.h"
#include "common/angleutils.h"
struct TSourceLoc { struct TSourceLoc {
int first_file; int first_file;
...@@ -74,4 +78,15 @@ public: ...@@ -74,4 +78,15 @@ public:
TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {} TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
}; };
// Integer to TString conversion
template <typename T>
inline TString str(T i)
{
ASSERT(std::numeric_limits<T>::is_integer);
char buffer[((8 * sizeof(T)) / 3) + 3];
const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
snprintf(buffer, sizeof(buffer), formatStr, i);
return buffer;
}
#endif // _COMMON_INCLUDED_ #endif // _COMMON_INCLUDED_
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#ifndef TRANSLATOR_NODESEARCH_H_ #ifndef TRANSLATOR_NODESEARCH_H_
#define TRANSLATOR_NODESEARCH_H_ #define TRANSLATOR_NODESEARCH_H_
#include "compiler/translator/intermediate.h"
namespace sh namespace sh
{ {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "compiler/translator/HLSLLayoutEncoder.h" #include "compiler/translator/HLSLLayoutEncoder.h"
#include "compiler/translator/FlagStd140Structs.h" #include "compiler/translator/FlagStd140Structs.h"
#include "compiler/translator/NodeSearch.h" #include "compiler/translator/NodeSearch.h"
#include "compiler/translator/RewriteElseBlocks.h"
#include <algorithm> #include <algorithm>
#include <cfloat> #include <cfloat>
...@@ -23,16 +24,6 @@ ...@@ -23,16 +24,6 @@
namespace sh namespace sh
{ {
// Integer to TString conversion
template <typename T>
TString str(T i)
{
ASSERT(std::numeric_limits<T>::is_integer);
char buffer[(CHAR_BIT * sizeof(T) / 3) + 3];
const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
snprintf(buffer, sizeof(buffer), formatStr, i);
return buffer;
}
TString OutputHLSL::TextureFunction::name() const TString OutputHLSL::TextureFunction::name() const
{ {
...@@ -173,6 +164,13 @@ void OutputHLSL::output() ...@@ -173,6 +164,13 @@ void OutputHLSL::output()
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot); const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.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 && mContext.shaderType == SH_VERTEX_SHADER)
{
RewriteElseBlocks(mContext.treeRoot);
}
mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header
header(); header();
...@@ -1674,6 +1672,10 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) ...@@ -1674,6 +1672,10 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesFragDepth = true; mUsesFragDepth = true;
out << "gl_Depth"; out << "gl_Depth";
} }
else if (qualifier == EvqInternal)
{
out << name;
}
else else
{ {
out << decorate(name); out << decorate(name);
......
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RewriteElseBlocks.cpp: Implementation for tree transform to change
// all if-else blocks to if-if blocks.
//
#include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/NodeSearch.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
{
TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type)
{
TType variableType(type, EbpHigh, EvqInternal);
return new TIntermSymbol(-1, name, variableType);
}
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 *unary = new TIntermUnary(op, operand->getType());
unary->setOperand(operand);
return unary;
}
bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
{
switch (node->getOp())
{
case EOpSequence:
{
for (size_t statementIndex = 0; statementIndex != node->getSequence().size(); statementIndex++)
{
TIntermNode *statement = node->getSequence()[statementIndex];
TIntermSelection *selection = statement->getAsSelectionNode();
if (selection && selection->getFalseBlock() != NULL)
{
node->getSequence()[statementIndex] = rewriteSelection(selection);
delete selection;
}
}
}
break;
default: break;
}
return true;
}
TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
{
ASSERT(selection->getFalseBlock() != NULL);
TString temporaryName = "cond_" + str(mTemporaryIndex++);
TIntermTyped *typedCondition = selection->getCondition()->getAsTyped();
TType resultType(EbtBool, EbpUndefined);
TIntermSymbol *conditionSymbolA = MakeNewTemporary(temporaryName, EbtBool);
TIntermSymbol *conditionSymbolB = MakeNewTemporary(temporaryName, EbtBool);
TIntermSymbol *conditionSymbolC = MakeNewTemporary(temporaryName, EbtBool);
TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolA,
typedCondition, resultType);
TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolB);
TIntermSelection *falseBlock = new TIntermSelection(negatedCondition,
selection->getFalseBlock(), NULL);
TIntermSelection *newIfElse = new TIntermSelection(conditionSymbolC,
selection->getTrueBlock(), falseBlock);
TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration);
declaration->getSequence().push_back(storeCondition);
TIntermAggregate *block = new TIntermAggregate(EOpSequence);
block->getSequence().push_back(declaration);
block->getSequence().push_back(newIfElse);
return block;
}
void RewriteElseBlocks(TIntermNode *node)
{
ElseBlockRewriter rewriter;
node->traverse(&rewriter);
}
}
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RewriteElseBlocks.h: Prototype for tree transform to change
// all if-else blocks to if-if blocks.
//
#ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_
#define COMPILER_REWRITE_ELSE_BLOCKS_H_
#include "compiler/translator/intermediate.h"
namespace sh
{
class ElseBlockRewriter : public TIntermTraverser
{
public:
ElseBlockRewriter()
: TIntermTraverser(false, false, true, false)
, mTemporaryIndex(0)
{}
protected:
bool visitAggregate(Visit visit, TIntermAggregate *aggregate);
private:
int mTemporaryIndex;
TIntermNode *rewriteSelection(TIntermSelection *selection);
};
void RewriteElseBlocks(TIntermNode *node);
}
#endif // COMPILER_REWRITE_ELSE_BLOCKS_H_
...@@ -428,7 +428,7 @@ public: ...@@ -428,7 +428,7 @@ public:
protected: protected:
TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {} TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {} TIntermOperator(TOperator o, const TType& t) : TIntermTyped(t), op(o) {}
TOperator op; TOperator op;
}; };
...@@ -468,7 +468,7 @@ protected: ...@@ -468,7 +468,7 @@ protected:
// //
class TIntermUnary : public TIntermOperator { class TIntermUnary : public TIntermOperator {
public: public:
TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {} TIntermUnary(TOperator o, const TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {} TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
virtual void traverse(TIntermTraverser*); virtual void traverse(TIntermTraverser*);
......
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