Hash :
8dc9e83e
Author :
Date :
2022-02-16T21:48:53
Translator: Fix RunAtTheEndOfShader w.r.t discard RunAtTheEndOfShader wrapped main() if it ended in discard. However, it didn't account for the fact that the discard instruction could be wrapped in a block. This change makes RunAtTheEndOfShader more conservative w.r.t discard and has it wrap main() on any encounter of discard. The change additionally adds AST validation to ensure transformations don't generate dead code after branches. Test credit to Cody Northrop. Test: GLSLTest_ES3.ConstantConditionGuardingDiscard Test: GLSLTest_ES3.NestedUnconditionalDiscards Bug: angleproject:7033 Change-Id: Ie9d5210a5cfbb13449720a8a3f44666df9443d98 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3471014 Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
//
// Copyright 2019 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.
//
#ifndef COMPILER_TRANSLATOR_VALIDATEAST_H_
#define COMPILER_TRANSLATOR_VALIDATEAST_H_
#include "compiler/translator/BaseTypes.h"
#include "compiler/translator/Common.h"
namespace sh
{
class TDiagnostics;
class TIntermNode;
// The following options (stored in Compiler) tell the validator what to validate. Some validations
// are conditional to certain passes.
struct ValidateASTOptions
{
// TODO: add support for the flags marked with TODO. http://anglebug.com/2733
// Check that every node always has only one parent,
bool validateSingleParent = true;
// Check that all symbols reference TVariables that have been declared. For built-ins, this
// makes sure that the same GLSL built-in uses the same TVariable consistently.
bool validateVariableReferences = true;
// Whether validateVariableReferences should also include specialization constants. Their
// declaration is output after their usage is discovered, so this is disabled until then.
bool validateSpecConstReferences = false;
// Check that TIntermUnary and TIntermAggregate nodes with a built-in op reference a function
// with said op.
bool validateBuiltInOps = true;
// Check that all EOpCallFunctionInAST have their corresponding function definitions in the AST,
// with matching symbol ids. There should also be at least a prototype declaration before the
// function is called.
bool validateFunctionCall = true;
// Check that EOpCallInternalRawFunction is not used. This OP is deprecated and needs to be
// removed. http://anglebug.com/6059
bool validateNoRawFunctionCalls = true;
// Check that there are no null nodes where they are not allowed, for example as children of
// TIntermDeclaration or TIntermBlock.
bool validateNullNodes = true;
// Check that symbols that reference variables have consistent qualifiers and symbol ids with
// the variable declaration. The following needs to be validated:
//
// Implemented:
//
// - Function parameters having one of EvqParam* qualifiers.
// - gl_ClipDistance, gl_CullDistance and gl_LastFragData are correctly qualified even when
// redeclared in the shader.
//
// TODO:
//
// - Function-local variables must have the EvqTemporary qualifier.
// - Symbol references and declarations have identical qualifiers.
bool validateQualifiers = true;
// Check that every symbol has its precision specified. That includes variables, block members,
// function parameters and return values.
bool validatePrecision = true;
// Check that variable declarations that can't have initializers don't have initializers
// (varyings, uniforms for example).
bool validateInitializers = true; // TODO
// Check that there is only one TFunction with each function name referenced in the nodes (no
// two TFunctions with the same name, taking internal/non-internal namespaces into account).
bool validateUniqueFunctions = true; // TODO
// Check that references to structs are matched with the corresponding struct declaration.
bool validateStructUsage = true;
// Check that expression nodes have the correct type considering their operand(s). The
// following validation is possible:
//
// Implemented:
//
// - Binary node that indexes T[] should have type T
// - Binary nodes with EOpIndexDirect* should have a constant as the right node
// - Switch nodes should have an integer type in the selector
//
// TODO:
//
// - Function calls (including built-ins) have the same return type in the node and function.
// - Unary and binary operators have the correct type based on operands
// - Swizzle result has same type as the operand except for vector size
// - Ternary operator has the same type as the operands
// - Case expressions have the same type as the switch selector
bool validateExpressionTypes = true;
// If SeparateDeclarations has been run, check for the absence of multi declarations as well.
bool validateMultiDeclarations = false;
// If PruneNoOps has been run, check that no statements are ever added after branches in the
// same block. Those statements would be dead code.
bool validateNoStatementsAfterBranch = false;
// Once set, disallows any further transformations on the tree. Used before AST post-processing
// which requires that the tree remains unmodified.
bool validateNoMoreTransformations = false;
};
// Check for errors and output error messages on the context.
// Returns true if there are no errors.
bool ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options);
} // namespace sh
#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_