blob: 6db5c36c2c3911abf152ed9070527ef7b5ef9859 [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 <utility>
#include "flutter/fml/logging.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/backend/vulkan/context_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,
vk::Device device,
vk::CommandPool command_pool,
SurfaceProducerVK* surface_producer) {
vk::CommandBufferAllocateInfo allocate_info;
allocate_info.setLevel(vk::CommandBufferLevel::ePrimary);
allocate_info.setCommandBufferCount(1);
allocate_info.setCommandPool(command_pool);
auto res = device.allocateCommandBuffersUnique(allocate_info);
if (res.result != vk::Result::eSuccess) {
VALIDATION_LOG << "Failed to allocate command buffer: "
<< vk::to_string(res.result);
return nullptr;
}
vk::UniqueCommandBuffer cmd = std::move(res.value[0]);
return std::make_shared<CommandBufferVK>(context, device, surface_producer,
command_pool, std::move(cmd));
}
CommandBufferVK::CommandBufferVK(std::weak_ptr<const Context> context,
vk::Device device,
SurfaceProducerVK* surface_producer,
vk::CommandPool command_pool,
vk::UniqueCommandBuffer command_buffer)
: CommandBuffer(std::move(context)),
device_(device),
command_pool_(command_pool),
command_buffer_(std::move(command_buffer)),
surface_producer_(surface_producer) {
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(*command_buffer_, label);
}
}
bool CommandBufferVK::IsValid() const {
return is_valid_;
}
bool CommandBufferVK::OnSubmitCommands(CompletionCallback callback) {
// TODO(https://github.com/flutter/flutter/issues/112387)
// This needs to be the place where the command buffer, renderpass,
// and the various descriptor sets in use by the command buffer are
// disposed of.
if (callback) {
callback(CommandBuffer::Status::kCompleted);
}
return true;
}
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_.createRenderPassUnique(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;
}
return std::make_shared<RenderPassVK>(
context_, device_, std::move(target), std::move(command_buffer_),
std::move(render_pass_create_res.value), surface_producer_);
}
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