| // |
| // Copyright 2016 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. |
| // |
| // LinkProgramPerfTest: |
| // Performance tests compiling a lot of shaders. |
| // |
| |
| #include "ANGLEPerfTest.h" |
| |
| #include <array> |
| |
| #include "common/vector_utils.h" |
| #include "util/shader_utils.h" |
| |
| using namespace angle; |
| |
| namespace |
| { |
| |
| enum class TaskOption |
| { |
| CompileOnly, |
| CompileAndLink, |
| |
| Unspecified |
| }; |
| |
| enum class ThreadOption |
| { |
| SingleThread, |
| MultiThread, |
| |
| Unspecified |
| }; |
| |
| struct LinkProgramParams final : public RenderTestParams |
| { |
| LinkProgramParams(TaskOption taskOptionIn, ThreadOption threadOptionIn) |
| { |
| iterationsPerStep = 1; |
| |
| majorVersion = 2; |
| minorVersion = 0; |
| windowWidth = 256; |
| windowHeight = 256; |
| taskOption = taskOptionIn; |
| threadOption = threadOptionIn; |
| } |
| |
| std::string story() const override |
| { |
| std::stringstream strstr; |
| strstr << RenderTestParams::story(); |
| |
| if (taskOption == TaskOption::CompileOnly) |
| { |
| strstr << "_compile_only"; |
| } |
| else if (taskOption == TaskOption::CompileAndLink) |
| { |
| strstr << "_compile_and_link"; |
| } |
| |
| if (threadOption == ThreadOption::SingleThread) |
| { |
| strstr << "_single_thread"; |
| } |
| else if (threadOption == ThreadOption::MultiThread) |
| { |
| strstr << "_multi_thread"; |
| } |
| |
| if (eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE) |
| { |
| strstr << "_null"; |
| } |
| |
| return strstr.str(); |
| } |
| |
| TaskOption taskOption; |
| ThreadOption threadOption; |
| }; |
| |
| std::ostream &operator<<(std::ostream &os, const LinkProgramParams ¶ms) |
| { |
| os << params.backendAndStory().substr(1); |
| return os; |
| } |
| |
| class LinkProgramBenchmark : public ANGLERenderTest, |
| public ::testing::WithParamInterface<LinkProgramParams> |
| { |
| public: |
| LinkProgramBenchmark(); |
| |
| void initializeBenchmark() override; |
| void destroyBenchmark() override; |
| void drawBenchmark() override; |
| |
| protected: |
| GLuint mVertexBuffer = 0; |
| }; |
| |
| LinkProgramBenchmark::LinkProgramBenchmark() : ANGLERenderTest("LinkProgram", GetParam()) {} |
| |
| void LinkProgramBenchmark::initializeBenchmark() |
| { |
| if (GetParam().threadOption == ThreadOption::SingleThread) |
| { |
| glMaxShaderCompilerThreadsKHR(0); |
| } |
| |
| std::array<Vector3, 6> vertices = {{Vector3(-1.0f, 1.0f, 0.5f), Vector3(-1.0f, -1.0f, 0.5f), |
| Vector3(1.0f, -1.0f, 0.5f), Vector3(-1.0f, 1.0f, 0.5f), |
| Vector3(1.0f, -1.0f, 0.5f), Vector3(1.0f, 1.0f, 0.5f)}}; |
| |
| glGenBuffers(1, &mVertexBuffer); |
| glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); |
| glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vector3), vertices.data(), |
| GL_STATIC_DRAW); |
| } |
| |
| void LinkProgramBenchmark::destroyBenchmark() |
| { |
| glDeleteBuffers(1, &mVertexBuffer); |
| } |
| |
| void LinkProgramBenchmark::drawBenchmark() |
| { |
| static const char *vertexShader = |
| "attribute vec2 position;\n" |
| "void main() {\n" |
| " gl_Position = vec4(position, 0, 1);\n" |
| "}"; |
| static const char *fragmentShader = |
| "precision mediump float;\n" |
| "void main() {\n" |
| " gl_FragColor = vec4(1, 0, 0, 1);\n" |
| "}"; |
| GLuint vs = CompileShader(GL_VERTEX_SHADER, vertexShader); |
| GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader); |
| |
| ASSERT_NE(0u, vs); |
| ASSERT_NE(0u, fs); |
| if (GetParam().taskOption == TaskOption::CompileOnly) |
| { |
| glDeleteShader(vs); |
| glDeleteShader(fs); |
| return; |
| } |
| |
| GLuint program = glCreateProgram(); |
| ASSERT_NE(0u, program); |
| |
| glAttachShader(program, vs); |
| glDeleteShader(vs); |
| glAttachShader(program, fs); |
| glDeleteShader(fs); |
| glLinkProgram(program); |
| glUseProgram(program); |
| |
| GLint positionLoc = glGetAttribLocation(program, "position"); |
| glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 8, nullptr); |
| glEnableVertexAttribArray(positionLoc); |
| |
| // Draw with the program to ensure the shader gets compiled and used. |
| glDrawArrays(GL_TRIANGLES, 0, 6); |
| |
| glDeleteProgram(program); |
| } |
| |
| using namespace egl_platform; |
| |
| LinkProgramParams LinkProgramD3D11Params(TaskOption taskOption, ThreadOption threadOption) |
| { |
| LinkProgramParams params(taskOption, threadOption); |
| params.eglParameters = D3D11(); |
| return params; |
| } |
| |
| LinkProgramParams LinkProgramD3D9Params(TaskOption taskOption, ThreadOption threadOption) |
| { |
| LinkProgramParams params(taskOption, threadOption); |
| params.eglParameters = D3D9(); |
| return params; |
| } |
| |
| LinkProgramParams LinkProgramOpenGLOrGLESParams(TaskOption taskOption, ThreadOption threadOption) |
| { |
| LinkProgramParams params(taskOption, threadOption); |
| params.eglParameters = OPENGL_OR_GLES(); |
| return params; |
| } |
| |
| LinkProgramParams LinkProgramVulkanParams(TaskOption taskOption, ThreadOption threadOption) |
| { |
| LinkProgramParams params(taskOption, threadOption); |
| params.eglParameters = VULKAN(); |
| return params; |
| } |
| |
| TEST_P(LinkProgramBenchmark, Run) |
| { |
| run(); |
| } |
| |
| ANGLE_INSTANTIATE_TEST( |
| LinkProgramBenchmark, |
| LinkProgramD3D11Params(TaskOption::CompileOnly, ThreadOption::MultiThread), |
| LinkProgramD3D9Params(TaskOption::CompileOnly, ThreadOption::MultiThread), |
| LinkProgramOpenGLOrGLESParams(TaskOption::CompileOnly, ThreadOption::MultiThread), |
| LinkProgramVulkanParams(TaskOption::CompileOnly, ThreadOption::MultiThread), |
| LinkProgramD3D11Params(TaskOption::CompileAndLink, ThreadOption::MultiThread), |
| LinkProgramD3D9Params(TaskOption::CompileAndLink, ThreadOption::MultiThread), |
| LinkProgramOpenGLOrGLESParams(TaskOption::CompileAndLink, ThreadOption::MultiThread), |
| LinkProgramVulkanParams(TaskOption::CompileAndLink, ThreadOption::MultiThread), |
| LinkProgramD3D11Params(TaskOption::CompileOnly, ThreadOption::SingleThread), |
| LinkProgramD3D9Params(TaskOption::CompileOnly, ThreadOption::SingleThread), |
| LinkProgramOpenGLOrGLESParams(TaskOption::CompileOnly, ThreadOption::SingleThread), |
| LinkProgramVulkanParams(TaskOption::CompileOnly, ThreadOption::SingleThread), |
| LinkProgramD3D11Params(TaskOption::CompileAndLink, ThreadOption::SingleThread), |
| LinkProgramD3D9Params(TaskOption::CompileAndLink, ThreadOption::SingleThread), |
| LinkProgramOpenGLOrGLESParams(TaskOption::CompileAndLink, ThreadOption::SingleThread), |
| LinkProgramVulkanParams(TaskOption::CompileAndLink, ThreadOption::SingleThread)); |
| |
| } // anonymous namespace |