1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // VulkanSecondaryCommandBuffer:
7 // Implementation of VulkanSecondaryCommandBuffer.
8 //
9
10 #include "libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.h"
11
12 #include "common/debug.h"
13 #include "libANGLE/renderer/vulkan/ContextVk.h"
14 #include "libANGLE/renderer/vulkan/vk_utils.h"
15
16 namespace rx
17 {
18 namespace vk
19 {
InitializeCommandPool(Context * context,CommandPool * pool,uint32_t queueFamilyIndex,bool hasProtectedContent)20 angle::Result VulkanSecondaryCommandBuffer::InitializeCommandPool(Context *context,
21 CommandPool *pool,
22 uint32_t queueFamilyIndex,
23 bool hasProtectedContent)
24 {
25 VkCommandPoolCreateInfo poolInfo = {};
26 poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
27 poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
28 poolInfo.queueFamilyIndex = queueFamilyIndex;
29 if (hasProtectedContent)
30 {
31 poolInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
32 }
33 ANGLE_VK_TRY(context, pool->init(context->getDevice(), poolInfo));
34 return angle::Result::Continue;
35 }
36
InitializeRenderPassInheritanceInfo(ContextVk * contextVk,const Framebuffer & framebuffer,const RenderPassDesc & renderPassDesc,VkCommandBufferInheritanceInfo * inheritanceInfoOut)37 angle::Result VulkanSecondaryCommandBuffer::InitializeRenderPassInheritanceInfo(
38 ContextVk *contextVk,
39 const Framebuffer &framebuffer,
40 const RenderPassDesc &renderPassDesc,
41 VkCommandBufferInheritanceInfo *inheritanceInfoOut)
42 {
43 vk::RenderPass *compatibleRenderPass = nullptr;
44 ANGLE_TRY(contextVk->getCompatibleRenderPass(renderPassDesc, &compatibleRenderPass));
45
46 inheritanceInfoOut->sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
47 inheritanceInfoOut->renderPass = compatibleRenderPass->getHandle();
48 inheritanceInfoOut->subpass = 0;
49 inheritanceInfoOut->framebuffer = framebuffer.getHandle();
50
51 return angle::Result::Continue;
52 }
53
initialize(Context * context,vk::CommandPool * pool,bool isRenderPassCommandBuffer,angle::PoolAllocator * allocator)54 angle::Result VulkanSecondaryCommandBuffer::initialize(Context *context,
55 vk::CommandPool *pool,
56 bool isRenderPassCommandBuffer,
57 angle::PoolAllocator *allocator)
58 {
59 VkDevice device = context->getDevice();
60
61 mCommandTracker.reset();
62 mAnyCommand = false;
63
64 VkCommandBufferAllocateInfo allocInfo = {};
65 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
66 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
67 allocInfo.commandBufferCount = 1;
68 allocInfo.commandPool = pool->getHandle();
69
70 ANGLE_VK_TRY(context, init(device, allocInfo));
71
72 // Outside-RP command buffers are begun automatically here. RP command buffers are begun when
73 // the render pass itself starts, as they require inheritence info.
74 if (!isRenderPassCommandBuffer)
75 {
76 VkCommandBufferInheritanceInfo inheritanceInfo = {};
77 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
78 ANGLE_TRY(begin(context, inheritanceInfo));
79 }
80
81 return angle::Result::Continue;
82 }
83
begin(Context * context,const VkCommandBufferInheritanceInfo & inheritanceInfo)84 angle::Result VulkanSecondaryCommandBuffer::begin(
85 Context *context,
86 const VkCommandBufferInheritanceInfo &inheritanceInfo)
87 {
88 ASSERT(!mAnyCommand);
89
90 VkCommandBufferBeginInfo beginInfo = {};
91 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
92 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
93 beginInfo.pInheritanceInfo = &inheritanceInfo;
94 if (inheritanceInfo.renderPass != VK_NULL_HANDLE)
95 {
96 beginInfo.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
97 }
98
99 ANGLE_VK_TRY(context, CommandBuffer::begin(beginInfo));
100 return angle::Result::Continue;
101 }
102
end(Context * context)103 angle::Result VulkanSecondaryCommandBuffer::end(Context *context)
104 {
105 ANGLE_VK_TRY(context, CommandBuffer::end());
106 return angle::Result::Continue;
107 }
108
reset()109 VkResult VulkanSecondaryCommandBuffer::reset()
110 {
111 mCommandTracker.reset();
112 mAnyCommand = false;
113 return CommandBuffer::reset();
114 }
115 } // namespace vk
116 } // namespace rx
117