blob: ad9109d0959646738dc59e1d3e7773e0145c8dbd [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 "vulkan_command_buffers.h"
#include "utils.h"
VulkanCommandBuffers::VulkanCommandBuffers(std::shared_ptr<VulkanLogicalDevice> device,
std::shared_ptr<VulkanCommandPool> command_pool,
const VulkanFramebuffer &framebuffer,
const vk::Extent2D &extent,
const vk::RenderPass &render_pass,
const vk::Pipeline &graphics_pipeline)
: initialized_(false),
device_(device),
command_pool_(command_pool),
command_buffers_(framebuffer.framebuffers().size()) {
params_ = std::make_unique<InitParams>(framebuffer, extent, render_pass, graphics_pipeline);
}
VulkanCommandBuffers::InitParams::InitParams(const VulkanFramebuffer &framebuffer,
const vk::Extent2D &extent,
const vk::RenderPass &render_pass,
const vk::Pipeline &graphics_pipeline)
: framebuffer_(framebuffer),
extent_(extent),
render_pass_(render_pass),
graphics_pipeline_(graphics_pipeline) {}
bool VulkanCommandBuffers::Init() {
if (initialized_) {
RTN_MSG(false, "VulkanCommandBuffers already initialized.\n");
}
vk::CommandBufferAllocateInfo alloc_info;
alloc_info.setCommandBufferCount(static_cast<uint32_t>(command_buffers_.size()));
alloc_info.setCommandPool(*command_pool_->command_pool());
alloc_info.level = vk::CommandBufferLevel::ePrimary;
auto rv_alloc = device_->device()->allocateCommandBuffersUnique(alloc_info);
if (vk::Result::eSuccess != rv_alloc.result) {
RTN_MSG(false, "VK Error: 0x%x - Failed to allocate command buffers.", rv_alloc.result);
}
command_buffers_ = std::move(rv_alloc.value);
vk::ClearValue clear_color;
clear_color.setColor(std::array<float, 4>({0.5f, 0.0f, 0.5f, 1.0f}));
auto framebuffer_iter = params_->framebuffer_.framebuffers().begin();
for (const auto &command_buffer : command_buffers_) {
const auto &framebuffer = *(framebuffer_iter++);
vk::CommandBufferBeginInfo begin_info(vk::CommandBufferUsageFlagBits::eSimultaneousUse);
auto result = command_buffer->begin(&begin_info);
if (vk::Result::eSuccess != result) {
RTN_MSG(false, "VK Error: 0x%x - Failed to begin command buffer.", result);
}
vk::Rect2D render_area;
render_area.extent = params_->extent_;
vk::RenderPassBeginInfo render_pass_info;
render_pass_info.renderPass = params_->render_pass_;
render_pass_info.framebuffer = *framebuffer;
render_pass_info.renderArea = render_area;
render_pass_info.clearValueCount = 1;
render_pass_info.pClearValues = &clear_color;
// Record commands to render pass.
command_buffer->beginRenderPass(&render_pass_info, vk::SubpassContents::eInline);
command_buffer->bindPipeline(vk::PipelineBindPoint::eGraphics, params_->graphics_pipeline_);
command_buffer->draw(3 /* vertexCount */, 1 /* instanceCount */, 0 /* firstVertex */,
0 /* firstInstance */);
command_buffer->endRenderPass();
command_buffer->end();
}
params_.reset();
initialized_ = true;
return true;
}
const std::vector<vk::UniqueCommandBuffer> &VulkanCommandBuffers::command_buffers() const {
return command_buffers_;
}