Hash :
c19ec948
Author :
Date :
2022-08-23T10:43:59
Vulkan: Implement imageless framebuffers
* Added the attachment image and create info objects to be used
for imageless framebuffers created in getFramebuffer().
* New helper class for framebuffers in RenderPassCommandBufferHelper:
MaybeImagelessFramebuffer, which includes a framebuffer object, if
the framebuffer is imageless, and the image views. This is to make
sure that the args for render pass begin info will be correctly set
up according to the status of the used framebuffer.
* Refactored the collection of attachments in getFramebuffer() into
a new function, getAttachmentsAndImagesFromRenderTargets(). It also
returns their corresponding ImageHelper* objects used to create the
framebuffer (from their image properties).
* New struct: RenderTargetInfo; which keeps track of render targets
and whether resolve image should be used for the render pass in the
form of the enum class RenderTargetImage.
* Added a new arg to getFramebuffer(): resolveRenderTargetIn; to use
when there is a valid resolveImageViewIn.
* Without using the framebuffer cache, we would require to handle
the framebuffer destruction by adding it to the garbage instead
of releasing it. For example, FramebufferVk::destroy() now adds
mCurrentFramebuffer to the garbage.
* Added new framebuffer unit tests.
* Added tests where two textures with different attributes are bound
to the same framebuffer before drawing, one after another.
* Added test where a blit occurs from a multisample texture into a
non-zero level of a resolve texture, each bound to a separate FBO.
* Added a new perf test to compare performance for enabled imageless
framebuffers vs disabled. (Credit: cclao)
Bug: angleproject:7553
Change-Id: Iacdbd73aaa01cbb0e37abf01ae4892bdfdd4b12f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3827644
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Amirali Abdolrashidi <abdolrashidi@google.com>
Reviewed-by: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
//
// 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