Path: blob/main_old/src/tests/perf_tests/CompilerPerf.cpp
1693 views
//1// Copyright 2018 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// CompilerPerfTest:6// Performance test for the shader translator. The test initializes the compiler once and then7// compiles the same shader repeatedly. There are different variations of the tests using8// different shaders.9//1011#include "ANGLEPerfTest.h"1213#include "GLSLANG/ShaderLang.h"14#include "compiler/translator/Compiler.h"15#include "compiler/translator/InitializeGlobals.h"16#include "compiler/translator/PoolAlloc.h"1718namespace19{2021const char *kSimpleESSL100FragSource = R"(22precision mediump float;23void main()24{25gl_FragColor = vec4(0, 1, 0, 1);26}27)";2829const char *kSimpleESSL100Id = "SimpleESSL100";3031const char *kSimpleESSL300FragSource = R"(#version 300 es32precision highp float;33out vec4 outColor;34void main()35{36outColor = vec4(0, 1, 0, 1);37}38)";3940const char *kSimpleESSL300Id = "SimpleESSL300";4142const char *kRealWorldESSL100FragSource = R"(precision highp float;43precision highp sampler2D;44precision highp int;45varying vec2 vPixelCoords; // in pixels46uniform int uCircleCount;47uniform sampler2D uCircleParameters;48uniform sampler2D uBrushTex;49void main(void)50{51float destAlpha = 0.0;52for (int i = 0; i < 32; ++i)53{54vec4 parameterColor = texture2D(uCircleParameters,vec2(0.25, (float(i) + 0.5) / 32.0));55vec2 center = parameterColor.xy;56float circleRadius = parameterColor.z;57float circleFlowAlpha = parameterColor.w;58vec4 parameterColor2 = texture2D(uCircleParameters,vec2(0.75, (float(i) + 0.5) / 32.0));59float circleRotation = parameterColor2.x;60vec2 centerDiff = vPixelCoords - center;61float radius = max(circleRadius, 0.5);62float flowAlpha = (circleRadius < 0.5) ? circleFlowAlpha * circleRadius * circleRadius * 4.0: circleFlowAlpha;63float antialiasMult = clamp((radius + 1.0 - length(centerDiff)) * 0.5, 0.0, 1.0);64mat2 texRotation = mat2(cos(circleRotation), -sin(circleRotation), sin(circleRotation), cos(circleRotation));65vec2 texCoords = texRotation * centerDiff / radius * 0.5 + 0.5;66float texValue = texture2D(uBrushTex, texCoords).r;67float circleAlpha = flowAlpha * antialiasMult * texValue;68if (i < uCircleCount)69{70destAlpha = clamp(circleAlpha + (1.0 - circleAlpha) * destAlpha, 0.0, 1.0);71}72}73gl_FragColor = vec4(0.0, 0.0, 0.0, destAlpha);74})";7576const char *kRealWorldESSL100Id = "RealWorldESSL100";7778// This shader is intended to trigger many AST transformations, particularly on the HLSL backend.79const char *kTrickyESSL300FragSource = R"(#version 300 es80precision highp float;81precision highp sampler2D;82precision highp isampler2D;83precision highp int;8485float globalF;8687uniform ivec4 uivec;88uniform int ui;8990struct SS91{92int iField;93float fField;94vec2 f2Field;95sampler2D sField;96isampler2D isField;97};98uniform SS us;99100out vec4 my_FragColor;101102float[3] sideEffectArray()103{104globalF += 1.0;105return float[3](globalF, globalF * 2.0, globalF * 3.0);106}107108// This struct is unused and can be pruned.109struct SUnused110{111vec2 fField;112};113114void main()115{116struct S2117{118float fField;119} s2;120vec4 foo = vec4(ui);121mat4 fooM = mat4(foo.x);122123// Some unused variables that can be pruned.124float fUnused, fUnused2;125ivec4 iUnused, iUnused2;126127globalF = us.fField;128s2.fField = us.fField;129130float[3] fa = sideEffectArray();131132globalF -= us.fField;133if (fa == sideEffectArray())134{135globalF += us.fField * sin(2.0);136}137138// Switch with fall-through.139switch (ui)140{141case 0:142// Sequence operator and matrix and vector dynamic indexing.143(globalF += 1.0, fooM[ui][ui] += fooM[ui - 1][uivec[ui] + 1]);144case 1:145// Built-in emulation.146foo[3] = tanh(foo[1]);147default:148// Sequence operator and length of an array expression with side effects.149foo[2] += (globalF -= 1.0, float((sideEffectArray()).length() * 2));150}151int i = 0;152do153{154s2.fField = us.fField * us.f2Field.x;155// Sequence operator and short-circuiting operator with side effects on the right hand side.156} while ((++i, i < int(us.fField) && ++i <= ui || ++i < ui * 2 - 3));157// Samplers in structures and integer texture sampling.158foo += texture(us.sField, us.f2Field) + intBitsToFloat(texture(us.isField, us.f2Field + 4.0));159my_FragColor = foo * s2.fField * globalF + fooM[ui];160})";161162const char *kTrickyESSL300Id = "TrickyESSL300";163164constexpr int kNumIterationsPerStep = 4;165166struct CompilerParameters167{168CompilerParameters() { output = SH_HLSL_4_1_OUTPUT; }169170CompilerParameters(ShShaderOutput output) : output(output) {}171172const char *str() const173{174switch (output)175{176case SH_HLSL_4_1_OUTPUT:177return "HLSL_4_1";178case SH_GLSL_450_CORE_OUTPUT:179return "GLSL_4_50";180case SH_ESSL_OUTPUT:181return "ESSL";182default:183UNREACHABLE();184return "unk";185}186}187188ShShaderOutput output;189};190191bool IsPlatformAvailable(const CompilerParameters ¶m)192{193switch (param.output)194{195case SH_HLSL_4_1_OUTPUT:196case SH_HLSL_4_0_FL9_3_OUTPUT:197case SH_HLSL_3_0_OUTPUT:198{199angle::PoolAllocator allocator;200InitializePoolIndex();201allocator.push();202SetGlobalPoolAllocator(&allocator);203ShHandle translator =204sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, param.output);205bool success = translator != nullptr;206SetGlobalPoolAllocator(nullptr);207allocator.pop();208FreePoolIndex();209if (!success)210{211return false;212}213break;214}215default:216break;217}218return true;219}220221struct CompilerPerfParameters final : public CompilerParameters222{223CompilerPerfParameters(ShShaderOutput output,224const char *shaderSource,225const char *shaderSourceId)226: CompilerParameters(output), shaderSource(shaderSource)227{228testId = shaderSourceId;229testId += "_";230testId += CompilerParameters::str();231}232233const char *shaderSource;234std::string testId;235};236237std::ostream &operator<<(std::ostream &stream, const CompilerPerfParameters &p)238{239stream << p.testId;240return stream;241}242243class CompilerPerfTest : public ANGLEPerfTest,244public ::testing::WithParamInterface<CompilerPerfParameters>245{246public:247CompilerPerfTest();248249void step() override;250251void SetUp() override;252void TearDown() override;253254protected:255void setTestShader(const char *str) { mTestShader = str; }256257private:258const char *mTestShader;259260ShBuiltInResources mResources;261angle::PoolAllocator mAllocator;262sh::TCompiler *mTranslator;263};264265CompilerPerfTest::CompilerPerfTest()266: ANGLEPerfTest("CompilerPerf", "", GetParam().testId, kNumIterationsPerStep)267{}268269void CompilerPerfTest::SetUp()270{271ANGLEPerfTest::SetUp();272273InitializePoolIndex();274mAllocator.push();275SetGlobalPoolAllocator(&mAllocator);276277const auto ¶ms = GetParam();278279mTranslator = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, params.output);280sh::InitBuiltInResources(&mResources);281mResources.FragmentPrecisionHigh = true;282if (!mTranslator->Init(mResources))283{284SafeDelete(mTranslator);285}286287setTestShader(params.shaderSource);288}289290void CompilerPerfTest::TearDown()291{292SafeDelete(mTranslator);293294SetGlobalPoolAllocator(nullptr);295mAllocator.pop();296297FreePoolIndex();298299ANGLEPerfTest::TearDown();300}301302void CompilerPerfTest::step()303{304const char *shaderStrings[] = {mTestShader};305306ShCompileOptions compileOptions = SH_OBJECT_CODE | SH_VARIABLES |307SH_INITIALIZE_UNINITIALIZED_LOCALS | SH_INIT_OUTPUT_VARIABLES;308309#if !defined(NDEBUG)310// Make sure that compilation succeeds and print the info log if it doesn't in debug mode.311if (!mTranslator->compile(shaderStrings, 1, compileOptions))312{313std::cout << "Compiling perf test shader failed with log:\n"314<< mTranslator->getInfoSink().info.c_str();315}316#endif317318for (unsigned int iteration = 0; iteration < kNumIterationsPerStep; ++iteration)319{320mTranslator->compile(shaderStrings, 1, compileOptions);321}322}323324TEST_P(CompilerPerfTest, Run)325{326run();327}328329ANGLE_INSTANTIATE_TEST(330CompilerPerfTest,331CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),332CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),333CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id),334CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kTrickyESSL300FragSource, kTrickyESSL300Id),335CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),336CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),337CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT,338kRealWorldESSL100FragSource,339kRealWorldESSL100Id),340CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kTrickyESSL300FragSource, kTrickyESSL300Id),341CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),342CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),343CompilerPerfParameters(SH_ESSL_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id),344CompilerPerfParameters(SH_ESSL_OUTPUT, kTrickyESSL300FragSource, kTrickyESSL300Id));345346} // anonymous namespace347348349