blob: 98f1e86fd806e516e90cc01c0ce664094c30be1f [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/renderer/backend/vulkan/command_buffer_vk.h"
#include <memory>
#include <utility>
#include "flutter/fml/logging.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/fenced_command_buffer_vk.h"
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/render_pass_vk.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/render_target.h"
namespace impeller {
std::shared_ptr<CommandBufferVK> CommandBufferVK::Create(
const std::weak_ptr<const Context>& context_arg,
vk::Device device) {
if (auto context = context_arg.lock()) {
auto context_vk = reinterpret_cast<const ContextVK*>(context.get());
auto queue = context_vk->GetGraphicsQueue();
auto command_pool = context_vk->CreateGraphicsCommandPool();
auto fenced_command_buffer = std::make_shared<FencedCommandBufferVK>(
device, queue, command_pool->Get());
return std::make_shared<CommandBufferVK>(
context, device, std::move(command_pool), fenced_command_buffer);
} else {
return nullptr;
}
}
CommandBufferVK::CommandBufferVK(
std::weak_ptr<const Context> context,
vk::Device device,
std::unique_ptr<CommandPoolVK> command_pool,
std::shared_ptr<FencedCommandBufferVK> command_buffer)
: CommandBuffer(std::move(context)),
device_(device),
command_pool_(std::move(command_pool)),
fenced_command_buffer_(std::move(command_buffer)) {
is_valid_ = true;
}
CommandBufferVK::~CommandBufferVK() = default;
void CommandBufferVK::SetLabel(const std::string& label) const {
if (auto context = context_.lock()) {
reinterpret_cast<const ContextVK*>(context.get())
->SetDebugName(fenced_command_buffer_->Get(), label);
}
}
bool CommandBufferVK::IsValid() const {
return is_valid_;
}
bool CommandBufferVK::OnSubmitCommands(CompletionCallback callback) {
bool submit = fenced_command_buffer_->Submit();
if (callback) {
callback(submit ? CommandBuffer::Status::kCompleted
: CommandBuffer::Status::kError);
}
return submit;
}
std::shared_ptr<RenderPass> CommandBufferVK::OnCreateRenderPass(
RenderTarget target) {
std::vector<vk::AttachmentDescription> color_attachments;
for (const auto& [k, attachment] : target.GetColorAttachments()) {
const TextureDescriptor& tex_desc =
attachment.texture->GetTextureDescriptor();
vk::AttachmentDescription color_attachment;
color_attachment.setFormat(ToVKImageFormat(tex_desc.format));
color_attachment.setSamples(ToVKSampleCountFlagBits(tex_desc.sample_count));
color_attachment.setLoadOp(ToVKAttachmentLoadOp(attachment.load_action));
color_attachment.setStoreOp(ToVKAttachmentStoreOp(attachment.store_action));
color_attachment.setStencilLoadOp(vk::AttachmentLoadOp::eDontCare);
color_attachment.setStencilStoreOp(vk::AttachmentStoreOp::eDontCare);
color_attachment.setInitialLayout(vk::ImageLayout::eColorAttachmentOptimal);
color_attachment.setFinalLayout(vk::ImageLayout::ePresentSrcKHR);
color_attachments.push_back(color_attachment);
}
// TODO (kaushikiska): support depth and stencil attachments.
vk::AttachmentReference color_attachment_ref;
color_attachment_ref.setAttachment(0);
color_attachment_ref.setLayout(vk::ImageLayout::eColorAttachmentOptimal);
vk::SubpassDescription subpass_desc;
subpass_desc.setPipelineBindPoint(vk::PipelineBindPoint::eGraphics);
subpass_desc.setColorAttachmentCount(color_attachments.size());
subpass_desc.setPColorAttachments(&color_attachment_ref);
vk::RenderPassCreateInfo render_pass_create;
render_pass_create.setAttachmentCount(color_attachments.size());
render_pass_create.setPAttachments(color_attachments.data());
render_pass_create.setSubpassCount(1);
render_pass_create.setPSubpasses(&subpass_desc);
auto render_pass_create_res = device_.createRenderPass(render_pass_create);
if (render_pass_create_res.result != vk::Result::eSuccess) {
VALIDATION_LOG << "Failed to create render pass: "
<< vk::to_string(render_pass_create_res.result);
return nullptr;
}
vk::RenderPass render_pass = render_pass_create_res.value;
return std::make_shared<RenderPassVK>(context_, device_, std::move(target),
fenced_command_buffer_, render_pass);
}
std::shared_ptr<BlitPass> CommandBufferVK::OnCreateBlitPass() const {
// TODO(kaushikiska): https://github.com/flutter/flutter/issues/112649
return nullptr;
}
std::shared_ptr<ComputePass> CommandBufferVK::OnCreateComputePass() const {
// TODO(dnfield): https://github.com/flutter/flutter/issues/110622
VALIDATION_LOG << "ComputePasses unimplemented for Vulkan";
return nullptr;
}
} // namespace impeller