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,SecondaryCommandPool * pool,uint32_t queueFamilyIndex,ProtectionType protectionType)20 angle::Result VulkanSecondaryCommandBuffer::InitializeCommandPool(Context *context,
21 SecondaryCommandPool *pool,
22 uint32_t queueFamilyIndex,
23 ProtectionType protectionType)
24 {
25 ANGLE_TRY(pool->init(context, queueFamilyIndex, protectionType));
26 return angle::Result::Continue;
27 }
28
InitializeRenderPassInheritanceInfo(ContextVk * contextVk,const Framebuffer & framebuffer,const RenderPassDesc & renderPassDesc,VkCommandBufferInheritanceInfo * inheritanceInfoOut,VkCommandBufferInheritanceRenderingInfo * renderingInfoOut,gl::DrawBuffersArray<VkFormat> * colorFormatStorageOut)29 angle::Result VulkanSecondaryCommandBuffer::InitializeRenderPassInheritanceInfo(
30 ContextVk *contextVk,
31 const Framebuffer &framebuffer,
32 const RenderPassDesc &renderPassDesc,
33 VkCommandBufferInheritanceInfo *inheritanceInfoOut,
34 VkCommandBufferInheritanceRenderingInfo *renderingInfoOut,
35 gl::DrawBuffersArray<VkFormat> *colorFormatStorageOut)
36 {
37 *inheritanceInfoOut = {};
38 inheritanceInfoOut->sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
39
40 if (contextVk->getFeatures().preferDynamicRendering.enabled)
41 {
42 renderPassDesc.populateRenderingInheritanceInfo(contextVk->getRenderer(), renderingInfoOut,
43 colorFormatStorageOut);
44 AddToPNextChain(inheritanceInfoOut, renderingInfoOut);
45 }
46 else
47 {
48 const RenderPass *compatibleRenderPass = nullptr;
49 ANGLE_TRY(contextVk->getCompatibleRenderPass(renderPassDesc, &compatibleRenderPass));
50 inheritanceInfoOut->renderPass = compatibleRenderPass->getHandle();
51 inheritanceInfoOut->subpass = 0;
52 inheritanceInfoOut->framebuffer = framebuffer.getHandle();
53 }
54
55 return angle::Result::Continue;
56 }
57
initialize(Context * context,SecondaryCommandPool * pool,bool isRenderPassCommandBuffer,SecondaryCommandMemoryAllocator * allocator)58 angle::Result VulkanSecondaryCommandBuffer::initialize(Context *context,
59 SecondaryCommandPool *pool,
60 bool isRenderPassCommandBuffer,
61 SecondaryCommandMemoryAllocator *allocator)
62 {
63 mCommandPool = pool;
64 mCommandTracker.reset();
65 mAnyCommand = false;
66
67 ANGLE_TRY(pool->allocate(context, this));
68
69 // Outside-RP command buffers are begun automatically here. RP command buffers are begun when
70 // the render pass itself starts, as they require inheritance info.
71 if (!isRenderPassCommandBuffer)
72 {
73 VkCommandBufferInheritanceInfo inheritanceInfo = {};
74 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
75 ANGLE_TRY(begin(context, inheritanceInfo));
76 }
77
78 return angle::Result::Continue;
79 }
80
destroy()81 void VulkanSecondaryCommandBuffer::destroy()
82 {
83 if (valid())
84 {
85 ASSERT(mCommandPool != nullptr);
86 mCommandPool->collect(this);
87 }
88 }
89
begin(Context * context,const VkCommandBufferInheritanceInfo & inheritanceInfo)90 angle::Result VulkanSecondaryCommandBuffer::begin(
91 Context *context,
92 const VkCommandBufferInheritanceInfo &inheritanceInfo)
93 {
94 ASSERT(!mAnyCommand);
95
96 VkCommandBufferBeginInfo beginInfo = {};
97 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
98 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
99 beginInfo.pInheritanceInfo = &inheritanceInfo;
100 // For render pass command buffers, specify that the command buffer is entirely inside a render
101 // pass. This is determined by either the render pass object existing, or the
102 // VkCommandBufferInheritanceRenderingInfo specified in the pNext chain.
103 if (inheritanceInfo.renderPass != VK_NULL_HANDLE || inheritanceInfo.pNext != nullptr)
104 {
105 beginInfo.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
106 }
107
108 ANGLE_VK_TRY(context, CommandBuffer::begin(beginInfo));
109 return angle::Result::Continue;
110 }
111
end(Context * context)112 angle::Result VulkanSecondaryCommandBuffer::end(Context *context)
113 {
114 ANGLE_VK_TRY(context, CommandBuffer::end());
115 return angle::Result::Continue;
116 }
117
reset()118 VkResult VulkanSecondaryCommandBuffer::reset()
119 {
120 mCommandTracker.reset();
121 mAnyCommand = false;
122 return CommandBuffer::reset();
123 }
124 } // namespace vk
125 } // namespace rx
126