blob: 2c5ddfd0a528ea665fb432299b105bc397673e98 [file] [log] [blame]
Olli Etuaho1436d432018-01-24 14:38:22 +02001//
2// Copyright 2018 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// CompilerPerfTest:
7// Performance test for the shader translator. The test initializes the compiler once and then
8// compiles the same shader repeatedly. There are different variations of the tests using
9// different shaders.
10//
11
12#include "ANGLEPerfTest.h"
13
14#include "GLSLANG/ShaderLang.h"
15#include "compiler/translator/Compiler.h"
16#include "compiler/translator/InitializeGlobals.h"
17#include "compiler/translator/PoolAlloc.h"
18
19namespace
20{
21
22const char *kSimpleESSL100FragSource = R"(
23precision mediump float;
24void main()
25{
26 gl_FragColor = vec4(0, 1, 0, 1);
27}
28)";
29
30const char *kSimpleESSL100Id = "SimpleESSL100";
31
32const char *kSimpleESSL300FragSource = R"(#version 300 es
33precision highp float;
34out vec4 outColor;
35void main()
36{
37 outColor = vec4(0, 1, 0, 1);
38}
39)";
40
41const char *kSimpleESSL300Id = "SimpleESSL300";
42
43const char *kRealWorldESSL100FragSource = R"(precision highp float;
44precision highp sampler2D;
45precision highp int;
46varying vec2 vPixelCoords; // in pixels
47uniform int uCircleCount;
48uniform sampler2D uCircleParameters;
49uniform sampler2D uBrushTex;
50void main(void)
51{
52 float destAlpha = 0.0;
53 for (int i = 0; i < 32; ++i)
54 {
55 vec4 parameterColor = texture2D(uCircleParameters,vec2(0.25, (float(i) + 0.5) / 32.0));
56 vec2 center = parameterColor.xy;
57 float circleRadius = parameterColor.z;
58 float circleFlowAlpha = parameterColor.w;
59 vec4 parameterColor2 = texture2D(uCircleParameters,vec2(0.75, (float(i) + 0.5) / 32.0));
60 float circleRotation = parameterColor2.x;
61 vec2 centerDiff = vPixelCoords - center;
62 float radius = max(circleRadius, 0.5);
63 float flowAlpha = (circleRadius < 0.5) ? circleFlowAlpha * circleRadius * circleRadius * 4.0: circleFlowAlpha;
64 float antialiasMult = clamp((radius + 1.0 - length(centerDiff)) * 0.5, 0.0, 1.0);
65 mat2 texRotation = mat2(cos(circleRotation), -sin(circleRotation), sin(circleRotation), cos(circleRotation));
66 vec2 texCoords = texRotation * centerDiff / radius * 0.5 + 0.5;
67 float texValue = texture2D(uBrushTex, texCoords).r;
68 float circleAlpha = flowAlpha * antialiasMult * texValue;
69 if (i < uCircleCount)
70 {
71 destAlpha = clamp(circleAlpha + (1.0 - circleAlpha) * destAlpha, 0.0, 1.0);
72 }
73 }
74 gl_FragColor = vec4(0.0, 0.0, 0.0, destAlpha);
75})";
76
77const char *kRealWorldESSL100Id = "RealWorldESSL100";
78
79struct CompilerPerfParameters final : public angle::CompilerParameters
80{
81 CompilerPerfParameters(ShShaderOutput output,
82 const char *shaderSource,
83 const char *shaderSourceId)
84 : angle::CompilerParameters(output), shaderSource(shaderSource)
85 {
86 testId = shaderSourceId;
87 testId += "_";
88 testId += angle::CompilerParameters::str();
89 }
90
91 const char *shaderSource;
92 std::string testId;
93};
94
95std::ostream &operator<<(std::ostream &stream, const CompilerPerfParameters &p)
96{
97 stream << p.testId;
98 return stream;
99}
100
101class CompilerPerfTest : public ANGLEPerfTest,
102 public ::testing::WithParamInterface<CompilerPerfParameters>
103{
104 public:
105 CompilerPerfTest();
106
107 void step() override;
108
109 void SetUp() override;
110 void TearDown() override;
111
112 protected:
113 void setTestShader(const char *str) { mTestShader = str; }
114
115 private:
116 const char *mTestShader;
117
118 ShBuiltInResources mResources;
119 TPoolAllocator mAllocator;
120 sh::TCompiler *mTranslator;
121};
122
123CompilerPerfTest::CompilerPerfTest() : ANGLEPerfTest("CompilerPerf", GetParam().testId)
124{
125}
126
127void CompilerPerfTest::SetUp()
128{
129 ANGLEPerfTest::SetUp();
130
131 InitializePoolIndex();
132 mAllocator.push();
133 SetGlobalPoolAllocator(&mAllocator);
134
135 const auto &params = GetParam();
136
137 mTranslator = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, params.output);
138 sh::InitBuiltInResources(&mResources);
139 mResources.FragmentPrecisionHigh = true;
140 if (!mTranslator->Init(mResources))
141 {
142 SafeDelete(mTranslator);
143 }
144
145 setTestShader(params.shaderSource);
146}
147
148void CompilerPerfTest::TearDown()
149{
150 SafeDelete(mTranslator);
151
152 SetGlobalPoolAllocator(nullptr);
153 mAllocator.pop();
154
155 FreePoolIndex();
156
157 ANGLEPerfTest::TearDown();
158}
159
160void CompilerPerfTest::step()
161{
162 const char *shaderStrings[] = {mTestShader};
163
164 ShCompileOptions compileOptions = SH_OBJECT_CODE | SH_VARIABLES |
165 SH_INITIALIZE_UNINITIALIZED_LOCALS | SH_INIT_OUTPUT_VARIABLES;
166
167 const int kNumIterationsPerStep = 10;
168
169#if !defined(NDEBUG)
170 // Make sure that compilation succeeds and print the info log if it doesn't in debug mode.
171 if (!mTranslator->compile(shaderStrings, 1, compileOptions))
172 {
173 std::cout << "Compiling perf test shader failed with log:\n"
174 << mTranslator->getInfoSink().info.c_str();
175 }
176#endif
177
178 for (unsigned int iteration = 0; iteration < kNumIterationsPerStep; ++iteration)
179 {
180 mTranslator->compile(shaderStrings, 1, compileOptions);
181 }
182}
183
184TEST_P(CompilerPerfTest, Run)
185{
186 run();
187}
188
189ANGLE_INSTANTIATE_TEST(
190 CompilerPerfTest,
191 CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
192 CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
193 CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id),
194 CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
195 CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
196 CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT,
197 kRealWorldESSL100FragSource,
198 kRealWorldESSL100Id),
199 CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
200 CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
201 CompilerPerfParameters(SH_ESSL_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id));
202
203} // anonymous namespace