Commit 89a69a03 by Olli Etuaho Committed by Commit Bot

Generate performance warnings in HLSL translation

Generate performance warnings for some code that undergoes heavy emulation when translated to HLSL: 1. Dynamic indexing of vectors and matrices. 2. Non-empty fall-through cases in switch/case. The warnings are generated only when code is translated to HLSL. Generating them in the parsing stage would add too much maintenance burden. Improves switch statement fall-through handling in cases where an empty fall-through case follows a non-empty one so that extra performance warnings are not generated. BUG=angleproject:1116 Change-Id: I7c85d78fe7c4f8e6042bda72ceaaf6e37dadfe6c Reviewed-on: https://chromium-review.googlesource.com/732986 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 4cd889ec
...@@ -626,7 +626,10 @@ bool TCompiler::compile(const char *const shaderStrings[], ...@@ -626,7 +626,10 @@ bool TCompiler::compile(const char *const shaderStrings[],
OutputTree(root, infoSink.info); OutputTree(root, infoSink.info);
if (compileOptions & SH_OBJECT_CODE) if (compileOptions & SH_OBJECT_CODE)
translate(root, compileOptions); {
PerformanceDiagnostics perfDiagnostics(&mDiagnostics);
translate(root, compileOptions, &perfDiagnostics);
}
// The IntermNode tree doesn't need to be deleted here, since the // The IntermNode tree doesn't need to be deleted here, since the
// memory will be freed in a big chunk by the PoolAllocator. // memory will be freed in a big chunk by the PoolAllocator.
......
...@@ -156,8 +156,10 @@ class TCompiler : public TShHandleBase ...@@ -156,8 +156,10 @@ class TCompiler : public TShHandleBase
// Add emulated functions to the built-in function emulator. // Add emulated functions to the built-in function emulator.
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
ShCompileOptions compileOptions){}; ShCompileOptions compileOptions){};
// Translate to object code. // Translate to object code. May generate performance warnings through the diagnostics.
virtual void translate(TIntermBlock *root, ShCompileOptions compileOptions) = 0; virtual void translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics) = 0;
// Insert statements to reference all members in unused uniform blocks with standard and shared // Insert statements to reference all members in unused uniform blocks with standard and shared
// layout. This is to work around a Mac driver that treats unused standard/shared // layout. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive. // uniform blocks as inactive.
......
...@@ -91,4 +91,15 @@ void TDiagnostics::resetErrorCount() ...@@ -91,4 +91,15 @@ void TDiagnostics::resetErrorCount()
mNumWarnings = 0; mNumWarnings = 0;
} }
PerformanceDiagnostics::PerformanceDiagnostics(TDiagnostics *diagnostics)
: mDiagnostics(diagnostics)
{
ASSERT(diagnostics);
}
void PerformanceDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
{
mDiagnostics->warning(loc, reason, token);
}
} // namespace sh } // namespace sh
...@@ -50,6 +50,18 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable ...@@ -50,6 +50,18 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
int mNumWarnings; int mNumWarnings;
}; };
// Diagnostics wrapper to use when the code is only allowed to generate warnings.
class PerformanceDiagnostics : public angle::NonCopyable
{
public:
PerformanceDiagnostics(TDiagnostics *diagnostics);
void warning(const TSourceLoc &loc, const char *reason, const char *token);
private:
TDiagnostics *mDiagnostics;
};
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_ #endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
...@@ -121,7 +121,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -121,7 +121,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
int numRenderTargets, int numRenderTargets,
const std::vector<Uniform> &uniforms, const std::vector<Uniform> &uniforms,
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
TSymbolTable *symbolTable) TSymbolTable *symbolTable,
PerformanceDiagnostics *perfDiagnostics)
: TIntermTraverser(true, true, true, symbolTable), : TIntermTraverser(true, true, true, symbolTable),
mShaderType(shaderType), mShaderType(shaderType),
mShaderVersion(shaderVersion), mShaderVersion(shaderVersion),
...@@ -130,7 +131,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -130,7 +131,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
mOutputType(outputType), mOutputType(outputType),
mCompileOptions(compileOptions), mCompileOptions(compileOptions),
mNumRenderTargets(numRenderTargets), mNumRenderTargets(numRenderTargets),
mCurrentFunctionMetadata(nullptr) mCurrentFunctionMetadata(nullptr),
mPerfDiagnostics(perfDiagnostics)
{ {
mInsideFunction = false; mInsideFunction = false;
...@@ -2173,7 +2175,7 @@ bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node) ...@@ -2173,7 +2175,7 @@ bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node)
ASSERT(node->getStatementList()); ASSERT(node->getStatementList());
if (visit == PreVisit) if (visit == PreVisit)
{ {
node->setStatementList(RemoveSwitchFallThrough(node->getStatementList())); node->setStatementList(RemoveSwitchFallThrough(node->getStatementList(), mPerfDiagnostics));
} }
outputTriplet(out, visit, "switch (", ") ", ""); outputTriplet(out, visit, "switch (", ") ", "");
// The curly braces get written when visiting the statementList block. // The curly braces get written when visiting the statementList block.
......
...@@ -40,7 +40,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -40,7 +40,8 @@ class OutputHLSL : public TIntermTraverser
int numRenderTargets, int numRenderTargets,
const std::vector<Uniform> &uniforms, const std::vector<Uniform> &uniforms,
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
TSymbolTable *symbolTable); TSymbolTable *symbolTable,
PerformanceDiagnostics *perfDiagnostics);
~OutputHLSL(); ~OutputHLSL();
...@@ -241,6 +242,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -241,6 +242,8 @@ class OutputHLSL : public TIntermTraverser
// arrays can't be return values in HLSL. // arrays can't be return values in HLSL.
std::vector<ArrayHelperFunction> mArrayConstructIntoFunctions; std::vector<ArrayHelperFunction> mArrayConstructIntoFunctions;
PerformanceDiagnostics *mPerfDiagnostics;
private: private:
TString samplerNamePrefixFromStruct(TIntermTyped *node); TString samplerNamePrefixFromStruct(TIntermTyped *node);
bool ancestorEvaluatesToSamplerInStruct(); bool ancestorEvaluatesToSamplerInStruct();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "compiler/translator/RemoveDynamicIndexing.h" #include "compiler/translator/RemoveDynamicIndexing.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/IntermNode_util.h"
...@@ -281,7 +282,9 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, ...@@ -281,7 +282,9 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type,
class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
{ {
public: public:
RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable, int shaderVersion); RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable,
int shaderVersion,
PerformanceDiagnostics *perfDiagnostics);
bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override;
...@@ -305,13 +308,18 @@ class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser ...@@ -305,13 +308,18 @@ class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
// V[j++][i]++. // V[j++][i]++.
// where V is an array of vectors, j++ will only be evaluated once. // where V is an array of vectors, j++ will only be evaluated once.
bool mRemoveIndexSideEffectsInSubtree; bool mRemoveIndexSideEffectsInSubtree;
PerformanceDiagnostics *mPerfDiagnostics;
}; };
RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable, RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
int shaderVersion) TSymbolTable *symbolTable,
int shaderVersion,
PerformanceDiagnostics *perfDiagnostics)
: TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion),
mUsedTreeInsertion(false), mUsedTreeInsertion(false),
mRemoveIndexSideEffectsInSubtree(false) mRemoveIndexSideEffectsInSubtree(false),
mPerfDiagnostics(perfDiagnostics)
{ {
} }
...@@ -398,6 +406,10 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod ...@@ -398,6 +406,10 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
} }
else if (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node)) else if (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node))
{ {
mPerfDiagnostics->warning(node->getLine(),
"Performance: dynamic indexing of vectors and "
"matrices is emulated and can be slow.",
"[]");
bool write = isLValueRequiredHere(); bool write = isLValueRequiredHere();
#if defined(ANGLE_ENABLE_ASSERTS) #if defined(ANGLE_ENABLE_ASSERTS)
...@@ -515,9 +527,12 @@ void RemoveDynamicIndexingTraverser::nextIteration() ...@@ -515,9 +527,12 @@ void RemoveDynamicIndexingTraverser::nextIteration()
} // namespace } // namespace
void RemoveDynamicIndexing(TIntermNode *root, TSymbolTable *symbolTable, int shaderVersion) void RemoveDynamicIndexing(TIntermNode *root,
TSymbolTable *symbolTable,
int shaderVersion,
PerformanceDiagnostics *perfDiagnostics)
{ {
RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion); RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion, perfDiagnostics);
do do
{ {
traverser.nextIteration(); traverser.nextIteration();
......
...@@ -15,8 +15,12 @@ namespace sh ...@@ -15,8 +15,12 @@ namespace sh
class TIntermNode; class TIntermNode;
class TSymbolTable; class TSymbolTable;
class PerformanceDiagnostics;
void RemoveDynamicIndexing(TIntermNode *root, TSymbolTable *symbolTable, int shaderVersion); void RemoveDynamicIndexing(TIntermNode *root,
TSymbolTable *symbolTable,
int shaderVersion,
PerformanceDiagnostics *perfDiagnostics);
} // namespace sh } // namespace sh
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "compiler/translator/RemoveSwitchFallThrough.h" #include "compiler/translator/RemoveSwitchFallThrough.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/IntermTraverse.h"
namespace sh namespace sh
...@@ -21,10 +22,12 @@ namespace ...@@ -21,10 +22,12 @@ namespace
class RemoveSwitchFallThroughTraverser : public TIntermTraverser class RemoveSwitchFallThroughTraverser : public TIntermTraverser
{ {
public: public:
static TIntermBlock *removeFallThrough(TIntermBlock *statementList); static TIntermBlock *removeFallThrough(TIntermBlock *statementList,
PerformanceDiagnostics *perfDiagnostics);
private: private:
RemoveSwitchFallThroughTraverser(TIntermBlock *statementList); RemoveSwitchFallThroughTraverser(TIntermBlock *statementList,
PerformanceDiagnostics *perfDiagnostics);
void visitSymbol(TIntermSymbol *node) override; void visitSymbol(TIntermSymbol *node) override;
void visitConstantUnion(TIntermConstantUnion *node) override; void visitConstantUnion(TIntermConstantUnion *node) override;
...@@ -49,11 +52,14 @@ class RemoveSwitchFallThroughTraverser : public TIntermTraverser ...@@ -49,11 +52,14 @@ class RemoveSwitchFallThroughTraverser : public TIntermTraverser
bool mLastStatementWasBreak; bool mLastStatementWasBreak;
TIntermBlock *mPreviousCase; TIntermBlock *mPreviousCase;
std::vector<TIntermBlock *> mCasesSharingBreak; std::vector<TIntermBlock *> mCasesSharingBreak;
PerformanceDiagnostics *mPerfDiagnostics;
}; };
TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough(TIntermBlock *statementList) TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough(
TIntermBlock *statementList,
PerformanceDiagnostics *perfDiagnostics)
{ {
RemoveSwitchFallThroughTraverser rm(statementList); RemoveSwitchFallThroughTraverser rm(statementList, perfDiagnostics);
ASSERT(statementList); ASSERT(statementList);
statementList->traverse(&rm); statementList->traverse(&rm);
ASSERT(rm.mPreviousCase || statementList->getSequence()->empty()); ASSERT(rm.mPreviousCase || statementList->getSequence()->empty());
...@@ -69,11 +75,14 @@ TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough(TIntermBlock * ...@@ -69,11 +75,14 @@ TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough(TIntermBlock *
return rm.mStatementListOut; return rm.mStatementListOut;
} }
RemoveSwitchFallThroughTraverser::RemoveSwitchFallThroughTraverser(TIntermBlock *statementList) RemoveSwitchFallThroughTraverser::RemoveSwitchFallThroughTraverser(
TIntermBlock *statementList,
PerformanceDiagnostics *perfDiagnostics)
: TIntermTraverser(true, false, false), : TIntermTraverser(true, false, false),
mStatementList(statementList), mStatementList(statementList),
mLastStatementWasBreak(false), mLastStatementWasBreak(false),
mPreviousCase(nullptr) mPreviousCase(nullptr),
mPerfDiagnostics(perfDiagnostics)
{ {
mStatementListOut = new TIntermBlock(); mStatementListOut = new TIntermBlock();
} }
...@@ -158,14 +167,10 @@ void RemoveSwitchFallThroughTraverser::handlePreviousCase() ...@@ -158,14 +167,10 @@ void RemoveSwitchFallThroughTraverser::handlePreviousCase()
mCasesSharingBreak.push_back(mPreviousCase); mCasesSharingBreak.push_back(mPreviousCase);
if (mLastStatementWasBreak) if (mLastStatementWasBreak)
{ {
bool labelsWithNoStatements = true;
for (size_t i = 0; i < mCasesSharingBreak.size(); ++i) for (size_t i = 0; i < mCasesSharingBreak.size(); ++i)
{ {
if (mCasesSharingBreak.at(i)->getSequence()->size() > 1) ASSERT(!mCasesSharingBreak.at(i)->getSequence()->empty());
{ if (mCasesSharingBreak.at(i)->getSequence()->size() == 1)
labelsWithNoStatements = false;
}
if (labelsWithNoStatements)
{ {
// Fall-through is allowed in case the label has no statements. // Fall-through is allowed in case the label has no statements.
outputSequence(mCasesSharingBreak.at(i)->getSequence(), 0); outputSequence(mCasesSharingBreak.at(i)->getSequence(), 0);
...@@ -173,6 +178,13 @@ void RemoveSwitchFallThroughTraverser::handlePreviousCase() ...@@ -173,6 +178,13 @@ void RemoveSwitchFallThroughTraverser::handlePreviousCase()
else else
{ {
// Include all the statements that this case can fall through under the same label. // Include all the statements that this case can fall through under the same label.
if (mCasesSharingBreak.size() > i + 1u)
{
mPerfDiagnostics->warning(mCasesSharingBreak.at(i)->getLine(),
"Performance: non-empty fall-through cases in "
"switch statements generate extra code.",
"switch");
}
for (size_t j = i; j < mCasesSharingBreak.size(); ++j) for (size_t j = i; j < mCasesSharingBreak.size(); ++j)
{ {
size_t startIndex = size_t startIndex =
...@@ -192,6 +204,7 @@ bool RemoveSwitchFallThroughTraverser::visitCase(Visit, TIntermCase *node) ...@@ -192,6 +204,7 @@ bool RemoveSwitchFallThroughTraverser::visitCase(Visit, TIntermCase *node)
handlePreviousCase(); handlePreviousCase();
mPreviousCase = new TIntermBlock(); mPreviousCase = new TIntermBlock();
mPreviousCase->getSequence()->push_back(node); mPreviousCase->getSequence()->push_back(node);
mPreviousCase->setLine(node->getLine());
// Don't traverse the condition of the case statement // Don't traverse the condition of the case statement
return false; return false;
} }
...@@ -248,9 +261,10 @@ bool RemoveSwitchFallThroughTraverser::visitBranch(Visit, TIntermBranch *node) ...@@ -248,9 +261,10 @@ bool RemoveSwitchFallThroughTraverser::visitBranch(Visit, TIntermBranch *node)
} // anonymous namespace } // anonymous namespace
TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList) TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList,
PerformanceDiagnostics *perfDiagnostics)
{ {
return RemoveSwitchFallThroughTraverser::removeFallThrough(statementList); return RemoveSwitchFallThroughTraverser::removeFallThrough(statementList, perfDiagnostics);
} }
} // namespace sh } // namespace sh
...@@ -15,10 +15,12 @@ namespace sh ...@@ -15,10 +15,12 @@ namespace sh
{ {
class TIntermBlock; class TIntermBlock;
class PerformanceDiagnostics;
// When given a statementList from a switch AST node, return an updated // When given a statementList from a switch AST node, return an updated
// statementList that has fall-through removed. // statementList that has fall-through removed.
TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList); TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList,
PerformanceDiagnostics *perfDiagnostics);
} // namespace sh } // namespace sh
......
...@@ -30,7 +30,9 @@ void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, ...@@ -30,7 +30,9 @@ void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
} }
} }
void TranslatorESSL::translate(TIntermBlock *root, ShCompileOptions compileOptions) void TranslatorESSL::translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics * /*perfDiagnostics*/)
{ {
// The ESSL output doesn't define a default precision for float, so float literal statements // The ESSL output doesn't define a default precision for float, so float literal statements
// end up with no precision which is invalid ESSL. // end up with no precision which is invalid ESSL.
......
...@@ -21,7 +21,9 @@ class TranslatorESSL : public TCompiler ...@@ -21,7 +21,9 @@ class TranslatorESSL : public TCompiler
void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
ShCompileOptions compileOptions) override; ShCompileOptions compileOptions) override;
void translate(TIntermBlock *root, ShCompileOptions compileOptions) override; void translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override; bool shouldFlattenPragmaStdglInvariantAll() override;
private: private:
......
...@@ -45,7 +45,9 @@ void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, ...@@ -45,7 +45,9 @@ void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion); InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion);
} }
void TranslatorGLSL::translate(TIntermBlock *root, ShCompileOptions compileOptions) void TranslatorGLSL::translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics * /*perfDiagnostics*/)
{ {
TInfoSinkBase &sink = getInfoSink().obj; TInfoSinkBase &sink = getInfoSink().obj;
......
...@@ -21,7 +21,9 @@ class TranslatorGLSL : public TCompiler ...@@ -21,7 +21,9 @@ class TranslatorGLSL : public TCompiler
void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
ShCompileOptions compileOptions) override; ShCompileOptions compileOptions) override;
void translate(TIntermBlock *root, ShCompileOptions compileOptions) override; void translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override; bool shouldFlattenPragmaStdglInvariantAll() override;
bool shouldCollectVariables(ShCompileOptions compileOptions) override; bool shouldCollectVariables(ShCompileOptions compileOptions) override;
......
...@@ -34,7 +34,9 @@ TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutpu ...@@ -34,7 +34,9 @@ TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutpu
{ {
} }
void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptions) void TranslatorHLSL::translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics)
{ {
const ShBuiltInResources &resources = getResources(); const ShBuiltInResources &resources = getResources();
int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
...@@ -71,7 +73,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptio ...@@ -71,7 +73,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptio
if (!shouldRunLoopAndIndexingValidation(compileOptions)) if (!shouldRunLoopAndIndexingValidation(compileOptions))
{ {
// HLSL doesn't support dynamic indexing of vectors and matrices. // HLSL doesn't support dynamic indexing of vectors and matrices.
RemoveDynamicIndexing(root, &getSymbolTable(), getShaderVersion()); RemoveDynamicIndexing(root, &getSymbolTable(), getShaderVersion(), perfDiagnostics);
} }
// Work around D3D9 bug that would manifest in vertex shaders with selection blocks which // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
...@@ -126,7 +128,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptio ...@@ -126,7 +128,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptio
sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), getSourcePath(), getOutputType(), numRenderTargets, getUniforms(),
compileOptions, &getSymbolTable()); compileOptions, &getSymbolTable(), perfDiagnostics);
outputHLSL.output(root, getInfoSink().obj); outputHLSL.output(root, getInfoSink().obj);
......
...@@ -24,7 +24,9 @@ class TranslatorHLSL : public TCompiler ...@@ -24,7 +24,9 @@ class TranslatorHLSL : public TCompiler
const std::map<std::string, unsigned int> *getUniformRegisterMap() const; const std::map<std::string, unsigned int> *getUniformRegisterMap() const;
protected: protected:
void translate(TIntermBlock *root, ShCompileOptions compileOptions) override; void translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override; bool shouldFlattenPragmaStdglInvariantAll() override;
// collectVariables needs to be run always so registers can be assigned. // collectVariables needs to be run always so registers can be assigned.
......
...@@ -94,7 +94,9 @@ TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec) ...@@ -94,7 +94,9 @@ TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
{ {
} }
void TranslatorVulkan::translate(TIntermBlock *root, ShCompileOptions compileOptions) void TranslatorVulkan::translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics * /*perfDiagnostics*/)
{ {
TInfoSinkBase &sink = getInfoSink().obj; TInfoSinkBase &sink = getInfoSink().obj;
......
...@@ -23,7 +23,9 @@ class TranslatorVulkan : public TCompiler ...@@ -23,7 +23,9 @@ class TranslatorVulkan : public TCompiler
TranslatorVulkan(sh::GLenum type, ShShaderSpec spec); TranslatorVulkan(sh::GLenum type, ShShaderSpec spec);
protected: protected:
void translate(TIntermBlock *root, ShCompileOptions compileOptions) override; void translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override; bool shouldFlattenPragmaStdglInvariantAll() override;
}; };
......
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