blob: 6e6096a8412c65124e2dfbed7cd752ff943c9bfc [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,
vk::CommandPool command_pool) {
if (auto context = context_arg.lock()) {
auto queue =
reinterpret_cast<const ContextVK*>(context.get())->GetGraphicsQueue();
auto fenced_command_buffer =
std::make_shared<FencedCommandBufferVK>(device, queue, command_pool);
return std::make_shared<CommandBufferVK>(context, device, command_pool,
fenced_command_buffer);
} else {
return nullptr;
}
}
CommandBufferVK::CommandBufferVK(
std::weak_ptr<const Context> context,
vk::Device device,
vk::CommandPool command_pool,
std::shared_ptr<FencedCommandBufferVK> command_buffer)
: CommandBuffer(std::move(context)),
device_(device),
command_pool_(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