xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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