xref: /aosp_15_r20/external/angle/src/tests/perf_tests/LinkProgramPerfTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 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 // LinkProgramPerfTest:
7 //   Performance tests compiling a lot of shaders.
8 //
9 
10 #include "ANGLEPerfTest.h"
11 
12 #include <array>
13 
14 #include "common/vector_utils.h"
15 #include "util/shader_utils.h"
16 
17 using namespace angle;
18 
19 namespace
20 {
21 
22 enum class TaskOption
23 {
24     CompileOnly,
25     CompileAndLink,
26 
27     Unspecified
28 };
29 
30 enum class ThreadOption
31 {
32     SingleThread,
33     MultiThread,
34 
35     Unspecified
36 };
37 
38 struct LinkProgramParams final : public RenderTestParams
39 {
LinkProgramParams__anonefc827280111::LinkProgramParams40     LinkProgramParams(TaskOption taskOptionIn, ThreadOption threadOptionIn)
41     {
42         iterationsPerStep = 1;
43 
44         majorVersion = 2;
45         minorVersion = 0;
46         windowWidth  = 256;
47         windowHeight = 256;
48         taskOption   = taskOptionIn;
49         threadOption = threadOptionIn;
50     }
51 
story__anonefc827280111::LinkProgramParams52     std::string story() const override
53     {
54         std::stringstream strstr;
55         strstr << RenderTestParams::story();
56 
57         if (taskOption == TaskOption::CompileOnly)
58         {
59             strstr << "_compile_only";
60         }
61         else if (taskOption == TaskOption::CompileAndLink)
62         {
63             strstr << "_compile_and_link";
64         }
65 
66         if (threadOption == ThreadOption::SingleThread)
67         {
68             strstr << "_single_thread";
69         }
70         else if (threadOption == ThreadOption::MultiThread)
71         {
72             strstr << "_multi_thread";
73         }
74 
75         if (eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
76         {
77             strstr << "_null";
78         }
79 
80         return strstr.str();
81     }
82 
83     TaskOption taskOption;
84     ThreadOption threadOption;
85 };
86 
operator <<(std::ostream & os,const LinkProgramParams & params)87 std::ostream &operator<<(std::ostream &os, const LinkProgramParams &params)
88 {
89     os << params.backendAndStory().substr(1);
90     return os;
91 }
92 
93 class LinkProgramBenchmark : public ANGLERenderTest,
94                              public ::testing::WithParamInterface<LinkProgramParams>
95 {
96   public:
97     LinkProgramBenchmark();
98 
99     void initializeBenchmark() override;
100     void destroyBenchmark() override;
101     void drawBenchmark() override;
102 
103   protected:
104     GLuint mVertexBuffer = 0;
105 };
106 
LinkProgramBenchmark()107 LinkProgramBenchmark::LinkProgramBenchmark() : ANGLERenderTest("LinkProgram", GetParam()) {}
108 
initializeBenchmark()109 void LinkProgramBenchmark::initializeBenchmark()
110 {
111     if (GetParam().threadOption != ThreadOption::SingleThread &&
112         !IsGLExtensionEnabled("GL_KHR_parallel_shader_compile"))
113     {
114         skipTest("non-single-thread but missing GL_KHR_parallel_shader_compile");
115         return;
116     }
117 
118     if (IsGLExtensionEnabled("GL_KHR_parallel_shader_compile") &&
119         GetParam().threadOption == ThreadOption::SingleThread)
120     {
121         glMaxShaderCompilerThreadsKHR(0);
122     }
123 
124     std::array<Vector3, 6> vertices = {{Vector3(-1.0f, 1.0f, 0.5f), Vector3(-1.0f, -1.0f, 0.5f),
125                                         Vector3(1.0f, -1.0f, 0.5f), Vector3(-1.0f, 1.0f, 0.5f),
126                                         Vector3(1.0f, -1.0f, 0.5f), Vector3(1.0f, 1.0f, 0.5f)}};
127 
128     glGenBuffers(1, &mVertexBuffer);
129     glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
130     glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vector3), vertices.data(),
131                  GL_STATIC_DRAW);
132 }
133 
destroyBenchmark()134 void LinkProgramBenchmark::destroyBenchmark()
135 {
136     glDeleteBuffers(1, &mVertexBuffer);
137 }
138 
drawBenchmark()139 void LinkProgramBenchmark::drawBenchmark()
140 {
141     static const char *vertexShader =
142         "attribute vec2 position;\n"
143         "void main() {\n"
144         "    gl_Position = vec4(position, 0, 1);\n"
145         "}";
146     static const char *fragmentShader =
147         "precision mediump float;\n"
148         "void main() {\n"
149         "    gl_FragColor = vec4(1, 0, 0, 1);\n"
150         "}";
151     GLuint vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
152     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
153 
154     ASSERT_NE(0u, vs);
155     ASSERT_NE(0u, fs);
156     if (GetParam().taskOption == TaskOption::CompileOnly)
157     {
158         glDeleteShader(vs);
159         glDeleteShader(fs);
160         return;
161     }
162 
163     GLuint program = glCreateProgram();
164     ASSERT_NE(0u, program);
165 
166     glAttachShader(program, vs);
167     glDeleteShader(vs);
168     glAttachShader(program, fs);
169     glDeleteShader(fs);
170     glLinkProgram(program);
171     glUseProgram(program);
172 
173     GLint positionLoc = glGetAttribLocation(program, "position");
174     glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 8, nullptr);
175     glEnableVertexAttribArray(positionLoc);
176 
177     // Draw with the program to ensure the shader gets compiled and used.
178     glDrawArrays(GL_TRIANGLES, 0, 6);
179 
180     glDeleteProgram(program);
181 }
182 
183 using namespace egl_platform;
184 
LinkProgramD3D11Params(TaskOption taskOption,ThreadOption threadOption)185 LinkProgramParams LinkProgramD3D11Params(TaskOption taskOption, ThreadOption threadOption)
186 {
187     LinkProgramParams params(taskOption, threadOption);
188     params.eglParameters = D3D11();
189     return params;
190 }
191 
LinkProgramMetalParams(TaskOption taskOption,ThreadOption threadOption)192 LinkProgramParams LinkProgramMetalParams(TaskOption taskOption, ThreadOption threadOption)
193 {
194     LinkProgramParams params(taskOption, threadOption);
195     params.eglParameters = METAL();
196     return params;
197 }
198 
LinkProgramOpenGLOrGLESParams(TaskOption taskOption,ThreadOption threadOption)199 LinkProgramParams LinkProgramOpenGLOrGLESParams(TaskOption taskOption, ThreadOption threadOption)
200 {
201     LinkProgramParams params(taskOption, threadOption);
202     params.eglParameters = OPENGL_OR_GLES();
203     return params;
204 }
205 
LinkProgramVulkanParams(TaskOption taskOption,ThreadOption threadOption)206 LinkProgramParams LinkProgramVulkanParams(TaskOption taskOption, ThreadOption threadOption)
207 {
208     LinkProgramParams params(taskOption, threadOption);
209     params.eglParameters = VULKAN();
210     return params;
211 }
212 
TEST_P(LinkProgramBenchmark,Run)213 TEST_P(LinkProgramBenchmark, Run)
214 {
215     run();
216 }
217 
218 ANGLE_INSTANTIATE_TEST(
219     LinkProgramBenchmark,
220     LinkProgramD3D11Params(TaskOption::CompileOnly, ThreadOption::MultiThread),
221     LinkProgramMetalParams(TaskOption::CompileOnly, ThreadOption::MultiThread),
222     LinkProgramOpenGLOrGLESParams(TaskOption::CompileOnly, ThreadOption::MultiThread),
223     LinkProgramVulkanParams(TaskOption::CompileOnly, ThreadOption::MultiThread),
224     LinkProgramD3D11Params(TaskOption::CompileAndLink, ThreadOption::MultiThread),
225     LinkProgramMetalParams(TaskOption::CompileAndLink, ThreadOption::MultiThread),
226     LinkProgramOpenGLOrGLESParams(TaskOption::CompileAndLink, ThreadOption::MultiThread),
227     LinkProgramVulkanParams(TaskOption::CompileAndLink, ThreadOption::MultiThread),
228     LinkProgramD3D11Params(TaskOption::CompileOnly, ThreadOption::SingleThread),
229     LinkProgramMetalParams(TaskOption::CompileOnly, ThreadOption::SingleThread),
230     LinkProgramOpenGLOrGLESParams(TaskOption::CompileOnly, ThreadOption::SingleThread),
231     LinkProgramVulkanParams(TaskOption::CompileOnly, ThreadOption::SingleThread),
232     LinkProgramD3D11Params(TaskOption::CompileAndLink, ThreadOption::SingleThread),
233     LinkProgramMetalParams(TaskOption::CompileAndLink, ThreadOption::SingleThread),
234     LinkProgramOpenGLOrGLESParams(TaskOption::CompileAndLink, ThreadOption::SingleThread),
235     LinkProgramVulkanParams(TaskOption::CompileAndLink, ThreadOption::SingleThread));
236 
237 }  // anonymous namespace
238