Commit 1436d434 by Olli Etuaho Committed by Commit Bot

Add a simple compiler perf test

The perf test initializes the compiler once and then translates the same shader to HLSL, GLSL or ESSL repeatedly. There are three variations of the test compiling different shaders. One is a real-world shader. BUG=angleproject:2267 TEST=angle_perftests Change-Id: Ie07b67d7548d105c4c93dff3b6196233d83b5b8c Reviewed-on: https://chromium-review.googlesource.com/883784Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 17e3d2d5
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
'<(angle_path)/src/tests/perf_tests/BindingPerf.cpp', '<(angle_path)/src/tests/perf_tests/BindingPerf.cpp',
'<(angle_path)/src/tests/perf_tests/BitSetIteratorPerf.cpp', '<(angle_path)/src/tests/perf_tests/BitSetIteratorPerf.cpp',
'<(angle_path)/src/tests/perf_tests/BufferSubData.cpp', '<(angle_path)/src/tests/perf_tests/BufferSubData.cpp',
'<(angle_path)/src/tests/perf_tests/CompilerPerf.cpp',
'<(angle_path)/src/tests/perf_tests/DrawCallPerf.cpp', '<(angle_path)/src/tests/perf_tests/DrawCallPerf.cpp',
'<(angle_path)/src/tests/perf_tests/DrawCallPerfParams.cpp', '<(angle_path)/src/tests/perf_tests/DrawCallPerfParams.cpp',
'<(angle_path)/src/tests/perf_tests/DrawCallPerfParams.h', '<(angle_path)/src/tests/perf_tests/DrawCallPerfParams.h',
......
//
// Copyright 2018 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.
//
// CompilerPerfTest:
// Performance test for the shader translator. The test initializes the compiler once and then
// compiles the same shader repeatedly. There are different variations of the tests using
// different shaders.
//
#include "ANGLEPerfTest.h"
#include "GLSLANG/ShaderLang.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/InitializeGlobals.h"
#include "compiler/translator/PoolAlloc.h"
namespace
{
const char *kSimpleESSL100FragSource = R"(
precision mediump float;
void main()
{
gl_FragColor = vec4(0, 1, 0, 1);
}
)";
const char *kSimpleESSL100Id = "SimpleESSL100";
const char *kSimpleESSL300FragSource = R"(#version 300 es
precision highp float;
out vec4 outColor;
void main()
{
outColor = vec4(0, 1, 0, 1);
}
)";
const char *kSimpleESSL300Id = "SimpleESSL300";
const char *kRealWorldESSL100FragSource = R"(precision highp float;
precision highp sampler2D;
precision highp int;
varying vec2 vPixelCoords; // in pixels
uniform int uCircleCount;
uniform sampler2D uCircleParameters;
uniform sampler2D uBrushTex;
void main(void)
{
float destAlpha = 0.0;
for (int i = 0; i < 32; ++i)
{
vec4 parameterColor = texture2D(uCircleParameters,vec2(0.25, (float(i) + 0.5) / 32.0));
vec2 center = parameterColor.xy;
float circleRadius = parameterColor.z;
float circleFlowAlpha = parameterColor.w;
vec4 parameterColor2 = texture2D(uCircleParameters,vec2(0.75, (float(i) + 0.5) / 32.0));
float circleRotation = parameterColor2.x;
vec2 centerDiff = vPixelCoords - center;
float radius = max(circleRadius, 0.5);
float flowAlpha = (circleRadius < 0.5) ? circleFlowAlpha * circleRadius * circleRadius * 4.0: circleFlowAlpha;
float antialiasMult = clamp((radius + 1.0 - length(centerDiff)) * 0.5, 0.0, 1.0);
mat2 texRotation = mat2(cos(circleRotation), -sin(circleRotation), sin(circleRotation), cos(circleRotation));
vec2 texCoords = texRotation * centerDiff / radius * 0.5 + 0.5;
float texValue = texture2D(uBrushTex, texCoords).r;
float circleAlpha = flowAlpha * antialiasMult * texValue;
if (i < uCircleCount)
{
destAlpha = clamp(circleAlpha + (1.0 - circleAlpha) * destAlpha, 0.0, 1.0);
}
}
gl_FragColor = vec4(0.0, 0.0, 0.0, destAlpha);
})";
const char *kRealWorldESSL100Id = "RealWorldESSL100";
struct CompilerPerfParameters final : public angle::CompilerParameters
{
CompilerPerfParameters(ShShaderOutput output,
const char *shaderSource,
const char *shaderSourceId)
: angle::CompilerParameters(output), shaderSource(shaderSource)
{
testId = shaderSourceId;
testId += "_";
testId += angle::CompilerParameters::str();
}
const char *shaderSource;
std::string testId;
};
std::ostream &operator<<(std::ostream &stream, const CompilerPerfParameters &p)
{
stream << p.testId;
return stream;
}
class CompilerPerfTest : public ANGLEPerfTest,
public ::testing::WithParamInterface<CompilerPerfParameters>
{
public:
CompilerPerfTest();
void step() override;
void SetUp() override;
void TearDown() override;
protected:
void setTestShader(const char *str) { mTestShader = str; }
private:
const char *mTestShader;
ShBuiltInResources mResources;
TPoolAllocator mAllocator;
sh::TCompiler *mTranslator;
};
CompilerPerfTest::CompilerPerfTest() : ANGLEPerfTest("CompilerPerf", GetParam().testId)
{
}
void CompilerPerfTest::SetUp()
{
ANGLEPerfTest::SetUp();
InitializePoolIndex();
mAllocator.push();
SetGlobalPoolAllocator(&mAllocator);
const auto &params = GetParam();
mTranslator = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, params.output);
sh::InitBuiltInResources(&mResources);
mResources.FragmentPrecisionHigh = true;
if (!mTranslator->Init(mResources))
{
SafeDelete(mTranslator);
}
setTestShader(params.shaderSource);
}
void CompilerPerfTest::TearDown()
{
SafeDelete(mTranslator);
SetGlobalPoolAllocator(nullptr);
mAllocator.pop();
FreePoolIndex();
ANGLEPerfTest::TearDown();
}
void CompilerPerfTest::step()
{
const char *shaderStrings[] = {mTestShader};
ShCompileOptions compileOptions = SH_OBJECT_CODE | SH_VARIABLES |
SH_INITIALIZE_UNINITIALIZED_LOCALS | SH_INIT_OUTPUT_VARIABLES;
const int kNumIterationsPerStep = 10;
#if !defined(NDEBUG)
// Make sure that compilation succeeds and print the info log if it doesn't in debug mode.
if (!mTranslator->compile(shaderStrings, 1, compileOptions))
{
std::cout << "Compiling perf test shader failed with log:\n"
<< mTranslator->getInfoSink().info.c_str();
}
#endif
for (unsigned int iteration = 0; iteration < kNumIterationsPerStep; ++iteration)
{
mTranslator->compile(shaderStrings, 1, compileOptions);
}
}
TEST_P(CompilerPerfTest, Run)
{
run();
}
ANGLE_INSTANTIATE_TEST(
CompilerPerfTest,
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
CompilerPerfParameters(SH_HLSL_4_1_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id),
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
CompilerPerfParameters(SH_GLSL_450_CORE_OUTPUT,
kRealWorldESSL100FragSource,
kRealWorldESSL100Id),
CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL100FragSource, kSimpleESSL100Id),
CompilerPerfParameters(SH_ESSL_OUTPUT, kSimpleESSL300FragSource, kSimpleESSL300Id),
CompilerPerfParameters(SH_ESSL_OUTPUT, kRealWorldESSL100FragSource, kRealWorldESSL100Id));
} // anonymous namespace
...@@ -9,6 +9,37 @@ ...@@ -9,6 +9,37 @@
namespace angle namespace angle
{ {
CompilerParameters::CompilerParameters()
{
output = SH_HLSL_4_1_OUTPUT;
}
CompilerParameters::CompilerParameters(ShShaderOutput output) : output(output)
{
}
const char *CompilerParameters::str() const
{
switch (output)
{
case SH_HLSL_4_1_OUTPUT:
return "HLSL_4_1";
case SH_GLSL_450_CORE_OUTPUT:
return "GLSL_4_50";
case SH_ESSL_OUTPUT:
return "ESSL";
default:
UNREACHABLE();
return "unk";
}
}
std::ostream &operator<<(std::ostream &stream, const CompilerParameters &p)
{
stream << p.str();
return stream;
}
PlatformParameters::PlatformParameters() PlatformParameters::PlatformParameters()
: PlatformParameters(2, 0, EGLPlatformParameters()) : PlatformParameters(2, 0, EGLPlatformParameters())
{ {
......
...@@ -17,12 +17,25 @@ ...@@ -17,12 +17,25 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include "angle_test_instantiate.h"
#include "EGLWindow.h" #include "EGLWindow.h"
#include "GLSLANG/ShaderLang.h"
#include "angle_test_instantiate.h"
namespace angle namespace angle
{ {
struct CompilerParameters
{
CompilerParameters();
CompilerParameters(ShShaderOutput output);
const char *str() const;
ShShaderOutput output;
};
std::ostream &operator<<(std::ostream &stream, const CompilerParameters &pp);
struct PlatformParameters struct PlatformParameters
{ {
PlatformParameters(); PlatformParameters();
......
...@@ -14,11 +14,43 @@ ...@@ -14,11 +14,43 @@
#include "EGLWindow.h" #include "EGLWindow.h"
#include "OSWindow.h" #include "OSWindow.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/InitializeGlobals.h"
#include "test_utils/angle_test_configs.h" #include "test_utils/angle_test_configs.h"
namespace angle namespace angle
{ {
bool IsPlatformAvailable(const CompilerParameters &param)
{
switch (param.output)
{
case SH_HLSL_4_1_OUTPUT:
case SH_HLSL_4_0_FL9_3_OUTPUT:
case SH_HLSL_3_0_OUTPUT:
{
TPoolAllocator allocator;
InitializePoolIndex();
allocator.push();
SetGlobalPoolAllocator(&allocator);
ShHandle translator =
sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL2_SPEC, param.output);
bool success = translator != nullptr;
SetGlobalPoolAllocator(nullptr);
allocator.pop();
FreePoolIndex();
if (!success)
{
return false;
}
break;
}
default:
break;
}
return true;
}
bool IsPlatformAvailable(const PlatformParameters &param) bool IsPlatformAvailable(const PlatformParameters &param)
{ {
switch (param.getRenderer()) switch (param.getRenderer())
......
...@@ -17,8 +17,11 @@ ...@@ -17,8 +17,11 @@
namespace angle namespace angle
{ {
struct CompilerParameters;
struct PlatformParameters; struct PlatformParameters;
bool IsPlatformAvailable(const CompilerParameters &param);
bool IsPlatformAvailable(const PlatformParameters &param); bool IsPlatformAvailable(const PlatformParameters &param);
// This functions is used to filter which tests should be registered, // This functions is used to filter which tests should be registered,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment