• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // BlitFramebufferPerf:
7 //   Performance tests for glBlitFramebuffer in ES3. Includes tests for
8 //   color, depth, and stencil blit, as well as the mutlisample versions.
9 //   The test works by clearing a framebuffer, then blitting it to a second.
10 
11 #include "ANGLEPerfTest.h"
12 
13 #include "util/gles_loader_autogen.h"
14 
15 namespace
16 {
17 constexpr unsigned int kIterationsPerStep = 5;
18 
19 enum class BufferType
20 {
21     COLOR,
22     DEPTH,
23     STENCIL,
24     DEPTH_STENCIL
25 };
26 
BufferTypeString(BufferType type)27 const char *BufferTypeString(BufferType type)
28 {
29     switch (type)
30     {
31         case BufferType::COLOR:
32             return "color";
33         case BufferType::DEPTH:
34             return "depth";
35         case BufferType::STENCIL:
36             return "stencil";
37         case BufferType::DEPTH_STENCIL:
38             return "depth_stencil";
39         default:
40             return "error";
41     }
42 }
43 
BufferTypeMask(BufferType type)44 GLbitfield BufferTypeMask(BufferType type)
45 {
46     switch (type)
47     {
48         case BufferType::COLOR:
49             return GL_COLOR_BUFFER_BIT;
50         case BufferType::DEPTH:
51             return GL_DEPTH_BUFFER_BIT;
52         case BufferType::STENCIL:
53             return GL_STENCIL_BUFFER_BIT;
54         case BufferType::DEPTH_STENCIL:
55             return (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
56         default:
57             return 0;
58     }
59 }
60 
BufferTypeFormat(BufferType type)61 GLenum BufferTypeFormat(BufferType type)
62 {
63     switch (type)
64     {
65         case BufferType::COLOR:
66             return GL_RGBA8;
67         case BufferType::DEPTH:
68             return GL_DEPTH_COMPONENT24;
69         case BufferType::STENCIL:
70             return GL_STENCIL_INDEX8;
71         case BufferType::DEPTH_STENCIL:
72             return GL_DEPTH24_STENCIL8;
73         default:
74             return GL_NONE;
75     }
76 }
77 
BufferTypeAttachment(BufferType type)78 GLenum BufferTypeAttachment(BufferType type)
79 {
80     switch (type)
81     {
82         case BufferType::COLOR:
83             return GL_COLOR_ATTACHMENT0;
84         case BufferType::DEPTH:
85             return GL_DEPTH_ATTACHMENT;
86         case BufferType::STENCIL:
87             return GL_STENCIL_ATTACHMENT;
88         case BufferType::DEPTH_STENCIL:
89             return GL_DEPTH_STENCIL_ATTACHMENT;
90         default:
91             return GL_NONE;
92     }
93 }
94 
95 struct BlitFramebufferParams final : public RenderTestParams
96 {
BlitFramebufferParams__anonc74dede70111::BlitFramebufferParams97     BlitFramebufferParams()
98     {
99         iterationsPerStep = kIterationsPerStep;
100         majorVersion      = 3;
101         minorVersion      = 0;
102         windowWidth       = 256;
103         windowHeight      = 256;
104     }
105 
story__anonc74dede70111::BlitFramebufferParams106     std::string story() const override
107     {
108         std::stringstream storyStr;
109         storyStr << RenderTestParams::story();
110         storyStr << "_" << BufferTypeString(type);
111         if (samples > 1)
112         {
113             storyStr << "_" << samples << "_samples";
114         }
115         return storyStr.str();
116     }
117 
118     BufferType type              = BufferType::COLOR;
119     unsigned int framebufferSize = 512;
120     unsigned int samples         = 0;
121 };
122 
operator <<(std::ostream & os,const BlitFramebufferParams & params)123 std::ostream &operator<<(std::ostream &os, const BlitFramebufferParams &params)
124 {
125     os << params.backendAndStory().substr(1);
126     return os;
127 }
128 
129 class BlitFramebufferPerf : public ANGLERenderTest,
130                             public ::testing::WithParamInterface<BlitFramebufferParams>
131 {
132   public:
BlitFramebufferPerf()133     BlitFramebufferPerf() : ANGLERenderTest("BlitFramebufferPerf", GetParam()) {}
134 
135     void initializeBenchmark() override;
136     void destroyBenchmark() override;
137     void drawBenchmark() override;
138 
139   private:
140     GLuint mReadFramebuffer  = 0;
141     GLuint mReadRenderbuffer = 0;
142     GLuint mDrawFramebuffer  = 0;
143     GLuint mDrawRenderbuffer = 0;
144 };
145 
initializeBenchmark()146 void BlitFramebufferPerf::initializeBenchmark()
147 {
148     const auto &param = GetParam();
149 
150     glGenFramebuffers(1, &mReadFramebuffer);
151     glGenFramebuffers(1, &mDrawFramebuffer);
152 
153     glBindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer);
154     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
155 
156     // Create source and destination Renderbuffers.
157     glGenRenderbuffers(1, &mReadRenderbuffer);
158     glGenRenderbuffers(1, &mDrawRenderbuffer);
159 
160     ASSERT_GL_NO_ERROR();
161 
162     GLenum format     = BufferTypeFormat(param.type);
163     GLuint size       = param.framebufferSize;
164     GLenum attachment = BufferTypeAttachment(param.type);
165 
166     glBindRenderbuffer(GL_RENDERBUFFER, mReadRenderbuffer);
167     glRenderbufferStorageMultisample(GL_RENDERBUFFER, param.samples, format, size, size);
168     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, attachment, GL_RENDERBUFFER, mReadRenderbuffer);
169     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
170 
171     glBindRenderbuffer(GL_RENDERBUFFER, mDrawRenderbuffer);
172     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, format, size, size);
173     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, attachment, GL_RENDERBUFFER, mDrawRenderbuffer);
174     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
175 
176     ASSERT_GL_NO_ERROR();
177 }
178 
destroyBenchmark()179 void BlitFramebufferPerf::destroyBenchmark()
180 {
181     glDeleteFramebuffers(1, &mReadFramebuffer);
182     glDeleteRenderbuffers(1, &mReadRenderbuffer);
183     glDeleteFramebuffers(1, &mDrawFramebuffer);
184     glDeleteRenderbuffers(1, &mDrawRenderbuffer);
185 }
186 
drawBenchmark()187 void BlitFramebufferPerf::drawBenchmark()
188 {
189     const auto &param = GetParam();
190     auto size         = param.framebufferSize;
191     auto mask         = BufferTypeMask(param.type);
192 
193     // We don't read from the draw buffer (ie rendering) to simplify the test, but we could.
194     // This might trigger a flush, or we could trigger a flush manually to ensure the blit happens.
195     // TODO(jmadill): Investigate performance on Vulkan, and placement of Clear call.
196 
197     switch (param.type)
198     {
199         case BufferType::COLOR:
200         {
201             GLfloat clearValues[4] = {1.0f, 0.0f, 0.0f, 1.0f};
202             glClearBufferfv(GL_COLOR, 0, clearValues);
203             break;
204         }
205         case BufferType::DEPTH:
206         {
207             GLfloat clearDepthValue = 0.5f;
208             glClearBufferfv(GL_DEPTH, 0, &clearDepthValue);
209             break;
210         }
211         case BufferType::STENCIL:
212         {
213             GLint clearStencilValue = 1;
214             glClearBufferiv(GL_STENCIL, 0, &clearStencilValue);
215             break;
216         }
217         case BufferType::DEPTH_STENCIL:
218             glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 1);
219             break;
220     }
221 
222     for (unsigned int iteration = 0; iteration < param.iterationsPerStep; ++iteration)
223     {
224         glBlitFramebuffer(0, 0, size, size, 0, 0, size, size, mask, GL_NEAREST);
225     }
226 }
227 
TEST_P(BlitFramebufferPerf,Run)228 TEST_P(BlitFramebufferPerf, Run)
229 {
230     run();
231 }
232 
D3D11(BufferType type,unsigned int samples)233 BlitFramebufferParams D3D11(BufferType type, unsigned int samples)
234 {
235     BlitFramebufferParams params;
236     params.eglParameters = angle::egl_platform::D3D11();
237     params.type          = type;
238     params.samples       = samples;
239     return params;
240 }
241 }  // anonymous namespace
242 
243 // TODO(jmadill): Programatically generate these combinations.
244 ANGLE_INSTANTIATE_TEST(BlitFramebufferPerf,
245                        D3D11(BufferType::COLOR, 0),
246                        D3D11(BufferType::DEPTH, 0),
247                        D3D11(BufferType::STENCIL, 0),
248                        D3D11(BufferType::DEPTH_STENCIL, 0),
249                        D3D11(BufferType::COLOR, 2),
250                        D3D11(BufferType::DEPTH, 2),
251                        D3D11(BufferType::STENCIL, 2),
252                        D3D11(BufferType::DEPTH_STENCIL, 2));
253