1 //
2 // Copyright 2017 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 // MultiviewPerfTest:
7 // Performance tests for multiview rendering.
8 // - MultiviewCPUBoundBenchmark issues many draw calls and state changes to stress the CPU.
9 // - MultiviewGPUBoundBenchmark draws half a million quads with multiple attributes per vertex in
10 // order to stress the GPU's memory system.
11 //
12
13 #include "ANGLEPerfTest.h"
14 #include "common/vector_utils.h"
15 #include "platform/FeaturesD3D.h"
16 #include "test_utils/MultiviewTest.h"
17 #include "test_utils/gl_raii.h"
18 #include "util/shader_utils.h"
19
20 #include <string.h>
21
22 using namespace angle;
23
24 namespace
25 {
26
GetShaderExtensionHeader(bool usesMultiview,int numViews,GLenum shaderType,ExtensionName multiviewExtension)27 std::string GetShaderExtensionHeader(bool usesMultiview,
28 int numViews,
29 GLenum shaderType,
30 ExtensionName multiviewExtension)
31 {
32 if (!usesMultiview)
33 {
34 return "";
35 }
36
37 std::string ext;
38 switch (multiviewExtension)
39 {
40 case multiview:
41 ext = "GL_OVR_multiview";
42 break;
43 case multiview2:
44 ext = "GL_OVR_multiview2";
45 break;
46 default:
47 ext = "extension_error";
48 }
49
50 if (shaderType == GL_VERTEX_SHADER)
51 {
52 return "#extension " + ext + " : require\nlayout(num_views = " + ToString(numViews) +
53 ") in;\n";
54 }
55 return "#extension " + ext + " : require\n";
56 }
57
58 struct Vertex
59 {
60 Vector4 position;
61 Vector4 colorAttributeData[6];
62 };
63
64 enum class MultiviewOption
65 {
66 NoAcceleration,
67 InstancedMultiviewVertexShader,
68 InstancedMultiviewGeometryShader,
69
70 Unspecified
71 };
72
73 using MultiviewPerfWorkload = std::pair<int, int>;
74
75 struct MultiviewPerfParams final : public RenderTestParams
76 {
MultiviewPerfParams__anon66c5d5b20111::MultiviewPerfParams77 MultiviewPerfParams(const EGLPlatformParameters &platformParametersIn,
78 const MultiviewPerfWorkload &workloadIn,
79 MultiviewOption multiviewOptionIn,
80 ExtensionName multiviewExtensionIn)
81 {
82 iterationsPerStep = 1;
83 majorVersion = 3;
84 minorVersion = 0;
85 eglParameters = platformParametersIn;
86 windowWidth = workloadIn.first;
87 windowHeight = workloadIn.second;
88 multiviewOption = multiviewOptionIn;
89 numViews = 2;
90 multiviewExtension = multiviewExtensionIn;
91 }
92
story__anon66c5d5b20111::MultiviewPerfParams93 std::string story() const override
94 {
95 std::string name = RenderTestParams::story();
96 switch (multiviewOption)
97 {
98 case MultiviewOption::NoAcceleration:
99 name += "_no_acc";
100 break;
101 case MultiviewOption::InstancedMultiviewVertexShader:
102 name += "_instanced_multiview_vertex_shader";
103 break;
104 case MultiviewOption::InstancedMultiviewGeometryShader:
105 name += "_instanced_multiview_geometry_shader";
106 break;
107 default:
108 name += "_error";
109 break;
110 }
111 std::string ext;
112 switch (multiviewExtension)
113 {
114 case multiview:
115 ext = "GL_OVR_multiview";
116 break;
117 case multiview2:
118 ext = "GL_OVR_multiview2";
119 break;
120 default:
121 ext = "extension_error";
122 break;
123 }
124 name += "_" + ext;
125 name += "_" + ToString(numViews) + "_views";
126 return name;
127 }
128
129 MultiviewOption multiviewOption;
130 int numViews;
131 angle::ExtensionName multiviewExtension;
132 };
133
operator <<(std::ostream & os,const MultiviewPerfParams & params)134 std::ostream &operator<<(std::ostream &os, const MultiviewPerfParams ¶ms)
135 {
136 os << params.backendAndStory().substr(1);
137 return os;
138 }
139
140 class MultiviewBenchmark : public ANGLERenderTest,
141 public ::testing::WithParamInterface<MultiviewPerfParams>
142 {
143 public:
MultiviewBenchmark(const std::string & testName)144 MultiviewBenchmark(const std::string &testName)
145 : ANGLERenderTest(testName, GetParam()), mProgram(0)
146 {
147 switch (GetParam().multiviewExtension)
148 {
149 case multiview:
150 addExtensionPrerequisite("GL_OVR_multiview");
151 break;
152 case multiview2:
153 addExtensionPrerequisite("GL_OVR_multiview2");
154 break;
155 default:
156 // Unknown extension.
157 break;
158 }
159 }
160
~MultiviewBenchmark()161 virtual ~MultiviewBenchmark()
162 {
163 if (mProgram != 0)
164 {
165 glDeleteProgram(mProgram);
166 }
167 }
168
169 void initializeBenchmark() override;
170 void drawBenchmark() final;
171
overrideWorkaroundsD3D(FeaturesD3D * features)172 void overrideWorkaroundsD3D(FeaturesD3D *features) override
173 {
174 features->overrideFeatures(
175 {"select_view_in_geometry_shader"},
176 GetParam().multiviewOption == MultiviewOption::InstancedMultiviewGeometryShader);
177 }
178
179 protected:
180 virtual void renderScene() = 0;
181
createProgram(const char * vs,const char * fs)182 void createProgram(const char *vs, const char *fs)
183 {
184 mProgram = CompileProgram(vs, fs);
185 if (mProgram == 0)
186 {
187 FAIL() << "shader compilation failed.";
188 }
189 glUseProgram(mProgram);
190 ASSERT_GL_NO_ERROR();
191 }
192
193 GLuint mProgram;
194 GLVertexArray mVAO;
195 GLBuffer mVBO;
196
197 private:
198 GLFramebuffer mFramebuffer;
199 GLTexture mColorTexture;
200 GLTexture mDepthTexture;
201 };
202
203 class MultiviewCPUBoundBenchmark : public MultiviewBenchmark
204 {
205 public:
MultiviewCPUBoundBenchmark()206 MultiviewCPUBoundBenchmark() : MultiviewBenchmark("MultiviewCPUBoundBenchmark") {}
207
208 void initializeBenchmark() override;
209
210 protected:
211 void renderScene() override;
212 };
213
214 class MultiviewGPUBoundBenchmark : public MultiviewBenchmark
215 {
216 public:
MultiviewGPUBoundBenchmark()217 MultiviewGPUBoundBenchmark() : MultiviewBenchmark("MultiviewGPUBoundBenchmark") {}
218
219 void initializeBenchmark() override;
220
221 protected:
222 void renderScene() override;
223 };
224
initializeBenchmark()225 void MultiviewBenchmark::initializeBenchmark()
226 {
227 const MultiviewPerfParams *params = static_cast<const MultiviewPerfParams *>(&mTestParams);
228
229 switch (params->multiviewOption)
230 {
231 case MultiviewOption::NoAcceleration:
232 // No acceleration texture arrays
233 glBindTexture(GL_TEXTURE_2D, mColorTexture);
234 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, params->windowWidth, params->windowHeight, 0,
235 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
236
237 glBindTexture(GL_TEXTURE_2D, mDepthTexture);
238 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, params->windowWidth,
239 params->windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
240
241 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
242 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
243 mColorTexture, 0);
244 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
245 mDepthTexture, 0);
246 break;
247 case MultiviewOption::InstancedMultiviewVertexShader:
248 case MultiviewOption::InstancedMultiviewGeometryShader:
249 {
250 // Multiview texture arrays
251 glBindTexture(GL_TEXTURE_2D_ARRAY, mColorTexture);
252 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, params->windowWidth,
253 params->windowHeight, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
254
255 glBindTexture(GL_TEXTURE_2D_ARRAY, mDepthTexture);
256 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, params->windowWidth,
257 params->windowHeight, 2, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
258
259 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
260 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0,
261 0, params->numViews);
262 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTexture, 0,
263 0, params->numViews);
264 break;
265 }
266 case MultiviewOption::Unspecified:
267 // implementation error.
268 break;
269 }
270
271 GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
272 glDrawBuffers(1, DrawBuffers);
273
274 ASSERT_GL_NO_ERROR();
275 }
276
drawBenchmark()277 void MultiviewBenchmark::drawBenchmark()
278 {
279 const MultiviewPerfParams *params = static_cast<const MultiviewPerfParams *>(&mTestParams);
280 const int viewWidth = params->windowWidth / params->numViews;
281 const int viewHeight = params->windowHeight;
282
283 switch (params->multiviewOption)
284 {
285 case MultiviewOption::NoAcceleration:
286 glEnable(GL_SCISSOR_TEST);
287 // Iterate over each view and render the scene.
288 for (int i = 0; i < params->numViews; ++i)
289 {
290 glViewport(viewWidth * i, 0, viewWidth, viewHeight);
291 glScissor(viewWidth * i, 0, viewWidth, viewHeight);
292 renderScene();
293 }
294 break;
295 case MultiviewOption::InstancedMultiviewVertexShader:
296 case MultiviewOption::InstancedMultiviewGeometryShader:
297 glViewport(0, 0, viewWidth, viewHeight);
298 glScissor(0, 0, viewWidth, viewHeight);
299 renderScene();
300 break;
301 case MultiviewOption::Unspecified:
302 // implementation error.
303 break;
304 }
305
306 ASSERT_GL_NO_ERROR();
307 }
308
initializeBenchmark()309 void MultiviewCPUBoundBenchmark::initializeBenchmark()
310 {
311 MultiviewBenchmark::initializeBenchmark();
312
313 const MultiviewPerfParams *params = static_cast<const MultiviewPerfParams *>(&mTestParams);
314 const bool usesMultiview = (params->multiviewOption != MultiviewOption::NoAcceleration);
315
316 const std::string vs = "#version 300 es\n" +
317 GetShaderExtensionHeader(usesMultiview, params->numViews,
318 GL_VERTEX_SHADER, params->multiviewExtension) +
319 "layout(location=0) in vec4 vPosition;\n"
320 "uniform vec2 uOffset;\n"
321 "void main()\n"
322 "{\n"
323 " vec4 v = vPosition;\n"
324 " v.xy += uOffset;\n"
325 " gl_Position = v;\n"
326 "}\n";
327
328 const std::string fs =
329 "#version 300 es\n" +
330 GetShaderExtensionHeader(usesMultiview, params->numViews, GL_FRAGMENT_SHADER,
331 params->multiviewExtension) +
332 "precision mediump float;\n"
333 "out vec4 col;\n"
334 "uniform float uColor;\n"
335 "void main()\n"
336 "{\n"
337 " col = vec4(1.);\n"
338 "}\n";
339
340 createProgram(vs.c_str(), fs.c_str());
341
342 const float viewWidth = static_cast<float>(params->windowWidth / params->numViews);
343 const float viewHeight = static_cast<float>(params->windowHeight);
344 const float quadWidth = 2.f / viewWidth;
345 const float quadHeight = 2.f / viewHeight;
346 Vector4 vertices[6] = {Vector4(.0f, .0f, .0f, 1.f),
347 Vector4(quadWidth, .0f, .0f, 1.f),
348 Vector4(quadWidth, quadHeight, 0.f, 1.f),
349 Vector4(.0f, .0f, 0.f, 1.f),
350 Vector4(quadWidth, quadHeight, .0f, 1.f),
351 Vector4(.0f, quadHeight, .0f, 1.f)};
352
353 glBindVertexArray(mVAO);
354
355 glBindBuffer(GL_ARRAY_BUFFER, mVBO);
356 glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(Vector4), vertices, GL_STATIC_DRAW);
357
358 const GLint posLoc = glGetAttribLocation(mProgram, "vPosition");
359 glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
360 glEnableVertexAttribArray(posLoc);
361
362 // Render once to guarantee that the program is compiled and linked.
363 drawBenchmark();
364
365 ASSERT_GL_NO_ERROR();
366 }
367
renderScene()368 void MultiviewCPUBoundBenchmark::renderScene()
369 {
370 glClearColor(0, 0, 0, 0);
371 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
372 glUseProgram(mProgram);
373
374 glBindVertexArray(mVAO);
375
376 const MultiviewPerfParams *params = static_cast<const MultiviewPerfParams *>(&mTestParams);
377 const int viewWidth = params->windowWidth / params->numViews;
378 const int viewHeight = params->windowHeight;
379
380 for (int w = 0; w < viewWidth; ++w)
381 {
382 for (int h = 0; h < viewHeight; ++h)
383 {
384 const float wf = static_cast<float>(w) / viewWidth;
385 const float wh = static_cast<float>(h) / viewHeight;
386 glUniform2f(glGetUniformLocation(mProgram, "uOffset"), 2.f * wf - 1.f, 2.f * wh - 1.f);
387 glUniform1f(glGetUniformLocation(mProgram, "uColor"), wf);
388 glDrawArrays(GL_TRIANGLES, 0, 6);
389 }
390 }
391 }
392
initializeBenchmark()393 void MultiviewGPUBoundBenchmark::initializeBenchmark()
394 {
395 MultiviewBenchmark::initializeBenchmark();
396
397 const MultiviewPerfParams *params = static_cast<const MultiviewPerfParams *>(&mTestParams);
398 const bool usesMultiview = (params->multiviewOption != MultiviewOption::NoAcceleration);
399
400 const std::string &vs = "#version 300 es\n" +
401 GetShaderExtensionHeader(usesMultiview, params->numViews,
402 GL_VERTEX_SHADER, params->multiviewExtension) +
403 "layout(location=0) in vec4 vPosition;\n"
404 "layout(location=1) in vec4 vert_Col0;\n"
405 "layout(location=2) in vec4 vert_Col1;\n"
406 "layout(location=3) in vec4 vert_Col2;\n"
407 "layout(location=4) in vec4 vert_Col3;\n"
408 "layout(location=5) in vec4 vert_Col4;\n"
409 "layout(location=6) in vec4 vert_Col5;\n"
410 "out vec4 frag_Col0;\n"
411 "out vec4 frag_Col1;\n"
412 "out vec4 frag_Col2;\n"
413 "out vec4 frag_Col3;\n"
414 "out vec4 frag_Col4;\n"
415 "out vec4 frag_Col5;\n"
416 "void main()\n"
417 "{\n"
418 " frag_Col0 = vert_Col0;\n"
419 " frag_Col1 = vert_Col1;\n"
420 " frag_Col2 = vert_Col2;\n"
421 " frag_Col3 = vert_Col3;\n"
422 " frag_Col4 = vert_Col4;\n"
423 " frag_Col5 = vert_Col5;\n"
424 " gl_Position = vPosition;\n"
425 "}\n";
426
427 const std::string &fs =
428 "#version 300 es\n" +
429 GetShaderExtensionHeader(usesMultiview, params->numViews, GL_FRAGMENT_SHADER,
430 params->multiviewExtension) +
431 "precision mediump float;\n"
432 "in vec4 frag_Col0;\n"
433 "in vec4 frag_Col1;\n"
434 "in vec4 frag_Col2;\n"
435 "in vec4 frag_Col3;\n"
436 "in vec4 frag_Col4;\n"
437 "in vec4 frag_Col5;\n"
438 "out vec4 col;\n"
439 "void main()\n"
440 "{\n"
441 " col += frag_Col0;\n"
442 " col += frag_Col1;\n"
443 " col += frag_Col2;\n"
444 " col += frag_Col3;\n"
445 " col += frag_Col4;\n"
446 " col += frag_Col5;\n"
447 "}\n";
448
449 createProgram(vs.c_str(), fs.c_str());
450 ASSERT_GL_NO_ERROR();
451
452 // Generate a vertex buffer of triangulated quads so that we have one quad per pixel.
453 const int viewWidth = params->windowWidth / params->numViews;
454 const int viewHeight = params->windowHeight;
455 const float quadWidth = 2.f / static_cast<float>(viewWidth);
456 const float quadHeight = 2.f / static_cast<float>(viewHeight);
457 const int kNumQuads = viewWidth * viewHeight;
458 const int kNumVerticesPerQuad = 6;
459 std::vector<Vertex> vertexData(kNumQuads * kNumVerticesPerQuad);
460 for (int h = 0; h < viewHeight; ++h)
461 {
462 for (int w = 0; w < viewWidth; ++w)
463 {
464 float wf = static_cast<float>(w) / viewWidth;
465 float hf = static_cast<float>(h) / viewHeight;
466
467 size_t index = static_cast<size_t>(h * viewWidth + w) * 6u;
468
469 auto &v0 = vertexData[index];
470 v0.position = Vector4(2.f * wf - 1.f, 2.f * hf - 1.f, .0f, 1.f);
471 memset(v0.colorAttributeData, 0, sizeof(v0.colorAttributeData));
472
473 auto &v1 = vertexData[index + 1];
474 v1.position = Vector4(v0.position.x() + quadWidth, v0.position.y(), .0f, 1.f);
475 memset(v1.colorAttributeData, 0, sizeof(v1.colorAttributeData));
476
477 auto &v2 = vertexData[index + 2];
478 v2.position = Vector4(v1.position.x(), v1.position.y() + quadHeight, .0f, 1.f);
479 memset(v2.colorAttributeData, 0, sizeof(v2.colorAttributeData));
480
481 auto &v3 = vertexData[index + 3];
482 v3.position = v0.position;
483 memset(v3.colorAttributeData, 0, sizeof(v3.colorAttributeData));
484
485 auto &v4 = vertexData[index + 4];
486 v4.position = v2.position;
487 memset(v4.colorAttributeData, 0, sizeof(v4.colorAttributeData));
488
489 auto &v5 = vertexData[index + 5];
490 v5.position = Vector4(v0.position.x(), v0.position.y() + quadHeight, .0f, 1.f);
491 memset(v5.colorAttributeData, 0, sizeof(v5.colorAttributeData));
492 }
493 }
494
495 glBindVertexArray(mVAO);
496
497 glBindBuffer(GL_ARRAY_BUFFER, mVBO);
498 glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(Vertex), vertexData.data(),
499 GL_STATIC_DRAW);
500
501 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
502 glEnableVertexAttribArray(0);
503
504 for (unsigned int i = 0u; i < 6u; ++i)
505 {
506 size_t offset = sizeof(Vector4) * (i + 1u);
507 glVertexAttribPointer(i + 1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),
508 reinterpret_cast<const void *>(offset));
509 glEnableVertexAttribArray(i + 1);
510 }
511
512 // Render once to guarantee that the program is compiled and linked.
513 drawBenchmark();
514 }
515
renderScene()516 void MultiviewGPUBoundBenchmark::renderScene()
517 {
518 glClearColor(0, 0, 0, 0);
519 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
520 glUseProgram(mProgram);
521
522 glBindVertexArray(mVAO);
523
524 const MultiviewPerfParams *params = static_cast<const MultiviewPerfParams *>(&mTestParams);
525 const int viewWidth = params->windowWidth / params->numViews;
526 const int viewHeight = params->windowHeight;
527 glDrawArrays(GL_TRIANGLES, 0, viewWidth * viewHeight * 6);
528 }
529
530 namespace
531 {
SmallWorkload()532 MultiviewPerfWorkload SmallWorkload()
533 {
534 return MultiviewPerfWorkload(64, 64);
535 }
536
BigWorkload()537 MultiviewPerfWorkload BigWorkload()
538 {
539 return MultiviewPerfWorkload(1024, 768);
540 }
541
NoAcceleration(const EGLPlatformParameters & eglParameters,const MultiviewPerfWorkload & workload,ExtensionName multiviewExtensionIn)542 MultiviewPerfParams NoAcceleration(const EGLPlatformParameters &eglParameters,
543 const MultiviewPerfWorkload &workload,
544 ExtensionName multiviewExtensionIn)
545 {
546 return MultiviewPerfParams(eglParameters, workload, MultiviewOption::NoAcceleration,
547 multiviewExtensionIn);
548 }
549
SelectViewInGeometryShader(const MultiviewPerfWorkload & workload,ExtensionName multiviewExtensionIn)550 MultiviewPerfParams SelectViewInGeometryShader(const MultiviewPerfWorkload &workload,
551 ExtensionName multiviewExtensionIn)
552 {
553 return MultiviewPerfParams(egl_platform::D3D11(), workload,
554 MultiviewOption::InstancedMultiviewGeometryShader,
555 multiviewExtensionIn);
556 }
557
SelectViewInVertexShader(const EGLPlatformParameters & eglParameters,const MultiviewPerfWorkload & workload,ExtensionName multiviewExtensionIn)558 MultiviewPerfParams SelectViewInVertexShader(const EGLPlatformParameters &eglParameters,
559 const MultiviewPerfWorkload &workload,
560 ExtensionName multiviewExtensionIn)
561 {
562 return MultiviewPerfParams(eglParameters, workload,
563 MultiviewOption::InstancedMultiviewVertexShader,
564 multiviewExtensionIn);
565 }
566 } // namespace
567
TEST_P(MultiviewCPUBoundBenchmark,Run)568 TEST_P(MultiviewCPUBoundBenchmark, Run)
569 {
570 run();
571 }
572
573 ANGLE_INSTANTIATE_TEST(
574 MultiviewCPUBoundBenchmark,
575 NoAcceleration(egl_platform::OPENGL_OR_GLES(), SmallWorkload(), ExtensionName::multiview),
576 NoAcceleration(egl_platform::D3D11(), SmallWorkload(), ExtensionName::multiview),
577 SelectViewInGeometryShader(SmallWorkload(), ExtensionName::multiview),
578 SelectViewInVertexShader(egl_platform::OPENGL_OR_GLES(),
579 SmallWorkload(),
580 ExtensionName::multiview),
581 SelectViewInVertexShader(egl_platform::D3D11(), SmallWorkload(), ExtensionName::multiview),
582 NoAcceleration(egl_platform::OPENGL_OR_GLES(), SmallWorkload(), ExtensionName::multiview2),
583 NoAcceleration(egl_platform::D3D11(), SmallWorkload(), ExtensionName::multiview2),
584 SelectViewInGeometryShader(SmallWorkload(), ExtensionName::multiview2),
585 SelectViewInVertexShader(egl_platform::OPENGL_OR_GLES(),
586 SmallWorkload(),
587 ExtensionName::multiview2),
588 SelectViewInVertexShader(egl_platform::D3D11(), SmallWorkload(), ExtensionName::multiview2));
589
TEST_P(MultiviewGPUBoundBenchmark,Run)590 TEST_P(MultiviewGPUBoundBenchmark, Run)
591 {
592 run();
593 }
594
595 ANGLE_INSTANTIATE_TEST(
596 MultiviewGPUBoundBenchmark,
597 NoAcceleration(egl_platform::OPENGL_OR_GLES(), BigWorkload(), ExtensionName::multiview),
598 NoAcceleration(egl_platform::D3D11(), BigWorkload(), ExtensionName::multiview),
599 SelectViewInGeometryShader(BigWorkload(), ExtensionName::multiview),
600 SelectViewInVertexShader(egl_platform::OPENGL_OR_GLES(),
601 BigWorkload(),
602 ExtensionName::multiview),
603 SelectViewInVertexShader(egl_platform::D3D11(), BigWorkload(), ExtensionName::multiview),
604 NoAcceleration(egl_platform::OPENGL_OR_GLES(), BigWorkload(), ExtensionName::multiview2),
605 NoAcceleration(egl_platform::D3D11(), BigWorkload(), ExtensionName::multiview2),
606 SelectViewInGeometryShader(BigWorkload(), ExtensionName::multiview2),
607 SelectViewInVertexShader(egl_platform::OPENGL_OR_GLES(),
608 BigWorkload(),
609 ExtensionName::multiview2),
610 SelectViewInVertexShader(egl_platform::D3D11(), BigWorkload(), ExtensionName::multiview2));
611
612 } // anonymous namespace
613