| // 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_; |
| } |