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;
114 case vk::ImageLayout::eColorAttachmentOptimal:
116 srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
117 srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
120 case vk::ImageLayout::eGeneral:
121 case vk::ImageLayout::eDepthStencilAttachmentOptimal:
122 case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
123 case vk::ImageLayout::eShaderReadOnlyOptimal:
124 case vk::ImageLayout::eTransferSrcOptimal:
125 case vk::ImageLayout::eTransferDstOptimal:
126 case vk::ImageLayout::ePreinitialized:
127 case vk::ImageLayout::eSharedPresentKHR:
134 case vk::ImageLayout::eColorAttachmentOptimal:
136 dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader;
137 dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eHostWrite;
140 case vk::ImageLayout::eDepthStencilAttachmentOptimal:
142 dstStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eEarlyFragmentTests;
143 dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
146 case vk::ImageLayout::ePresentSrcKHR:
148 dstStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
149 dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eMemoryRead;
151 case vk::ImageLayout::eGeneral:
152 case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
153 case vk::ImageLayout::eShaderReadOnlyOptimal:
154 case vk::ImageLayout::eTransferSrcOptimal:
155 case vk::ImageLayout::eTransferDstOptimal:
156 case vk::ImageLayout::ePreinitialized:
157 case vk::ImageLayout::eUndefined:
158 case vk::ImageLayout::eSharedPresentKHR:
164 RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
165 oldLayout, newLayout, aspectMask);
168 #pragma GCC diagnostic push
169 #pragma GCC diagnostic ignored "-Wframe-larger-than="
170 void CommandBuffer::RecordImageLayoutTransition(vk::Image image, vk::AccessFlags srcAccessMask,
171 vk::AccessFlags dstAccessMask, vk::PipelineStageFlags srcStageMask,
172 vk::PipelineStageFlags dstStageMask, vk::ImageLayout oldLayout,
173 vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask)
175 vk::ImageSubresourceRange subres;
176 subres.setLayerCount(1).setBaseMipLevel(0).setBaseArrayLayer(0).setLevelCount(1).setAspectMask(aspectMask);
179 auto barrier = vk::ImageMemoryBarrier{};
182 .setSubresourceRange(subres)
183 .setSrcAccessMask(srcAccessMask)
184 .setDstAccessMask(dstAccessMask)
185 .setOldLayout(oldLayout)
186 .setNewLayout(newLayout);
188 // todo: implement barriers batching
189 mCommandBuffer.pipelineBarrier(srcStageMask, dstStageMask, vk::DependencyFlags{}, nullptr, nullptr, barrier);
191 #pragma GCC diagnostic pop
193 /** Push wait semaphores */
194 void CommandBuffer::PushWaitSemaphores(const std::vector< vk::Semaphore >& semaphores,
195 const std::vector< vk::PipelineStageFlags >& stages)
197 mWaitSemaphores = semaphores;
198 mWaitStages = stages;
201 /** Push signal semaphores */
202 void CommandBuffer::PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
204 mSignalSemaphores = semaphores;
207 } // namespace Vulkan
208 } // namespace Graphics