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 ¶ms)
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 ¶ms = 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