xref: /aosp_15_r20/external/angle/src/tests/perf_tests/ParallelLinkProgramPerfTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2023 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // ParallelLinkProgramPerfTest:
7*8975f5c5SAndroid Build Coastguard Worker //   Tests performance of compiling and linking many shaders and programs in sequence.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include <array>
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #include "common/vector_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker enum class CompileLinkOrder
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker     // Most optimal behavior; all compiles are done first, then all links.
25*8975f5c5SAndroid Build Coastguard Worker     AllCompilesFirst,
26*8975f5c5SAndroid Build Coastguard Worker     // Less optimal, but still decent; each program's shaders are first compiled, then the program
27*8975f5c5SAndroid Build Coastguard Worker     // is linked before moving on to the next program.
28*8975f5c5SAndroid Build Coastguard Worker     Interleaved,
29*8975f5c5SAndroid Build Coastguard Worker     // Worst behavior, which unfortunately is what the large majority of applications do; each
30*8975f5c5SAndroid Build Coastguard Worker     // program's shaders are compiled, the program is linked, and the link status is immediately
31*8975f5c5SAndroid Build Coastguard Worker     // queried (causing the main thread to block on the link task).
32*8975f5c5SAndroid Build Coastguard Worker     InterleavedAndImmediateQuery,
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker     Unspecified,
35*8975f5c5SAndroid Build Coastguard Worker };
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker struct ParallelLinkProgramParams final : public RenderTestParams
38*8975f5c5SAndroid Build Coastguard Worker {
ParallelLinkProgramParams__anon97123a550111::ParallelLinkProgramParams39*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramParams(CompileLinkOrder order)
40*8975f5c5SAndroid Build Coastguard Worker     {
41*8975f5c5SAndroid Build Coastguard Worker         iterationsPerStep = 100;
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker         majorVersion     = 3;
44*8975f5c5SAndroid Build Coastguard Worker         minorVersion     = 0;
45*8975f5c5SAndroid Build Coastguard Worker         windowWidth      = 256;
46*8975f5c5SAndroid Build Coastguard Worker         windowHeight     = 256;
47*8975f5c5SAndroid Build Coastguard Worker         compileLinkOrder = order;
48*8975f5c5SAndroid Build Coastguard Worker     }
49*8975f5c5SAndroid Build Coastguard Worker 
story__anon97123a550111::ParallelLinkProgramParams50*8975f5c5SAndroid Build Coastguard Worker     std::string story() const override
51*8975f5c5SAndroid Build Coastguard Worker     {
52*8975f5c5SAndroid Build Coastguard Worker         std::stringstream strstr;
53*8975f5c5SAndroid Build Coastguard Worker         strstr << RenderTestParams::story();
54*8975f5c5SAndroid Build Coastguard Worker 
55*8975f5c5SAndroid Build Coastguard Worker         if (compileLinkOrder == CompileLinkOrder::AllCompilesFirst)
56*8975f5c5SAndroid Build Coastguard Worker         {
57*8975f5c5SAndroid Build Coastguard Worker             strstr << "_all_compiles_first";
58*8975f5c5SAndroid Build Coastguard Worker         }
59*8975f5c5SAndroid Build Coastguard Worker         else if (compileLinkOrder == CompileLinkOrder::Interleaved)
60*8975f5c5SAndroid Build Coastguard Worker         {
61*8975f5c5SAndroid Build Coastguard Worker             strstr << "_interleaved_compile_and_link";
62*8975f5c5SAndroid Build Coastguard Worker         }
63*8975f5c5SAndroid Build Coastguard Worker         else if (compileLinkOrder == CompileLinkOrder::InterleavedAndImmediateQuery)
64*8975f5c5SAndroid Build Coastguard Worker         {
65*8975f5c5SAndroid Build Coastguard Worker             strstr << "_interleaved_compile_and_link_with_immediate_query";
66*8975f5c5SAndroid Build Coastguard Worker         }
67*8975f5c5SAndroid Build Coastguard Worker 
68*8975f5c5SAndroid Build Coastguard Worker         if (std::find(eglParameters.disabledFeatureOverrides.begin(),
69*8975f5c5SAndroid Build Coastguard Worker                       eglParameters.disabledFeatureOverrides.end(),
70*8975f5c5SAndroid Build Coastguard Worker                       Feature::EnableParallelCompileAndLink) !=
71*8975f5c5SAndroid Build Coastguard Worker             eglParameters.disabledFeatureOverrides.end())
72*8975f5c5SAndroid Build Coastguard Worker         {
73*8975f5c5SAndroid Build Coastguard Worker             strstr << "_serial";
74*8975f5c5SAndroid Build Coastguard Worker         }
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker         if (eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
77*8975f5c5SAndroid Build Coastguard Worker         {
78*8975f5c5SAndroid Build Coastguard Worker             strstr << "_null";
79*8975f5c5SAndroid Build Coastguard Worker         }
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker         return strstr.str();
82*8975f5c5SAndroid Build Coastguard Worker     }
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker     CompileLinkOrder compileLinkOrder;
85*8975f5c5SAndroid Build Coastguard Worker };
86*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const ParallelLinkProgramParams & params)87*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const ParallelLinkProgramParams &params)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker     os << params.backendAndStory().substr(1);
90*8975f5c5SAndroid Build Coastguard Worker     return os;
91*8975f5c5SAndroid Build Coastguard Worker }
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker class ParallelLinkProgramBenchmark : public ANGLERenderTest,
94*8975f5c5SAndroid Build Coastguard Worker                                      public ::testing::WithParamInterface<ParallelLinkProgramParams>
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker   public:
97*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramBenchmark();
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker     void initializeBenchmark() override;
100*8975f5c5SAndroid Build Coastguard Worker     void destroyBenchmark() override;
101*8975f5c5SAndroid Build Coastguard Worker     void drawBenchmark() override;
102*8975f5c5SAndroid Build Coastguard Worker 
103*8975f5c5SAndroid Build Coastguard Worker   protected:
104*8975f5c5SAndroid Build Coastguard Worker     struct Program
105*8975f5c5SAndroid Build Coastguard Worker     {
106*8975f5c5SAndroid Build Coastguard Worker         std::string vertexShader;
107*8975f5c5SAndroid Build Coastguard Worker         std::string fragmentShader;
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         GLuint vs;
110*8975f5c5SAndroid Build Coastguard Worker         GLuint fs;
111*8975f5c5SAndroid Build Coastguard Worker         GLuint program;
112*8975f5c5SAndroid Build Coastguard Worker     };
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker     std::vector<Program> mPrograms;
115*8975f5c5SAndroid Build Coastguard Worker };
116*8975f5c5SAndroid Build Coastguard Worker 
ParallelLinkProgramBenchmark()117*8975f5c5SAndroid Build Coastguard Worker ParallelLinkProgramBenchmark::ParallelLinkProgramBenchmark()
118*8975f5c5SAndroid Build Coastguard Worker     : ANGLERenderTest("ParallelLinkProgram", GetParam())
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker     if (IsWindows() && IsNVIDIA() &&
121*8975f5c5SAndroid Build Coastguard Worker         GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
122*8975f5c5SAndroid Build Coastguard Worker     {
123*8975f5c5SAndroid Build Coastguard Worker         skipTest("http://anglebug.com/42266835 crashes the GL driver");
124*8975f5c5SAndroid Build Coastguard Worker     }
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker     if (IsLinux() && IsNVIDIA() &&
127*8975f5c5SAndroid Build Coastguard Worker         GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
128*8975f5c5SAndroid Build Coastguard Worker     {
129*8975f5c5SAndroid Build Coastguard Worker         skipTest("http://anglebug.com/42266835 flakily crashes the GL driver");
130*8975f5c5SAndroid Build Coastguard Worker     }
131*8975f5c5SAndroid Build Coastguard Worker }
132*8975f5c5SAndroid Build Coastguard Worker 
initializeBenchmark()133*8975f5c5SAndroid Build Coastguard Worker void ParallelLinkProgramBenchmark::initializeBenchmark()
134*8975f5c5SAndroid Build Coastguard Worker {
135*8975f5c5SAndroid Build Coastguard Worker     const ParallelLinkProgramParams &params = GetParam();
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker     // Generate N shaders and create the GL objects.  DrawBenchmark would then _only_ do compilation
138*8975f5c5SAndroid Build Coastguard Worker     // and link.
139*8975f5c5SAndroid Build Coastguard Worker     mPrograms.resize(params.iterationsPerStep);
140*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < params.iterationsPerStep; ++i)
141*8975f5c5SAndroid Build Coastguard Worker     {
142*8975f5c5SAndroid Build Coastguard Worker         std::ostringstream vs;
143*8975f5c5SAndroid Build Coastguard Worker         vs << R"(#version 300 es
144*8975f5c5SAndroid Build Coastguard Worker uniform UBO
145*8975f5c5SAndroid Build Coastguard Worker {
146*8975f5c5SAndroid Build Coastguard Worker     vec4 data[)"
147*8975f5c5SAndroid Build Coastguard Worker            << params.iterationsPerStep << R"(];
148*8975f5c5SAndroid Build Coastguard Worker };
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker uniform UBO2
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker     mat4 m[2];
153*8975f5c5SAndroid Build Coastguard Worker } ubo;
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker in mediump vec4 attr1;
156*8975f5c5SAndroid Build Coastguard Worker in mediump uvec4 attr2;
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker out highp vec3 var1;
159*8975f5c5SAndroid Build Coastguard Worker flat out lowp uvec2 var2;
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker void main()
162*8975f5c5SAndroid Build Coastguard Worker {
163*8975f5c5SAndroid Build Coastguard Worker     vec4 a = attr1 + vec4(attr2);)";
164*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < i * 5; ++j)
165*8975f5c5SAndroid Build Coastguard Worker         {
166*8975f5c5SAndroid Build Coastguard Worker             vs << R"(
167*8975f5c5SAndroid Build Coastguard Worker     a *= ubo.m[0];)";
168*8975f5c5SAndroid Build Coastguard Worker         }
169*8975f5c5SAndroid Build Coastguard Worker         vs << R"(
170*8975f5c5SAndroid Build Coastguard Worker     a += ubo.m[1][2];
171*8975f5c5SAndroid Build Coastguard Worker     var1 = cross(a.zxy, data[)"
172*8975f5c5SAndroid Build Coastguard Worker            << i << R"(].xxw);
173*8975f5c5SAndroid Build Coastguard Worker     var2 = uvec2(1, 3) * uvec2(6, 3);
174*8975f5c5SAndroid Build Coastguard Worker })";
175*8975f5c5SAndroid Build Coastguard Worker         mPrograms[i].vertexShader = vs.str();
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker         std::ostringstream fs;
178*8975f5c5SAndroid Build Coastguard Worker         fs << R"(#version 300 es
179*8975f5c5SAndroid Build Coastguard Worker uniform UBO
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker     highp vec4 data[)"
182*8975f5c5SAndroid Build Coastguard Worker            << params.iterationsPerStep << R"(];
183*8975f5c5SAndroid Build Coastguard Worker };
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker in highp vec3 var1;
186*8975f5c5SAndroid Build Coastguard Worker flat in lowp uvec2 var2;
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker uniform mediump sampler2D s;
189*8975f5c5SAndroid Build Coastguard Worker uniform mediump sampler2D s2;
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker layout(location = 0) out mediump vec4 color1;
192*8975f5c5SAndroid Build Coastguard Worker layout(location = 2) out highp uvec2 color2;
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker void main()
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker     color1 = var1.xyzx + texture(s, vec2(var2) / 9.);
197*8975f5c5SAndroid Build Coastguard Worker     mediump vec4 sum = vec4(0);
198*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 10; ++i)
199*8975f5c5SAndroid Build Coastguard Worker       sum += texture(s2, vec2(float(i / 2) / 5., float(i % 5) / 5.));
200*8975f5c5SAndroid Build Coastguard Worker     uvec2 res = uvec2(sum.xz + sum.yw);)";
201*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < i * 5; ++j)
202*8975f5c5SAndroid Build Coastguard Worker         {
203*8975f5c5SAndroid Build Coastguard Worker             fs << R"(
204*8975f5c5SAndroid Build Coastguard Worker     res += uvec2(data[)"
205*8975f5c5SAndroid Build Coastguard Worker                << (j % 100) << R"(]);)";
206*8975f5c5SAndroid Build Coastguard Worker         }
207*8975f5c5SAndroid Build Coastguard Worker         fs << R"(
208*8975f5c5SAndroid Build Coastguard Worker     color2 = res;
209*8975f5c5SAndroid Build Coastguard Worker })";
210*8975f5c5SAndroid Build Coastguard Worker         mPrograms[i].fragmentShader = fs.str();
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker         mPrograms[i].vs      = glCreateShader(GL_VERTEX_SHADER);
213*8975f5c5SAndroid Build Coastguard Worker         mPrograms[i].fs      = glCreateShader(GL_FRAGMENT_SHADER);
214*8975f5c5SAndroid Build Coastguard Worker         mPrograms[i].program = glCreateProgram();
215*8975f5c5SAndroid Build Coastguard Worker 
216*8975f5c5SAndroid Build Coastguard Worker         const char *vsCStr = mPrograms[i].vertexShader.c_str();
217*8975f5c5SAndroid Build Coastguard Worker         const char *fsCStr = mPrograms[i].fragmentShader.c_str();
218*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(mPrograms[i].vs, 1, &vsCStr, 0);
219*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(mPrograms[i].fs, 1, &fsCStr, 0);
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(mPrograms[i].program, mPrograms[i].vs);
222*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(mPrograms[i].program, mPrograms[i].fs);
223*8975f5c5SAndroid Build Coastguard Worker     }
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
226*8975f5c5SAndroid Build Coastguard Worker }
227*8975f5c5SAndroid Build Coastguard Worker 
destroyBenchmark()228*8975f5c5SAndroid Build Coastguard Worker void ParallelLinkProgramBenchmark::destroyBenchmark()
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker     const ParallelLinkProgramParams &params = GetParam();
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < params.iterationsPerStep; ++i)
233*8975f5c5SAndroid Build Coastguard Worker     {
234*8975f5c5SAndroid Build Coastguard Worker         glDetachShader(mPrograms[i].program, mPrograms[i].vs);
235*8975f5c5SAndroid Build Coastguard Worker         glDetachShader(mPrograms[i].program, mPrograms[i].fs);
236*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(mPrograms[i].vs);
237*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(mPrograms[i].fs);
238*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mPrograms[i].program);
239*8975f5c5SAndroid Build Coastguard Worker     }
240*8975f5c5SAndroid Build Coastguard Worker }
241*8975f5c5SAndroid Build Coastguard Worker 
drawBenchmark()242*8975f5c5SAndroid Build Coastguard Worker void ParallelLinkProgramBenchmark::drawBenchmark()
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker     const ParallelLinkProgramParams &params = GetParam();
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < params.iterationsPerStep; ++i)
247*8975f5c5SAndroid Build Coastguard Worker     {
248*8975f5c5SAndroid Build Coastguard Worker         // Compile the shaders, and if interleaved, link the corresponding programs.
249*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(mPrograms[i].vs);
250*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(mPrograms[i].fs);
251*8975f5c5SAndroid Build Coastguard Worker         if (params.compileLinkOrder != CompileLinkOrder::AllCompilesFirst)
252*8975f5c5SAndroid Build Coastguard Worker         {
253*8975f5c5SAndroid Build Coastguard Worker             glLinkProgram(mPrograms[i].program);
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker             if (params.compileLinkOrder == CompileLinkOrder::InterleavedAndImmediateQuery)
256*8975f5c5SAndroid Build Coastguard Worker             {
257*8975f5c5SAndroid Build Coastguard Worker                 GLint linkStatus = GL_TRUE;
258*8975f5c5SAndroid Build Coastguard Worker                 glGetProgramiv(mPrograms[i].program, GL_LINK_STATUS, &linkStatus);
259*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_TRUE(linkStatus) << i;
260*8975f5c5SAndroid Build Coastguard Worker             }
261*8975f5c5SAndroid Build Coastguard Worker         }
262*8975f5c5SAndroid Build Coastguard Worker     }
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker     // If asked to link after all shaders are compiled, link all the programs now
265*8975f5c5SAndroid Build Coastguard Worker     if (params.compileLinkOrder == CompileLinkOrder::AllCompilesFirst)
266*8975f5c5SAndroid Build Coastguard Worker     {
267*8975f5c5SAndroid Build Coastguard Worker         for (uint32_t i = 0; i < params.iterationsPerStep; ++i)
268*8975f5c5SAndroid Build Coastguard Worker         {
269*8975f5c5SAndroid Build Coastguard Worker             glLinkProgram(mPrograms[i].program);
270*8975f5c5SAndroid Build Coastguard Worker         }
271*8975f5c5SAndroid Build Coastguard Worker     }
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     // Now that all the compile and link jobs have been scheduled, wait for them all to finish.
274*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < params.iterationsPerStep; ++i)
275*8975f5c5SAndroid Build Coastguard Worker     {
276*8975f5c5SAndroid Build Coastguard Worker         GLint compileResult;
277*8975f5c5SAndroid Build Coastguard Worker         glGetShaderiv(mPrograms[i].vs, GL_COMPILE_STATUS, &compileResult);
278*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(compileResult, 0) << i;
279*8975f5c5SAndroid Build Coastguard Worker         glGetShaderiv(mPrograms[i].fs, GL_COMPILE_STATUS, &compileResult);
280*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(compileResult, 0) << i;
281*8975f5c5SAndroid Build Coastguard Worker 
282*8975f5c5SAndroid Build Coastguard Worker         GLint linkStatus = GL_TRUE;
283*8975f5c5SAndroid Build Coastguard Worker         glGetProgramiv(mPrograms[i].program, GL_LINK_STATUS, &linkStatus);
284*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(linkStatus) << i;
285*8975f5c5SAndroid Build Coastguard Worker     }
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker     // ANGLE supports running some optional link subtasks beyond the actual end of the link.  Ensure
288*8975f5c5SAndroid Build Coastguard Worker     // those are all finished by triggerring a wait on the jobs of the last program.  Currently,
289*8975f5c5SAndroid Build Coastguard Worker     // detaching and attaching shaders does that (among other operations).
290*8975f5c5SAndroid Build Coastguard Worker     const uint32_t last = params.iterationsPerStep - 1;
291*8975f5c5SAndroid Build Coastguard Worker     glDetachShader(mPrograms[last].program, mPrograms[last].vs);
292*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(mPrograms[last].program, mPrograms[last].vs);
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
295*8975f5c5SAndroid Build Coastguard Worker }
296*8975f5c5SAndroid Build Coastguard Worker 
297*8975f5c5SAndroid Build Coastguard Worker using namespace egl_platform;
298*8975f5c5SAndroid Build Coastguard Worker 
ParallelLinkProgramD3D11Params(CompileLinkOrder compileLinkOrder)299*8975f5c5SAndroid Build Coastguard Worker ParallelLinkProgramParams ParallelLinkProgramD3D11Params(CompileLinkOrder compileLinkOrder)
300*8975f5c5SAndroid Build Coastguard Worker {
301*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramParams params(compileLinkOrder);
302*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = D3D11();
303*8975f5c5SAndroid Build Coastguard Worker     return params;
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker 
ParallelLinkProgramMetalParams(CompileLinkOrder compileLinkOrder)306*8975f5c5SAndroid Build Coastguard Worker ParallelLinkProgramParams ParallelLinkProgramMetalParams(CompileLinkOrder compileLinkOrder)
307*8975f5c5SAndroid Build Coastguard Worker {
308*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramParams params(compileLinkOrder);
309*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = METAL();
310*8975f5c5SAndroid Build Coastguard Worker     return params;
311*8975f5c5SAndroid Build Coastguard Worker }
312*8975f5c5SAndroid Build Coastguard Worker 
ParallelLinkProgramOpenGLOrGLESParams(CompileLinkOrder compileLinkOrder)313*8975f5c5SAndroid Build Coastguard Worker ParallelLinkProgramParams ParallelLinkProgramOpenGLOrGLESParams(CompileLinkOrder compileLinkOrder)
314*8975f5c5SAndroid Build Coastguard Worker {
315*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramParams params(compileLinkOrder);
316*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = OPENGL_OR_GLES();
317*8975f5c5SAndroid Build Coastguard Worker     return params;
318*8975f5c5SAndroid Build Coastguard Worker }
319*8975f5c5SAndroid Build Coastguard Worker 
ParallelLinkProgramVulkanParams(CompileLinkOrder compileLinkOrder)320*8975f5c5SAndroid Build Coastguard Worker ParallelLinkProgramParams ParallelLinkProgramVulkanParams(CompileLinkOrder compileLinkOrder)
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramParams params(compileLinkOrder);
323*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = VULKAN();
324*8975f5c5SAndroid Build Coastguard Worker     params.enable(Feature::EnableParallelCompileAndLink);
325*8975f5c5SAndroid Build Coastguard Worker     return params;
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker 
SerialLinkProgramVulkanParams(CompileLinkOrder compileLinkOrder)328*8975f5c5SAndroid Build Coastguard Worker ParallelLinkProgramParams SerialLinkProgramVulkanParams(CompileLinkOrder compileLinkOrder)
329*8975f5c5SAndroid Build Coastguard Worker {
330*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramParams params(compileLinkOrder);
331*8975f5c5SAndroid Build Coastguard Worker     params.eglParameters = VULKAN();
332*8975f5c5SAndroid Build Coastguard Worker     params.disable(Feature::EnableParallelCompileAndLink);
333*8975f5c5SAndroid Build Coastguard Worker     return params;
334*8975f5c5SAndroid Build Coastguard Worker }
335*8975f5c5SAndroid Build Coastguard Worker 
336*8975f5c5SAndroid Build Coastguard Worker // Test parallel link performance
TEST_P(ParallelLinkProgramBenchmark,Run)337*8975f5c5SAndroid Build Coastguard Worker TEST_P(ParallelLinkProgramBenchmark, Run)
338*8975f5c5SAndroid Build Coastguard Worker {
339*8975f5c5SAndroid Build Coastguard Worker     run();
340*8975f5c5SAndroid Build Coastguard Worker }
341*8975f5c5SAndroid Build Coastguard Worker 
342*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(
343*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramBenchmark,
344*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramD3D11Params(CompileLinkOrder::AllCompilesFirst),
345*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramD3D11Params(CompileLinkOrder::Interleaved),
346*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramMetalParams(CompileLinkOrder::AllCompilesFirst),
347*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramMetalParams(CompileLinkOrder::Interleaved),
348*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramOpenGLOrGLESParams(CompileLinkOrder::AllCompilesFirst),
349*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramOpenGLOrGLESParams(CompileLinkOrder::Interleaved),
350*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramVulkanParams(CompileLinkOrder::AllCompilesFirst),
351*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramVulkanParams(CompileLinkOrder::Interleaved),
352*8975f5c5SAndroid Build Coastguard Worker     ParallelLinkProgramVulkanParams(CompileLinkOrder::InterleavedAndImmediateQuery),
353*8975f5c5SAndroid Build Coastguard Worker     SerialLinkProgramVulkanParams(CompileLinkOrder::AllCompilesFirst),
354*8975f5c5SAndroid Build Coastguard Worker     SerialLinkProgramVulkanParams(CompileLinkOrder::Interleaved),
355*8975f5c5SAndroid Build Coastguard Worker     SerialLinkProgramVulkanParams(CompileLinkOrder::InterleavedAndImmediateQuery));
356*8975f5c5SAndroid Build Coastguard Worker 
357*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
358