Commit 12b0b399 by Olli Etuaho Committed by Commit Bot

Clean up ValidateOutputs

Remove the validateOutputs method from Compiler and replace it with a static method alongside the traverser. This encapsulates the ValidateOutputs implementation better. TEST=angle_unittests BUG=angleproject:2068 Change-Id: I1788cb9726db41ca35fd0e746f8d48ced7fee74f Reviewed-on: https://chromium-review.googlesource.com/535477 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent bb1b19b6
...@@ -366,7 +366,10 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -366,7 +366,10 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
PruneEmptyDeclarations(root); PruneEmptyDeclarations(root);
if (success && shaderVersion >= 300 && shaderType == GL_FRAGMENT_SHADER) if (success && shaderVersion >= 300 && shaderType == GL_FRAGMENT_SHADER)
success = validateOutputs(root); {
success = ValidateOutputs(root, getExtensionBehavior(), compileResources.MaxDrawBuffers,
&mDiagnostics);
}
if (success && shouldRunLoopAndIndexingValidation(compileOptions)) if (success && shouldRunLoopAndIndexingValidation(compileOptions))
success = success =
...@@ -874,14 +877,6 @@ bool TCompiler::pruneUnusedFunctions(TIntermBlock *root) ...@@ -874,14 +877,6 @@ bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
return true; return true;
} }
bool TCompiler::validateOutputs(TIntermNode *root)
{
ValidateOutputs validateOutputs(getExtensionBehavior(), compileResources.MaxDrawBuffers);
root->traverse(&validateOutputs);
validateOutputs.validate(&mDiagnostics);
return (mDiagnostics.numErrors() == 0);
}
bool TCompiler::limitExpressionComplexity(TIntermBlock *root) bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
{ {
TMaxDepthTraverser traverser(maxExpressionComplexity + 1); TMaxDepthTraverser traverser(maxExpressionComplexity + 1);
......
...@@ -133,8 +133,6 @@ class TCompiler : public TShHandleBase ...@@ -133,8 +133,6 @@ class TCompiler : public TShHandleBase
void setResourceString(); void setResourceString();
// Return false if the call depth is exceeded. // Return false if the call depth is exceeded.
bool checkCallDepth(); bool checkCallDepth();
// Returns true if a program has no conflicting or missing fragment outputs
bool validateOutputs(TIntermNode *root);
// 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){};
......
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
// validity.
#include "compiler/translator/ValidateOutputs.h" #include "compiler/translator/ValidateOutputs.h"
#include <set>
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h" #include "compiler/translator/ParseContext.h"
namespace sh namespace sh
...@@ -18,9 +25,29 @@ void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagno ...@@ -18,9 +25,29 @@ void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagno
diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str()); diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
} }
} // namespace class ValidateOutputsTraverser : public TIntermTraverser
{
public:
ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
void validate(TDiagnostics *diagnostics) const;
void visitSymbol(TIntermSymbol *) override;
private:
int mMaxDrawBuffers;
bool mAllowUnspecifiedOutputLocationResolution;
bool mUsesFragDepth;
ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers) typedef std::vector<TIntermSymbol *> OutputVector;
OutputVector mOutputs;
OutputVector mUnspecifiedLocationOutputs;
OutputVector mYuvOutputs;
std::set<std::string> mVisitedSymbols;
};
ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
int maxDrawBuffers)
: TIntermTraverser(true, false, false), : TIntermTraverser(true, false, false),
mMaxDrawBuffers(maxDrawBuffers), mMaxDrawBuffers(maxDrawBuffers),
mAllowUnspecifiedOutputLocationResolution( mAllowUnspecifiedOutputLocationResolution(
...@@ -29,7 +56,7 @@ ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxD ...@@ -29,7 +56,7 @@ ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxD
{ {
} }
void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
{ {
TString name = symbol->getSymbol(); TString name = symbol->getSymbol();
TQualifier qualifier = symbol->getQualifier(); TQualifier qualifier = symbol->getQualifier();
...@@ -60,7 +87,7 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) ...@@ -60,7 +87,7 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol)
} }
} }
void ValidateOutputs::validate(TDiagnostics *diagnostics) const void ValidateOutputsTraverser::validate(TDiagnostics *diagnostics) const
{ {
ASSERT(diagnostics); ASSERT(diagnostics);
OutputVector validOutputs(mMaxDrawBuffers); OutputVector validOutputs(mMaxDrawBuffers);
...@@ -128,4 +155,18 @@ void ValidateOutputs::validate(TDiagnostics *diagnostics) const ...@@ -128,4 +155,18 @@ void ValidateOutputs::validate(TDiagnostics *diagnostics) const
} }
} }
} // anonymous namespace
bool ValidateOutputs(TIntermBlock *root,
const TExtensionBehavior &extBehavior,
int maxDrawBuffers,
TDiagnostics *diagnostics)
{
ValidateOutputsTraverser validateOutputs(extBehavior, maxDrawBuffers);
root->traverse(&validateOutputs);
int numErrorsBefore = diagnostics->numErrors();
validateOutputs.validate(diagnostics);
return (diagnostics->numErrors() == numErrorsBefore);
}
} // namespace sh } // namespace sh
...@@ -3,40 +3,27 @@ ...@@ -3,40 +3,27 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
// validity.
//
#ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ #ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
#define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ #define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/IntermNode.h"
#include <set>
namespace sh namespace sh
{ {
class TInfoSinkBase; class TIntermBlock;
class TDiagnostics;
class ValidateOutputs : public TIntermTraverser
{
public:
ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
void validate(TDiagnostics *diagnostics) const;
void visitSymbol(TIntermSymbol *) override;
private:
int mMaxDrawBuffers;
bool mAllowUnspecifiedOutputLocationResolution;
bool mUsesFragDepth;
typedef std::vector<TIntermSymbol *> OutputVector; // Returns true if the shader has no conflicting or otherwise erroneous fragment outputs.
OutputVector mOutputs; bool ValidateOutputs(TIntermBlock *root,
OutputVector mUnspecifiedLocationOutputs; const TExtensionBehavior &extBehavior,
OutputVector mYuvOutputs; int maxDrawBuffers,
std::set<std::string> mVisitedSymbols; TDiagnostics *diagnostics);
};
} // 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