| // |
| // Copyright 2022 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // ImagelessFramebufferPerfTest: |
| // Performance test for imageless framebuffers. It binds and draws many textures to the FBO both |
| // using imageless framebuffers (if supported) and with imageless framebuffer disabled. |
| // |
| |
| #include "ANGLEPerfTest.h" |
| #include "test_utils/gl_raii.h" |
| |
| #include <iostream> |
| #include <random> |
| #include <sstream> |
| |
| namespace angle |
| { |
| constexpr unsigned int kIterationsPerStep = 1; |
| constexpr unsigned int kTextureSize = 64; |
| constexpr std::size_t kTextureCount = 100; |
| |
| struct ImagelessFramebufferAttachmentParams final : public RenderTestParams |
| { |
| ImagelessFramebufferAttachmentParams() |
| { |
| iterationsPerStep = kIterationsPerStep; |
| |
| // Common default params |
| majorVersion = 3; |
| minorVersion = 0; |
| } |
| |
| std::string story() const override; |
| bool isImagelessFramebufferEnabled = false; |
| }; |
| |
| std::ostream &operator<<(std::ostream &os, const ImagelessFramebufferAttachmentParams ¶ms) |
| { |
| os << params.backendAndStory().substr(1); |
| return os; |
| } |
| |
| std::string ImagelessFramebufferAttachmentParams::story() const |
| { |
| std::stringstream strstr; |
| |
| strstr << RenderTestParams::story(); |
| strstr << (!isImagelessFramebufferEnabled ? "_imageless_framebuffer_disabled" : "_default"); |
| |
| return strstr.str(); |
| } |
| |
| class ImagelessFramebufferAttachmentBenchmark |
| : public ANGLERenderTest, |
| public ::testing::WithParamInterface<ImagelessFramebufferAttachmentParams> |
| { |
| public: |
| ImagelessFramebufferAttachmentBenchmark() : ANGLERenderTest("ImagelessFramebuffers", GetParam()) |
| {} |
| void initializeBenchmark() override; |
| void drawBenchmark() override; |
| |
| protected: |
| std::array<GLTexture, kTextureCount> mTextures; |
| GLuint mProgram = 0; |
| }; |
| |
| void ImagelessFramebufferAttachmentBenchmark::initializeBenchmark() |
| { |
| constexpr char kVS[] = R"(void main() |
| { |
| gl_Position = vec4(0); |
| })"; |
| |
| constexpr char kFS[] = R"(void main(void) |
| { |
| gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); |
| })"; |
| |
| mProgram = CompileProgram(kVS, kFS); |
| ASSERT_NE(0u, mProgram); |
| glUseProgram(mProgram); |
| |
| for (GLTexture &texture : mTextures) |
| { |
| glBindTexture(GL_TEXTURE_2D, texture); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTextureSize, kTextureSize, 0, GL_RGBA, |
| GL_UNSIGNED_BYTE, nullptr); |
| } |
| } |
| |
| void ImagelessFramebufferAttachmentBenchmark::drawBenchmark() |
| { |
| const auto ¶ms = GetParam(); |
| |
| GLFramebuffer fbo; |
| |
| for (size_t it = 0; it < params.iterationsPerStep; ++it) |
| { |
| glBindFramebuffer(GL_FRAMEBUFFER, fbo); |
| for (size_t i = 0; i < kTextureCount; ++i) |
| { |
| for (size_t j = 0; j < kTextureCount; ++j) |
| { |
| if (j == i) |
| continue; |
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, |
| mTextures[i], 0); |
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, |
| mTextures[j], 0); |
| glDrawArrays(GL_POINTS, 0, 1); |
| } |
| } |
| } |
| |
| ASSERT_GL_NO_ERROR(); |
| } |
| |
| ImagelessFramebufferAttachmentParams ImagelessVulkanEnabledParams() |
| { |
| ImagelessFramebufferAttachmentParams params; |
| params.eglParameters = egl_platform::VULKAN().disable(Feature::PreferSubmitAtFBOBoundary); |
| params.isImagelessFramebufferEnabled = true; |
| |
| return params; |
| } |
| |
| ImagelessFramebufferAttachmentParams ImagelessVulkanDisabledParams() |
| { |
| ImagelessFramebufferAttachmentParams params; |
| params.eglParameters = egl_platform::VULKAN() |
| .disable(Feature::PreferSubmitAtFBOBoundary) |
| .disable(Feature::SupportsImagelessFramebuffer); |
| params.isImagelessFramebufferEnabled = false; |
| |
| return params; |
| } |
| |
| // Runs tests to measure imageless framebuffer performance |
| TEST_P(ImagelessFramebufferAttachmentBenchmark, Run) |
| { |
| run(); |
| } |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImagelessFramebufferAttachmentBenchmark); |
| ANGLE_INSTANTIATE_TEST(ImagelessFramebufferAttachmentBenchmark, |
| ImagelessVulkanEnabledParams(), |
| ImagelessVulkanDisabledParams()); |
| |
| } // namespace angle |