1 //
2 // Copyright 2022 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 // MultisampledSwapchainResolveBenchmark:
7 // Performance test for resolving multisample swapchains in subpass
8 //
9
10 #include "ANGLEPerfTest.h"
11
12 #include <iostream>
13 #include <random>
14 #include <sstream>
15
16 #include "test_utils/gl_raii.h"
17 #include "util/shader_utils.h"
18
19 using namespace angle;
20
21 namespace
22 {
23 struct MultisampledSwapchainResolveParams final : public RenderTestParams
24 {
MultisampledSwapchainResolveParams__anonb79f57a40111::MultisampledSwapchainResolveParams25 MultisampledSwapchainResolveParams()
26 {
27 iterationsPerStep = 1;
28
29 windowWidth = 1920;
30 windowHeight = 1080;
31 multisample = true;
32 samples = 4;
33 }
34
35 std::string story() const override;
36 };
37
operator <<(std::ostream & os,const MultisampledSwapchainResolveParams & params)38 std::ostream &operator<<(std::ostream &os, const MultisampledSwapchainResolveParams ¶ms)
39 {
40 return os << params.backendAndStory().substr(1);
41 }
42
story() const43 std::string MultisampledSwapchainResolveParams::story() const
44 {
45 std::stringstream strstr;
46
47 strstr << RenderTestParams::story();
48
49 return strstr.str();
50 }
51
52 class MultisampledSwapchainResolveBenchmark
53 : public ANGLERenderTest,
54 public ::testing::WithParamInterface<MultisampledSwapchainResolveParams>
55 {
56 public:
57 MultisampledSwapchainResolveBenchmark();
58
59 void initializeBenchmark() override;
60 void destroyBenchmark() override;
61 void drawBenchmark() override;
62
63 protected:
64 void initShaders();
65
66 GLuint mProgram = 0;
67 };
68
MultisampledSwapchainResolveBenchmark()69 MultisampledSwapchainResolveBenchmark::MultisampledSwapchainResolveBenchmark()
70 : ANGLERenderTest("MultisampledSwapchainResolve", GetParam())
71 {}
72
initializeBenchmark()73 void MultisampledSwapchainResolveBenchmark::initializeBenchmark()
74 {
75 initShaders();
76 glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
77
78 ASSERT_GL_NO_ERROR();
79 }
80
initShaders()81 void MultisampledSwapchainResolveBenchmark::initShaders()
82 {
83 constexpr char kVS[] = R"(void main()
84 {
85 gl_Position = vec4(0);
86 })";
87
88 constexpr char kFS[] = R"(void main(void)
89 {
90 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
91 })";
92
93 mProgram = CompileProgram(kVS, kFS);
94 ASSERT_NE(0u, mProgram);
95
96 glUseProgram(mProgram);
97
98 ASSERT_GL_NO_ERROR();
99 }
100
destroyBenchmark()101 void MultisampledSwapchainResolveBenchmark::destroyBenchmark()
102 {
103 glDeleteProgram(mProgram);
104 }
105
drawBenchmark()106 void MultisampledSwapchainResolveBenchmark::drawBenchmark()
107 {
108 // Initially clear the color attachment to avoid having to load from the resolved image.
109 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
110 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
111
112 // Perform a draw just to have something in the render pass. With the position attributes
113 // not set, a constant default value is used, resulting in a very cheap draw.
114 glDrawArrays(GL_TRIANGLES, 0, 3);
115
116 ASSERT_GL_NO_ERROR();
117 }
118
VulkanParams()119 MultisampledSwapchainResolveParams VulkanParams()
120 {
121 MultisampledSwapchainResolveParams params;
122 params.eglParameters = egl_platform::VULKAN();
123 params.majorVersion = 3;
124 params.minorVersion = 0;
125 return params;
126 }
127
128 } // anonymous namespace
129
TEST_P(MultisampledSwapchainResolveBenchmark,Run)130 TEST_P(MultisampledSwapchainResolveBenchmark, Run)
131 {
132 run();
133 }
134
135 using namespace params;
136
137 ANGLE_INSTANTIATE_TEST(MultisampledSwapchainResolveBenchmark, VulkanParams());
138