Vulkan renderer backend (#2564)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
This commit is contained in:
Adrian Cojocaru
2024-08-01 22:49:49 +03:00
committed by GitHub
parent 88993b9420
commit 072aa32e8b
103 changed files with 11459 additions and 135 deletions

View File

@@ -0,0 +1,48 @@
#pragma once
#include <mbgl/gfx/headless_backend.hpp>
#include <mbgl/vulkan/renderer_backend.hpp>
#include <memory>
#include <functional>
namespace mbgl {
namespace vulkan {
class Texture2D;
class HeadlessBackend final : public vulkan::RendererBackend, public gfx::HeadlessBackend {
public:
HeadlessBackend(Size = {256, 256},
SwapBehaviour = SwapBehaviour::NoFlush,
gfx::ContextMode = gfx::ContextMode::Unique);
~HeadlessBackend() override;
gfx::Renderable& getDefaultRenderable() override;
PremultipliedImage readStillImage() override;
RendererBackend* getRendererBackend() override;
void swap();
class Impl {
public:
virtual ~Impl() = default;
virtual bool glNeedsActiveContextOnDestruction() const { return false; }
virtual void activateContext() {}
virtual void deactivateContext() {}
virtual void getContext() {}
};
private:
void activate() override;
void deactivate() override;
void createImpl();
private:
std::unique_ptr<Impl> impl;
bool active = false;
std::unique_ptr<Texture2D> texture;
};
} // namespace vulkan
} // namespace mbgl

View File

@@ -0,0 +1,113 @@
#include <mbgl/vulkan/headless_backend.hpp>
#include <mbgl/vulkan/renderable_resource.hpp>
#include <mbgl/vulkan/context.hpp>
#include <mbgl/vulkan/texture2d.hpp>
#include <mbgl/gfx/backend_scope.hpp>
#include <cassert>
#include <stdexcept>
#include <type_traits>
namespace mbgl {
namespace vulkan {
class HeadlessRenderableResource final : public vulkan::SurfaceRenderableResource {
public:
HeadlessRenderableResource(HeadlessBackend& backend_)
: SurfaceRenderableResource(backend_) {
if (backend_.getDevice() && !renderPass) {
init(backend_.getSize().width, backend_.getSize().height);
}
}
~HeadlessRenderableResource() noexcept override = default;
void createPlatformSurface() override {}
void bind() override {}
};
HeadlessBackend::HeadlessBackend(const Size size_,
gfx::HeadlessBackend::SwapBehaviour,
const gfx::ContextMode contextMode_)
: mbgl::vulkan::RendererBackend(contextMode_),
mbgl::gfx::HeadlessBackend(size_) {
init();
}
HeadlessBackend::~HeadlessBackend() {
gfx::BackendScope guard{*this, gfx::BackendScope::ScopeType::Implicit};
texture.reset();
// Explicitly reset the renderable resource
resource.reset();
// Explicitly reset the context so that it is destructed and cleaned up
// before we destruct the impl object.
getThreadPool().runRenderJobs(true /* closeQueue */);
context.reset();
}
void HeadlessBackend::activate() {
active = true;
if (!impl) {
createImpl();
}
assert(impl);
}
void HeadlessBackend::deactivate() {
assert(impl);
active = false;
}
gfx::Renderable& HeadlessBackend::getDefaultRenderable() {
if (!resource) {
resource = std::make_unique<HeadlessRenderableResource>(*this);
}
return *this;
}
void HeadlessBackend::swap() {
static_cast<Context&>(*context).waitFrame();
}
PremultipliedImage HeadlessBackend::readStillImage() {
auto& contextImpl = static_cast<Context&>(*context);
auto& resourceImpl = static_cast<HeadlessRenderableResource&>(*resource);
if (!texture) {
texture = std::make_unique<Texture2D>(contextImpl);
texture->setFormat(gfx::TexturePixelType::RGBA, gfx::TextureChannelDataType::UnsignedByte);
texture->setSize(size);
texture->setUsage(Texture2DUsage::Read);
}
contextImpl.waitFrame();
texture->copyImage(resourceImpl.getAcquiredImage());
return std::move(*texture->readImage());
}
RendererBackend* HeadlessBackend::getRendererBackend() {
return this;
}
void HeadlessBackend::createImpl() {
assert(!impl);
impl = std::make_unique<Impl>();
}
} // namespace vulkan
namespace gfx {
template <>
std::unique_ptr<gfx::HeadlessBackend> Backend::Create<gfx::Backend::Type::Vulkan>(
const Size size, gfx::Renderable::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode) {
return std::make_unique<vulkan::HeadlessBackend>(size, swapBehavior, contextMode);
}
} // namespace gfx
} // namespace mbgl