1da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org// 2da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 3da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org// Use of this source code is governed by a BSD-style license that can be 4da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org// found in the LICENSE file. 5da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org// 6da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org#include <sstream> 7da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org#include <string> 8da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org#include <vector> 9da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org#include "GLSLANG/ShaderLang.h" 10da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org#include "gtest/gtest.h" 11da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 12da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org#define SHADER(Src) #Src 13da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 14da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgclass ExpressionLimitTest : public testing::Test { 15da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgprotected: 16da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const int kMaxExpressionComplexity = 16; 17da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const int kMaxCallStackDepth = 16; 18da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* kExpressionTooComplex; 19da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* kCallStackTooDeep; 20da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* kHasRecursion; 21da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 22da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org virtual void SetUp() 23da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 24da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org memset(&resources, 0, sizeof(resources)); 25da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 26da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ASSERT_TRUE(ShInitialize() != 0) << "Could not ShInitialize"; 27da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 28da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateResources(&resources); 29da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 30da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 31da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org virtual void TearDown() 32da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 33da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ASSERT_TRUE(ShFinalize() != 0); 34da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 35da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 36da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Set up the per compile resources 37da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void GenerateResources(ShBuiltInResources* resources) 38da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 39da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShInitBuiltInResources(resources); 40da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 41da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxVertexAttribs = 8; 42da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxVertexUniformVectors = 128; 43da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxVaryingVectors = 8; 44da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxVertexTextureImageUnits = 0; 45da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxCombinedTextureImageUnits = 8; 46da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxTextureImageUnits = 8; 47da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxFragmentUniformVectors = 16; 48da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxDrawBuffers = 1; 49da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 50da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->OES_standard_derivatives = 0; 51da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->OES_EGL_image_external = 0; 52da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 53da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxExpressionComplexity = kMaxExpressionComplexity; 54da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org resources->MaxCallStackDepth = kMaxCallStackDepth; 55da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 56da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 57da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void GenerateLongExpression(int length, std::stringstream* ss) 58da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 59da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org for (int ii = 0; ii < length; ++ii) { 60da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org *ss << "+ vec4(" << ii << ")"; 61da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 62da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 63da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 64da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::string GenerateShaderWithLongExpression(int length) 65da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 66da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderStart = SHADER( 67da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 68da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 69da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() 70da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 71da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = u_color 72da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 73da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 74da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::stringstream ss; 75da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ss << shaderStart; 76da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateLongExpression(length, &ss); 77da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ss << "; }"; 78da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 79da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return ss.str(); 80da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 81da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 82da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::string GenerateShaderWithUnusedLongExpression(int length) 83da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 84da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderStart = SHADER( 85da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 86da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 87da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() 88da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 89da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = u_color; 90da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 91da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunction() { 92da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return u_color 93da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 94da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 95da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::stringstream ss; 96da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 97da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ss << shaderStart; 98da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateLongExpression(length, &ss); 99da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ss << "; }"; 100da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 101da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return ss.str(); 102da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 103da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 104da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void GenerateDeepFunctionStack(int length, std::stringstream* ss) 105da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 106da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderStart = SHADER( 107da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 108da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 109da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function0() { 110da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return u_color; 111da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 112da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 113da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 114da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org *ss << shaderStart; 115da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org for (int ii = 0; ii < length; ++ii) { 116da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org *ss << "vec4 function" << (ii + 1) << "() {\n" 117da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org << " return function" << ii << "();\n" 118da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org << "}\n"; 119da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 120da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 121da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 122da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::string GenerateShaderWithDeepFunctionStack(int length) 123da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 124da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::stringstream ss; 125da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 126da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateDeepFunctionStack(length, &ss); 127da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 128da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ss << "void main() {\n" 129da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org << " gl_FragColor = function" << length << "();\n" 130da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org << "}"; 131da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 132da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return ss.str(); 133da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 134da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 135da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::string GenerateShaderWithUnusedDeepFunctionStack(int length) 136da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org { 137da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::stringstream ss; 138da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 139da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateDeepFunctionStack(length, &ss); 140da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 141da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ss << "void main() {\n" 142da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org << " gl_FragColor = vec4(0,0,0,0);\n" 143da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org << "}"; 144da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 145da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 146da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return ss.str(); 147da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 148da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 149da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Compiles a shader and if there's an error checks for a specific 150da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // substring in the error log. This way we know the error is specific 151da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // to the issue we are testing. 152da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org bool CheckShaderCompilation(ShHandle compiler, 153da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org const char* source, 154da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org int compileOptions, 155da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org const char* expected_error) { 156da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org bool success = ShCompile(compiler, &source, 1, compileOptions); 157da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org if (success) { 158da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org success = !expected_error; 159da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } else { 160da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org size_t bufferLen = 0; 161da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &bufferLen); 162da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org char* buffer(new char [bufferLen]); 163da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShGetInfoLog(compiler, buffer); 164da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org std::string log(buffer, buffer + bufferLen); 165da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org delete [] buffer; 166da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org if (expected_error) 167da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org success = log.find(expected_error) != std::string::npos; 168da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 169da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(success) << log << "\n----shader----\n" << source; 170da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 171da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return success; 172da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 173da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 174da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShBuiltInResources resources; 175da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org}; 176da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 177da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgconst char* ExpressionLimitTest::kExpressionTooComplex = 178da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org "Expression too complex"; 179da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgconst char* ExpressionLimitTest::kCallStackTooDeep = 180da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org "call stack too deep"; 181da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgconst char* ExpressionLimitTest::kHasRecursion = 182da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org "Function recursion detected"; 183da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 184da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgTEST_F(ExpressionLimitTest, ExpressionComplexity) 185da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org{ 186da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderSpec spec = SH_WEBGL_SPEC; 187da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderOutput output = SH_ESSL_OUTPUT; 188da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShHandle vertexCompiler = ShConstructCompiler( 189da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org SH_FRAGMENT_SHADER, spec, output, &resources); 190da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org int compileOptions = SH_LIMIT_EXPRESSION_COMPLEXITY; 191da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 192da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test expression under the limit passes. 193da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 194da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 195da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithLongExpression( 196da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxExpressionComplexity - 10).c_str(), 197da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, NULL)); 198da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test expression over the limit fails. 199da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 200da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 201da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithLongExpression( 202da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxExpressionComplexity + 10).c_str(), 203da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kExpressionTooComplex)); 204da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test expression over the limit without a limit does not fail. 205da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 206da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 207da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithLongExpression( 208da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxExpressionComplexity + 10).c_str(), 209da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions & ~SH_LIMIT_EXPRESSION_COMPLEXITY, NULL)); 210da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org} 211da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 212da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgTEST_F(ExpressionLimitTest, UnusedExpressionComplexity) 213da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org{ 214da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderSpec spec = SH_WEBGL_SPEC; 215da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderOutput output = SH_ESSL_OUTPUT; 216da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShHandle vertexCompiler = ShConstructCompiler( 217da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org SH_FRAGMENT_SHADER, spec, output, &resources); 218da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org int compileOptions = SH_LIMIT_EXPRESSION_COMPLEXITY; 219da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 220da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test expression under the limit passes. 221da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 222da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 223da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithUnusedLongExpression( 224da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxExpressionComplexity - 10).c_str(), 225da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, NULL)); 226da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test expression over the limit fails. 227da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 228da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 229da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithUnusedLongExpression( 230da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxExpressionComplexity + 10).c_str(), 231da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kExpressionTooComplex)); 232da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test expression over the limit without a limit does not fail. 233da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 234da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 235da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithUnusedLongExpression( 236da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxExpressionComplexity + 10).c_str(), 237da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions & ~SH_LIMIT_EXPRESSION_COMPLEXITY, NULL)); 238da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org} 239da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 240da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgTEST_F(ExpressionLimitTest, CallStackDepth) 241da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org{ 242da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderSpec spec = SH_WEBGL_SPEC; 243da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderOutput output = SH_ESSL_OUTPUT; 244da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShHandle vertexCompiler = ShConstructCompiler( 245da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org SH_FRAGMENT_SHADER, spec, output, &resources); 246da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org int compileOptions = SH_LIMIT_CALL_STACK_DEPTH; 247da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 248da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test call stack under the limit passes. 249da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 250da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 251da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithDeepFunctionStack( 252da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxCallStackDepth - 10).c_str(), 253da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, NULL)); 254da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test call stack over the limit fails. 255da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 256da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 257da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithDeepFunctionStack( 258da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxCallStackDepth + 10).c_str(), 259da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kCallStackTooDeep)); 260da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test call stack over the limit without limit does not fail. 261da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 262da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 263da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithDeepFunctionStack( 264da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxCallStackDepth + 10).c_str(), 265da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions & ~SH_LIMIT_CALL_STACK_DEPTH, NULL)); 266da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org} 267da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 268da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgTEST_F(ExpressionLimitTest, UnusedCallStackDepth) 269da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org{ 270da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderSpec spec = SH_WEBGL_SPEC; 271da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderOutput output = SH_ESSL_OUTPUT; 272da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShHandle vertexCompiler = ShConstructCompiler( 273da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org SH_FRAGMENT_SHADER, spec, output, &resources); 274da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org int compileOptions = SH_LIMIT_CALL_STACK_DEPTH; 275da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 276da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test call stack under the limit passes. 277da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 278da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 279da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithUnusedDeepFunctionStack( 280da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxCallStackDepth - 10).c_str(), 281da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, NULL)); 282da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test call stack over the limit fails. 283da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 284da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 285da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithUnusedDeepFunctionStack( 286da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxCallStackDepth + 10).c_str(), 287da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kCallStackTooDeep)); 288da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Test call stack over the limit without limit does not fail. 289da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 290da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, 291da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org GenerateShaderWithUnusedDeepFunctionStack( 292da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org kMaxCallStackDepth + 10).c_str(), 293da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions & ~SH_LIMIT_CALL_STACK_DEPTH, NULL)); 294da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org} 295da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 296da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.orgTEST_F(ExpressionLimitTest, Recursion) 297da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org{ 298da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderSpec spec = SH_WEBGL_SPEC; 299da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShShaderOutput output = SH_ESSL_OUTPUT; 300da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ShHandle vertexCompiler = ShConstructCompiler( 301da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org SH_FRAGMENT_SHADER, spec, output, &resources); 302da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org int compileOptions = 0; 303da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 304da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion0 = SHADER( 305da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 306da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 307da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 308da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return someFunc(); 309da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 310da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 311da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 312da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = u_color * someFunc(); 313da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 314da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 315da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 316da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion1 = SHADER( 317da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 318da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 319da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 320da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc(); 321da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 322da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc1() { 323da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return someFunc(); 324da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 325da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 326da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 327da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return someFunc1(); 328da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 329da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 330da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 331da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = u_color * someFunc(); 332da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 333da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 334da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 335da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion2 = SHADER( 336da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 337da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 338da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 339da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org if (u_color.x > 0.5) { 340da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return someFunc(); 341da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } else { 342da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return vec4(1); 343da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 344da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 345da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 346da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 347da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = someFunc(); 348da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 349da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 350da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 351da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion3 = SHADER( 352da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 353da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 354da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 355da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org if (u_color.x > 0.5) { 356da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return vec4(1); 357da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } else { 358da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return someFunc(); 359da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 360da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 361da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 362da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 363da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = someFunc(); 364da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 365da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 366da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 367da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion4 = SHADER( 368da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 369da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 370da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 371da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return (u_color.x > 0.5) ? vec4(1) : someFunc(); 372da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 373da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 374da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 375da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = someFunc(); 376da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 377da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 378da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 379da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion5 = SHADER( 380da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 381da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 382da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 383da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return (u_color.x > 0.5) ? someFunc() : vec4(1); 384da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 385da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 386da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 387da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = someFunc(); 388da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 389da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 390da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 391da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion6 = SHADER( 392da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 393da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 394da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 someFunc() { 395da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return someFunc(); 396da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 397da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 398da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 399da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = u_color; 400da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 401da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 402da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 403da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithNoRecursion = SHADER( 404da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 405da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 406da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 407da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec3 rgb(int r, int g, int b) { 408da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0); 409da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 410da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 411da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // these external calls used to incorrectly trigger 412da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // recursion detection. 413da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec3 hairColor0 = rgb(151, 200, 234); 414da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec3 faceColor2 = rgb(183, 148, 133); 415da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 416da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 417da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = u_color + vec4(hairColor0 + faceColor2, 0); 418da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 419da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 420da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 421da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion7 = SHADER( 422da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 423da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 424da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 425da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function2() { 426da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return u_color; 427da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 428da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 429da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function1() { 430da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 a = function2(); 431da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 b = function1(); 432da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return a + b; 433da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 434da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 435da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 436da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = function1(); 437da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 438da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 439da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 440da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org static const char* shaderWithRecursion8 = SHADER( 441da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org precision mediump float; 442da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org uniform vec4 u_color; 443da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 444da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function1(); 445da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 446da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function3() { 447da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return function1(); 448da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 449da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 450da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function2() { 451da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return function3(); 452da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 453da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 454da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vec4 function1() { 455da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org return function2(); 456da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 457da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 458da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org void main() { 459da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org gl_FragColor = function1(); 460da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org } 461da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org ); 462da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 463da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check simple recursions fails. 464da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 465da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion0, 466da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 467da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check simple recursions fails. 468da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 469da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion1, 470da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 471da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check if recursions fails. 472da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 473da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion2, 474da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 475da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check if recursions fails. 476da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 477da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion3, 478da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 479da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check ternary recursions fails. 480da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 481da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion4, 482da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 483da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check ternary recursions fails. 484da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 485da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion5, 486da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 487da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check unused recursions passes. 488da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 489da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion6, 490da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, NULL)); 491da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 492da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion7, 493da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 494da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 495da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion8, 496da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, kHasRecursion)); 497da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check unused recursions fails if limiting call stack 498da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // since we check all paths. 499da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 500da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithRecursion6, 501da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions | SH_LIMIT_CALL_STACK_DEPTH, kHasRecursion)); 502da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 503da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check unused recursions passes. 504da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 505da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithNoRecursion, 506da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions, NULL)); 507da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org // Check unused recursions passes if limiting call stack. 508da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org EXPECT_TRUE(CheckShaderCompilation( 509da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org vertexCompiler, shaderWithNoRecursion, 510da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org compileOptions | SH_LIMIT_CALL_STACK_DEPTH, NULL)); 511da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org} 512da8ea022340eba4899339874eefd5407612717b1shannonwoods@chromium.org 513