2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/graphics/vulkan/vulkan-command-buffer.h>
20 #include <dali/graphics/vulkan/vulkan-command-pool.h>
21 #include <dali/graphics/vulkan/vulkan-graphics.h>
30 CommandBuffer::CommandBuffer(Graphics& graphics, CommandPool& ownerPool)
31 : CommandBuffer(graphics, ownerPool,
32 vk::CommandBufferAllocateInfo().setCommandBufferCount(1).setLevel(vk::CommandBufferLevel::ePrimary))
36 CommandBuffer::CommandBuffer(Graphics& graphics, CommandPool& ownerPool,
37 const vk::CommandBufferAllocateInfo& allocateInfo)
38 : mGraphics(graphics), mCommandPool(ownerPool), mRecording(false)
40 assert(allocateInfo.commandBufferCount == 1 && "Number of buffers to allocate must be equal 1!");
41 mCommandBuffer = VkAssert(mGraphics.GetDevice().allocateCommandBuffers(allocateInfo))[0];
44 CommandBuffer::~CommandBuffer()
48 mGraphics.GetDevice().freeCommandBuffers(mCommandPool.GetPool(), mCommandBuffer);
52 /** Begin recording */
53 void CommandBuffer::Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
55 assert(!mRecording && "CommandBuffer already is in the recording state");
56 auto info = vk::CommandBufferBeginInfo{};
57 info.setPInheritanceInfo(inheritanceInfo);
58 info.setFlags(usageFlags);
59 VkAssert(mCommandBuffer.begin(info));
63 /** Finish recording */
64 void CommandBuffer::End()
66 assert(mRecording && "CommandBuffer is not in the recording state!");
67 VkAssert(mCommandBuffer.end());
71 /** Reset command buffer */
72 void CommandBuffer::Reset()
74 assert(!mRecording && "Can't reset command buffer during recording!");
75 assert(mCommandBuffer && "Invalid command buffer!");
76 mCommandBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources);
79 /** Free command buffer */
80 void CommandBuffer::Free()
82 assert(mCommandBuffer && "Invalid command buffer!");
83 mGraphics.GetDevice().freeCommandBuffers(mCommandPool.GetPool(), mCommandBuffer);
86 /** Records image layout transition barrier for one image */
87 void CommandBuffer::ImageLayoutTransition(vk::Image image,
88 vk::ImageLayout oldLayout,
89 vk::ImageLayout newLayout,
90 vk::ImageAspectFlags aspectMask)
92 // must be in recording state
94 // just push new image barrier until any command is being called or buffer recording ends.
95 // it will make sure we batch barriers together rather than calling cmdPipelineBarrier
96 // for each separately
97 vk::AccessFlags srcAccessMask, dstAccessMask;
98 vk::PipelineStageFlags srcStageMask, dstStageMask;
100 // TODO: add other transitions
103 case vk::ImageLayout::eUndefined:
105 srcStageMask = vk::PipelineStageFlagBits::eTopOfPipe;
108 case vk::ImageLayout::ePresentSrcKHR:
110 srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
111 srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
113 case vk::ImageLayout::eColorAttachmentOptimal:
115 srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
116 srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
119 case vk::ImageLayout::eGeneral:
120 case vk::ImageLayout::eDepthStencilAttachmentOptimal:
121 case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
122 case vk::ImageLayout::eShaderReadOnlyOptimal:
123 case vk::ImageLayout::eTransferSrcOptimal:
124 case vk::ImageLayout::eTransferDstOptimal:
125 case vk::ImageLayout::ePreinitialized:
133 case vk::ImageLayout::eColorAttachmentOptimal:
135 dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader;
136 dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eHostWrite;
139 case vk::ImageLayout::eDepthStencilAttachmentOptimal:
141 dstStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eEarlyFragmentTests;
142 dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
145 case vk::ImageLayout::ePresentSrcKHR:
147 dstStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
148 dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eMemoryRead;
150 case vk::ImageLayout::eGeneral:
151 case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
152 case vk::ImageLayout::eShaderReadOnlyOptimal:
153 case vk::ImageLayout::eTransferSrcOptimal:
154 case vk::ImageLayout::eTransferDstOptimal:
155 case vk::ImageLayout::ePreinitialized:
156 case vk::ImageLayout::eUndefined:
162 RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
163 oldLayout, newLayout, aspectMask);
166 #pragma GCC diagnostic push
167 #pragma GCC diagnostic ignored "-Wframe-larger-than="
168 void CommandBuffer::RecordImageLayoutTransition(vk::Image image, vk::AccessFlags srcAccessMask,
169 vk::AccessFlags dstAccessMask, vk::PipelineStageFlags srcStageMask,
170 vk::PipelineStageFlags dstStageMask, vk::ImageLayout oldLayout,
171 vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask)
173 vk::ImageSubresourceRange subres;
174 subres.setLayerCount(1).setBaseMipLevel(0).setBaseArrayLayer(0).setLevelCount(1).setAspectMask(aspectMask);
177 auto barrier = vk::ImageMemoryBarrier{};
180 .setSubresourceRange(subres)
181 .setSrcAccessMask(srcAccessMask)
182 .setDstAccessMask(dstAccessMask)
183 .setOldLayout(oldLayout)
184 .setNewLayout(newLayout);
186 // todo: implement barriers batching
187 mCommandBuffer.pipelineBarrier(srcStageMask, dstStageMask, vk::DependencyFlags{}, nullptr, nullptr, barrier);
189 #pragma GCC diagnostic pop
191 /** Push wait semaphores */
192 void CommandBuffer::PushWaitSemaphores(const std::vector< vk::Semaphore >& semaphores,
193 const std::vector< vk::PipelineStageFlags >& stages)
195 mWaitSemaphores = semaphores;
196 mWaitStages = stages;
199 /** Push signal semaphores */
200 void CommandBuffer::PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
202 mSignalSemaphores = semaphores;
205 } // namespace Vulkan
206 } // namespace Graphics