xref: /aosp_15_r20/external/angle/src/tests/perf_tests/FramebufferAttachmentPerfTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 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 // FramebufferAttachPerfTest:
7 //   Performance test for attaching and detaching resources to a Framebuffer.
8 //
9 
10 #include "ANGLEPerfTest.h"
11 #include "test_utils/gl_raii.h"
12 
13 #include <iostream>
14 #include <random>
15 #include <sstream>
16 
17 namespace angle
18 {
19 constexpr unsigned int kIterationsPerStep = 256;
20 constexpr unsigned int kTextureSize       = 256;
21 constexpr std::size_t kTextureCount       = 4;
22 constexpr std::size_t kFboCount           = kTextureCount;
23 constexpr std::size_t kAdditionalFboCount = kFboCount * kFboCount;
24 
25 struct FramebufferAttachmentParams final : public RenderTestParams
26 {
FramebufferAttachmentParamsangle::FramebufferAttachmentParams27     FramebufferAttachmentParams()
28     {
29         iterationsPerStep = kIterationsPerStep;
30 
31         // Common default params
32         majorVersion = 3;
33         minorVersion = 0;
34         windowWidth  = kTextureSize;
35         windowHeight = kTextureSize;
36     }
37 
38     std::string story() const override;
39 };
40 
operator <<(std::ostream & os,const FramebufferAttachmentParams & params)41 std::ostream &operator<<(std::ostream &os, const FramebufferAttachmentParams &params)
42 {
43     os << params.backendAndStory().substr(1);
44     return os;
45 }
46 
story() const47 std::string FramebufferAttachmentParams::story() const
48 {
49     std::stringstream strstr;
50 
51     strstr << RenderTestParams::story();
52 
53     return strstr.str();
54 }
55 
56 class FramebufferAttachmentBenchmark
57     : public ANGLERenderTest,
58       public ::testing::WithParamInterface<FramebufferAttachmentParams>
59 {
60   public:
FramebufferAttachmentBenchmark()61     FramebufferAttachmentBenchmark() : ANGLERenderTest("Framebuffers", GetParam()) {}
62     void initializeBenchmark() override;
63     void drawBenchmark() override;
64 
65   protected:
66     void initTextures();
67 
68     std::array<GLTexture, kTextureCount> mTextures;
69     std::array<GLFramebuffer, kFboCount> mFbo;
70 };
71 
initializeBenchmark()72 void FramebufferAttachmentBenchmark::initializeBenchmark()
73 {
74     initTextures();
75 
76     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
77     glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
78 
79     ASSERT_GL_NO_ERROR();
80 
81     GLint maxAttachmentCount;
82     glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxAttachmentCount);
83     if (mTextures.size() > static_cast<size_t>(maxAttachmentCount))
84     {
85         skipTest("Texture count exceeds maximum attachment unit count");
86     }
87 }
88 
initTextures()89 void FramebufferAttachmentBenchmark::initTextures()
90 {
91     std::vector<GLubyte> textureData(kTextureSize * kTextureSize * 4);
92     for (auto &byte : textureData)
93     {
94         byte = rand() % 255u;
95     }
96 
97     for (GLTexture &texture : mTextures)
98     {
99         glBindTexture(GL_TEXTURE_2D, texture);
100         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
101                      GL_UNSIGNED_BYTE, textureData.data());
102         glBindTexture(GL_TEXTURE_2D, 0);
103     }
104 }
105 
drawBenchmark()106 void FramebufferAttachmentBenchmark::drawBenchmark()
107 {
108     const auto &params = GetParam();
109 
110     size_t fboCount     = mFbo.size();
111     size_t textureCount = mTextures.size();
112 
113     for (size_t it = 0; it < params.iterationsPerStep; ++it)
114     {
115         // Attach
116         for (size_t fboIndex = 0; fboIndex < fboCount; fboIndex++)
117         {
118             glBindFramebuffer(GL_FRAMEBUFFER, mFbo[fboIndex]);
119             for (size_t textureIndex = 0; textureIndex < textureCount; textureIndex++)
120             {
121                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + textureIndex,
122                                        GL_TEXTURE_2D, mTextures[textureIndex], 0);
123             }
124             glBindFramebuffer(GL_FRAMEBUFFER, 0);
125         }
126 
127         // Detach
128         for (size_t fboIndex = 0; fboIndex < fboCount; fboIndex++)
129         {
130             glBindFramebuffer(GL_FRAMEBUFFER, mFbo[fboIndex]);
131             for (size_t index = 0; index < textureCount; index++)
132             {
133                 size_t textureIndex = mTextures.size() - (index + 1);
134                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + textureIndex,
135                                        GL_TEXTURE_2D, 0, 0);
136             }
137             glBindFramebuffer(GL_FRAMEBUFFER, 0);
138         }
139     }
140 
141     ASSERT_GL_NO_ERROR();
142 }
143 
144 class FramebufferAttachmentStateUpdateBenchmark : public FramebufferAttachmentBenchmark
145 {
146   public:
FramebufferAttachmentStateUpdateBenchmark()147     FramebufferAttachmentStateUpdateBenchmark() : FramebufferAttachmentBenchmark() {}
148     void initializeBenchmark() override;
149     void destroyBenchmark() override;
150     void drawBenchmark() override;
151 
152   private:
153     std::array<GLFramebuffer, kAdditionalFboCount> mAdditionalFbo;
154 };
155 
initializeBenchmark()156 void FramebufferAttachmentStateUpdateBenchmark::initializeBenchmark()
157 {
158     FramebufferAttachmentBenchmark::initializeBenchmark();
159 
160     // Attach
161     for (size_t fboIndex = 0; fboIndex < mAdditionalFbo.size(); fboIndex++)
162     {
163         glBindFramebuffer(GL_FRAMEBUFFER, mAdditionalFbo[fboIndex]);
164         for (size_t textureIndex = 0; textureIndex < mTextures.size(); textureIndex++)
165         {
166             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + textureIndex,
167                                    GL_TEXTURE_2D, mTextures[textureIndex], 0);
168         }
169         glBindFramebuffer(GL_FRAMEBUFFER, 0);
170     }
171 }
172 
destroyBenchmark()173 void FramebufferAttachmentStateUpdateBenchmark::destroyBenchmark()
174 {
175     // Detach
176     for (size_t fboIndex = 0; fboIndex < mAdditionalFbo.size(); fboIndex++)
177     {
178         glBindFramebuffer(GL_FRAMEBUFFER, mAdditionalFbo[fboIndex]);
179         for (size_t index = 0; index < mTextures.size(); index++)
180         {
181             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, GL_TEXTURE_2D, 0,
182                                    0);
183         }
184         glBindFramebuffer(GL_FRAMEBUFFER, 0);
185     }
186 
187     FramebufferAttachmentBenchmark::destroyBenchmark();
188 }
189 
drawBenchmark()190 void FramebufferAttachmentStateUpdateBenchmark::drawBenchmark()
191 {
192     const auto &params = GetParam();
193 
194     size_t textureCount  = mTextures.size();
195     GLenum nearestFilter = GL_NEAREST;
196     GLenum linearFilter  = GL_LINEAR;
197     for (size_t it = 0; it < params.iterationsPerStep; ++it)
198     {
199         for (size_t textureIndex = 0; textureIndex < textureCount; textureIndex++)
200         {
201             glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
202             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
203                             (it % 2) ? linearFilter : nearestFilter);
204             glBindTexture(GL_TEXTURE_2D, 0);
205         }
206     }
207 
208     ASSERT_GL_NO_ERROR();
209 }
210 
VulkanParams()211 FramebufferAttachmentParams VulkanParams()
212 {
213     FramebufferAttachmentParams params;
214     params.eglParameters = egl_platform::VULKAN_NULL();
215 
216     return params;
217 }
218 
TEST_P(FramebufferAttachmentBenchmark,Run)219 TEST_P(FramebufferAttachmentBenchmark, Run)
220 {
221     run();
222 }
223 
TEST_P(FramebufferAttachmentStateUpdateBenchmark,Run)224 TEST_P(FramebufferAttachmentStateUpdateBenchmark, Run)
225 {
226     run();
227 }
228 
229 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferAttachmentBenchmark);
230 ANGLE_INSTANTIATE_TEST(FramebufferAttachmentBenchmark, VulkanParams());
231 
232 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferAttachmentStateUpdateBenchmark);
233 ANGLE_INSTANTIATE_TEST(FramebufferAttachmentStateUpdateBenchmark, VulkanParams());
234 }  // namespace angle
235