xref: /aosp_15_r20/external/angle/src/tests/perf_tests/ImagelessFramebufferPerfTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // ImagelessFramebufferPerfTest:
7 //   Performance test for imageless framebuffers. It binds and draws many textures to the FBO both
8 //   using imageless framebuffers (if supported) and with imageless framebuffer disabled.
9 //
10 
11 #include "ANGLEPerfTest.h"
12 #include "test_utils/gl_raii.h"
13 
14 #include <iostream>
15 #include <random>
16 #include <sstream>
17 
18 namespace angle
19 {
20 constexpr unsigned int kIterationsPerStep = 1;
21 constexpr unsigned int kTextureSize       = 64;
22 constexpr std::size_t kTextureCount       = 100;
23 
24 struct ImagelessFramebufferAttachmentParams final : public RenderTestParams
25 {
ImagelessFramebufferAttachmentParamsangle::ImagelessFramebufferAttachmentParams26     ImagelessFramebufferAttachmentParams()
27     {
28         iterationsPerStep = kIterationsPerStep;
29 
30         // Common default params
31         majorVersion = 3;
32         minorVersion = 0;
33     }
34 
35     std::string story() const override;
36     bool isImagelessFramebufferEnabled = false;
37 };
38 
operator <<(std::ostream & os,const ImagelessFramebufferAttachmentParams & params)39 std::ostream &operator<<(std::ostream &os, const ImagelessFramebufferAttachmentParams &params)
40 {
41     os << params.backendAndStory().substr(1);
42     return os;
43 }
44 
story() const45 std::string ImagelessFramebufferAttachmentParams::story() const
46 {
47     std::stringstream strstr;
48 
49     strstr << RenderTestParams::story();
50     strstr << (!isImagelessFramebufferEnabled ? "_imageless_framebuffer_disabled" : "_default");
51 
52     return strstr.str();
53 }
54 
55 class ImagelessFramebufferAttachmentBenchmark
56     : public ANGLERenderTest,
57       public ::testing::WithParamInterface<ImagelessFramebufferAttachmentParams>
58 {
59   public:
ImagelessFramebufferAttachmentBenchmark()60     ImagelessFramebufferAttachmentBenchmark() : ANGLERenderTest("ImagelessFramebuffers", GetParam())
61     {}
62     void initializeBenchmark() override;
63     void drawBenchmark() override;
64 
65   protected:
66     std::array<GLTexture, kTextureCount> mTextures;
67     GLuint mProgram = 0;
68 };
69 
initializeBenchmark()70 void ImagelessFramebufferAttachmentBenchmark::initializeBenchmark()
71 {
72     constexpr char kVS[] = R"(void main()
73 {
74     gl_Position = vec4(0);
75 })";
76 
77     constexpr char kFS[] = R"(void main(void)
78 {
79     gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
80 })";
81 
82     mProgram = CompileProgram(kVS, kFS);
83     ASSERT_NE(0u, mProgram);
84     glUseProgram(mProgram);
85 
86     for (GLTexture &texture : mTextures)
87     {
88         glBindTexture(GL_TEXTURE_2D, texture);
89         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTextureSize, kTextureSize, 0, GL_RGBA,
91                      GL_UNSIGNED_BYTE, nullptr);
92     }
93 }
94 
drawBenchmark()95 void ImagelessFramebufferAttachmentBenchmark::drawBenchmark()
96 {
97     const auto &params = GetParam();
98 
99     GLFramebuffer fbo;
100 
101     for (size_t it = 0; it < params.iterationsPerStep; ++it)
102     {
103         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
104         for (size_t i = 0; i < kTextureCount; ++i)
105         {
106             for (size_t j = 0; j < kTextureCount; ++j)
107             {
108                 if (j == i)
109                     continue;
110                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
111                                        mTextures[i], 0);
112                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
113                                        mTextures[j], 0);
114                 glDrawArrays(GL_POINTS, 0, 1);
115             }
116         }
117     }
118 
119     ASSERT_GL_NO_ERROR();
120 }
121 
ImagelessVulkanEnabledParams()122 ImagelessFramebufferAttachmentParams ImagelessVulkanEnabledParams()
123 {
124     ImagelessFramebufferAttachmentParams params;
125     params.eglParameters = egl_platform::VULKAN().disable(Feature::PreferSubmitAtFBOBoundary);
126     params.isImagelessFramebufferEnabled = true;
127 
128     return params;
129 }
130 
ImagelessVulkanDisabledParams()131 ImagelessFramebufferAttachmentParams ImagelessVulkanDisabledParams()
132 {
133     ImagelessFramebufferAttachmentParams params;
134     params.eglParameters = egl_platform::VULKAN()
135                                .disable(Feature::PreferSubmitAtFBOBoundary)
136                                .disable(Feature::SupportsImagelessFramebuffer);
137     params.isImagelessFramebufferEnabled = false;
138 
139     return params;
140 }
141 
142 // Runs tests to measure imageless framebuffer performance
TEST_P(ImagelessFramebufferAttachmentBenchmark,Run)143 TEST_P(ImagelessFramebufferAttachmentBenchmark, Run)
144 {
145     run();
146 }
147 
148 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImagelessFramebufferAttachmentBenchmark);
149 ANGLE_INSTANTIATE_TEST(ImagelessFramebufferAttachmentBenchmark,
150                        ImagelessVulkanEnabledParams(),
151                        ImagelessVulkanDisabledParams());
152 
153 }  // namespace angle
154