1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License. 5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 8d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// 9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software 10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and 13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License. 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 156407fe82e29ab16920742bd47b93e14bc5f0e119Nicolas Capens#include "Compiler.h" 16cc863da574ed5079b055574127fe5788a9a0fc33Nicolas Capens#include "intermediate.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TInfoSinkBase; 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct TLoopInfo { 21d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens struct TIndex { 22d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int id; // symbol id. 23d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } index; 24d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TIntermLoop* loop; 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef TVector<TLoopInfo> TLoopStack; 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Traverses intermediate tree to ensure that the shader does not exceed the 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// minimum functionality mandated in GLSL 1.0 spec, Appendix A. 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ValidateLimitations : public TIntermTraverser { 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 32d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens ValidateLimitations(GLenum shaderType, TInfoSinkBase& sink); 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 34d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int numErrors() const { return mNumErrors; } 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 36d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens virtual bool visitBinary(Visit, TIntermBinary*); 37d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens virtual bool visitUnary(Visit, TIntermUnary*); 38d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens virtual bool visitAggregate(Visit, TIntermAggregate*); 39d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens virtual bool visitLoop(Visit, TIntermLoop*); 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate: 42d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void error(TSourceLoc loc, const char *reason, const char* token); 43d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 44d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool withinLoopBody() const; 45d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool isLoopIndex(const TIntermSymbol* symbol) const; 46d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateLoopType(TIntermLoop* node); 47d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info); 48d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info); 49d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info); 50d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info); 51d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Returns true if none of the loop indices is used as the argument to 52d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // the given function out or inout parameter. 53d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateFunctionCall(TIntermAggregate* node); 54d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateOperation(TIntermOperator* node, TIntermNode* operand); 55d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 56d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Returns true if indexing does not exceed the minimum functionality 57d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // mandated in GLSL 1.0 spec, Appendix A, Section 5. 58d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool isConstExpr(TIntermNode* node); 59d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool isConstIndexExpr(TIntermNode* node); 60d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool validateIndexing(TIntermBinary* node); 61d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 62d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens GLenum mShaderType; 63d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& mSink; 64d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int mNumErrors; 65d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TLoopStack mLoopStack; 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 68